Skip to main content

Asset Management

The AssetManagerPlugin handles the download, management, caching, parsing, loading and adding of assets to the scene. Extensions can be added for loading different file types and also to export textures, materials and GLTF models.

This plugin must be added before doing any operation:

import { 
ViewerApp,
AssetManagerPlugin,
} from "webgi";
... // your code
const viewer = ...
... // viewer setup and other plugins.
const manager = await viewer.addPlugin(AssetManagerPlugin);
...
// after adding the manager can be accessed from the viewer like this:
const manager = viewer.getManager();

Adding assets

The plugin exposes functions for importing and adding assets to the scene for different use-cases.

To download, import and add an asset from path:

 const options = {
autoScale: true, // Scales the object before adding to the scene.
autoScaleRadius: 2, // Scales the object bounding box to 2 World Units, if autoScale is true
pseudoCenter: true, // centers the object to origin on load
// check docs for other options (if required)
}
const assets = await manager.addFromPath("https://demo-assets.pixotronics.com/pixo/gltf/cube.glb", options)

This function returns the same instance for successive calls with the same path to avoid re-importing. If this is not the goal, or to import a local file object, use the addAsset function

const asset: IAsset = {
path: 'https://demo-assets.pixotronics.com/pixo/gltf/cube.glb', // URL to file( for download ) or name of the local file.
file: ... // optional: File object in memory to avoid downloading or for local files.
}
const models = await manager.addAsset(asset, options);

addAsset returns the same object instance for the same asset, so to get a new object, make a new IAsset but with the same path.

These functions take any kind of asset URL and automatically identifies what to do with it. Models and 3D objects are added to the scene, materials and textures are imported and kept in the library, zip files and other compressed archives are decompressed and its contents are loaded.

Since its possible to import multiple files in a single URL(by using zip files or any other way), the functions above return an array. If it is ensured only one asset is contained in the URL, use addAssetSingle to automatically get the first object and type-cast it as required. Check the type docs for more.

If an object is imported manually, it needs to be processed for realtime rendering before adding to the scene. This can be done with the manager using addImported

const mesh = new THREE.Mesh()
... // setting up the obj
const models = viewer.getManager().addImported(mesh, options) // Process and add to the scene. options similar to addAsset

Importing assets

Asset manager, internally uses AssetImporter to download and import assets in js.

Sometimes it is required to import assets, perform some operations and then add to the scene or use the asset for another purpose. This can be done by getting the importer instance from the manager and using the public functions to handle import and processing. Sample:

const importer = viewer.getManager().importer!;
const options = {
processImported: true, // default = true
}
const models = await importer.importPath(url, options); // This works similar to manager.addFromPath

This call also does some viewer specific processing. Set processImported to false, if the asset will be used for some other purpose or to defer it to a later stage. importer.processImported() can be used to do the processing later.

Importer has other helper functions for importing single assets similar to the one in manager.

If an asset is added and/or processed manually with the importer, it can be added to the scene by using manager.addProcessedAssets:

const options = {
processImported: false, // default = true
}
const models = await importer.importPath(url, options);
// ... processing models

const options2 = {
pseudoCenter: true,
}
const processed = await importer.processImported(models, options2);
// .. post processing operations on processed

const options3 = {
autoScale: true,
}
await manager.addProcessedAssets(processed, options3) // finally add to scene

Importing materials

Materials are saved as .pmat, .dmat, .mat or .json formats. These can be loaded directly with the asset manager:

const material =  await viewer.getManager()!.importer!.importSinglePath<IMaterial<MeshStandardMaterial2>>('./assets/material/metal.pmat')  
// Set it on a mesh
mesh.userData.setMaterial(material)
// or copy properties to another material
mesh.material.copyProps(material)

Importing textures

Textures/Maps in .png, .jpeg, .svg, .hdr, .ktx2, webp, .ktx(limited support), .hdr.png are supported. These can be loaded directly from the asset importer:

const texture = await viewer.getManager()!.importer!.importSinglePath<ITexture>('./assets/images/image.png', {generateMipmaps: false})

// Set any texture properties
texture.mapping = THREE.EquirectangularReflectionMapping // This must be set when loading an equirectangular image like environment map.
texture.encoding = THREE.sRGBEncoding // By default encoding would be linear unless specified in the file or file format.
texture.flipY = true // sometimes this is required or the texture is flipped.
note

Some formats might require additional plugins to be added, before they can be imported (See below).

See the Extending with three.js article for more details on using the assets.

Importing plugin presets

Presets and viewer config in format .vjson and .json can be imported and applied directly with the asset importer. To import the viewer config:

await viewer.getManager().importer.importPath('./assets/presets/config.vjson', {processImported: true})

This will import the config in json format and apply to the viewer along with all the plugins.

This is done in the process step. To just import the json data and disable applying it on the viewer set processImported to false. It can later be applied by calling processImported() in the importer

To import a single plugin preset:

await viewer.getManager().importer.importPath('./assets/presets/preset.Ground.json', {processImported: true})

This would find the plugin in the viewer(in this case GroundPlugin) based on the type in the JSON, and apply the loaded settings

Supported import formats

By default AssetImporter adds loaders for loading files of the below formats:

  • GLTF - .gltf and .glb files, with draco compression.
  • HDR - .hdr and .hdr.png files with RGBE encoding.
  • PNG/JPG/SVG - all image formats supported by the current browser.
  • VJSON - .vjson files for viewer and plugin configuration presets.
  • PMAT - .pmat (physical material) for saved physical material preset files.
  • JSON - .json files and presets.
  • TXT - simple .txt files.
  • HDR.PNG - To load HDR encoded png files from hdrpng.js.

Formats supported by additional plugins:

  • FBX - FBX models. Add FBXLoadPlugin after the manager
  • EXR - Environment maps in EXR format. Add EXRLoadPlugin after the manager
  • KTX2 - .ktx2 compressed textures. Add KTX2LoadPlugin after the manager
  • OBJ/MTL - OBJ models with MTL materials/ Add ObjMtlLoadPlugin after the manager
  • ZIP - Zip compressed archives. Add ZipLoadPlugin after the manager. Some plugins and functionality may add this as a dependency automatically. All files in a zip archive are extracted and reimported automatically.
  • DMAT - .dmat Diamond material presets. Add DiamondPlugin after the manager.

Caching imported assets

A Cache or Storage can be provided to the AssetManagerPlugin to save all downloaded assets which can be used the next time.

const manager = await viewer.addPlugin(AssetManagerPlugin, undefined, undefined, {  
storage: caches ? await caches.open('webgi-cache-storage') : undefined,
})

Here caches is the global property available in browsers: https://developer.mozilla.org/en-US/docs/Web/API/caches

See more details on Web API for Cache and Storage and CacheStorage interfaces

Note that browser will automatically cache the assets in CacheStorage if the correct tags are sent with the asset from the hosting/backend. In that case this is not required.

Exporting assets and presets

Use the sandbox editor to export assets and custom plugin and setting presets.

Config/presets

To export the complete scene settings which includes viewer configuration and plugin settings:

const json = viewer.getManager().exportViewerConfig();

To export presets with one or more plugin settings.

const filter = [GroundPlugin.PluginType, TonemapPlugin.PluginType]
const json = viewer.getManager().exportPluginPresets(filter);

To export a single plugin:

const json = viewer.getManager().exportPluginPreset(viewer.getPlugin(GroundPlugin));
// this can be imported with importPluginPreset
viewer.getManager().importPluginPreset(json);
// or it can be saved in a file and loaded as a JSON.

JSON can be converted to Blob to download with downloadBlob like this:

const blob = new Blob([JSON.stringify(json, null, 2)], {type: 'application/json'})
await downloadBlob(blob, 'file.json')

Asset Export plugin

To export the scene data, materials, textures and GLTF, AssetExporterPlugin can be used. First add this plugin:

await viewer.addPlugin(AssetExporterPlugin)

// Optionally, Add the draco compression module to export GLB with KHR_draco_mesh_compression
await viewer.addPlugin(GLTFDracoExportPlugin)

Export GLB

To export the complete scene in glb format:

const options = {
compress: true, // This will work if GLTFDracoExportPlugin is added
name: 'scene',
viewerConfig: true // This also added the viewer config and plugin settings to the glb
}
// Get the blob
const blob = viewer.getPlugin(AssetExporterPlugin).exportScene(options);
// Download the blob
if (blob) downloadBlob(blob, exportOptions.name + '.' + blob.ext)

To export a single Object3D (along with children) instead of the complete scene graph, use the functions in AssetExporter :

const object3D = viewer.scene.findObjectsByName('Cube')[0];
const blob = viewer.getPlugin(AssetExporterPlugin).exporter.exportObject(object3D, options)); // options same as above.
note

exportObject can be used to export any object imported with the AssetImporter: (Object3D/nodes)IModel, (Textures)ITexture, (Materials)IMaterial.