Hook into Export functionality, or add Publish functionality

Hello,

My company is looking to replace another 3D engine and its editor (Sumerian) with BabylonJS in our production websites. It looks like both will fit our needs and be a great addition to our tech stack, but there is one absence that we need to address in our artists’ workflow.

The editor for Sumerian integrates with AWS services to basically do the following (let’s call it the “publishing process”, exposed by a publish button:

  1. Bundle scene assets into proprietary .sumerian format
  2. Upload the files to an S3 bucket fronted by a CloudFront CDN
  3. Invalidate the CloudFront files so that the latest version is fetched and served by the CDN edge caches

We then have a module (the “top level” or “parent” scene) that uses the Sumerian scene loader to orchestrate the dynamic loading and unloading of other scenes (“child” scenes).

We intend to replace our Sumerian editor-based workflow with the Babylon desktop editor, but our scene loading architecture – and the performance of our website, which has many very small scenes and then a few very heavy scenes – benefits heavily from downloading a copy of scene at runtime. Most of the time this will be a cache hit, either in the browser cache or the CDN cache, but after the publishing process is run, we would expect it to be a cache miss and the user would download the fresh copy and load that at runtime.

Is there any way currently to hook into the Export function, or add a Publish function and a hook into it, that would allow us to mimic this functionality? All we need is the ability to run a Javascript callback on export (and ideally the path of the exported file).

Thank you for all you are doing! We are excited to work with Babylon.

Jeremy

3 Likes

Hi Jeremy,

Very happy to read this post :slight_smile:

I assume you want to export the scene to the .babylon format and store it. First, babylon has an internal cache support that might come in handy here - Optimize using Cached Resources - Babylon.js Documentation . Second - the Serialize function (of the scene serializer) is not async, so no callback is needed when calling it. You can call this function whwnever you want to update the scene, and after it finishes have it invalidate the file uploaded.

I noticed you wrote that you are planning on working with the editor. If it is an editor-specific question, @julien-moreau who is responsible for it will be the best person to answer (and the happiest person to know that you are using the desktop editor :slight_smile: )

1 Like

As @RaananW said, this is an amazing news ! @Deltakosh will be glad to read this in the morning.

About the editor, I bet @julien-moreau will be so pumped by the news he ll add the missing feature in no time :slight_smile:

1 Like

Hey Raanan,

Thanks for the link – great to know that I could setup a workflow outside of the Babylon Editor proper to serialize and upload the scenes, say as part of a pre- or post-commit hook. That being said it would definitely be better for our artists to have a one-click method that would not require setting up per-scene repositories or anything like that.

Looking forward to hearing from @julien-moreau. One question: is the editor open source? Couldn’t find a repository for it.

@sebavan Happy to provide some good news lol. I’m sure you will be seeing a lot of new usernames around here in short order as my coworkers start asking more questions.

2 Likes

Here is the repo GitHub - BabylonJS/Editor: Visual editor for Babylon.js if you want to contribute.

1 Like

Awesome! I just took a look at the source, and it looks like I would just need to modify toolbar.ts to add the publish button and it’s click handler. I’ll need to continue reading the source to see how to generate the modal with options fields. It looks like most of the other toolbar functions are handled by a static method on a “singleton”, so I imagine I’ll be adding a new method and some new properties to the Tools class?

I also need to take a look and see if the editor currently has a way of grabbing AWS credentials (~/.aws/credentials on linux) from the local filesystem to authorize the AWS service client objects – I’m leaning towards a provider dropdown, then when selecting AWS from the dropdown, requiring the bucket name, file prefix (its path), cloudfront distribution ID, and profile name. I think that’s the minimum information necessary to bake in this functionality for AWS as a CDN provider.

@julien-moreau @sebavan what do you think? I’d hate for my first PR to be hot garbage so bear with me while I get up to speed on your standards.

Edit: did the easy part, and in terms of the functionality I’m creating a scene-publisher.ts class using scene-serializer.ts as a scaffold. Hopefully I’ll have a decent pull request tomorrow for @julien-moreau to look at. image

1 Like

I could definitely use some feedback on how to keep this provider-generic – I’m not sure how to make fields dependent on the selected provider with the current setup of creating a new Window. I figure there’s a couple of options:

  1. Change from having a Publish Scene… option to a Publish to AWS…, Publish to Azure…, et cetera – one option per provider
  2. Move the CDN provider to Project Settings, then use that to determine what Form to render. Select AWS as the provider for project and it would render the form with the AWS profile, bucket name, distribution id, and S3 object path.

@julien-moreau would you mind sharing your thoughts?

2 Likes

@jkeys excellent !!! And sure I’m happy :slight_smile:

First, I suggest that you start from the v4 (that will be released in few weeks) of the editor instead of the v3. The v4 is based on React and doesn’t need you to understand the custom UI system of the v3 (that is less powerful than the react one).

The v4 has been developed from scratch and is aimed to be more flexible, more powerful, more maintainable etc.

What I suggest is:

  • Add the publish feature directly on the editor as a generic feature (as you said)
  • Or, I can add a plugin system to the editor so the publish feature can be the one you are developing or only your custom system to publish your scenes (no need to be a generic feature)

The latest v4 commit is located on the branch “feature/react”: GitHub - BabylonJS/Editor at feature/react

The plugin system I’m talking would allow you to add a custom menu to the toolbar, add custom panels in the editor etc. Are you more interested by a plugin system? Or more interested to contribute and add a generic publish feature?

According to your answer, I’ll begin the plugin system right now. Or, will help you to integrate the generic publish system in the v4 :slight_smile:

You rox!

2 Likes

As additional informations, the v4 is a full Electron app. That means you have full access to node.js and Electron features (including native modules). What you can do with node.js can be done with the editor :slight_smile:

1 Like

Hey @julien-moreau,

That sounds great, our websites actually use React so I’d be happy to start porting my changes in a fork of the feature/react branch.

I think we’d be happy with a plugin system which would allow us to customize the plugin more to our workflow (we could also contribute a generic version of the publish plugin to your codebase). Publish functionality probably more properly resides in a plugin system anyway.

Thank you! Looking forward to seeing details on the plugin system.

Jeremy

1 Like

Excellent, just started the plugins system. I’m creating a sample plugin on the repo. Will let you know once done :slight_smile:

1 Like

This is great! As soon as I have some more details on the plugin system I’ll start porting what I’ve got into a new plugin.

I took a look at your initial scaffold commit, LGTM :wink: :smiley:

One question in anticipation: if I wanted to cache the provider and scene publish settings – manual entry every time would defeat the point of the plugin – would I do that in localStorage? In general how do you prefer I export/import editor scene data to/from the local filesystem?

1 Like

@jkeys excellent question :slight_smile:

Using local storage will be scoped to the Babylon.JS Editor App itself. That means it will not create collisions with other local storages of other apps or web browsers.

For me, but I can be wrong, I don’t see any problem that the plugin uses the local storage to save preferences. Just delimitate the name like “publish-plugin-amazon-settings” for example.

Also, what i propose is to also save the settings of the plugin for the current workspace being opened in the editor.

The plugin can implement “get” and “set” for preferences that will be called on the project is being saved by the user and when the project is being loaded.

export interface IPlugin {
    /**
     * Defines the list of all toolbar elements to add when the plugin has been loaded.
     */
    toolbar?: Undefinable<IPluginToolbar[]>;

    /**
     * If implemented, should return an object (plain JSON object) that will be saved
     * in the workspace file. This will be typically used to store preferences of the plugin
     * work a given workspace and not globally.
     * If implemented, the preferences will be saved in the .editorworkspace file each time the user
     * saves the project.
     */
    getWorkspacePreferences?: () => any;
    /**
     * When the plugin saved preferences (@see .getWorkspacePreferences) this function
     * will be called giving the plain JSON representation of the user's preferences for
     * the current plugin.
     */
    setWorkspacePreferences?: (preferences: any) => void;
}

What do you think about that ?

1 Like

That looks like a great solution – per-workspace settings is the best I think. I’ll implement setWorkspacePreferences getWorkspacePreferences with calls to localStorage using the notation you provided to avoid namespace collisions. Thanks for the input!

Excellent! Plugins system is almost ready, just trying to polish and be sure this will be a good way to manage plugins in the editor

Once done, i’lol publish the « babylonjs-editor » module that contains the editor typingS so your plugin can be developed outside the editor’s directory :slight_smile:

2 Likes

The editor is using @blueprintjs for the react component libraries. Are you familiar with it ?

If not, you can use your own by adding the dependency in your package.json file but it is preferable to have the same lib for the UI so the plugin will have the same look

1 Like

I’m familiar with it in passing; as far as I’m concerned if you’ve used one component library, you’ve used them all. (I feel a great disturbance in the force – as if a million component library authors cried out in terror, and were suddenly silenced.) :smiley:

It’s your project, so I’ll stick with your dependencies and use the relevant BlueprintJS components.

Excellent! =D

As dicussed, I released the version 4.0.0-beta.1 and explained the way to add plugins here: Add Plugins System · Issue #186 · BabylonJS/Editor · GitHub

Let me know in the issue if you encounter any problem :slight_smile:
Thanks!

3 Likes

Apologies for my double-posting excitement lol. I’m glad to continue the code-scale conversation on Github to spare the readers of this forum.

2 Likes

The first version of this plugin has been released! Install and usage instructions can be found on the Github README.

Some TODOs and enhancements:

  1. Robust support for gLTF and .babylon formats – currently only .glb is fully supported
  2. Support for other cloud providers (Azure, GCP, Rackspace)
  3. Generate and display (with copy to clipboard button) the URL(s) that correspond to the uploaded object path
2 Likes