Skip to content

Commit e376f7d

Browse files
Yuri Pourreyuripourre
authored andcommitted
feat: Add context menu item to export scene
1 parent 7f55483 commit e376f7d

File tree

2 files changed

+42
-1
lines changed

2 files changed

+42
-1
lines changed

editor/src/editor/layout/toolbar.tsx

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@ import { ipcRenderer } from "electron";
22
import { dirname, join } from "path/posix";
33

44
import { Component, ReactNode } from "react";
5+
import { writeJSON } from "fs-extra";
6+
import { toast } from "sonner";
57

68
import { Menubar, MenubarContent, MenubarItem, MenubarMenu, MenubarSeparator, MenubarShortcut, MenubarTrigger } from "../../ui/shadcn/ui/menubar";
79

810
import { isDarwin } from "../../tools/os";
911
import { execNodePty } from "../../tools/node-pty";
10-
import { openSingleFileDialog } from "../../tools/dialog";
12+
import { openSingleFileDialog, openSingleFolderDialog } from "../../tools/dialog";
1113
import { visualStudioCodeAvailable } from "../../tools/process";
1214

1315
import { showConfirm } from "../../ui/dialog";
@@ -22,6 +24,7 @@ import { getMeshCommands } from "../dialogs/command-palette/mesh";
2224
import { getLightCommands } from "../dialogs/command-palette/light";
2325
import { getCameraCommands } from "../dialogs/command-palette/camera";
2426
import { ICommandPaletteType } from "../dialogs/command-palette/command-palette";
27+
import { SceneSerializer } from "babylonjs";
2528

2629
export interface IEditorToolbarProps {
2730
editor: Editor;
@@ -37,6 +40,7 @@ export class EditorToolbar extends Component<IEditorToolbarProps> {
3740

3841
ipcRenderer.on("editor:open-project", () => this._handleOpenProject());
3942
ipcRenderer.on("editor:open-vscode", () => this._handleOpenVisualStudioCode());
43+
ipcRenderer.on("editor:export-scene-babylon", () => this._handleExportSceneBabylon());
4044

4145
this._meshCommands = getMeshCommands(this.props.editor);
4246
this._lightCommands = getLightCommands(this.props.editor);
@@ -83,6 +87,8 @@ export class EditorToolbar extends Component<IEditorToolbarProps> {
8387
Export <MenubarShortcut>CTRL+G</MenubarShortcut>
8488
</MenubarItem>
8589

90+
<MenubarItem onClick={() => this._handleExportSceneBabylon()}>Export Scene (.babylon)</MenubarItem>
91+
8692
<MenubarSeparator />
8793

8894
<MenubarItem disabled={!visualStudioCodeAvailable} onClick={() => this._handleOpenVisualStudioCode()}>
@@ -224,4 +230,35 @@ export class EditorToolbar extends Component<IEditorToolbarProps> {
224230
const p = await execNodePty(`code "${join(dirname(this.props.editor.state.projectPath), "/")}"`);
225231
await p.wait();
226232
}
233+
234+
private async _handleExportSceneBabylon(): Promise<void> {
235+
const folderPath = openSingleFolderDialog("Select folder to save the .babylon file");
236+
if (!folderPath) {
237+
return;
238+
}
239+
240+
try {
241+
const scene = this.props.editor.layout.preview.scene;
242+
const data = await SceneSerializer.SerializeAsync(scene);
243+
244+
// Generate a filename with date and time
245+
const now = new Date();
246+
const dateStr = now.toISOString().replace(/[:.]/g, "-").replace("T", "_").split("Z")[0];
247+
const fileName = `scene_${dateStr}.babylon`;
248+
const filePath = join(folderPath, fileName);
249+
250+
await writeJSON(filePath, data, {
251+
spaces: 4,
252+
encoding: "utf8",
253+
});
254+
255+
this.props.editor.layout.console.log(`Scene exported successfully to ${filePath}`);
256+
toast.success(`Scene exported successfully to ${filePath}`);
257+
} catch (e) {
258+
if (e instanceof Error) {
259+
this.props.editor.layout.console.error(`Error exporting scene: ${e.message}`);
260+
toast.error("Error exporting scene");
261+
}
262+
}
263+
}
227264
}

editor/src/editor/menu.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ export function setupEditorMenu(): void {
5252
accelerator: "CommandOrControl+G",
5353
click: () => BrowserWindow.getFocusedWindow()?.webContents.send("export"),
5454
},
55+
{
56+
label: "Export Scene (.babylon)",
57+
click: () => BrowserWindow.getFocusedWindow()?.webContents.send("editor:export-scene-babylon"),
58+
},
5559
{
5660
type: "separator",
5761
},

0 commit comments

Comments
 (0)