@@ -2,12 +2,14 @@ import { ipcRenderer } from "electron";
22import { dirname , join } from "path/posix" ;
33
44import { Component , ReactNode } from "react" ;
5+ import { writeJSON } from "fs-extra" ;
6+ import { toast } from "sonner" ;
57
68import { Menubar , MenubarContent , MenubarItem , MenubarMenu , MenubarSeparator , MenubarShortcut , MenubarTrigger } from "../../ui/shadcn/ui/menubar" ;
79
810import { isDarwin } from "../../tools/os" ;
911import { execNodePty } from "../../tools/node-pty" ;
10- import { openSingleFileDialog } from "../../tools/dialog" ;
12+ import { openSingleFileDialog , openSingleFolderDialog } from "../../tools/dialog" ;
1113import { visualStudioCodeAvailable } from "../../tools/process" ;
1214
1315import { showConfirm } from "../../ui/dialog" ;
@@ -22,6 +24,7 @@ import { getMeshCommands } from "../dialogs/command-palette/mesh";
2224import { getLightCommands } from "../dialogs/command-palette/light" ;
2325import { getCameraCommands } from "../dialogs/command-palette/camera" ;
2426import { ICommandPaletteType } from "../dialogs/command-palette/command-palette" ;
27+ import { SceneSerializer } from "babylonjs" ;
2528
2629export 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}
0 commit comments