Auto Spec

When to use it?

There are some scenarios where you don't really want to use the Spec features.

On the one hand this can be the case for very simple applications where you just want to display and switch between certain 3d models. In this case there is no need for "element" or "parameter" definition, therefore the Spec doesn't really provide any advantages.

On the other hand there can be very complex applications which can not be solved with standard Spec functionalities. In this case the user typically wants to bypass the Spec and viewer features and directly program vanilla Babylon.js code. Some examples are:

  • Mesh clicking observers for "hotspots"
  • Drawing additional meshes using the MeshBuilder
  • "Parametric" programming with Morph Targets

Even if the Spec is not needed here, it is required for bootstrapping the viewer! However this task has now been automated, as described in the following chapter.

How to use it?

The Spec generation can be triggered with Viewer.generateSpec:

const genData: SpecGenerationData[] = [
{
name: 'Cup',
url: '...basePath/Cup.babylon',
},
{
name: 'Plate',
url: '...basePath/Plate.babylon',
},
];

const spec = Viewer.generateSpec(genData);

const viewer = new Viewer(canvas, spec);
await viewer.bootstrap([]);

Such an auto generated Spec consists of 2 major parts:

  • Global definitions (viewer/scene settings, environment, camera/animation definitions, ...)
  • Variant specific definitions (babylon/gltf source file, elements, instances, ...)

The global part of an auto generated spec uses the same settings as shown on the front page of the viewer docs. This ensures that the chosen scene and engine settings for the auto generated Spec generally work fine.

The variant specific part highly depends on the 3d files that should be loaded into the scene. Therefore the user has to provide information about the url and the name of the models that should be imported into the Spec. The algorithm then creates variant definitions in the following way:

  • 1 variant for each url/name pair
  • 1 element named Main for each variant which includes all meshes from the associated 3d file
  • 1 variant instance for each variant, invisible and set to be lazy loaded by default
  • The variants & variant instances are named the same using the name from the given SpecGenerationData

How to overwrite and extend parts of the auto generated Spec?

In many cases the generated Spec will need some slight adjustments. For example there is no environment set by default. However it's not a big deal to add this manually afterwards, since the output of Viewer.generateSpec is just a JSON object with a very detailed typing (see StructureJson).

const genData: SpecGenerationData[] = [...];

const spec = Viewer.generateSpec(genData);

// add an environment parameter
spec.scene.parameters = {
[Parameter.ENVIRONMENT]: '...basePath/Environment.env',
};

const viewer = new Viewer(canvas, spec);
await viewer.bootstrap([]);

Keep in mind that the auto spec creates variant instances which are all hidden per default. Therefore it's required to show the dedicated instance manually. This can be done by calling viewer.variantInstances.show after bootstrapping the viewer.

How to use Combeenation babylon assets?

The url/name pairs that are required for Viewer.generateSpec are compatible with the babylon asset data, that can be retrieved from the AssetUtils.getAllBabylonAssetInfo call, which is part of the Combeenation utils package.

This function returns all babylon assets that are assigned to the configurator which can be passsed directly to Viewer.generateSpec to create a spec with 1 variant & 1 variant instance for each of those babylon asset.

import { AssetUtils } from '@combeenation/custom-js-utils';

// receive asset data for Spec generation from Combeenation system
const assetData = AssetUtils.getAllBabylonAssetInfo();

const spec = Viewer.generateSpec(assetData);

const viewer = new Viewer(canvas, spec);
await viewer.bootstrap([]);

Accessing auto-generated variant instances

Variant instances can still be accessed and used as if the Spec was written manually, whereas the names of the auto-generated instances equal the names of the babylon assets in the asset editor.

Caution when working with babylon assets in folders!

Typically, nested assets can be accessed with dotted path notation (eg: Folder.MyAsset) in the Combeenation system. However this doesn't work for auto-generated variants, since the viewer interprets dots as seperators for variant inheritance. In this way Folder and MyAsset would become 2 individual assets, which will certainly lead to errors.

In order to avoid this issue, nested variants have to seperated by slashes (/). Here is an example for showing a variant instance, which is based on a nested asset:

viewer.variantInstances.show('Models3D/Cup');

Full example

Here's an example of how this is all works together:

import { AssetUtils } from '@combeenation/custom-js-utils';

// receive asset data for Spec generation from Combeenation system
const assetData = AssetUtils.getAllBabylonAssetInfo();

const spec = Viewer.generateSpec(assetData);

spec.scene.parameters = {
[Parameter.ENVIRONMENT]: '...basePath/Environment.env',
};

const viewer = new Viewer(canvas, spec);
await viewer.bootstrap([]);

// Ensure that at least 1 variant instance is shown in the scene
viewer.variantInstances.show('Cup');

Generated using TypeDoc