/** * The resource each asset type loads, keyed by the `type` string passed to the {@link Asset} * constructor and to {@link AssetRegistry#find}: `'texture'` maps to {@link Texture}, `'material'` * to {@link Material} and so on. This is what types {@link Asset#resource}: an `Asset<'texture'>` * holds a {@link Texture}. An application that registers its own resource handler with * {@link ResourceLoader#addHandler} extends the map - and with it the typing of * {@link Asset#resource}, {@link AssetRegistry#find}, {@link AssetRegistry#findAll} and * {@link AssetRegistry#loadFromUrl} - by augmenting this interface: * * ```ts * declare module 'playcanvas' { * interface AssetMap { * mytype: MyResource; * } * } * ``` */ export interface AssetMap { /** * - An animation: an {@link AnimTrack} when loaded from * a glTF or GLB file, or a legacy {@link Animation} when loaded from JSON. */ animation: Animation | AnimTrack; /** * - An animation clip. */ animclip: AnimTrack; /** * - An animation state graph. */ animstategraph: AnimStateGraph; /** * - A sound. */ audio: Sound; /** * - The raw contents of the file. */ binary: ArrayBuffer; /** * - A bundle: an archive whose files back other assets. */ bundle: Bundle; /** * - The renders, materials, textures, animations and * gsplats of a glTF or GLB file. */ container: ContainerResource; /** * - The CSS text. */ css: string; /** * - The cube map, or null when the asset provides only prefiltered * levels. {@link Asset#resources} holds the cube map followed by its six prefiltered levels, with * null for each level the asset does not provide. */ cubemap: Texture | null; /** * - Folders hold no resource. */ folder: null; /** * - A {@link Font} loaded from a font file. */ font: Font | CanvasFont; /** * - A Gaussian splat resource, or the * octree resource of a level-of-detail splat scene. */ gsplat: GSplatResourceBase | GSplatOctreeResource; /** * - The root entity of an instantiated scene hierarchy. */ hierarchy: Entity; /** * - The HTML text. */ html: string; /** * - The parsed JSON data. */ json: unknown; /** * - A material, a {@link StandardMaterial} unless a custom parser * creates another kind. */ material: Material; /** * - A model. */ model: Model; /** * - The meshes of one glTF mesh, created when a container asset loads. */ render: Render; /** * - A scene. */ scene: Scene; /** * - The settings block of a scene file. */ scenesettings: object; /** * - The script classes declared by a script file, * keyed by class name. */ script: Record; /** * - The shader source text. */ shader: string; /** * - A sprite. */ sprite: Sprite; /** * - A template. */ template: Template; /** * - The text of the file. */ text: string; /** * - A texture. */ texture: Texture; /** * - A texture atlas. */ textureatlas: TextureAtlas; } /** * The type of an {@link Asset}, such as `'texture'` or `'material'`: the keys of {@link AssetMap}. * This is what the {@link Asset} constructor, {@link AssetRegistry#find}, * {@link AssetRegistry#findAll} and {@link AssetRegistry#loadFromUrl} take, and what * {@link AssetResource} is indexed by. */ export type AssetType = keyof AssetMap & string; /** * The resource an {@link Asset} of type `K` holds: `AssetMap[K]` for a type in {@link AssetMap}, so * `AssetResource<'texture'>` is {@link Texture}, and `unknown` for any other string, including a * plain `string`. This is the type of {@link Asset#resource}. */ export type AssetResource = K extends AssetType ? AssetMap[K] : unknown; /** * Callback used by {@link Asset#ready} and called when an asset is ready. */ export type AssetReadyCallback = (asset: Asset) => void; /** * The resource each asset type loads, keyed by the `type` string passed to the {@link Asset} * constructor and to {@link AssetRegistry#find}: `'texture'` maps to {@link Texture}, `'material'` * to {@link Material} and so on. This is what types {@link Asset#resource}: an `Asset<'texture'>` * holds a {@link Texture}. An application that registers its own resource handler with * {@link ResourceLoader#addHandler} extends the map - and with it the typing of * {@link Asset#resource}, {@link AssetRegistry#find}, {@link AssetRegistry#findAll} and * {@link AssetRegistry#loadFromUrl} - by augmenting this interface: * * ```ts * declare module 'playcanvas' { * interface AssetMap { * mytype: MyResource; * } * } * ``` * * @typedef {object} AssetMap * @property {Animation | AnimTrack} animation - An animation: an {@link AnimTrack} when loaded from * a glTF or GLB file, or a legacy {@link Animation} when loaded from JSON. * @property {AnimTrack} animclip - An animation clip. * @property {AnimStateGraph} animstategraph - An animation state graph. * @property {Sound} audio - A sound. * @property {ArrayBuffer} binary - The raw contents of the file. * @property {Bundle} bundle - A bundle: an archive whose files back other assets. * @property {ContainerResource} container - The renders, materials, textures, animations and * gsplats of a glTF or GLB file. * @property {string} css - The CSS text. * @property {Texture | null} cubemap - The cube map, or null when the asset provides only prefiltered * levels. {@link Asset#resources} holds the cube map followed by its six prefiltered levels, with * null for each level the asset does not provide. * @property {null} folder - Folders hold no resource. * @property {Font | CanvasFont} font - A {@link Font} loaded from a font file. * @property {GSplatResourceBase | GSplatOctreeResource} gsplat - A Gaussian splat resource, or the * octree resource of a level-of-detail splat scene. * @property {Entity} hierarchy - The root entity of an instantiated scene hierarchy. * @property {string} html - The HTML text. * @property {unknown} json - The parsed JSON data. * @property {Material} material - A material, a {@link StandardMaterial} unless a custom parser * creates another kind. * @property {Model} model - A model. * @property {Render} render - The meshes of one glTF mesh, created when a container asset loads. * @property {Scene} scene - A scene. * @property {object} scenesettings - The settings block of a scene file. * @property {Record} script - The script classes declared by a script file, * keyed by class name. * @property {string} shader - The shader source text. * @property {Sprite} sprite - A sprite. * @property {Template} template - A template. * @property {string} text - The text of the file. * @property {Texture} texture - A texture. * @property {TextureAtlas} textureatlas - A texture atlas. */ /** * The type of an {@link Asset}, such as `'texture'` or `'material'`: the keys of {@link AssetMap}. * This is what the {@link Asset} constructor, {@link AssetRegistry#find}, * {@link AssetRegistry#findAll} and {@link AssetRegistry#loadFromUrl} take, and what * {@link AssetResource} is indexed by. * * @typedef {keyof AssetMap & string} AssetType */ /** * The resource an {@link Asset} of type `K` holds: `AssetMap[K]` for a type in {@link AssetMap}, so * `AssetResource<'texture'>` is {@link Texture}, and `unknown` for any other string, including a * plain `string`. This is the type of {@link Asset#resource}. * * @template {AssetType | (string & {})} K * @typedef {K extends AssetType ? AssetMap[K] : unknown} AssetResource */ /** * @template {AssetType | (string & {})} [K=string] * @callback AssetReadyCallback * Callback used by {@link Asset#ready} and called when an asset is ready. * @param {Asset} asset - The ready asset. * @returns {void} */ /** * An Asset is the engine's record of a single resource: a texture, a material, a glTF container, a * sound, a script and so on. Assets live in the application's {@link AssetRegistry} at * {@link AppBase#assets}, which loads them on demand. * * An asset has five parts: * * - `type` selects the {@link ResourceHandler} that loads it and the type of `resource`. * - `file` names the file that holds the data, when there is one. * - `data` carries JSON that either is the resource, as for materials, or describes how to process * the file, as for texture and model mappings. * - `options` carries handler-specific load options. * - `resource` holds the loaded object, such as a {@link Texture}. `resources` holds every object * the handler produced when there is more than one, such as a cube map and its prefiltered levels. * * Loading is driven by the registry: call {@link AssetRegistry#load}, or set {@link preload} so the * asset loads when added. Wait for the result with {@link ready} or listen for the `load` and * `error` events. {@link unload} releases the resource. * * The `type` string also types the resource: `new Asset('brick', 'texture', file)` creates an * `Asset<'texture'>` whose `resource` is a {@link Texture} once loaded, and * `app.assets.find('brick', 'texture')` returns one. See {@link AssetMap} for the built-in types * and for adding application-defined ones. An asset whose type is only known as a `string` has a * `resource` of type `unknown`. * * @example * const asset = new Asset('brick', 'texture', { url: 'textures/brick.png' }); * app.assets.add(asset); * app.assets.load(asset); * asset.ready((asset) => { * material.diffuseMap = asset.resource; * }); * @template {AssetType | (string & {})} [K=string] * @category Asset */ export class Asset extends EventHandler { /** * Fired when the asset has completed loading. * * @event * @example * asset.on('load', (asset) => { * console.log(`Asset loaded: ${asset.name}`); * }); */ static EVENT_LOAD: string; /** * Fired just before the asset unloads the resource. This allows for the opportunity to prepare * for an asset that will be unloaded. E.g. Changing the texture of a model to a default before * the one it was using is unloaded. * * @event * @example * asset.on('unload', (asset) => { * console.log(`Asset about to unload: ${asset.name}`); * }); */ static EVENT_UNLOAD: string; /** * Fired when the asset is removed from the asset registry. * * @event * @example * asset.on('remove', (asset) => { * console.log(`Asset removed: ${asset.name}`); * }); */ static EVENT_REMOVE: string; /** * Fired if the asset encounters an error while loading. * * @event * @example * asset.on('error', (err, asset) => { * console.error(`Error loading asset ${asset.name}: ${err}`); * }); */ static EVENT_ERROR: string; /** * Fired when one of the asset properties `file`, `data`, `resource` or `resources` is changed. * * @event * @example * asset.on('change', (asset, property, newValue, oldValue) => { * console.log(`Asset ${asset.name} has property ${property} changed from ${oldValue} to ${newValue}`); * }); */ static EVENT_CHANGE: string; /** * Fired as the asset's file downloads, with the number of bytes received so far and the total * expected. Only asset types whose file is fetched as binary data report progress: * `animation` (GLB only), `audio`, `binary`, `container`, `gsplat`, `model` and `texture`. * Textures loaded through an image element have no download progress, so they fire once at 0 * and once at a fixed placeholder total, whether or not the file was downloaded. * * Please note: * - downloads are skipped when `asset.file.contents` is supplied, so no progress is reported * - totalBytes may not be reliable as it is based on the content-length header of the response * * @event * @example * asset.on('progress', (receivedBytes, totalBytes) => { * console.log(`Asset ${asset.name} progress ${receivedBytes / totalBytes}`); * }); */ static EVENT_PROGRESS: string; /** * Fired when we add a new localized asset id to the asset. * * @event * @example * asset.on('add:localized', (locale, assetId) => { * console.log(`Asset ${asset.name} has added localized asset ${assetId} for locale ${locale}`); * }); */ static EVENT_ADDLOCALIZED: string; /** * Fired when we remove a localized asset id from the asset. * * @event * @example * asset.on('remove:localized', (locale, assetId) => { * console.log(`Asset ${asset.name} has removed localized asset ${assetId} for locale ${locale}`); * }); */ static EVENT_REMOVELOCALIZED: string; /** * Helper function to resolve asset file data and return the contents as an ArrayBuffer. If the * asset file contents are present, that is returned. Otherwise the file data is be downloaded * via http. * * @param {string} loadUrl - The URL as passed into the handler * @param {ResourceLoaderCallback} callback - The callback function to receive results. * @param {Asset} [asset] - The asset * @param {number} maxRetries - Number of retries if http download is required * @ignore */ static fetchArrayBuffer(loadUrl: string, callback: ResourceLoaderCallback, asset?: Asset, maxRetries?: number): void; /** * Create a new Asset record. Add it to the {@link AssetRegistry} with * {@link AssetRegistry#add} so the application can find and load it. * * @param {string} name - A non-unique but human-readable name which can be later used to * retrieve the asset. * @param {K} type - The type of asset (an {@link AssetType}), which selects the resource * handler and the type of {@link Asset#resource}. The types a developer commonly creates are: * * - "animation" - see {@link Animation} and {@link AnimTrack} * - "animclip" - see {@link AnimTrack} * - "animstategraph" - see {@link AnimStateGraph} * - "audio" - see {@link Sound} * - "binary" - an `ArrayBuffer` * - "container" - see {@link ContainerResource} * - "css" - a `string` * - "cubemap" - see {@link Texture}; null when only prefiltered levels are provided * - "font" - see {@link Font} * - "gsplat" - a Gaussian splat resource * - "html" - a `string` * - "json" - the parsed JSON * - "material" - see {@link Material} * - "model" - see {@link Model} * - "script" - see {@link Script} * - "shader" - a `string` * - "sprite" - see {@link Sprite} * - "text" - a `string` * - "texture" - see {@link Texture} * - "textureatlas" - see {@link TextureAtlas} * * Types that the engine creates itself while loading, such as `render` or `scene`, are omitted * here; every built-in type is listed in {@link AssetMap}. Any other string is accepted for an * application-defined handler; see {@link AssetMap} for typing its resource. * @param {object} [file] - Details about the file the asset is made from. At the least must * contain the 'url' field. For assets that don't contain file data use null. * @param {string} [file.url] - The URL of the resource file that contains the asset data. * @param {string} [file.filename] - The filename of the resource file or null if no filename * was set (e.g from using {@link AssetRegistry#loadFromUrl}). * @param {number} [file.size] - The size of the resource file or null if no size was set * (e.g. from using {@link AssetRegistry#loadFromUrl}). * @param {string} [file.hash] - The MD5 hash of the resource file data and the Asset data * field or null if hash was set (e.g from using {@link AssetRegistry#loadFromUrl}). * @param {ArrayBuffer} [file.contents] - Optional file contents. This is faster than wrapping * the data in a (base64 encoded) blob. Currently only used by container assets. * @param {object|string} [data] - JSON object or string with additional data about the asset. * (e.g. for texture and model assets) or contains the asset data itself (e.g. in the case of * materials). * @param {object} [options] - The asset handler options. For container options see * {@link ContainerHandler}. * @param {'anonymous'|'use-credentials'|null} [options.crossOrigin] - For use with texture assets * that are loaded using the browser. This setting overrides the default crossOrigin specifier. * For more details on crossOrigin and its use, see * https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/crossOrigin. * @example * // an Asset<'texture'>: once loaded, asset.resource is a Texture * const asset = new Asset("a texture", "texture", { * url: "http://example.com/my/assets/here/texture.png" * }); */ constructor(name: string, type: K, file?: { url?: string; filename?: string; size?: number; hash?: string; contents?: ArrayBuffer; }, data?: object | string, options?: { crossOrigin?: "anonymous" | "use-credentials" | null; }); /** * @type {AssetFile | null} * @private */ private _file; /** * A string-assetId dictionary that maps locale to asset id. * * @type {object} * @private */ private _i18n; /** * Whether to preload the asset. * * @private */ private _preload; /** * This is where the loaded resource(s) are stored. * * @type {AssetResource[]} * @private */ private _resources; /** * The asset id. * * @type {number} */ id: number; /** * True if the asset has finished attempting to load the resource. It is not guaranteed * that the resources are available as there could have been a network error. */ loaded: boolean; /** * True if the resource is currently being loaded. */ loading: boolean; /** * Optional JSON data that contains the asset handler options. * * @type {object} */ options: object; /** * The asset registry that this Asset belongs to. * * @type {AssetRegistry|null} */ registry: AssetRegistry | null; /** * Asset tags. Enables finding of assets by tags using the {@link AssetRegistry#findByTag} method. * * @type {Tags} */ tags: Tags; /** * The type of the asset: one of the {@link AssetType} names, or the name of an * application-defined resource handler. See {@link AssetMap}. * * @type {K} */ type: K; /** * The URL object. * * @type {string | null} * @ignore */ urlObject: string | null; _name: string; _data: any; /** * Sets the file details or null if no file. * * @type {object} */ set file(value: object); /** * Gets the file details or null if no file. * * @type {object} */ get file(): object; /** * Sets the asset name. * * @type {string} */ set name(value: string); /** * Gets the asset name. * * @type {string} */ get name(): string; /** * Sets optional asset JSON data. This contains either the complete resource data (such as in * the case of a material) or additional data (such as in the case of a model which contains * mappings from mesh to material). * * @type {object} */ set data(value: object); /** * Gets optional asset JSON data. * * @type {object} */ get data(): object; /** * Sets the asset resource. For example, a {@link StandardMaterial} or a {@link Texture}. The * value is checked against the asset's type. As with the elements of an array, the check is * bypassed when assigning through a variable typed as a plain `Asset`, so keep typed assets * typed where their resource is assigned. * * @param {AssetResource} value - The resource. */ set resource(value: AssetResource); /** * Gets the asset resource. Its type follows the asset's type: a {@link Texture} for an * `Asset<'texture'>`, a {@link Material} for an `Asset<'material'>` and so on (see * {@link AssetMap}), or `unknown` when the type is only known as a `string`. It is `undefined` * until the asset has loaded and after {@link Asset#unload}, so narrow it before use unless the * asset is known to be loaded, for example inside {@link Asset#ready}. * * @type {AssetResource | undefined} */ get resource(): AssetResource | undefined; /** * Sets the asset resources. Some assets can hold more than one runtime resource (cube maps, * for example). * * @type {AssetResource[]} */ set resources(value: AssetResource[]); /** * Gets the asset resources. For a cube map asset, the first entry is the cube map and the * remaining entries are its prefiltered levels, some of which may be `null`. * * @type {AssetResource[]} */ get resources(): AssetResource[]; /** * Sets whether to preload an asset. If true, the asset will be loaded during the preload phase * of application initialization or when calling {@link AssetRegistry#add}. * * @type {boolean} */ set preload(value: boolean); /** * Gets whether to preload an asset. * * @type {boolean} */ get preload(): boolean; set loadFaces(value: any); get loadFaces(): any; _loadFaces: any; /** * Return the URL required to fetch the file for this asset. * * @returns {string|null} The URL. Returns null if the asset has no associated file. * @example * const asset = app.assets.find("My Image", "texture"); * const img = "<img src='" + asset.getFileUrl() + "'>"; */ getFileUrl(): string | null; /** * Construct an asset URL from this asset's location and a relative path. If the relativePath * is a blob or Base64 URI, then return that instead. * * @param {string} relativePath - The relative path to be concatenated to this asset's base url. * @returns {string} Resulting URL of the asset. * @ignore */ getAbsoluteUrl(relativePath: string): string; /** * Returns the asset id of the asset that corresponds to the specified locale. * * @param {string} locale - The desired locale e.g. Ar-AR. * @returns {number} An asset id or null if there is no asset specified for the desired locale. * @ignore */ getLocalizedAssetId(locale: string): number; /** * Adds a replacement asset id for the specified locale. When the locale in * {@link AppBase#i18n} changes then references to this asset will be replaced with the * specified asset id. (Currently only supported by the {@link ElementComponent}). * * @param {string} locale - The locale e.g. Ar-AR. * @param {number} assetId - The asset id. * @ignore */ addLocalizedAssetId(locale: string, assetId: number): void; /** * Removes a localized asset. * * @param {string} locale - The locale e.g. Ar-AR. * @ignore */ removeLocalizedAssetId(locale: string): void; /** * Take a callback which is called as soon as the asset is loaded. If the asset is already * loaded the callback is called straight away. * * The callback fires on success only, and a failed load still marks the asset as loaded while * firing `error` rather than `load`. So a callback registered before the failure never runs, * and one registered after it runs immediately with {@link Asset#resource} still null. Listen * for the `error` event as well whenever a failure has to be handled, check `asset.resource` * inside the callback, and never await this callback alone. * * @param {AssetReadyCallback} callback - The function called when the asset is ready. Passed * the (asset) arguments. * @param {object} [scope] - Scope object to use when calling the callback. * @example * const asset = app.assets.find("My Asset"); * asset.ready((asset) => { * // asset loaded * }); * app.assets.load(asset); */ ready(callback: AssetReadyCallback, scope?: object): void; reload(): void; /** * Destroys the associated resource and marks asset as unloaded. * The `unload` event also fires while the asset is loading, allowing resource handlers to * cancel pending work. * * @example * const asset = app.assets.find("My Asset"); * asset.unload(); * // asset.resource is null */ unload(): void; } import type { Animation } from '../../scene/animation/animation.js'; import type { AnimTrack } from '../anim/evaluator/anim-track.js'; import type { AnimStateGraph } from '../anim/state-graph/anim-state-graph.js'; import type { Sound } from '../../platform/sound/sound.js'; import type { Bundle } from '../bundle/bundle.js'; import type { ContainerResource } from '../handlers/container.js'; import type { Texture } from '../../platform/graphics/texture.js'; import type { Font } from '../font/font.js'; import type { CanvasFont } from '../font/canvas-font.js'; import type { GSplatResourceBase } from '../../scene/gsplat/gsplat-resource-base.js'; import type { GSplatOctreeResource } from '../../scene/gsplat-unified/gsplat-octree.resource.js'; import type { Entity } from '../entity.js'; import type { Material } from '../../scene/materials/material.js'; import type { Model } from '../../scene/model.js'; import type { Render } from '../../scene/render.js'; import type { Scene } from '../../scene/scene.js'; import type { Script } from '../script/script.js'; import type { Sprite } from '../../scene/sprite.js'; import type { Template } from '../template.js'; import type { TextureAtlas } from '../../scene/texture-atlas.js'; import { EventHandler } from '../../core/event-handler.js'; import type { AssetRegistry } from './asset-registry.js'; import { Tags } from '../../core/tags.js'; import type { ResourceLoaderCallback } from '../handlers/loader.js';