菜单优化

This commit is contained in:
Rowland 2026-07-02 10:33:09 +08:00
parent 758aa6ff83
commit 08d528c686
2 changed files with 278 additions and 265 deletions

View File

@ -1912,10 +1912,10 @@ void MetaCoreDrawMeshRendererMaterialSlotSummary(
std::size_t materialSlotIndex,
const MetaCoreAssetGuid& materialGuid
) {
ImGui::TextDisabled("Slot %d", static_cast<int>(materialSlotIndex));
ImGui::TextDisabled("槽位 %d", static_cast<int>(materialSlotIndex));
if (!materialGuid.IsValid()) {
ImGui::SameLine();
ImGui::TextDisabled("<None>");
ImGui::TextDisabled("<>");
return;
}
@ -1937,27 +1937,27 @@ void MetaCoreDrawMeshRendererMaterialSlotSummary(
if (resolvedMaterial.has_value()) {
ImGui::TextDisabled(
"Source: %s / %s",
"来源: %s / %s",
resolvedMaterial->SourceAsset.RelativePath.filename().string().c_str(),
resolvedMaterial->GeneratedKind.c_str()
);
}
ImGui::TextDisabled("Guid: %s", materialGuid.ToString().c_str());
ImGui::TextDisabled("GUID: %s", materialGuid.ToString().c_str());
if (materialAsset.has_value()) {
const std::string baseColorTexture = MetaCoreBuildTextureSlotSummary(
editorContext,
"BaseColor",
"基础颜色",
materialAsset->BaseColorTexture
);
const std::string normalTexture = MetaCoreBuildTextureSlotSummary(
editorContext,
"Normal",
"法线",
materialAsset->NormalTexture
);
const std::string metalRoughTexture = MetaCoreBuildTextureSlotSummary(
editorContext,
"MetalRough",
"金属粗糙度",
materialAsset->MetallicRoughnessTexture
);
@ -2377,7 +2377,7 @@ void MetaCoreDrawCameraComponentInspector(MetaCoreEditorContext& editorContext,
}
float backgroundAlpha = camera.BackgroundAlpha;
ImGui::DragFloat("背景 Alpha", &backgroundAlpha, 0.01F, 0.0F, 1.0F);
ImGui::DragFloat("背景透明度", &backgroundAlpha, 0.01F, 0.0F, 1.0F);
MetaCoreTrackComponentInspectorEdit(editorContext, "修改检查器属性", true);
if (ImGui::IsItemEdited()) {
MetaCoreApplyValueToSelectedObjects(
@ -2403,7 +2403,7 @@ void MetaCoreDrawLightComponentInspector(MetaCoreEditorContext& editorContext, M
const bool multiEdit = editorContext.GetSelectedObjectIds().size() > 1;
if (multiEdit) {
ImGui::TextDisabled("Multi-edit %zu objects", editorContext.GetSelectedObjectIds().size());
ImGui::TextDisabled("多选编辑 %zu 个对象", editorContext.GetSelectedObjectIds().size());
}
const auto sharedColor = MetaCoreGetSharedSelectedValue<glm::vec3>(
@ -2415,22 +2415,22 @@ void MetaCoreDrawLightComponentInspector(MetaCoreEditorContext& editorContext, M
);
glm::vec3 color = sharedColor.value_or(gameObject.GetComponent<MetaCoreLightComponent>().Color);
if (multiEdit && !sharedColor.has_value()) {
ImGui::TextDisabled("Color: Mixed");
ImGui::TextDisabled("颜色: 混合值");
}
if (prefabObject != nullptr && prefabObject->Light.has_value() &&
!MetaCoreNearlyEqualVec3(gameObject.GetComponent<MetaCoreLightComponent>().Color, prefabObject->Light->Color)) {
ImGui::TextColored(ImVec4(0.93F, 0.72F, 0.18F, 1.0F), "Color Overrides");
ImGui::TextColored(ImVec4(0.93F, 0.72F, 0.18F, 1.0F), "颜色已覆盖");
ImGui::SameLine();
if (ImGui::SmallButton("Apply##LightColor")) {
if (ImGui::SmallButton("应用##LightColor")) {
(void)MetaCoreApplySelectedPrefabField(editorContext, "Light", "color");
}
ImGui::SameLine();
if (ImGui::SmallButton("Revert##LightColor")) {
if (ImGui::SmallButton("回退##LightColor")) {
(void)MetaCoreRevertSelectedPrefabField(editorContext, "Light", "color");
color = prefabObject->Light->Color;
}
}
ImGui::ColorEdit3("Color", glm::value_ptr(color));
ImGui::ColorEdit3("颜色", glm::value_ptr(color));
MetaCoreTrackComponentInspectorEdit(editorContext, "修改检查器属性", true);
if (ImGui::IsItemEdited()) {
MetaCoreApplyValueToSelectedObjects(
@ -2451,22 +2451,22 @@ void MetaCoreDrawLightComponentInspector(MetaCoreEditorContext& editorContext, M
);
float intensity = sharedIntensity.value_or(gameObject.GetComponent<MetaCoreLightComponent>().Intensity);
if (multiEdit && !sharedIntensity.has_value()) {
ImGui::TextDisabled("Intensity: Mixed");
ImGui::TextDisabled("强度: 混合值");
}
if (prefabObject != nullptr && prefabObject->Light.has_value() &&
!MetaCoreNearlyEqual(gameObject.GetComponent<MetaCoreLightComponent>().Intensity, prefabObject->Light->Intensity)) {
ImGui::TextColored(ImVec4(0.93F, 0.72F, 0.18F, 1.0F), "Intensity Overrides");
ImGui::TextColored(ImVec4(0.93F, 0.72F, 0.18F, 1.0F), "强度已覆盖");
ImGui::SameLine();
if (ImGui::SmallButton("Apply##LightIntensity")) {
if (ImGui::SmallButton("应用##LightIntensity")) {
(void)MetaCoreApplySelectedPrefabField(editorContext, "Light", "intensity");
}
ImGui::SameLine();
if (ImGui::SmallButton("Revert##LightIntensity")) {
if (ImGui::SmallButton("回退##LightIntensity")) {
(void)MetaCoreRevertSelectedPrefabField(editorContext, "Light", "intensity");
intensity = prefabObject->Light->Intensity;
}
}
ImGui::DragFloat("Intensity", &intensity, 0.05F, 0.0F, 8.0F);
ImGui::DragFloat("强度", &intensity, 0.05F, 0.0F, 8.0F);
MetaCoreTrackComponentInspectorEdit(editorContext, "修改检查器属性", true);
if (ImGui::IsItemEdited()) {
MetaCoreApplyValueToSelectedObjects(
@ -2488,23 +2488,23 @@ void MetaCoreDrawLightComponentInspector(MetaCoreEditorContext& editorContext, M
);
bool isEnabled = sharedEnabled.value_or(gameObject.GetComponent<MetaCoreLightComponent>().Enabled);
if (multiEdit && !sharedEnabled.has_value()) {
ImGui::TextDisabled("Enabled: Mixed");
ImGui::TextDisabled("启用: 混合值");
}
// 处理 Prefab 覆盖标记以及应用和回退按钮
if (prefabObject != nullptr && prefabObject->Light.has_value() &&
gameObject.GetComponent<MetaCoreLightComponent>().Enabled != prefabObject->Light->Enabled) {
ImGui::TextColored(ImVec4(0.93F, 0.72F, 0.18F, 1.0F), "Enabled Overrides");
ImGui::TextColored(ImVec4(0.93F, 0.72F, 0.18F, 1.0F), "启用已覆盖");
ImGui::SameLine();
if (ImGui::SmallButton("Apply##LightEnabled")) {
if (ImGui::SmallButton("应用##LightEnabled")) {
(void)MetaCoreApplySelectedPrefabField(editorContext, "Light", "enabled");
}
ImGui::SameLine();
if (ImGui::SmallButton("Revert##LightEnabled")) {
if (ImGui::SmallButton("回退##LightEnabled")) {
(void)MetaCoreRevertSelectedPrefabField(editorContext, "Light", "enabled");
isEnabled = prefabObject->Light->Enabled;
}
}
ImGui::Checkbox("Enabled##Light", &isEnabled);
ImGui::Checkbox("启用##Light", &isEnabled);
MetaCoreTrackComponentInspectorEdit(editorContext, "修改检查器属性", false);
if (ImGui::IsItemEdited()) {
// 应用新的启用状态到所有选中的光源组件
@ -2637,9 +2637,9 @@ void MetaCoreDrawAnimatorComponentInspector(MetaCoreEditorContext& editorContext
if (animator.SourceModelAssetGuid.IsValid()) {
sourceLabel += " [" + animator.SourceModelAssetGuid.ToString() + "]";
}
ImGui::TextDisabled("Source: %s", sourceLabel.c_str());
ImGui::TextDisabled("来源: %s", sourceLabel.c_str());
if (modelDocument.has_value()) {
ImGui::TextDisabled("Clips: %d", static_cast<int>(modelDocument->Animations.size()));
ImGui::TextDisabled("动画片段: %d", static_cast<int>(modelDocument->Animations.size()));
} else {
ImGui::TextColored(ImVec4(0.95F, 0.55F, 0.20F, 1.0F), "模型动画元数据不可用");
}
@ -2676,8 +2676,8 @@ void MetaCoreDrawAnimatorComponentInspector(MetaCoreEditorContext& editorContext
};
drawPersistedBool("启用##Animator", &MetaCoreAnimatorComponent::Enabled);
drawPersistedBool("Play On Start", &MetaCoreAnimatorComponent::PlayOnStart);
drawPersistedBool("Loop", &MetaCoreAnimatorComponent::Loop);
drawPersistedBool("开始时播放", &MetaCoreAnimatorComponent::PlayOnStart);
drawPersistedBool("循环", &MetaCoreAnimatorComponent::Loop);
if (modelDocument.has_value() && !modelDocument->Animations.empty()) {
std::int32_t clipIndex = std::clamp<std::int32_t>(
@ -2687,20 +2687,20 @@ void MetaCoreDrawAnimatorComponentInspector(MetaCoreEditorContext& editorContext
);
const std::string currentClipLabel =
modelDocument->Animations[static_cast<std::size_t>(clipIndex)].Name.empty()
? ("Clip " + std::to_string(clipIndex))
? ("动画片段 " + std::to_string(clipIndex))
: modelDocument->Animations[static_cast<std::size_t>(clipIndex)].Name;
ImGui::SetNextItemWidth(-1);
if (ImGui::BeginCombo("Clip", currentClipLabel.c_str())) {
if (ImGui::BeginCombo("动画片段", currentClipLabel.c_str())) {
for (std::size_t index = 0; index < modelDocument->Animations.size(); ++index) {
const auto& clip = modelDocument->Animations[index];
const std::string label = clip.Name.empty()
? ("Clip " + std::to_string(index))
? ("动画片段 " + std::to_string(index))
: clip.Name;
const bool selected = static_cast<std::size_t>(clipIndex) == index;
if (ImGui::Selectable(label.c_str(), selected)) {
const auto newClipIndex = static_cast<std::int32_t>(index);
const std::string newClipName = clip.Name;
(void)editorContext.ExecuteSnapshotCommand("修改 Animator Clip", [&]() {
(void)editorContext.ExecuteSnapshotCommand("修改 Animator 动画片段", [&]() {
MetaCoreForEachSelectedGameObject(editorContext, [&](MetaCoreGameObject& selectedObject) {
if (!selectedObject.HasComponent<MetaCoreAnimatorComponent>()) {
return;
@ -2721,7 +2721,7 @@ void MetaCoreDrawAnimatorComponentInspector(MetaCoreEditorContext& editorContext
ImGui::EndCombo();
}
} else {
ImGui::TextDisabled("没有可播放动画 Clip");
ImGui::TextDisabled("没有可播放动画片段");
}
float speed = MetaCoreGetSharedSelectedValue<float>(
@ -2733,7 +2733,7 @@ void MetaCoreDrawAnimatorComponentInspector(MetaCoreEditorContext& editorContext
},
[](float lhs, float rhs) { return MetaCoreNearlyEqual(lhs, rhs); }
).value_or(animator.Speed);
ImGui::DragFloat("Speed", &speed, 0.05F, 0.0F, 8.0F);
ImGui::DragFloat("速度", &speed, 0.05F, 0.0F, 8.0F);
MetaCoreTrackComponentInspectorEdit(editorContext, "修改 Animator", true);
if (ImGui::IsItemEdited()) {
MetaCoreApplyValueToSelectedObjects(
@ -2752,7 +2752,7 @@ void MetaCoreDrawAnimatorComponentInspector(MetaCoreEditorContext& editorContext
float timeSeconds = std::max(0.0F, animator.RuntimeTimeSeconds);
const float sliderMax = durationSeconds > 0.0F ? durationSeconds : std::max(1.0F, timeSeconds);
if (ImGui::Button(animator.RuntimePlaying ? "Pause" : "Play")) {
if (ImGui::Button(animator.RuntimePlaying ? "暂停" : "播放")) {
const bool play = !animator.RuntimePlaying;
MetaCoreForEachSelectedGameObject(editorContext, [&](MetaCoreGameObject& selectedObject) {
if (!selectedObject.HasComponent<MetaCoreAnimatorComponent>()) {
@ -2767,7 +2767,7 @@ void MetaCoreDrawAnimatorComponentInspector(MetaCoreEditorContext& editorContext
editorContext.GetScene().IncrementRevision();
}
ImGui::SameLine();
if (ImGui::Button("Stop")) {
if (ImGui::Button("停止")) {
MetaCoreForEachSelectedGameObject(editorContext, [&](MetaCoreGameObject& selectedObject) {
if (!selectedObject.HasComponent<MetaCoreAnimatorComponent>()) {
return;
@ -2780,7 +2780,7 @@ void MetaCoreDrawAnimatorComponentInspector(MetaCoreEditorContext& editorContext
timeSeconds = 0.0F;
}
ImGui::SliderFloat("Time", &timeSeconds, 0.0F, sliderMax, "%.3f s");
ImGui::SliderFloat("时间", &timeSeconds, 0.0F, sliderMax, "%.3f s");
if (ImGui::IsItemEdited()) {
MetaCoreForEachSelectedGameObject(editorContext, [&](MetaCoreGameObject& selectedObject) {
if (!selectedObject.HasComponent<MetaCoreAnimatorComponent>()) {
@ -2799,7 +2799,7 @@ void MetaCoreDrawAnimatorComponentInspector(MetaCoreEditorContext& editorContext
}
if (durationSeconds > 0.0F) {
ImGui::TextDisabled("Duration: %.3f s", durationSeconds);
ImGui::TextDisabled("时长: %.3f s", durationSeconds);
}
}
@ -2870,7 +2870,7 @@ void MetaCoreDrawScriptComponentInspector(MetaCoreEditorContext& editorContext,
}
if (open) {
ImGui::TextDisabled("TypeId: %s", instance.ScriptTypeId.empty() ? "<empty>" : instance.ScriptTypeId.c_str());
ImGui::TextDisabled("类型 ID: %s", instance.ScriptTypeId.empty() ? "<>" : instance.ScriptTypeId.c_str());
bool enabled = instance.Enabled;
ImGui::Checkbox("启用", &enabled);
@ -3196,7 +3196,7 @@ void MetaCoreDrawUiRendererComponentInspector(MetaCoreEditorContext& editorConte
editorContext.GetScene().IncrementRevision();
}
ImGui::TextDisabled("2D 使用屏幕空间层级3D 使用对象 Transform、世界尺寸和每单位像素。");
ImGui::TextDisabled("2D 使用屏幕空间层级3D 使用对象变换、世界尺寸和每单位像素。");
}
void MetaCoreDrawMeshRendererComponentInspector(MetaCoreEditorContext& editorContext, MetaCoreGameObject& gameObject) {
@ -3225,8 +3225,8 @@ void MetaCoreDrawMeshRendererComponentInspector(MetaCoreEditorContext& editorCon
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0F);
int meshSourceIndex = static_cast<int>(meshRenderer.MeshSource);
const char* meshSourceItems[] = {"Builtin", "Asset"};
if (ImGui::Combo("Mesh Source", &meshSourceIndex, meshSourceItems, IM_ARRAYSIZE(meshSourceItems))) {
const char* meshSourceItems[] = {"内置", "资源"};
if (ImGui::Combo("网格来源", &meshSourceIndex, meshSourceItems, IM_ARRAYSIZE(meshSourceItems))) {
MetaCoreTrackComponentInspectorEdit(editorContext, "修改检查器属性", false);
const MetaCoreMeshSourceKind meshSource = static_cast<MetaCoreMeshSourceKind>(meshSourceIndex);
MetaCoreApplyValueToSelectedObjects(
@ -3240,8 +3240,8 @@ void MetaCoreDrawMeshRendererComponentInspector(MetaCoreEditorContext& editorCon
if (meshRenderer.MeshSource == MetaCoreMeshSourceKind::Builtin) {
int builtinMeshIndex = static_cast<int>(meshRenderer.BuiltinMesh);
const char* builtinMeshItems[] = {"Cube", "Plane"};
if (ImGui::Combo("Builtin Mesh", &builtinMeshIndex, builtinMeshItems, IM_ARRAYSIZE(builtinMeshItems))) {
const char* builtinMeshItems[] = {"立方体", "平面"};
if (ImGui::Combo("内置网格", &builtinMeshIndex, builtinMeshItems, IM_ARRAYSIZE(builtinMeshItems))) {
MetaCoreTrackComponentInspectorEdit(editorContext, "修改检查器属性", false);
const MetaCoreBuiltinMeshType builtinMesh = static_cast<MetaCoreBuiltinMeshType>(builtinMeshIndex);
MetaCoreApplyValueToSelectedObjects(
@ -3259,18 +3259,18 @@ void MetaCoreDrawMeshRendererComponentInspector(MetaCoreEditorContext& editorCon
// 清爽显示模型资源,避免过于冗长
if (sourceAsset.has_value()) {
ImGui::Text("Model: %s", sourceAsset->RelativePath.filename().string().c_str());
ImGui::Text("模型: %s", sourceAsset->RelativePath.filename().string().c_str());
} else {
ImGui::Text("Model: %s", meshRenderer.SourceModelPath.c_str());
ImGui::Text("模型: %s", meshRenderer.SourceModelPath.c_str());
}
ImGui::SameLine();
ImGui::TextDisabled("(Node %d)", meshRenderer.ModelNodeIndex);
ImGui::TextDisabled("(节点 %d)", meshRenderer.ModelNodeIndex);
ImGui::SameLine();
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.18F, 0.18F, 0.18F, 1.0F));
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.24F, 0.24F, 0.24F, 1.0F));
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.20F, 0.20F, 0.20F, 1.0F));
if (ImGui::Button("Open##SourceModel")) {
if (ImGui::Button("打开##SourceModel")) {
MetaCoreOpenSourceModelFromMeshRenderer(editorContext, meshRenderer);
}
ImGui::PopStyleColor(3);
@ -3279,7 +3279,7 @@ void MetaCoreDrawMeshRendererComponentInspector(MetaCoreEditorContext& editorCon
const auto meshChoices = MetaCoreCollectMeshAssetChoices(editorContext);
MetaCoreAssetGuid meshAssetGuid = meshRenderer.MeshAssetGuid;
// 渲染 Mesh 资源选择 Combo隐藏底层的 Mesh Asset Guid 输入框
if (MetaCoreDrawGeneratedAssetCombo("Mesh Asset", meshChoices, meshAssetGuid)) {
if (MetaCoreDrawGeneratedAssetCombo("网格资源", meshChoices, meshAssetGuid)) {
MetaCoreTrackComponentInspectorEdit(editorContext, "修改检查器属性", false);
MetaCoreApplyValueToSelectedObjects(
editorContext,
@ -3295,16 +3295,16 @@ void MetaCoreDrawMeshRendererComponentInspector(MetaCoreEditorContext& editorCon
ImGui::PopStyleColor();
// Materials 材质槽位折叠重构
if (ImGui::TreeNodeEx("Materials", ImGuiTreeNodeFlags_DefaultOpen | ImGuiTreeNodeFlags_SpanAvailWidth)) {
if (ImGui::TreeNodeEx("材质", ImGuiTreeNodeFlags_DefaultOpen | ImGuiTreeNodeFlags_SpanAvailWidth)) {
int materialSlotCount = static_cast<int>(meshRenderer.MaterialAssetGuids.size());
// Size 槽位数量排版
if (ImGui::BeginTable("MaterialSizeTable", 2, ImGuiTableFlags_SizingStretchProp)) {
ImGui::TableSetupColumn("Label", ImGuiTableColumnFlags_WidthFixed, 100.0F);
ImGui::TableSetupColumn("Value", ImGuiTableColumnFlags_WidthStretch);
ImGui::TableSetupColumn("标签", ImGuiTableColumnFlags_WidthFixed, 100.0F);
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthStretch);
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::TextUnformatted("Size");
ImGui::TextUnformatted("槽位数");
ImGui::TableNextColumn();
ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0.0F, 0.0F, 0.0F, 0.0F));
@ -3353,14 +3353,14 @@ void MetaCoreDrawMeshRendererComponentInspector(MetaCoreEditorContext& editorCon
// 槽位列表循环
for (std::size_t materialIndex = 0; materialIndex < meshRenderer.MaterialAssetGuids.size(); ++materialIndex) {
MetaCoreAssetGuid materialGuid = meshRenderer.MaterialAssetGuids[materialIndex];
const std::string elementLabel = "Element " + std::to_string(materialIndex);
const std::string elementLabel = "元素 " + std::to_string(materialIndex);
const std::string materialSlotTableId = "MaterialSlotTable_" + std::to_string(materialIndex);
if (!ImGui::BeginTable(materialSlotTableId.c_str(), 2, ImGuiTableFlags_SizingStretchProp)) {
continue;
}
ImGui::TableSetupColumn("Label", ImGuiTableColumnFlags_WidthFixed, 100.0F);
ImGui::TableSetupColumn("Value", ImGuiTableColumnFlags_WidthStretch);
ImGui::TableSetupColumn("标签", ImGuiTableColumnFlags_WidthFixed, 100.0F);
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthStretch);
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::TextUnformatted(elementLabel.c_str());
@ -3373,16 +3373,16 @@ void MetaCoreDrawMeshRendererComponentInspector(MetaCoreEditorContext& editorCon
comboWidth = 1.0F;
}
std::string materialName = "None (Material)";
std::string materialName = "无 (材质)";
if (materialGuid.IsValid()) {
const auto assetEditingService = editorContext.GetModuleRegistry().ResolveService<MetaCoreIAssetEditingService>();
const auto materialAsset = assetEditingService != nullptr
? assetEditingService->LoadMaterialAsset(materialGuid)
: std::nullopt;
if (materialAsset.has_value() && !materialAsset->Name.empty()) {
materialName = materialAsset->Name + " (Material)";
materialName = materialAsset->Name + " (材质)";
} else {
materialName = materialGuid.ToString() + " (Material)";
materialName = materialGuid.ToString() + " (材质)";
}
}
@ -3450,7 +3450,7 @@ void MetaCoreDrawMeshRendererComponentInspector(MetaCoreEditorContext& editorCon
ImGui::OpenPopup(popupName.c_str());
}
if (ImGui::BeginPopup(popupName.c_str())) {
if (ImGui::Selectable("<None>", !materialGuid.IsValid())) {
if (ImGui::Selectable("<>", !materialGuid.IsValid())) {
materialGuid = MetaCoreAssetGuid{};
}
if (ImGui::Selectable("新建材质并绑定", false)) {
@ -3481,7 +3481,7 @@ void MetaCoreDrawMeshRendererComponentInspector(MetaCoreEditorContext& editorCon
// 右键快捷弹出菜单,收容所有高级/调试指令
if (ImGui::BeginPopupContextItem(("MaterialSlotContext##" + std::to_string(materialIndex)).c_str())) {
if (ImGui::MenuItem("清空槽位 (Clear Slot)")) {
if (ImGui::MenuItem("清空槽位")) {
MetaCoreClearMaterialSlotOnSelectedObjects(editorContext, materialIndex);
materialGuid = MetaCoreAssetGuid{};
editorContext.AddConsoleMessage(MetaCoreLogLevel::Info, "Material", "已清空材质槽位");
@ -3493,7 +3493,7 @@ void MetaCoreDrawMeshRendererComponentInspector(MetaCoreEditorContext& editorCon
editorContext.AddConsoleMessage(MetaCoreLogLevel::Warning, "Material", "新建材质并绑定失败");
}
}
if (ImGui::MenuItem("恢复模型默认材质 (Restore Default)")) {
if (ImGui::MenuItem("恢复模型默认材质")) {
if (MetaCoreRestoreDefaultMaterialSlotOnSelectedObjects(editorContext, materialIndex)) {
editorContext.AddConsoleMessage(MetaCoreLogLevel::Info, "Material", "已恢复模型默认材质槽位");
if (gameObject.HasComponent<MetaCoreMeshRendererComponent>() &&
@ -3506,7 +3506,7 @@ void MetaCoreDrawMeshRendererComponentInspector(MetaCoreEditorContext& editorCon
}
if (materialGuid.IsValid()) {
ImGui::Separator();
if (ImGui::MenuItem("重新应用材质资源到实例 (Reapply to Instance)")) {
if (ImGui::MenuItem("重新应用材质资源到实例")) {
if (MetaCoreReapplyMaterialResourceToSelectedObjects(editorContext, materialIndex)) {
editorContext.AddConsoleMessage(MetaCoreLogLevel::Info, "Material", "已将材质资源重新应用到实例");
} else {
@ -3514,7 +3514,7 @@ void MetaCoreDrawMeshRendererComponentInspector(MetaCoreEditorContext& editorCon
}
}
if (editorContext.GetSelectedObjectIds().size() == 1) {
if (ImGui::MenuItem("将实例预览写回材质资源 (Push to Resource)")) {
if (ImGui::MenuItem("将实例预览写回材质资源")) {
if (MetaCorePushSelectedMeshRendererPreviewToMaterialResource(editorContext, materialIndex)) {
editorContext.AddConsoleMessage(MetaCoreLogLevel::Info, "Material", "已将当前实例预览写回材质资源");
} else {
@ -3523,7 +3523,7 @@ void MetaCoreDrawMeshRendererComponentInspector(MetaCoreEditorContext& editorCon
}
}
ImGui::Separator();
if (ImGui::MenuItem("打开材质资源 (Open Material Resource)")) {
if (ImGui::MenuItem("打开材质资源")) {
const auto assetEditingService = editorContext.GetModuleRegistry().ResolveService<MetaCoreIAssetEditingService>();
if (const auto resolvedMaterial = assetEditingService != nullptr
? assetEditingService->ResolveGeneratedAsset(materialGuid)
@ -3563,22 +3563,22 @@ void MetaCoreDrawMeshRendererComponentInspector(MetaCoreEditorContext& editorCon
ImGui::TreePop();
}
// 二级折叠菜单:Lighting (照明设置占位,对标 Unity)
if (ImGui::CollapsingHeader("Lighting")) {
// 二级折叠菜单:照明设置占位,对标 Unity
if (ImGui::CollapsingHeader("照明")) {
ImGui::Columns(2, "LightingCols", false);
ImGui::SetColumnWidth(0, 160.0F);
ImGui::Text("Cast Shadows");
ImGui::Text("投射阴影");
ImGui::NextColumn();
ImGui::BeginDisabled();
const char* shadowItems[] = {"Off", "On", "Two Sided", "Shadows Only"};
const char* shadowItems[] = {"关闭", "开启", "双面", "仅阴影"};
int shadowIndex = 1; // 默认 "On"
ImGui::SetNextItemWidth(-1);
ImGui::Combo("##CastShadows", &shadowIndex, shadowItems, IM_ARRAYSIZE(shadowItems));
ImGui::EndDisabled();
ImGui::NextColumn();
ImGui::Text("Receive Shadows");
ImGui::Text("接收阴影");
ImGui::NextColumn();
ImGui::BeginDisabled();
bool receiveShadows = true;
@ -3586,7 +3586,7 @@ void MetaCoreDrawMeshRendererComponentInspector(MetaCoreEditorContext& editorCon
ImGui::EndDisabled();
ImGui::NextColumn();
ImGui::Text("Contribute GI");
ImGui::Text("参与全局光照");
ImGui::NextColumn();
ImGui::BeginDisabled();
bool contributeGI = false;
@ -3596,57 +3596,57 @@ void MetaCoreDrawMeshRendererComponentInspector(MetaCoreEditorContext& editorCon
ImGui::Columns(1);
}
// 二级折叠菜单:Probes (探测器设置占位,对标 Unity)
if (ImGui::CollapsingHeader("Probes")) {
// 二级折叠菜单:探针设置占位,对标 Unity
if (ImGui::CollapsingHeader("探针")) {
ImGui::Columns(2, "ProbesCols", false);
ImGui::SetColumnWidth(0, 160.0F);
ImGui::Text("Light Probes");
ImGui::Text("光照探针");
ImGui::NextColumn();
ImGui::BeginDisabled();
const char* lightProbeItems[] = {"Off", "Blend Probes", "Use Proxy Volume"};
const char* lightProbeItems[] = {"关闭", "混合探针", "使用代理体积"};
int lpIndex = 1;
ImGui::SetNextItemWidth(-1);
ImGui::Combo("##LightProbes", &lpIndex, lightProbeItems, IM_ARRAYSIZE(lightProbeItems));
ImGui::EndDisabled();
ImGui::NextColumn();
ImGui::Text("Reflection Probes");
ImGui::Text("反射探针");
ImGui::NextColumn();
ImGui::BeginDisabled();
const char* reflProbeItems[] = {"Off", "Blend Probes", "Blend Probes And Skybox"};
const char* reflProbeItems[] = {"关闭", "混合探针", "混合探针和天空盒"};
int rpIndex = 1;
ImGui::SetNextItemWidth(-1);
ImGui::Combo("##ReflectionProbes", &rpIndex, reflProbeItems, IM_ARRAYSIZE(reflProbeItems));
ImGui::EndDisabled();
ImGui::NextColumn();
ImGui::Text("Anchor Override");
ImGui::Text("锚点覆盖");
ImGui::NextColumn();
ImGui::BeginDisabled();
ImGui::SetNextItemWidth(-1);
ImGui::Button("None (Transform)");
ImGui::Button("无 (变换)");
ImGui::EndDisabled();
ImGui::Columns(1);
}
// 二级折叠菜单:Additional Settings (额外渲染设置占位,对标 Unity)
if (ImGui::CollapsingHeader("Additional Settings")) {
// 二级折叠菜单:额外渲染设置占位,对标 Unity
if (ImGui::CollapsingHeader("额外设置")) {
ImGui::Columns(2, "AddSettingsCols", false);
ImGui::SetColumnWidth(0, 160.0F);
ImGui::Text("Motion Vectors");
ImGui::Text("运动矢量");
ImGui::NextColumn();
ImGui::BeginDisabled();
const char* mvItems[] = {"Camera Motion Only", "Per Object Motion", "Force No Motion"};
const char* mvItems[] = {"仅相机运动", "逐对象运动", "强制无运动"};
int mvIndex = 1;
ImGui::SetNextItemWidth(-1);
ImGui::Combo("##MotionVectors", &mvIndex, mvItems, IM_ARRAYSIZE(mvItems));
ImGui::EndDisabled();
ImGui::NextColumn();
ImGui::Text("Dynamic Occlusion");
ImGui::Text("动态遮挡");
ImGui::NextColumn();
ImGui::BeginDisabled();
bool dynOcc = true;
@ -3708,7 +3708,7 @@ void MetaCoreDrawMeshRendererComponentInspector(MetaCoreEditorContext& editorCon
ImGui::Columns(2, "MeshInstanceProps", false);
ImGui::SetColumnWidth(0, 160.0F);
ImGui::Text("BaseColor (Instance)");
ImGui::Text("基础颜色 (实例)");
ImGui::NextColumn();
ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0.0F, 0.0F, 0.0F, 0.0F));
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0F);
@ -3731,7 +3731,7 @@ void MetaCoreDrawMeshRendererComponentInspector(MetaCoreEditorContext& editorCon
ImGui::PopStyleColor();
ImGui::NextColumn();
ImGui::Text("Visible (Instance)");
ImGui::Text("可见 (实例)");
ImGui::NextColumn();
if (multiEdit && !sharedVisible.has_value()) {
ImGui::TextDisabled("混合值");
@ -3757,7 +3757,7 @@ void MetaCoreDrawMeshRendererComponentInspector(MetaCoreEditorContext& editorCon
continue;
}
std::string materialName = "Default-Material";
std::string materialName = "默认材质";
const auto assetEditingService = editorContext.GetModuleRegistry().ResolveService<MetaCoreIAssetEditingService>();
const auto materialDocument = assetEditingService != nullptr
? assetEditingService->LoadMaterialAsset(materialGuid)
@ -3770,7 +3770,7 @@ void MetaCoreDrawMeshRendererComponentInspector(MetaCoreEditorContext& editorCon
float frameHeight = ImGui::GetFrameHeight();
// 留出材质球图标的空间
std::string headerLabel = " " + materialName + " (Material)##InlineMaterialPanel_" + std::to_string(materialIndex);
std::string headerLabel = " " + materialName + " (材质)##InlineMaterialPanel_" + std::to_string(materialIndex);
bool isPanelOpen = ImGui::CollapsingHeader(headerLabel.c_str());
@ -3829,36 +3829,36 @@ void MetaCoreDrawMeshRendererComponentInspector(MetaCoreEditorContext& editorCon
// 材质基本属性编辑
float baseColorRes[3] = {materialAsset.BaseColor.x, materialAsset.BaseColor.y, materialAsset.BaseColor.z};
const bool baseColorChanged = ImGui::ColorEdit3(("Base Color##Res" + std::to_string(materialIndex)).c_str(), baseColorRes);
const bool baseColorChanged = ImGui::ColorEdit3(("基础颜色##Res" + std::to_string(materialIndex)).c_str(), baseColorRes);
if (baseColorChanged) {
materialAsset.BaseColor = {baseColorRes[0], baseColorRes[1], baseColorRes[2]};
}
markContinuousEdit(baseColorChanged);
markContinuousEdit(ImGui::SliderFloat(
("Metallic##Res" + std::to_string(materialIndex)).c_str(),
("金属度##Res" + std::to_string(materialIndex)).c_str(),
&materialAsset.Metallic,
0.0F,
1.0F
));
markContinuousEdit(ImGui::SliderFloat(
("Roughness##Res" + std::to_string(materialIndex)).c_str(),
("粗糙度##Res" + std::to_string(materialIndex)).c_str(),
&materialAsset.Roughness,
0.0F,
1.0F
));
markDiscreteEdit(ImGui::Checkbox(("Double Sided##Res" + std::to_string(materialIndex)).c_str(), &materialAsset.DoubleSided));
markDiscreteEdit(ImGui::Checkbox(("双面渲染##Res" + std::to_string(materialIndex)).c_str(), &materialAsset.DoubleSided));
const char* alphaModeItems[] = {"Opaque", "Mask", "Blend"};
const char* alphaModeItems[] = {"不透明", "镂空裁剪", "透明混合"};
int alphaModeIndex = static_cast<int>(materialAsset.AlphaMode);
if (ImGui::Combo(("Alpha Mode##Res" + std::to_string(materialIndex)).c_str(), &alphaModeIndex, alphaModeItems, IM_ARRAYSIZE(alphaModeItems))) {
if (ImGui::Combo(("透明模式##Res" + std::to_string(materialIndex)).c_str(), &alphaModeIndex, alphaModeItems, IM_ARRAYSIZE(alphaModeItems))) {
materialAsset.AlphaMode = static_cast<MetaCoreMaterialAlphaMode>(alphaModeIndex);
previewModified = true;
commitModified = true;
}
if (materialAsset.AlphaMode == MetaCoreMaterialAlphaMode::Mask) {
markContinuousEdit(ImGui::SliderFloat(
("Alpha Cutoff##Res" + std::to_string(materialIndex)).c_str(),
("裁剪阈值##Res" + std::to_string(materialIndex)).c_str(),
&materialAsset.AlphaCutoff,
0.0F,
1.0F
@ -3868,37 +3868,37 @@ void MetaCoreDrawMeshRendererComponentInspector(MetaCoreEditorContext& editorCon
// 贴图通道配置
const auto textureChoices = MetaCoreCollectTextureAssetChoices(editorContext);
MetaCoreAssetGuid baseColorTexture = materialAsset.BaseColorTexture;
if (MetaCoreDrawGeneratedAssetCombo(("Base Color Texture##Res" + std::to_string(materialIndex)).c_str(), textureChoices, baseColorTexture)) {
if (MetaCoreDrawGeneratedAssetCombo(("基础颜色贴图##Res" + std::to_string(materialIndex)).c_str(), textureChoices, baseColorTexture)) {
materialAsset.BaseColorTexture = baseColorTexture;
previewModified = true;
commitModified = true;
}
MetaCoreAssetGuid metalRoughTexture = materialAsset.MetallicRoughnessTexture;
if (MetaCoreDrawGeneratedAssetCombo(("MetalRough Texture##Res" + std::to_string(materialIndex)).c_str(), textureChoices, metalRoughTexture)) {
if (MetaCoreDrawGeneratedAssetCombo(("金属粗糙度贴图##Res" + std::to_string(materialIndex)).c_str(), textureChoices, metalRoughTexture)) {
materialAsset.MetallicRoughnessTexture = metalRoughTexture;
previewModified = true;
commitModified = true;
}
MetaCoreAssetGuid normalTexture = materialAsset.NormalTexture;
if (MetaCoreDrawGeneratedAssetCombo(("Normal Texture##Res" + std::to_string(materialIndex)).c_str(), textureChoices, normalTexture)) {
if (MetaCoreDrawGeneratedAssetCombo(("法线贴图##Res" + std::to_string(materialIndex)).c_str(), textureChoices, normalTexture)) {
materialAsset.NormalTexture = normalTexture;
previewModified = true;
commitModified = true;
}
float emissiveColor[3] = {materialAsset.EmissiveColor.x, materialAsset.EmissiveColor.y, materialAsset.EmissiveColor.z};
const bool emissiveColorChanged = ImGui::ColorEdit3(("Emissive Color##Res" + std::to_string(materialIndex)).c_str(), emissiveColor);
const bool emissiveColorChanged = ImGui::ColorEdit3(("发光颜色##Res" + std::to_string(materialIndex)).c_str(), emissiveColor);
if (emissiveColorChanged) {
materialAsset.EmissiveColor = {emissiveColor[0], emissiveColor[1], emissiveColor[2]};
}
markContinuousEdit(emissiveColorChanged);
MetaCoreAssetGuid emissiveTexture = materialAsset.EmissiveTexture;
if (MetaCoreDrawGeneratedAssetCombo(("Emissive Texture##Res" + std::to_string(materialIndex)).c_str(), textureChoices, emissiveTexture)) {
if (MetaCoreDrawGeneratedAssetCombo(("发光贴图##Res" + std::to_string(materialIndex)).c_str(), textureChoices, emissiveTexture)) {
materialAsset.EmissiveTexture = emissiveTexture;
previewModified = true;
commitModified = true;
}
MetaCoreAssetGuid aoTexture = materialAsset.AoTexture;
if (MetaCoreDrawGeneratedAssetCombo(("AO Texture##Res" + std::to_string(materialIndex)).c_str(), textureChoices, aoTexture)) {
if (MetaCoreDrawGeneratedAssetCombo(("遮蔽 AO 贴图##Res" + std::to_string(materialIndex)).c_str(), textureChoices, aoTexture)) {
materialAsset.AoTexture = aoTexture;
previewModified = true;
commitModified = true;
@ -7906,7 +7906,7 @@ public:
Descriptors_.clear();
Descriptors_.push_back(MetaCoreComponentDescriptor{
"Transform",
"Transform",
"变换",
[](const MetaCoreGameObject&) { return true; },
[](MetaCoreGameObject&) { return false; },
[](MetaCoreGameObject&) { return false; },
@ -7924,7 +7924,7 @@ public:
});
Descriptors_.push_back(MetaCoreComponentDescriptor{
"Camera",
"Camera",
"相机",
[](const MetaCoreGameObject& gameObject) { return gameObject.HasComponent<MetaCoreCameraComponent>(); },
[](MetaCoreGameObject& gameObject) {
if (gameObject.HasComponent<MetaCoreCameraComponent>()) {
@ -7969,7 +7969,7 @@ public:
});
Descriptors_.push_back(MetaCoreComponentDescriptor{
"Light",
"Light",
"灯光",
[](const MetaCoreGameObject& gameObject) { return gameObject.HasComponent<MetaCoreLightComponent>(); },
[](MetaCoreGameObject& gameObject) {
if (gameObject.HasComponent<MetaCoreLightComponent>()) {
@ -8059,7 +8059,7 @@ public:
});
Descriptors_.push_back(MetaCoreComponentDescriptor{
"Animator",
"Animator",
"动画器",
[](const MetaCoreGameObject& gameObject) { return gameObject.HasComponent<MetaCoreAnimatorComponent>(); },
[](MetaCoreGameObject& gameObject) {
if (gameObject.HasComponent<MetaCoreAnimatorComponent>()) {
@ -8149,7 +8149,7 @@ public:
});
Descriptors_.push_back(MetaCoreComponentDescriptor{
"UiRenderer",
"UI Renderer",
"UI 渲染器",
[](const MetaCoreGameObject& gameObject) { return gameObject.HasComponent<MetaCoreUiRendererComponent>(); },
[](MetaCoreGameObject& gameObject) {
if (gameObject.HasComponent<MetaCoreUiRendererComponent>()) {
@ -8194,7 +8194,7 @@ public:
});
Descriptors_.push_back(MetaCoreComponentDescriptor{
"MeshRenderer",
"Mesh Renderer",
"网格渲染器",
[](const MetaCoreGameObject& gameObject) { return gameObject.HasComponent<MetaCoreMeshRendererComponent>(); },
[](MetaCoreGameObject& gameObject) {
if (gameObject.HasComponent<MetaCoreMeshRendererComponent>()) {

View File

@ -126,10 +126,10 @@ static std::unordered_map<std::string, MetaCoreModelAnimationPreviewState> Model
case MetaCoreModelAssetKind::Gltf:
return "glTF";
case MetaCoreModelAssetKind::Generic:
return "Generic";
return "通用";
case MetaCoreModelAssetKind::Unknown:
default:
return "Unknown";
return "未知";
}
}
@ -2759,13 +2759,13 @@ private:
}
if (isModelInstance && ImGui::IsItemHovered()) {
ImGui::BeginTooltip();
ImGui::TextDisabled("Model Instance");
ImGui::TextDisabled("模型实例");
if (sourceModelAsset.has_value()) {
ImGui::Text("Source: %s", sourceModelAsset->RelativePath.filename().string().c_str());
ImGui::Text("来源: %s", sourceModelAsset->RelativePath.filename().string().c_str());
} else {
ImGui::Text("Source: %s", gameObject.GetComponent<MetaCoreMeshRendererComponent>().SourceModelPath.c_str());
ImGui::Text("来源: %s", gameObject.GetComponent<MetaCoreMeshRendererComponent>().SourceModelPath.c_str());
}
ImGui::Text("Node Index: %d", gameObject.GetComponent<MetaCoreMeshRendererComponent>().ModelNodeIndex);
ImGui::Text("节点索引: %d", gameObject.GetComponent<MetaCoreMeshRendererComponent>().ModelNodeIndex);
ImGui::EndTooltip();
}
@ -4271,6 +4271,19 @@ struct MetaCoreGeneratedResourceListEntry {
std::string SecondaryText{};
};
[[nodiscard]] const char* MetaCoreGeneratedResourceKindLabel(std::string_view kind) {
if (kind == "mesh") {
return "网格";
}
if (kind == "material") {
return "材质";
}
if (kind == "texture") {
return "贴图";
}
return "资源";
}
[[nodiscard]] std::string MetaCoreBuildGeneratedResourceSubId(
std::string_view kind,
const MetaCoreAssetGuid& assetGuid
@ -4328,9 +4341,9 @@ void MetaCoreClearGeneratedResourceSelection(MetaCoreEditorContext& editorContex
) {
std::vector<MetaCoreGeneratedResourceListEntry> entries;
entries.reserve(document.GeneratedMeshAssets.size() + document.GeneratedMaterialAssets.size() + document.GeneratedTextureAssets.size());
for (const auto& meshAsset : document.GeneratedMeshAssets) entries.push_back({meshAsset.AssetGuid, "mesh", meshAsset.Name, "Mesh"});
for (const auto& materialAsset : document.GeneratedMaterialAssets) entries.push_back({materialAsset.AssetGuid, "material", materialAsset.Name, "Material"});
for (const auto& textureAsset : document.GeneratedTextureAssets) entries.push_back({textureAsset.AssetGuid, "texture", textureAsset.Name, "Texture"});
for (const auto& meshAsset : document.GeneratedMeshAssets) entries.push_back({meshAsset.AssetGuid, "mesh", meshAsset.Name, "网格"});
for (const auto& materialAsset : document.GeneratedMaterialAssets) entries.push_back({materialAsset.AssetGuid, "material", materialAsset.Name, "材质"});
for (const auto& textureAsset : document.GeneratedTextureAssets) entries.push_back({textureAsset.AssetGuid, "texture", textureAsset.Name, "贴图"});
return entries;
}
@ -4697,8 +4710,8 @@ void MetaCoreDrawMaterialPreviewCard(const MetaCoreMaterialAssetDocument& materi
bool changed = false;
ImGui::PushID(id);
if (ImGui::BeginTable("TextureSlot", 2, ImGuiTableFlags_SizingStretchProp)) {
ImGui::TableSetupColumn("Label", ImGuiTableColumnFlags_WidthFixed, 118.0F);
ImGui::TableSetupColumn("Value", ImGuiTableColumnFlags_WidthStretch);
ImGui::TableSetupColumn("标签", ImGuiTableColumnFlags_WidthFixed, 118.0F);
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthStretch);
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::TextUnformatted(label);
@ -4828,8 +4841,8 @@ void MetaCoreDrawMaterialPreviewCard(const MetaCoreMaterialAssetDocument& materi
const bool useTwoColumns = availableWidth >= 520.0F;
if (useTwoColumns) {
ImGui::BeginTable("MaterialVisualLayout", 2, ImGuiTableFlags_SizingStretchProp);
ImGui::TableSetupColumn("Properties", ImGuiTableColumnFlags_WidthStretch, 0.62F);
ImGui::TableSetupColumn("Preview", ImGuiTableColumnFlags_WidthStretch, 0.38F);
ImGui::TableSetupColumn("属性", ImGuiTableColumnFlags_WidthStretch, 0.62F);
ImGui::TableSetupColumn("预览", ImGuiTableColumnFlags_WidthStretch, 0.38F);
ImGui::TableNextRow();
ImGui::TableNextColumn();
}
@ -4891,7 +4904,7 @@ void MetaCoreDrawMaterialPreviewCard(const MetaCoreMaterialAssetDocument& materi
if (ImGui::CollapsingHeader("高级信息")) {
ImGui::TextDisabled("着色模型: %s", MetaCoreMaterialShaderModelLabel(materialDocument.ShaderModel));
ImGui::TextDisabled("透明模式: %s", MetaCoreMaterialAlphaModeLabel(materialDocument.AlphaMode));
ImGui::TextDisabled("StableImportKey: %s", materialDocument.StableImportKey.empty() ? "<无>" : materialDocument.StableImportKey.c_str());
ImGui::TextDisabled("稳定导入键: %s", materialDocument.StableImportKey.empty() ? "<无>" : materialDocument.StableImportKey.c_str());
}
if (useTwoColumns) {
@ -5008,48 +5021,48 @@ void DrawGeneratedMeshDetails(
const MetaCoreMeshAssetDocument& meshAsset = loadedMesh.value_or(selectedMesh);
ImGui::Separator();
ImGui::TextDisabled("MESH RESOURCE");
ImGui::Text("Name: %s", meshAsset.Name.empty() ? "<Unnamed>" : meshAsset.Name.c_str());
ImGui::TextDisabled("Guid: %s", meshAsset.AssetGuid.ToString().c_str());
ImGui::Text("Vertices: %d", meshAsset.VertexCount);
ImGui::Text("Indices: %d", meshAsset.IndexCount);
ImGui::Text("SubMeshes: %d", static_cast<int>(meshAsset.SubMeshes.size()));
ImGui::TextDisabled("网格资源");
ImGui::Text("名称: %s", meshAsset.Name.empty() ? "<未命名>" : meshAsset.Name.c_str());
ImGui::TextDisabled("GUID: %s", meshAsset.AssetGuid.ToString().c_str());
ImGui::Text("顶点: %d", meshAsset.VertexCount);
ImGui::Text("索引: %d", meshAsset.IndexCount);
ImGui::Text("子网格: %d", static_cast<int>(meshAsset.SubMeshes.size()));
ImGui::Text(
"Bounds Min: %.2f, %.2f, %.2f",
"包围盒最小值: %.2f, %.2f, %.2f",
meshAsset.BoundingBoxMin.x,
meshAsset.BoundingBoxMin.y,
meshAsset.BoundingBoxMin.z
);
ImGui::Text(
"Bounds Max: %.2f, %.2f, %.2f",
"包围盒最大值: %.2f, %.2f, %.2f",
meshAsset.BoundingBoxMax.x,
meshAsset.BoundingBoxMax.y,
meshAsset.BoundingBoxMax.z
);
const auto references = FindSceneObjectsUsingMesh(editorContext, meshAsset.AssetGuid);
ImGui::Text("Scene References: %d", static_cast<int>(references.size()));
ImGui::Text("场景引用: %d", static_cast<int>(references.size()));
if (!references.empty()) {
if (ImGui::Button("Highlight Scene Objects##SelectedMesh")) {
if (ImGui::Button("高亮场景对象##SelectedMesh")) {
editorContext.SetSelection(references, references.front());
}
DrawReferencedObjectList(editorContext, references, "SelectedMeshRefs");
}
if (!meshAsset.SubMeshes.empty() && ImGui::TreeNode("SubMeshes##SelectedMesh")) {
if (!meshAsset.SubMeshes.empty() && ImGui::TreeNode("子网格##SelectedMesh")) {
for (std::size_t subMeshIndex = 0; subMeshIndex < meshAsset.SubMeshes.size(); ++subMeshIndex) {
const MetaCoreMeshSubMeshDocument& subMesh = meshAsset.SubMeshes[subMeshIndex];
const std::string subMeshLabel =
(subMesh.Name.empty() ? ("SubMesh " + std::to_string(subMeshIndex)) : subMesh.Name) +
(subMesh.Name.empty() ? ("子网格 " + std::to_string(subMeshIndex)) : subMesh.Name) +
"##SelectedMeshSub_" + std::to_string(subMeshIndex);
if (ImGui::TreeNode(subMeshLabel.c_str())) {
ImGui::Text("Material Slot: %d", subMesh.MaterialSlotIndex);
ImGui::Text("材质槽位: %d", subMesh.MaterialSlotIndex);
if (subMesh.MaterialSlotIndex >= 0 &&
static_cast<std::size_t>(subMesh.MaterialSlotIndex) < importedDocument.GeneratedMaterialAssets.size()) {
const MetaCoreMaterialAssetDocument& slotMaterial =
importedDocument.GeneratedMaterialAssets[static_cast<std::size_t>(subMesh.MaterialSlotIndex)];
ImGui::Text("Material: %s", slotMaterial.Name.empty() ? "<Unnamed>" : slotMaterial.Name.c_str());
if (ImGui::Button(("Open Material##SelectedMeshSub_" + std::to_string(subMeshIndex)).c_str())) {
ImGui::Text("材质: %s", slotMaterial.Name.empty() ? "<未命名>" : slotMaterial.Name.c_str());
if (ImGui::Button(("打开材质##SelectedMeshSub_" + std::to_string(subMeshIndex)).c_str())) {
MetaCoreSelectGeneratedResource(editorContext, "material", slotMaterial.AssetGuid);
}
}
@ -5072,34 +5085,34 @@ void DrawGeneratedTextureDetails(
const MetaCoreTextureAssetDocument& textureAsset = loadedTexture.value_or(selectedTexture);
ImGui::Separator();
ImGui::TextDisabled("TEXTURE RESOURCE");
ImGui::Text("Name: %s", textureAsset.Name.empty() ? "<Unnamed>" : textureAsset.Name.c_str());
ImGui::TextDisabled("Guid: %s", textureAsset.AssetGuid.ToString().c_str());
ImGui::Text("Source: %s", textureAsset.SourcePath.generic_string().c_str());
ImGui::Text("Usage: %s", textureAsset.UsageHint.empty() ? "<Unknown>" : textureAsset.UsageHint.c_str());
ImGui::TextDisabled("贴图资源");
ImGui::Text("名称: %s", textureAsset.Name.empty() ? "<未命名>" : textureAsset.Name.c_str());
ImGui::TextDisabled("GUID: %s", textureAsset.AssetGuid.ToString().c_str());
ImGui::Text("来源: %s", textureAsset.SourcePath.generic_string().c_str());
ImGui::Text("用途: %s", textureAsset.UsageHint.empty() ? "<未知>" : textureAsset.UsageHint.c_str());
ImGui::Text(
"Size: %d x %d x %d",
"尺寸: %d x %d x %d",
textureAsset.Width,
textureAsset.Height,
textureAsset.Channels
);
ImGui::Text(
"Payload: index=%llu size=%llu",
"载荷: 索引=%llu 大小=%llu",
static_cast<unsigned long long>(textureAsset.PayloadIndex),
static_cast<unsigned long long>(textureAsset.PayloadSize)
);
const auto sceneReferences = FindSceneObjectsUsingTexture(editorContext, importedDocument, textureAsset.AssetGuid);
ImGui::Text("Scene References: %d", static_cast<int>(sceneReferences.size()));
ImGui::Text("场景引用: %d", static_cast<int>(sceneReferences.size()));
if (!sceneReferences.empty()) {
if (ImGui::Button("Highlight Scene Objects##SelectedTexture")) {
if (ImGui::Button("高亮场景对象##SelectedTexture")) {
editorContext.SetSelection(sceneReferences, sceneReferences.front());
}
DrawReferencedObjectList(editorContext, sceneReferences, "SelectedTextureRefs");
}
const auto materialReferences = MetaCoreFindMaterialTextureReferences(importedDocument, textureAsset.AssetGuid);
if (!materialReferences.empty() && ImGui::TreeNode("Material Slots##SelectedTexture")) {
if (!materialReferences.empty() && ImGui::TreeNode("材质槽位##SelectedTexture")) {
for (std::size_t referenceIndex = 0; referenceIndex < materialReferences.size(); ++referenceIndex) {
const MetaCoreMaterialTextureReference& reference = materialReferences[referenceIndex];
const std::string label =
@ -5115,38 +5128,38 @@ void DrawGeneratedTextureDetails(
[[nodiscard]] const char* MetaCoreModelImportUpAxisLabel(MetaCoreModelImportUpAxis upAxis) {
switch (upAxis) {
case MetaCoreModelImportUpAxis::YUp:
return "Y-Up";
return "Y 轴向上";
case MetaCoreModelImportUpAxis::ZUp:
return "Z-Up";
return "Z 轴向上";
case MetaCoreModelImportUpAxis::XUp:
return "X-Up";
return "X 轴向上";
case MetaCoreModelImportUpAxis::PreserveSource:
default:
return "Preserve Source";
return "保留源文件";
}
}
[[nodiscard]] const char* MetaCoreImportResultLabel(MetaCoreModelImportResult result) {
switch (result) {
case MetaCoreModelImportResult::Warning:
return "Warning";
return "警告";
case MetaCoreModelImportResult::Error:
return "Error";
return "错误";
case MetaCoreModelImportResult::Success:
default:
return "Success";
return "成功";
}
}
[[nodiscard]] const char* MetaCoreImportMessageSeverityLabel(MetaCoreImportMessageSeverity severity) {
switch (severity) {
case MetaCoreImportMessageSeverity::Warning:
return "Warning";
return "警告";
case MetaCoreImportMessageSeverity::Error:
return "Error";
return "错误";
case MetaCoreImportMessageSeverity::Info:
default:
return "Info";
return "信息";
}
}
@ -5238,7 +5251,7 @@ void DrawMissingAnimatorPrompt(MetaCoreEditorContext& editorContext, MetaCoreGam
ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(0.18F, 0.16F, 0.10F, 1.0F));
ImGui::BeginChild("MissingAnimatorPrompt", ImVec2(0, 58), true, ImGuiWindowFlags_NoScrollbar);
ImGui::Text("该模型包含 %d 个动画 Clip但当前根对象没有 Animator。", static_cast<int>(modelDocument->Animations.size()));
if (ImGui::Button("添加 Animator 并播放", ImVec2(-1, 24))) {
if (ImGui::Button("添加动画器并播放", ImVec2(-1, 24))) {
const MetaCoreId objectId = selectedObject.GetId();
const MetaCoreAssetRecord sourceRecord = *sourceAsset;
const MetaCoreModelAssetDocument sourceDocument = *modelDocument;
@ -5470,60 +5483,60 @@ void DrawModelAssetDetails(MetaCoreEditorContext& editorContext, MetaCoreIAssetD
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(4, 4));
if (ImGui::BeginChild("ModelInspector", ImVec2(0, 0), true, 0)) {
ImGui::TextDisabled("MODEL ASSET");
ImGui::TextDisabled("模型资源");
ImGui::SameLine(ImGui::GetWindowWidth() - 70.0F);
if (ImGui::Button("Instantiate", ImVec2(60, 0))) (void)MetaCoreInstantiateModelAsset(editorContext, selectedAsset.Guid, std::nullopt);
if (ImGui::Button("实例化", ImVec2(60, 0))) (void)MetaCoreInstantiateModelAsset(editorContext, selectedAsset.Guid, std::nullopt);
ImGui::Separator();
// Summary Table
if (ImGui::BeginTable("ModelSummaryTable", 2, ImGuiTableFlags_SizingFixedFit)) {
ImGui::TableNextRow(); ImGui::TableNextColumn(); ImGui::Text("File Name"); ImGui::TableNextColumn(); ImGui::TextUnformatted(selectedAsset.RelativePath.filename().string().c_str());
ImGui::TableNextRow(); ImGui::TableNextColumn(); ImGui::Text("Root Display"); ImGui::TableNextColumn(); ImGui::TextUnformatted(importedDocument->RootDisplayName.c_str());
ImGui::TableNextRow(); ImGui::TableNextColumn(); ImGui::Text("Type"); ImGui::TableNextColumn(); ImGui::Text("%s (%s)", MetaCoreModelAssetKindLabel(importedDocument->ModelKind), importedDocument->SourceFormat.c_str());
ImGui::TableNextRow(); ImGui::TableNextColumn(); ImGui::Text("Importer"); ImGui::TableNextColumn(); ImGui::TextUnformatted(importedDocument->ImporterId.c_str());
ImGui::TableNextRow(); ImGui::TableNextColumn(); ImGui::Text("Guid"); ImGui::TableNextColumn(); ImGui::TextDisabled("%s", selectedAsset.Guid.ToString().c_str());
ImGui::TableNextRow(); ImGui::TableNextColumn(); ImGui::Text("Source"); ImGui::TableNextColumn(); ImGui::TextUnformatted(importedDocument->SourcePath.generic_string().c_str());
ImGui::TableNextRow(); ImGui::TableNextColumn(); ImGui::Text("Package"); ImGui::TableNextColumn(); ImGui::TextUnformatted((!assetRecord->PackagePath.empty() ? assetRecord->PackagePath : assetRecord->RelativePath).generic_string().c_str());
ImGui::TableNextRow(); ImGui::TableNextColumn(); ImGui::Text("Source Hash"); ImGui::TableNextColumn(); ImGui::Text("%llu", static_cast<unsigned long long>(importedDocument->SourceHash));
ImGui::TableNextRow(); ImGui::TableNextColumn(); ImGui::Text("Nodes"); ImGui::TableNextColumn(); ImGui::Text("%d", static_cast<int>(importedDocument->Nodes.size()));
ImGui::TableNextRow(); ImGui::TableNextColumn(); ImGui::Text("Meshes"); ImGui::TableNextColumn(); ImGui::Text("%d", static_cast<int>(importedDocument->GeneratedMeshAssets.size()));
ImGui::TableNextRow(); ImGui::TableNextColumn(); ImGui::Text("Materials"); ImGui::TableNextColumn(); ImGui::Text("%d", static_cast<int>(importedDocument->GeneratedMaterialAssets.size()));
ImGui::TableNextRow(); ImGui::TableNextColumn(); ImGui::Text("Textures"); ImGui::TableNextColumn(); ImGui::Text("%d", static_cast<int>(importedDocument->GeneratedTextureAssets.size()));
ImGui::TableNextRow(); ImGui::TableNextColumn(); ImGui::Text("Import Report"); ImGui::TableNextColumn(); ImGui::Text("%s (W:%d E:%d)", MetaCoreImportResultLabel(importedDocument->ImportReport.Result), warningCount, errorCount);
ImGui::TableNextRow(); ImGui::TableNextColumn(); ImGui::Text("文件名"); ImGui::TableNextColumn(); ImGui::TextUnformatted(selectedAsset.RelativePath.filename().string().c_str());
ImGui::TableNextRow(); ImGui::TableNextColumn(); ImGui::Text("根显示名"); ImGui::TableNextColumn(); ImGui::TextUnformatted(importedDocument->RootDisplayName.c_str());
ImGui::TableNextRow(); ImGui::TableNextColumn(); ImGui::Text("类型"); ImGui::TableNextColumn(); ImGui::Text("%s (%s)", MetaCoreModelAssetKindLabel(importedDocument->ModelKind), importedDocument->SourceFormat.c_str());
ImGui::TableNextRow(); ImGui::TableNextColumn(); ImGui::Text("导入器"); ImGui::TableNextColumn(); ImGui::TextUnformatted(importedDocument->ImporterId.c_str());
ImGui::TableNextRow(); ImGui::TableNextColumn(); ImGui::Text("GUID"); ImGui::TableNextColumn(); ImGui::TextDisabled("%s", selectedAsset.Guid.ToString().c_str());
ImGui::TableNextRow(); ImGui::TableNextColumn(); ImGui::Text("来源"); ImGui::TableNextColumn(); ImGui::TextUnformatted(importedDocument->SourcePath.generic_string().c_str());
ImGui::TableNextRow(); ImGui::TableNextColumn(); ImGui::Text("资源包"); ImGui::TableNextColumn(); ImGui::TextUnformatted((!assetRecord->PackagePath.empty() ? assetRecord->PackagePath : assetRecord->RelativePath).generic_string().c_str());
ImGui::TableNextRow(); ImGui::TableNextColumn(); ImGui::Text("源文件哈希"); ImGui::TableNextColumn(); ImGui::Text("%llu", static_cast<unsigned long long>(importedDocument->SourceHash));
ImGui::TableNextRow(); ImGui::TableNextColumn(); ImGui::Text("节点"); ImGui::TableNextColumn(); ImGui::Text("%d", static_cast<int>(importedDocument->Nodes.size()));
ImGui::TableNextRow(); ImGui::TableNextColumn(); ImGui::Text("网格"); ImGui::TableNextColumn(); ImGui::Text("%d", static_cast<int>(importedDocument->GeneratedMeshAssets.size()));
ImGui::TableNextRow(); ImGui::TableNextColumn(); ImGui::Text("材质"); ImGui::TableNextColumn(); ImGui::Text("%d", static_cast<int>(importedDocument->GeneratedMaterialAssets.size()));
ImGui::TableNextRow(); ImGui::TableNextColumn(); ImGui::Text("贴图"); ImGui::TableNextColumn(); ImGui::Text("%d", static_cast<int>(importedDocument->GeneratedTextureAssets.size()));
ImGui::TableNextRow(); ImGui::TableNextColumn(); ImGui::Text("导入报告"); ImGui::TableNextColumn(); ImGui::Text("%s (警告:%d 错误:%d)", MetaCoreImportResultLabel(importedDocument->ImportReport.Result), warningCount, errorCount);
ImGui::EndTable();
}
if (ImGui::BeginTabBar("ModelTabs")) {
if (ImGui::BeginTabItem("Overview")) {
ImGui::TextDisabled("Imported Structure");
ImGui::BulletText("Source Mesh Entries: %d", static_cast<int>(importedDocument->Meshes.size()));
ImGui::BulletText("Source Material Entries: %d", static_cast<int>(importedDocument->Materials.size()));
ImGui::BulletText("Source Texture Entries: %d", static_cast<int>(importedDocument->Textures.size()));
ImGui::BulletText("Generated Mesh Assets: %d", static_cast<int>(importedDocument->GeneratedMeshAssets.size()));
ImGui::BulletText("Generated Material Assets: %d", static_cast<int>(importedDocument->GeneratedMaterialAssets.size()));
ImGui::BulletText("Generated Texture Assets: %d", static_cast<int>(importedDocument->GeneratedTextureAssets.size()));
if (ImGui::BeginTabItem("概览")) {
ImGui::TextDisabled("导入结构");
ImGui::BulletText("源网格条目: %d", static_cast<int>(importedDocument->Meshes.size()));
ImGui::BulletText("源材质条目: %d", static_cast<int>(importedDocument->Materials.size()));
ImGui::BulletText("源贴图条目: %d", static_cast<int>(importedDocument->Textures.size()));
ImGui::BulletText("生成网格资源: %d", static_cast<int>(importedDocument->GeneratedMeshAssets.size()));
ImGui::BulletText("生成材质资源: %d", static_cast<int>(importedDocument->GeneratedMaterialAssets.size()));
ImGui::BulletText("生成贴图资源: %d", static_cast<int>(importedDocument->GeneratedTextureAssets.size()));
ImGui::Separator();
ImGui::TextDisabled("Hierarchy Summary");
ImGui::TextDisabled("层级摘要");
std::size_t rootCount = 0;
std::size_t meshNodeCount = 0;
for (const auto& node : importedDocument->Nodes) {
rootCount += node.ParentIndex < 0 ? 1U : 0U;
meshNodeCount += node.MeshIndex >= 0 ? 1U : 0U;
}
ImGui::BulletText("Root Nodes: %d", static_cast<int>(rootCount));
ImGui::BulletText("Renderable Nodes: %d", static_cast<int>(meshNodeCount));
ImGui::BulletText("根节点: %d", static_cast<int>(rootCount));
ImGui::BulletText("可渲染节点: %d", static_cast<int>(meshNodeCount));
ImGui::Separator();
ImGui::TextDisabled("Import State");
ImGui::BulletText("Result: %s", MetaCoreImportResultLabel(importedDocument->ImportReport.Result));
ImGui::BulletText("Fallback Used: %s", importedDocument->ImportReport.UsedFallback ? "Yes" : "No");
ImGui::BulletText("Warnings: %d", warningCount);
ImGui::BulletText("Errors: %d", errorCount);
ImGui::TextDisabled("导入状态");
ImGui::BulletText("结果: %s", MetaCoreImportResultLabel(importedDocument->ImportReport.Result));
ImGui::BulletText("使用回退: %s", importedDocument->ImportReport.UsedFallback ? "" : "");
ImGui::BulletText("警告: %d", warningCount);
ImGui::BulletText("错误: %d", errorCount);
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem("Nodes")) {
if (ImGui::BeginTabItem("节点")) {
if (importedDocument->Nodes.empty()) {
ImGui::TextDisabled("No nodes imported.");
ImGui::TextDisabled("没有导入节点。");
} else {
DrawModelNodeTreeRecursive(editorContext, *importedDocument, importedDocument->SourcePath, -1);
const std::string& selectedAssetSubId = editorContext.GetSelectedAssetSubId();
@ -5533,45 +5546,45 @@ void DrawModelAssetDetails(MetaCoreEditorContext& editorContext, MetaCoreIAssetD
static_cast<std::size_t>(selectedNodeIndex) < importedDocument->Nodes.size()) {
const auto& selectedNode = importedDocument->Nodes[static_cast<std::size_t>(selectedNodeIndex)];
ImGui::Separator();
ImGui::TextDisabled("Selected Node");
ImGui::Text("Name: %s", selectedNode.Name.empty() ? "<Unnamed>" : selectedNode.Name.c_str());
ImGui::Text("Stable Path: %s", selectedNode.StableNodePath.empty() ? "<None>" : selectedNode.StableNodePath.c_str());
ImGui::Text("Index: %d", selectedNodeIndex);
ImGui::Text("Parent: %d", selectedNode.ParentIndex);
ImGui::Text("Mesh: %d", selectedNode.MeshIndex);
ImGui::TextDisabled("选中节点");
ImGui::Text("名称: %s", selectedNode.Name.empty() ? "<未命名>" : selectedNode.Name.c_str());
ImGui::Text("稳定路径: %s", selectedNode.StableNodePath.empty() ? "<>" : selectedNode.StableNodePath.c_str());
ImGui::Text("索引: %d", selectedNodeIndex);
ImGui::Text("父节点: %d", selectedNode.ParentIndex);
ImGui::Text("网格: %d", selectedNode.MeshIndex);
std::size_t childCount = 0;
for (const auto& node : importedDocument->Nodes) {
if (node.ParentIndex == selectedNodeIndex) {
++childCount;
}
}
ImGui::Text("Children: %d", static_cast<int>(childCount));
ImGui::Text("子节点: %d", static_cast<int>(childCount));
if (selectedNode.MeshIndex >= 0 &&
static_cast<std::size_t>(selectedNode.MeshIndex) < importedDocument->Meshes.size()) {
const auto& meshMeta = importedDocument->Meshes[static_cast<std::size_t>(selectedNode.MeshIndex)];
ImGui::Text("Mesh Name: %s", meshMeta.Name.empty() ? "<Unnamed>" : meshMeta.Name.c_str());
ImGui::Text("Primitives: %d", meshMeta.PrimitiveCount);
ImGui::Text("Material Slots: %d", static_cast<int>(meshMeta.MaterialSlots.size()));
ImGui::Text("网格名称: %s", meshMeta.Name.empty() ? "<未命名>" : meshMeta.Name.c_str());
ImGui::Text("图元: %d", meshMeta.PrimitiveCount);
ImGui::Text("材质槽位: %d", static_cast<int>(meshMeta.MaterialSlots.size()));
}
const auto refs = FindSceneObjectsUsingModelNode(
editorContext,
importedDocument->SourcePath,
selectedNodeIndex
);
ImGui::Text("Scene Instances: %d", static_cast<int>(refs.size()));
if (ImGui::Button("Highlight Scene Objects##Node")) {
ImGui::Text("场景实例: %d", static_cast<int>(refs.size()));
if (ImGui::Button("高亮场景对象##Node")) {
if (!refs.empty()) {
editorContext.SetSelection(refs, refs.front());
}
}
if (!refs.empty()) {
ImGui::SameLine();
if (ImGui::Button("Select First Instance##Node")) {
if (ImGui::Button("选择第一个实例##Node")) {
editorContext.SelectOnly(refs.front());
}
if (refs.size() > 1) {
ImGui::SameLine();
if (ImGui::Button("Select All Instances##Node")) {
if (ImGui::Button("选择全部实例##Node")) {
editorContext.SetSelection(refs, refs.front());
}
}
@ -5581,12 +5594,12 @@ void DrawModelAssetDetails(MetaCoreEditorContext& editorContext, MetaCoreIAssetD
}
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem("Meshes")) {
if (ImGui::BeginTabItem("网格")) {
if (ImGui::BeginTable("MeshesTable", 4, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg)) {
ImGui::TableSetupColumn("Name");
ImGui::TableSetupColumn("Verts", ImGuiTableColumnFlags_WidthFixed, 50);
ImGui::TableSetupColumn("Indices", ImGuiTableColumnFlags_WidthFixed, 50);
ImGui::TableSetupColumn("SubMeshes", ImGuiTableColumnFlags_WidthFixed, 60);
ImGui::TableSetupColumn("名称");
ImGui::TableSetupColumn("顶点", ImGuiTableColumnFlags_WidthFixed, 50);
ImGui::TableSetupColumn("索引", ImGuiTableColumnFlags_WidthFixed, 50);
ImGui::TableSetupColumn("子网格", ImGuiTableColumnFlags_WidthFixed, 60);
ImGui::TableHeadersRow();
for (const auto& mesh : importedDocument->GeneratedMeshAssets) {
ImGui::TableNextRow();
@ -5609,11 +5622,11 @@ void DrawModelAssetDetails(MetaCoreEditorContext& editorContext, MetaCoreIAssetD
}
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem("Materials")) {
if (ImGui::BeginTabItem("材质")) {
if (ImGui::BeginTable("MatsTable", 3, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg)) {
ImGui::TableSetupColumn("Name");
ImGui::TableSetupColumn("DoubleSided", ImGuiTableColumnFlags_WidthFixed, 30);
ImGui::TableSetupColumn("Alpha", ImGuiTableColumnFlags_WidthFixed, 60);
ImGui::TableSetupColumn("名称");
ImGui::TableSetupColumn("双面", ImGuiTableColumnFlags_WidthFixed, 30);
ImGui::TableSetupColumn("透明", ImGuiTableColumnFlags_WidthFixed, 60);
ImGui::TableHeadersRow();
for (const auto& mat : importedDocument->GeneratedMaterialAssets) {
ImGui::TableNextRow();
@ -5634,11 +5647,11 @@ void DrawModelAssetDetails(MetaCoreEditorContext& editorContext, MetaCoreIAssetD
sizeof(payload)
);
ImGui::TextUnformatted(mat.Name.c_str());
ImGui::TextDisabled("Material");
ImGui::TextDisabled("材质");
ImGui::EndDragDropSource();
}
ImGui::TableNextColumn(); ImGui::TextUnformatted(mat.DoubleSided ? "Y" : "-");
ImGui::TableNextColumn(); ImGui::TextUnformatted(mat.AlphaMode == MetaCoreMaterialAlphaMode::Blend ? "Blend" : (mat.AlphaMode == MetaCoreMaterialAlphaMode::Mask ? "Mask" : "Opaque"));
ImGui::TableNextColumn(); ImGui::TextUnformatted(mat.AlphaMode == MetaCoreMaterialAlphaMode::Blend ? "透明混合" : (mat.AlphaMode == MetaCoreMaterialAlphaMode::Mask ? "镂空裁剪" : "不透明"));
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("%s", mat.StableImportKey.c_str());
}
@ -5647,12 +5660,12 @@ void DrawModelAssetDetails(MetaCoreEditorContext& editorContext, MetaCoreIAssetD
}
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem("Textures")) {
if (ImGui::BeginTabItem("贴图")) {
if (ImGui::BeginTable("TexturesTable", 4, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg)) {
ImGui::TableSetupColumn("Name");
ImGui::TableSetupColumn("Usage", ImGuiTableColumnFlags_WidthFixed, 100);
ImGui::TableSetupColumn("Size", ImGuiTableColumnFlags_WidthFixed, 120);
ImGui::TableSetupColumn("Source");
ImGui::TableSetupColumn("名称");
ImGui::TableSetupColumn("用途", ImGuiTableColumnFlags_WidthFixed, 100);
ImGui::TableSetupColumn("尺寸", ImGuiTableColumnFlags_WidthFixed, 120);
ImGui::TableSetupColumn("来源");
ImGui::TableHeadersRow();
for (std::size_t textureIndex = 0; textureIndex < importedDocument->GeneratedTextureAssets.size(); ++textureIndex) {
const auto& textureAsset = importedDocument->GeneratedTextureAssets[textureIndex];
@ -5693,9 +5706,9 @@ void DrawModelAssetDetails(MetaCoreEditorContext& editorContext, MetaCoreIAssetD
}
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem("Animations")) {
if (ImGui::BeginTabItem("动画")) {
if (importedDocument->Animations.empty()) {
ImGui::TextDisabled("No animations imported.");
ImGui::TextDisabled("没有导入动画。");
} else {
const std::string previewKey = selectedAsset.Guid.ToString();
auto& previewState = ModelAnimationPreviewStates_[previewKey];
@ -5728,14 +5741,14 @@ void DrawModelAssetDetails(MetaCoreEditorContext& editorContext, MetaCoreIAssetD
}
const std::string currentClipLabel = selectedClip.Name.empty()
? ("Clip " + std::to_string(previewState.ClipIndex))
? ("动画片段 " + std::to_string(previewState.ClipIndex))
: selectedClip.Name;
ImGui::SetNextItemWidth(-1);
if (ImGui::BeginCombo("Clip##ModelAnimationPreview", currentClipLabel.c_str())) {
if (ImGui::BeginCombo("动画片段##ModelAnimationPreview", currentClipLabel.c_str())) {
for (std::size_t clipIndex = 0; clipIndex < importedDocument->Animations.size(); ++clipIndex) {
const auto& clip = importedDocument->Animations[clipIndex];
const std::string clipLabel = clip.Name.empty()
? ("Clip " + std::to_string(clipIndex))
? ("动画片段 " + std::to_string(clipIndex))
: clip.Name;
const bool selected = clipIndex == static_cast<std::size_t>(previewState.ClipIndex);
if (ImGui::Selectable(clipLabel.c_str(), selected)) {
@ -5750,16 +5763,16 @@ void DrawModelAssetDetails(MetaCoreEditorContext& editorContext, MetaCoreIAssetD
ImGui::EndCombo();
}
if (ImGui::Button(previewState.Playing ? "Pause##ModelAnimationPreview" : "Play##ModelAnimationPreview")) {
if (ImGui::Button(previewState.Playing ? "暂停##ModelAnimationPreview" : "播放##ModelAnimationPreview")) {
previewState.Playing = !previewState.Playing;
}
ImGui::SameLine();
if (ImGui::Button("Stop##ModelAnimationPreview")) {
if (ImGui::Button("停止##ModelAnimationPreview")) {
previewState.Playing = false;
previewState.TimeSeconds = 0.0F;
}
ImGui::SameLine();
if (ImGui::Button("Instantiate and Play##ModelAnimationPreview")) {
if (ImGui::Button("实例化并播放##ModelAnimationPreview")) {
if (const auto instantiatedRootId = MetaCoreInstantiateModelAsset(editorContext, selectedAsset.Guid, std::nullopt);
instantiatedRootId.has_value()) {
if (MetaCoreGameObject rootObject = editorContext.GetScene().FindGameObject(*instantiatedRootId);
@ -5781,17 +5794,17 @@ void DrawModelAssetDetails(MetaCoreEditorContext& editorContext, MetaCoreIAssetD
}
const float sliderMax = durationSeconds > 0.0F ? durationSeconds : std::max(1.0F, previewState.TimeSeconds);
ImGui::SliderFloat("Time##ModelAnimationPreview", &previewState.TimeSeconds, 0.0F, sliderMax, "%.3f s");
ImGui::DragFloat("Speed##ModelAnimationPreview", &previewState.Speed, 0.05F, 0.0F, 8.0F);
ImGui::SliderFloat("时间##ModelAnimationPreview", &previewState.TimeSeconds, 0.0F, sliderMax, "%.3f s");
ImGui::DragFloat("速度##ModelAnimationPreview", &previewState.Speed, 0.05F, 0.0F, 8.0F);
previewState.Speed = std::max(0.0F, previewState.Speed);
ImGui::Checkbox("Loop##ModelAnimationPreview", &previewState.Loop);
ImGui::Checkbox("循环##ModelAnimationPreview", &previewState.Loop);
if (ImGui::BeginTable("AnimationsTable", 5, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg)) {
ImGui::TableSetupColumn("Name");
ImGui::TableSetupColumn("Duration", ImGuiTableColumnFlags_WidthFixed, 80);
ImGui::TableSetupColumn("Channels", ImGuiTableColumnFlags_WidthFixed, 70);
ImGui::TableSetupColumn("Samplers", ImGuiTableColumnFlags_WidthFixed, 70);
ImGui::TableSetupColumn("Targets", ImGuiTableColumnFlags_WidthFixed, 70);
ImGui::TableSetupColumn("名称");
ImGui::TableSetupColumn("时长", ImGuiTableColumnFlags_WidthFixed, 80);
ImGui::TableSetupColumn("通道", ImGuiTableColumnFlags_WidthFixed, 70);
ImGui::TableSetupColumn("采样器", ImGuiTableColumnFlags_WidthFixed, 70);
ImGui::TableSetupColumn("目标", ImGuiTableColumnFlags_WidthFixed, 70);
ImGui::TableHeadersRow();
for (std::size_t clipIndex = 0; clipIndex < importedDocument->Animations.size(); ++clipIndex) {
const auto& clip = importedDocument->Animations[clipIndex];
@ -5799,7 +5812,7 @@ void DrawModelAssetDetails(MetaCoreEditorContext& editorContext, MetaCoreIAssetD
ImGui::TableNextColumn();
const bool selected = clipIndex == static_cast<std::size_t>(previewState.ClipIndex);
const std::string label = clip.Name.empty()
? ("Clip " + std::to_string(clipIndex))
? ("动画片段 " + std::to_string(clipIndex))
: clip.Name;
if (ImGui::Selectable(label.c_str(), selected, ImGuiSelectableFlags_SpanAllColumns)) {
previewState.ClipIndex = static_cast<std::int32_t>(clipIndex);
@ -5823,18 +5836,18 @@ void DrawModelAssetDetails(MetaCoreEditorContext& editorContext, MetaCoreIAssetD
}
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem("Import Settings")) {
if (ImGui::BeginTabItem("导入设置")) {
// 当前阶段 Import Settings 为只读显示,后续迭代再开放编辑
const char* upAxisNames[] = {"Preserve Source", "Y-Up", "Z-Up", "X-Up"};
const char* upAxisNames[] = {"保留源文件", "Y 轴向上", "Z 轴向上", "X 轴向上"};
const int upAxisIndex = static_cast<int>(importedDocument->ImportSettings.UpAxis);
ImGui::Text("Up Axis: %s", (upAxisIndex >= 0 && upAxisIndex < 4) ? upAxisNames[upAxisIndex] : "Unknown");
ImGui::Text("Scale Factor: %.3f", importedDocument->ImportSettings.ScaleFactor);
ImGui::Text("Preserve Hierarchy: %s", importedDocument->ImportSettings.PreserveHierarchy ? "Yes" : "No");
ImGui::Text("Preserve Empty Nodes: %s", importedDocument->ImportSettings.PreserveEmptyNodes ? "Yes" : "No");
ImGui::Text("Preserve Material Slots: %s", importedDocument->ImportSettings.PreserveMaterialSlots ? "Yes" : "No");
ImGui::Text("向上轴: %s", (upAxisIndex >= 0 && upAxisIndex < 4) ? upAxisNames[upAxisIndex] : "未知");
ImGui::Text("缩放系数: %.3f", importedDocument->ImportSettings.ScaleFactor);
ImGui::Text("保留层级: %s", importedDocument->ImportSettings.PreserveHierarchy ? "" : "");
ImGui::Text("保留空节点: %s", importedDocument->ImportSettings.PreserveEmptyNodes ? "" : "");
ImGui::Text("保留材质槽位: %s", importedDocument->ImportSettings.PreserveMaterialSlots ? "" : "");
ImGui::Separator();
if (ImGui::Button("Reimport")) {
if (ImGui::Button("重新导入")) {
if (importPipelineService != nullptr && importPipelineService->ReimportAsset(selectedAsset.Guid)) {
(void)assetDatabaseService.Refresh();
editorContext.AddConsoleMessage(MetaCoreLogLevel::Info, "Import", "模型重新导入完成");
@ -5845,14 +5858,14 @@ void DrawModelAssetDetails(MetaCoreEditorContext& editorContext, MetaCoreIAssetD
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem("Import Report")) {
ImGui::Text("Result: %s", MetaCoreImportResultLabel(importedDocument->ImportReport.Result));
ImGui::Text("Fallback Used: %s", importedDocument->ImportReport.UsedFallback ? "Yes" : "No");
ImGui::Text("Warnings: %d", warningCount);
ImGui::Text("Errors: %d", errorCount);
if (ImGui::BeginTabItem("导入报告")) {
ImGui::Text("结果: %s", MetaCoreImportResultLabel(importedDocument->ImportReport.Result));
ImGui::Text("使用回退: %s", importedDocument->ImportReport.UsedFallback ? "" : "");
ImGui::Text("警告: %d", warningCount);
ImGui::Text("错误: %d", errorCount);
ImGui::Separator();
if (importedDocument->ImportReport.Messages.empty()) {
ImGui::TextDisabled("No import messages recorded.");
ImGui::TextDisabled("没有导入消息。");
} else {
for (std::size_t messageIndex = 0; messageIndex < importedDocument->ImportReport.Messages.size(); ++messageIndex) {
const MetaCoreImportMessageDocument& message = importedDocument->ImportReport.Messages[messageIndex];
@ -5884,21 +5897,21 @@ void DrawModelAssetDetails(MetaCoreEditorContext& editorContext, MetaCoreIAssetD
MetaCoreFindGeneratedResourceEntry(generatedEntries, selectedGeneratedGuid);
const std::string selectedLabel =
selectedEntry != nullptr
? selectedEntry->Kind + " | " + selectedEntry->Name
: selectedGeneratedKind + " | " + selectedGeneratedGuid.ToString();
ImGui::TextColored(ImVec4(0.2F, 0.7F, 0.9F, 1.0F), "Selected: %s", selectedLabel.c_str());
if (selectedGeneratedKind == "mesh" && ImGui::Button("Highlight Scene Objects")) {
? std::string(MetaCoreGeneratedResourceKindLabel(selectedEntry->Kind)) + " | " + selectedEntry->Name
: std::string(MetaCoreGeneratedResourceKindLabel(selectedGeneratedKind)) + " | " + selectedGeneratedGuid.ToString();
ImGui::TextColored(ImVec4(0.2F, 0.7F, 0.9F, 1.0F), "已选中: %s", selectedLabel.c_str());
if (selectedGeneratedKind == "mesh" && ImGui::Button("高亮场景对象")) {
const auto refs = FindSceneObjectsUsingMesh(editorContext, selectedGeneratedGuid);
if (!refs.empty()) editorContext.SetSelection(refs, refs.front());
} else if (selectedGeneratedKind == "material" && ImGui::Button("Highlight Scene Objects")) {
} else if (selectedGeneratedKind == "material" && ImGui::Button("高亮场景对象")) {
const auto refs = FindSceneObjectsUsingMaterial(editorContext, selectedGeneratedGuid);
if (!refs.empty()) editorContext.SetSelection(refs, refs.front());
} else if (selectedGeneratedKind == "texture" && ImGui::Button("Highlight Scene Objects")) {
} else if (selectedGeneratedKind == "texture" && ImGui::Button("高亮场景对象")) {
const auto refs = FindSceneObjectsUsingTexture(editorContext, *importedDocument, selectedGeneratedGuid);
if (!refs.empty()) editorContext.SetSelection(refs, refs.front());
}
ImGui::SameLine();
if (ImGui::Button("Unselect")) editorContext.ClearSelectedAssetSubId();
if (ImGui::Button("取消选择")) editorContext.ClearSelectedAssetSubId();
}
if (hasSelectedGeneratedResource && selectedGeneratedKind == "material") {
@ -6110,17 +6123,17 @@ void DrawPrefabDetails(MetaCoreEditorContext& editorContext, MetaCoreIAssetDatab
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(4, 4));
if (ImGui::BeginChild("PrefabInspector", ImVec2(0, 0), true, 0)) {
ImGui::TextDisabled("PREFAB ASSET");
ImGui::TextDisabled("预制体资源");
ImGui::Separator();
ImGui::Text("名称: %s", summary->Name.c_str());
ImGui::Text("对象总数: %d", (int)summary->ObjectCount);
ImGui::Text("根节点数: %d", (int)summary->RootCount);
if (summary->RootCount > 0) {
ImGui::Text("Root Nodes:");
ImGui::Text("根节点:");
for (const auto& rootName : summary->RootNames) ImGui::BulletText("%s", rootName.c_str());
}
ImGui::Spacing();
if (ImGui::Button("Open in Editor", ImVec2(-1, 0))) { /* Logic */ }
if (ImGui::Button("在编辑器中打开", ImVec2(-1, 0))) { /* Logic */ }
}
ImGui::EndChild();
ImGui::PopStyleVar();
@ -6137,13 +6150,13 @@ void DrawUiDocumentDetails(MetaCoreEditorContext& editorContext, MetaCoreIAssetD
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(4, 4));
if (ImGui::BeginChild("UiInspector", ImVec2(0, 0), true, 0)) {
ImGui::TextDisabled("UI DOCUMENT");
ImGui::TextDisabled("UI 文档");
ImGui::Separator();
ImGui::Text("名称: %s", summary->Name.c_str());
ImGui::Text("节点总数: %d", (int)summary->NodeCount);
ImGui::Text("根节点数: %d", (int)summary->RootCount);
ImGui::Spacing();
if (ImGui::Button("Edit Layout", ImVec2(-1, 0))) { /* Logic */ }
if (ImGui::Button("编辑布局", ImVec2(-1, 0))) { /* Logic */ }
}
ImGui::EndChild();
ImGui::PopStyleVar();
@ -6362,7 +6375,7 @@ void MetaCoreDrawAssetInspector(MetaCoreEditorContext& editorContext, MetaCoreIA
ImGui::Separator();
ImGui::Text("资源: %s", selectedAsset.RelativePath.filename().string().c_str());
ImGui::TextDisabled("类型: %s", selectedAsset.Type.c_str());
ImGui::TextDisabled("Guid: %s", selectedAsset.Guid.ToString().c_str());
ImGui::TextDisabled("GUID: %s", selectedAsset.Guid.ToString().c_str());
}
}
@ -7998,7 +8011,7 @@ public:
MetaCoreHasMeshRendererOverride(selectedObject, *prefabSourceObject);
}
ImGui::Text("Prefab 实例%s", hasAnyOverride ? " [覆盖]" : "");
ImGui::Text("预制体实例%s", hasAnyOverride ? " [覆盖]" : "");
ImGui::SameLine();
if (ImGui::SmallButton("应用")) {
(void)MetaCoreApplySelectedPrefabInstance(editorContext);