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 @@
+
+
+
+
+
+
+
+ 导出为 SMAP (.smap)
+ 导出为 IRAY (.zip)
+
+
+
+
+
+
+
+
+ 点击或拖拽 SMAP 文件到此区域
+ 必须提供一个基础 .smap 文件用于导出。
+
+
+
+
+
IRAY 转换参数 (必填)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
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('导出') }}
- 导出为 SMAP (.smap)
- 导出为 IRAY (.zip)
+ 导出为其他格式
@@ -396,6 +378,8 @@ const handleAutoCreateStorageCancel = () => {
+
+