From b665cd20322a17a7893936b3b3f1686a7b4a9ca5 Mon Sep 17 00:00:00 2001 From: xudan Date: Thu, 25 Sep 2025 17:03:42 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=9B=B4=E6=96=B0=E5=9C=BA=E6=99=AF?= =?UTF-8?q?=E8=BD=AC=E6=8D=A2=E5=8A=9F=E8=83=BD=EF=BC=8C=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E5=9C=A8=E5=AF=BC=E5=87=BA=E6=97=B6=E4=BC=A0=E9=80=92=20IRAY?= =?UTF-8?q?=20=E5=8F=82=E6=95=B0=EF=BC=8C=E4=BC=98=E5=8C=96=E5=AF=BC?= =?UTF-8?q?=E5=87=BA=E9=80=BB=E8=BE=91=E5=92=8C=E7=94=A8=E6=88=B7=E4=BA=A4?= =?UTF-8?q?=E4=BA=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/modal/ExportConverterModal.vue | 163 ++++++++++++++++++ src/hooks/useMapConversion.ts | 15 +- src/pages/scene-editor.vue | 50 ++---- 3 files changed, 194 insertions(+), 34 deletions(-) create mode 100644 src/components/modal/ExportConverterModal.vue diff --git a/src/components/modal/ExportConverterModal.vue b/src/components/modal/ExportConverterModal.vue new file mode 100644 index 0000000..8010a53 --- /dev/null +++ b/src/components/modal/ExportConverterModal.vue @@ -0,0 +1,163 @@ + + + diff --git a/src/hooks/useMapConversion.ts b/src/hooks/useMapConversion.ts index 96b426a..aac5326 100644 --- a/src/hooks/useMapConversion.ts +++ b/src/hooks/useMapConversion.ts @@ -90,7 +90,12 @@ export function useMapConversion() { } }; - const convertSceneToIray = async (sceneJson: string, smapFile: File, filename: string) => { + const convertSceneToIray = async ( + sceneJson: string, + smapFile: File, + filename: string, + irayParams?: { mapWidth: number; mapHeight: number; xAttrMin: number; yAttrMin: number }, + ) => { isConverting.value = true; try { const formData = new FormData(); @@ -98,6 +103,14 @@ export function useMapConversion() { formData.append('scene_file', sceneBlob, `${filename}.scene`); formData.append('smap_file', smapFile); + // Append IRAY parameters if they exist + if (irayParams) { + formData.append('map_width', String(irayParams.mapWidth)); + formData.append('map_height', String(irayParams.mapHeight)); + formData.append('x_attr_min', String(irayParams.xAttrMin)); + formData.append('y_attr_min', String(irayParams.yAttrMin)); + } + const response = await mapConverterHttp.post(`${API_BASE_URL}/smap-to-iray`, formData, { headers: { 'Content-Type': 'multipart/form-data' }, responseType: 'blob', diff --git a/src/pages/scene-editor.vue b/src/pages/scene-editor.vue index 2f0cbfc..817c52f 100644 --- a/src/pages/scene-editor.vue +++ b/src/pages/scene-editor.vue @@ -8,6 +8,7 @@ import expandIcon from '../assets/icons/png/expand.png'; import foldIcon from '../assets/icons/png/fold.png'; import BatchEditToolbar from '../components/batch-edit-toolbar.vue'; import AutoCreateStorageModal from '../components/modal/auto-create-storage-modal.vue'; +import ExportConverterModal, { type ExportConfirmPayload } from '../components/modal/ExportConverterModal.vue'; import ImportSmapModal from '../components/modal/ImportSmapModal.vue'; import { useMapConversion } from '../hooks/useMapConversion'; import { EditorService } from '../services/editor.service'; @@ -163,13 +164,7 @@ const importScene = async () => { const importSmapModalVisible = ref(false); -const handleImportSmapConfirm = async ({ - smapFile, - keepProperties, -}: { - smapFile: File; - keepProperties: boolean; -}) => { +const handleImportSmapConfirm = async ({ smapFile, keepProperties }: { smapFile: File; keepProperties: boolean }) => { let sceneJson: string | null = null; if (keepProperties) { // Update mode @@ -209,6 +204,8 @@ const importBinTask = async () => { }; // --- Export Logic --- +const exportModalVisible = ref(false); + const exportScene = () => { const json = editor.value?.save(); if (!json) return; @@ -219,37 +216,23 @@ const exportScene = () => { URL.revokeObjectURL(url); }; -const exportSmap = async () => { +const handleExportConfirm = async (payload: ExportConfirmPayload) => { const sceneJson = editor.value?.save(); if (!sceneJson) { message.error('无法获取当前场景数据,请确保场景不为空'); return; } - message.info('请选择一个基础 SMAP 文件用于导出'); - const smapFile = await selectFile('.smap'); - if (!smapFile) return; - - const sceneBlob = new Blob([sceneJson], { type: 'application/json' }); - const sceneFile = new File([sceneBlob], `${title.value || 'current'}.scene`, { - type: 'application/json', - }); - - await exportSceneToSmap(sceneFile, smapFile, smapFile.name.replace(/\.smap$/i, '')); -}; - -const exportAsIray = async () => { - const json = editor.value?.save(); - if (!json) { - message.error('无法获取当前场景数据,请确保场景不为空'); - return; + if (payload.format === 'smap') { + const sceneBlob = new Blob([sceneJson], { type: 'application/json' }); + const sceneFile = new File([sceneBlob], `${title.value || 'current'}.scene`, { + type: 'application/json', + }); + await exportSceneToSmap(sceneFile, payload.smapFile, payload.smapFile.name.replace(/\.smap$/i, '')); + } else if (payload.format === 'iray') { + // @ts-ignore + await convertSceneToIray(sceneJson, payload.smapFile, title.value || 'unknown', payload.irayParams); } - - message.info('请选择一个 SMAP 文件用于 IRAY 导出'); - const smapFile = await selectFile('.smap'); - if (!smapFile) return; - - await convertSceneToIray(json, smapFile, title.value || 'unknown'); }; const show = ref(true); @@ -340,8 +323,7 @@ const handleAutoCreateStorageCancel = () => { {{ $t('导出') }} @@ -396,6 +378,8 @@ const handleAutoCreateStorageCancel = () => { + +