UNPKG

@wonderlandengine/api

Version:

Wonderland Engine's JavaScript API.

1,674 lines 133 kB
/** * Types */ /// <reference types="webxr" /> import { WonderlandEngine } from './engine.js'; import { Emitter } from './utils/event.js'; import { Material } from './resources/material-manager.js'; import { ComponentProperty, PropertyRecord } from './property.js'; import { ImageLike, NumberArray, TypedArray, TypedArrayCtor } from './types.js'; import { Resource, SceneResource } from './resources/resource.js'; import { Prefab } from './prefab.js'; import { Scene } from './scene.js'; import { NativeComponents } from './component.js'; /** * Component constructor type. * * For more information, please have a look at the {@link Component} class. */ export type ComponentConstructor<T extends Component = Component> = { new (scene: Prefab, manager: number, id: number): T; } & { _isBaseComponent: boolean; _propertyOrder: string[]; TypeName: string; Properties: Record<string, ComponentProperty>; InheritProperties?: boolean; onRegister?: (engine: WonderlandEngine) => void; }; /** * Component prototype interface. * * User component's should have the same structure. */ export interface ComponentProto { /** * Triggered after the component instantiation. * For more information, please have a look at {@link Component.init}. */ init?: () => void; /** * Triggered after the component is activated for the first time. * For more information, please have a look at {@link Component.start}. */ start?: () => void; /** * Triggered once per frame. * For more information, please have a look at {@link Component.update}. * * @param dt Delta time, time since last update. */ update?: (dt: number) => void; /** * Triggered when the component goes from deactivated to activated. * For more information, please have a look at {@link Component.onActivate}. */ onActivate?: () => void; /** * Triggered when the component goes from activated to deactivated. * For more information, please have a look at {@link Component.onDeactivate}. */ onDeactivate?: () => void; /** * Triggered when the component is removed from its object. * For more information, please have a look at {@link Component.onDestroy}. * * @since 0.9.0 */ onDestroy?: () => void; } /** * Callback triggered on collision event. * * @param type Type of the event. * @param other Other component that was (un)collided with */ export type CollisionCallback = (type: CollisionEventType, other: PhysXComponent) => void; /** * Wonderland Engine API * @namespace WL */ /** * Default set of logging tags used by the API. */ export declare enum LogTag { /** Initialization, component registration, etc... */ Engine = 0, /** Scene loading */ Scene = 1, /** Component init, update, etc... */ Component = 2 } /** * Collider type enum for {@link CollisionComponent}. */ export declare enum Collider { /** * **Sphere Collider**: * * Simplest and most performant collision shape. If this type is set on a * {@link CollisionComponent}, only the first component of * {@link CollisionComponent#extents} will be used to determine the radius. */ Sphere = 0, /** * **Axis Aligned Bounding Box Collider**: * * Box that is always aligned to XYZ axis. It cannot be rotated but is more * efficient than {@link Collider.Box}. */ AxisAlignedBox = 1, /** * **Aligned Bounding Box Collider**: * * Box that matches the object's rotation and translation correctly. This * is the least efficient collider and should only be chosen over * {@link Collider.Sphere} and {@link Collider.AxisAlignedBox} if really * necessary. */ Box = 2 } /** * Alignment type enum for {@link TextComponent}. */ export declare enum Alignment { /** Text start is at object origin */ Left = 0, /** Text center is at object origin */ Center = 1, /** Text end is at object origin */ Right = 2 } /** * Vertical alignment type enum for {@link TextComponent}. */ export declare enum VerticalAlignment { /** Text line is at object origin */ Line = 0, /** Text middle is at object origin */ Middle = 1, /** Text top is at object origin */ Top = 2, /** Text bottom is at object origin */ Bottom = 3 } /** * Justification type enum for {@link TextComponent}. * * @deprecated Please use {@link VerticalAlignment} instead. */ export declare const Justification: typeof VerticalAlignment; /** * Effect type enum for {@link TextComponent}. */ export declare enum TextEffect { /** Text is rendered normally */ None = 0, /** Text is rendered with an outline */ Outline = 1, /** Text is rendered with a drop shadow */ Shadow = 2 } /** * Wrap mode enum for {@link TextComponent}. * * @since 1.2.1 */ export declare enum TextWrapMode { /** Text doesn't wrap automatically, only with explicit newline */ None = 0, /** Text wraps at word boundaries */ Soft = 1, /** Text wraps anywhere */ Hard = 2, /** Text is cut off */ Clip = 3 } /** * Input type enum for {@link InputComponent}. */ export declare enum InputType { /** Head input */ Head = 0, /** Left eye input */ EyeLeft = 1, /** Right eye input */ EyeRight = 2, /** Left controller input */ ControllerLeft = 3, /** Right controller input */ ControllerRight = 4, /** Left ray input */ RayLeft = 5, /** Right ray input */ RayRight = 6 } /** * Projection type enum for {@link ViewComponent}. */ export declare enum ProjectionType { /** Perspective projection */ Perspective = 0, /** Orthographic projection */ Orthographic = 1 } /** * Light type enum for {@link LightComponent}. */ export declare enum LightType { /** Point light */ Point = 0, /** Spot light */ Spot = 1, /** Sun light / Directional light */ Sun = 2 } /** * Animation state of {@link AnimationComponent}. */ export declare enum AnimationState { /** Animation is currently playing */ Playing = 0, /** Animation is paused and will continue at current playback * time on {@link AnimationComponent#play} */ Paused = 1, /** Animation is stopped */ Stopped = 2 } /** * Root motion mode of {@link AnimationComponent}. */ export declare enum RootMotionMode { /** Do nothing */ None = 0, /** Move and rotate root with the delta of its motion */ ApplyToOwner = 1, /** Store the motion to be retrieved by a JS script */ Script = 2 } /** * Rigid body force mode for {@link PhysXComponent#addForce} and {@link PhysXComponent#addTorque}. * * [PhysX API Reference](https://gameworksdocs.nvidia.com/PhysX/4.1/documentation/physxapi/files/structPxForceMode.html) */ export declare enum ForceMode { /** Apply as force */ Force = 0, /** Apply as impulse */ Impulse = 1, /** Apply as velocity change, mass dependent */ VelocityChange = 2, /** Apply as mass dependent force */ Acceleration = 3 } /** * Collision callback event type. */ export declare enum CollisionEventType { /** Touch/contact detected, collision */ Touch = 0, /** Touch/contact lost, uncollide */ TouchLost = 1, /** Touch/contact with trigger detected */ TriggerTouch = 2, /** Touch/contact with trigger lost */ TriggerTouchLost = 3 } /** * Rigid body {@link PhysXComponent#shape}. * * [PhysX SDK Guide](https://gameworksdocs.nvidia.com/PhysX/4.1/documentation/physxguide/Manual/Geometry.html#geometry-types). */ export declare enum Shape { /** No shape. */ None = 0, /** Sphere shape. */ Sphere = 1, /** Capsule shape. */ Capsule = 2, /** Box shape. */ Box = 3, /** Plane shape. */ Plane = 4, /** Convex mesh shape. */ ConvexMesh = 5, /** Triangle mesh shape. */ TriangleMesh = 6 } /** * Mesh attribute enum. * @since 0.9.0 */ export declare enum MeshAttribute { /** Position attribute, 3 floats */ Position = 0, /** Tangent attribute, 4 floats */ Tangent = 1, /** Normal attribute, 3 floats */ Normal = 2, /** Texture coordinate attribute, 2 floats */ TextureCoordinate = 3, /** Color attribute, 4 floats, RGBA, range `0` to `1` */ Color = 4, /** Joint id attribute, 8 unsigned ints */ JointId = 5, /** Joint weights attribute, 8 floats */ JointWeight = 6, /** Secondary texture coordinate attribute, 2 floats */ SecondaryTextureCoordinate = 7 } /** Proxy used to override prototypes of destroyed objects. */ export declare const DestroyedObjectInstance: {}; /** Proxy used to override prototypes of destroyed components. */ export declare const DestroyedComponentInstance: {}; /** Proxy used to override prototypes of destroyed prefabs. */ export declare const DestroyedPrefabInstance: {}; /** * Provides access to a component instance of a specified component type. * * @example * * This is how you extend this class to create your own custom * component: * * ```js * import { Component, Type } from '@wonderlandengine/api'; * * export class MyComponent extends Component { * static TypeName = 'my-component'; * static Properties = { * myBoolean: { type: Type.Boolean, default: false }, * }; * start() {} * onActivate() {} * onDeactivate() {} * update(dt) {} * } * ``` * * In a component, the scene can be accessed using `this.scene`: * * ```js * import { Component, Type } from '@wonderlandengine/api'; * * export class MyComponent extends Component { * static TypeName = 'my-component'; * start() { * const obj = this.scene.addObject(); * } * } * ``` */ export declare class Component { /** * Pack scene index and component id. * * @param scene Scene index. * @param id Component id. * @returns The packed id. * * @hidden */ static _pack(scene: number, id: number): number; /** * `true` for every class inheriting from this class. * * @note This is a workaround for `instanceof` to prevent issues * that could arise when an application ends up using multiple API versions. * * @hidden */ static readonly _isBaseComponent = true; /** * Fixed order of attributes in the `Properties` array. * * @note This is used for parameter deserialization and is filled during * component registration. * * @hidden */ static _propertyOrder: string[]; /** * Unique identifier for this component class. * * This is used to register, add, and retrieve components of a given type. */ static TypeName: string; /** * Properties of this component class. * * Properties are public attributes that can be configured via the * Wonderland Editor. * * Example: * * ```js * import { Component, Type } from '@wonderlandengine/api'; * class MyComponent extends Component { * static TypeName = 'my-component'; * static Properties = { * myBoolean: { type: Type.Boolean, default: false }, * myFloat: { type: Type.Float, default: false }, * myTexture: { type: Type.Texture, default: null }, * }; * } * ``` * * Properties are automatically added to each component instance, and are * accessible like any JS attribute: * * ```js * // Creates a new component and set each properties value: * const myComponent = object.addComponent(MyComponent, { * myBoolean: true, * myFloat: 42.0, * myTexture: null * }); * * // You can also override the properties on the instance: * myComponent.myBoolean = false; * myComponent.myFloat = -42.0; * ``` * * #### References * * Reference types (i.e., mesh, object, etc...) can also be listed as **required**: * * ```js * import {Component, Property} from '@wonderlandengine/api'; * * class MyComponent extends Component { * static Properties = { * myObject: Property.object({required: true}), * myAnimation: Property.animation({required: true}), * myTexture: Property.texture({required: true}), * myMesh: Property.mesh({required: true}), * } * } * ``` * * Please note that references are validated **once** before the call to {@link Component.start} only, * via the {@link Component.validateProperties} method. */ static Properties: Record<string, ComponentProperty>; /** * When set to `true`, the child class inherits from the parent * properties, as shown in the following example: * * ```js * import {Component, Property} from '@wonderlandengine/api'; * * class Parent extends Component { * static TypeName = 'parent'; * static Properties = {parentName: Property.string('parent')} * } * * class Child extends Parent { * static TypeName = 'child'; * static Properties = {name: Property.string('child')} * static InheritProperties = true; * * start() { * // Works because `InheritProperties` is `true`. * console.log(`${this.name} inherits from ${this.parentName}`); * } * } * ``` * * @note Properties defined in descendant classes will override properties * with the same name defined in ancestor classes. * * Defaults to `true`. */ static InheritProperties?: boolean; /** * Called when this component class is registered. * * @example * * This callback can be used to register dependencies of a component, * e.g., component classes that need to be registered in order to add * them at runtime with {@link Object3D.addComponent}, independent of whether * they are used in the editor. * * ```js * class Spawner extends Component { * static TypeName = 'spawner'; * * static onRegister(engine) { * engine.registerComponent(SpawnedComponent); * } * * // You can now use addComponent with SpawnedComponent * } * ``` * * @example * * This callback can be used to register different implementations of a * component depending on client features or API versions. * * ```js * // Properties need to be the same for all implementations! * const SharedProperties = {}; * * class Anchor extends Component { * static TypeName = 'spawner'; * static Properties = SharedProperties; * * static onRegister(engine) { * if(navigator.xr === undefined) { * /* WebXR unsupported, keep this dummy component *\/ * return; * } * /* WebXR supported! Override already registered dummy implementation * * with one depending on hit-test API support *\/ * engine.registerComponent(window.HitTestSource === undefined ? * AnchorWithoutHitTest : AnchorWithHitTest); * } * * // This one implements no functions * } * ``` */ static onRegister?: (engine: WonderlandEngine) => void; /** * Allows to inherit properties directly inside the editor. * * @note Do not use directly, prefer using {@link inheritProperties}. * * @hidden */ static _inheritProperties(): void; /** * Triggered when the component is initialized by the runtime. This method * will only be triggered **once** after instantiation. * * @note During the initialization phase, `this.scene` will not match * `engine.scene`, since `engine.scene` references the **active** scene: * * ```js * import {Component} from '@wonderlandengine/api'; * * class MyComponent extends Component{ * init() { * const activeScene = this.engine.scene; * console.log(this.scene === activeScene); // Prints `false` * } * start() { * const activeScene = this.engine.scene; * console.log(this.scene === activeScene); // Prints `true` * } * } * ``` */ init?(): void; /** * Triggered when the component is started by the runtime, or activated. * * You can use that to re-initialize the state of the component. */ start?(): void; /** * Triggered **every frame** by the runtime. * * You should perform your business logic in this method. Example: * * ```js * import { Component, Type } from '@wonderlandengine/api'; * * class TranslateForwardComponent extends Component { * static TypeName = 'translate-forward-component'; * static Properties = { * speed: { type: Type.Float, default: 1.0 } * }; * constructor() { * this._forward = new Float32Array([0, 0, 0]); * } * update(dt) { * this.object.getForward(this._forward); * this._forward[0] *= this.speed; * this._forward[1] *= this.speed; * this._forward[2] *= this.speed; * this.object.translate(this._forward); * } * } * ``` * * @param delta Elapsed time between this frame and the previous one, in **seconds**. */ update?(delta: number): void; /** * Triggered when the component goes from an inactive state to an active state. * * @note When using ({@link WonderlandEngine.switchTo}), all the components * that were previously active will trigger this method. * * @note You can manually activate or deactivate a component using: {@link Component.active:setter}. */ onActivate?(): void; /** * Triggered when the component goes from an activated state to an inactive state. * * @note When using ({@link WonderlandEngine.switchTo}), the components of * the scene getting deactivated will trigger this method. * * @note You can manually activate or deactivate a component using: {@link Component.active:setter}. */ onDeactivate?(): void; /** * Triggered when the component is removed from its object. * For more information, please have a look at {@link Component.onDestroy}. * * @note This method will not be triggered for inactive scene being destroyed. * * @since 0.9.0 */ onDestroy?(): void; /** Manager index. @hidden */ readonly _manager: number; /** Packed id, containing the scene and the local id. @hidden */ readonly _id: number; /** Id relative to the scene component's manager. @hidden */ readonly _localId: number; /** * Object containing this object. * * **Note**: This is cached for faster retrieval. * * @hidden */ _object: Object3D | null; /** Scene instance. @hidden */ protected readonly _scene: Prefab; /** * Create a new instance * * @param engine The engine instance. * @param manager Index of the manager. * @param id WASM component instance index. * * @hidden */ constructor(scene: Prefab, manager?: number, id?: number); /** Scene this component is part of. */ get scene(): Prefab; /** Hosting engine instance. */ get engine(): WonderlandEngine; /** The name of this component's type */ get type(): string; /** The object this component is attached to. */ get object(): Object3D; /** * Set whether this component is active. * * Activating/deactivating a component comes at a small cost of reordering * components in the respective component manager. This function therefore * is not a trivial assignment. * * Does nothing if the component is already activated/deactivated. * * @param active New active state. */ set active(active: boolean); /** `true` if the component is marked as active and its scene is active. */ get active(): boolean; /** * `true` if the component is marked as active in the scene, `false` otherwise. * * @note At the opposite of {@link Component.active}, this accessor doesn't * take into account whether the scene is active or not. */ get markedActive(): boolean; /** * Copy all the properties from `src` into this instance. * * @note Only properties are copied. If a component needs to * copy extra data, it needs to override this method. * * #### Example * * ```js * class MyComponent extends Component { * nonPropertyData = 'Hello World'; * * copy(src) { * super.copy(src); * this.nonPropertyData = src.nonPropertyData; * return this; * } * } * ``` * * @note This method is called by {@link Object3D.clone}. Do not attempt to: * - Create new component * - Read references to other objects * * When cloning via {@link Object3D.clone}, this method will be called before * {@link Component.start}. * * @note JavaScript component properties aren't retargeted. Thus, references * inside the source object will not be retargeted to the destination object, * at the exception of the skin data on {@link MeshComponent} and {@link AnimationComponent}. * * @param src The source component to copy from. * * @returns Reference to self (for method chaining). */ copy(src: Record<string, any>): this; /** * Remove this component from its objects and destroy it. * * It is best practice to set the component to `null` after, * to ensure it does not get used later. * * ```js * c.destroy(); * c = null; * ``` * @since 0.9.0 */ destroy(): void; /** * Checks equality by comparing ids and **not** the JavaScript reference. * * @deprecate Use JavaScript reference comparison instead: * * ```js * const componentA = obj.addComponent('mesh'); * const componentB = obj.addComponent('mesh'); * const componentC = componentB; * console.log(componentA === componentB); // false * console.log(componentA === componentA); // true * console.log(componentB === componentC); // true * ``` */ equals(otherComponent: Component | undefined | null): boolean; /** * Reset the component properties to default. * * @note This is automatically called during the component instantiation. * * @returns Reference to self (for method chaining). */ resetProperties(): this; /** @deprecated Use {@link Component.resetProperties} instead. */ reset(): this; /** * Validate the properties on this instance. * * @throws If any of the required properties isn't initialized * on this instance. */ validateProperties(): void; toString(): string; /** * `true` if the component is destroyed, `false` otherwise. * * If {@link WonderlandEngine.erasePrototypeOnDestroy} is `true`, * reading a custom property will not work: * * ```js * engine.erasePrototypeOnDestroy = true; * * const comp = obj.addComponent('mesh'); * comp.customParam = 'Hello World!'; * * console.log(comp.isDestroyed); // Prints `false` * comp.destroy(); * console.log(comp.isDestroyed); // Prints `true` * console.log(comp.customParam); // Throws an error * ``` * * @since 1.1.1 */ get isDestroyed(): boolean; /** @hidden */ _copy(src: this, offsetsPtr: number, copyInfoPtr: number): this; /** * Trigger the component {@link Component.init} method. * * @note Use this method instead of directly calling {@link Component.init}, * because this method creates an handler for the {@link Component.start}. * * @note This api is meant to be used internally. * * @hidden */ _triggerInit(): void; /** * Trigger the component {@link Component.update} method. * * @note This api is meant to be used internally. * * @hidden */ _triggerUpdate(dt: number): void; /** * Trigger the component {@link Component.onActivate} method. * * @note This api is meant to be used internally. * * @hidden */ _triggerOnActivate(): void; /** * Trigger the component {@link Component.onDeactivate} method. * * @note This api is meant to be used internally. * * @hidden */ _triggerOnDeactivate(): void; /** * Trigger the component {@link Component.onDestroy} method. * * @note This api is meant to be used internally. * * @hidden */ _triggerOnDestroy(): void; } /** * Components must be registered before loading / appending a scene. * * It's possible to end up with a broken component in the following cases: * * - Component wasn't registered when the scene was loaded * - Component instantiation failed * * This dummy component is thus used as a placeholder by the engine. */ export declare class BrokenComponent extends Component { static TypeName: string; } /** * Merge the ascendant properties of class * * This method walks the prototype chain, and merges * all the properties found in parent components. * * Example: * * ```js * import {Property, inheritProperties} from '@wonderlandengine/api'; * * class Parent { * static Properties = { parentProp: Property.string('parent') }; * } * * class Child extends Parent { * static Properties = { childProp: Property.string('child') }; * } * inheritProperties(Child); * ``` * * @param target The class in which properties should be merged * * @hidden */ export declare function inheritProperties(target: ComponentConstructor | PropertyRecord): void; /** * Native collision component. * * Provides access to a native collision component instance. */ export declare class CollisionComponent extends Component { /** @override */ static TypeName: string; /** @overload */ getExtents(): Float32Array; /** * Collision component extents. * * If {@link collider} returns {@link Collider.Sphere}, only the first * component of the returned vector is used. * * @param out Destination array/vector, expected to have at least 3 elements. * @returns The `out` parameter. */ getExtents<T extends NumberArray>(out: T): T; /** Collision component collider */ get collider(): Collider; /** * Set collision component collider. * * @param collider Collider of the collision component. */ set collider(collider: Collider); /** * Equivalent to {@link CollisionComponent.getExtents}. * * @note Prefer to use {@link CollisionComponent.getExtents} for performance. */ get extents(): Float32Array; /** * Set collision component extents. * * If {@link collider} returns {@link Collider.Sphere}, only the first * component of the passed vector is used. * * Example: * * ```js * // Spans 1 unit on the x-axis, 2 on the y-axis, 3 on the z-axis. * collision.extent = [1, 2, 3]; * ``` * * @param extents Extents of the collision component, expects a * 3 component array. */ set extents(extents: Readonly<NumberArray>); /** * Get collision component radius. * * @note If {@link collider} is not {@link Collider.Sphere}, the returned value * corresponds to the radius of a sphere enclosing the shape. * * Example: * * ```js * sphere.radius = 3.0; * console.log(sphere.radius); // 3.0 * * box.extents = [2.0, 2.0, 2.0]; * console.log(box.radius); // 1.732... * ``` * */ get radius(): number; /** * Set collision component radius. * * @param radius Radius of the collision component * * @note If {@link collider} is not {@link Collider.Sphere}, * the extents are set to form a square that fits a sphere with the provided radius. * * Example: * * ```js * aabbCollision.radius = 2.0; // AABB fits a sphere of radius 2.0 * boxCollision.radius = 3.0; // Box now fits a sphere of radius 3.0, keeping orientation * ``` * */ set radius(radius: number); /** * Collision component group. * * The groups is a bitmask that is compared to other components in {@link CollisionComponent#queryOverlaps} * or the group in {@link Scene#rayCast}. * * Colliders that have no common groups will not overlap with each other. If a collider * has none of the groups set for {@link Scene#rayCast}, the ray will not hit it. * * Each bit represents belonging to a group, see example. * * ```js * // c belongs to group 2 * c.group = (1 << 2); * * // c belongs to group 0 * c.group = (1 << 0); * * // c belongs to group 0 *and* 2 * c.group = (1 << 0) | (1 << 2); * * (c.group & (1 << 2)) != 0; // true * (c.group & (1 << 7)) != 0; // false * ``` */ get group(): number; /** * Set collision component group. * * @param group Group mask of the collision component. */ set group(group: number); /** * Query overlapping objects. * * Usage: * * ```js * const collision = object.getComponent('collision'); * const overlaps = collision.queryOverlaps(); * for(const otherCollision of overlaps) { * const otherObject = otherCollision.object; * console.log(`Collision with object ${otherObject.objectId}`); * } * ``` * * @returns Collision components overlapping this collider. */ queryOverlaps(): CollisionComponent[]; } /** * Native text component * * Provides access to a native text component instance */ export declare class TextComponent extends Component { /** @override */ static TypeName: string; /** Text component alignment. */ get alignment(): Alignment; /** * Set text component alignment. * * @param alignment Alignment for the text component. */ set alignment(alignment: Alignment); /** * Text component vertical alignment. * @since 1.2.0 */ get verticalAlignment(): VerticalAlignment; /** * Set text component vertical alignment. * * @param verticalAlignment Vertical for the text component. * @since 1.2.0 */ set verticalAlignment(verticalAlignment: VerticalAlignment); /** * Text component justification. * * @deprecated Please use {@link TextComponent.verticalAlignment} instead. */ get justification(): VerticalAlignment; /** * Set text component justification. * * @param justification Justification for the text component. * * @deprecated Please use {@link TextComponent.verticalAlignment} instead. */ set justification(justification: VerticalAlignment); /** * Whether text is justified horizontally. * * Aligns text horizontally to both margins by adding space between words. * * Requires {@link wrapMode} to be {@link TextWrapMode.Soft} or * {@link TextWrapMode.Hard} and non-0 {@link wrapWidth}. * * The last line in a paragraph is never justified and respects * {@link alignment}. * * @since 1.3.0 */ get justified(): boolean; /** * Set whether text is justified horizontally. * * @param justified New justified state for the text component. * @since 1.3.0 */ set justified(justified: boolean); /** Text component character spacing. */ get characterSpacing(): number; /** * Set text component character spacing. * * @param spacing Character spacing for the text component. */ set characterSpacing(spacing: number); /** Text component line spacing. */ get lineSpacing(): number; /** * Set text component line spacing. * * @param spacing Line spacing for the text component */ set lineSpacing(spacing: number); /** Text component effect. */ get effect(): TextEffect; /** * Set text component effect. * * @param effect Effect for the text component */ set effect(effect: TextEffect); /** * Equivalent to {@link getEffectOffset}. * * @note Prefer to use {@link getEffectOffset} for performance. * * @since 1.3.0 */ get effectOffset(): Float32Array; /** * Equivalent to {@link setEffectOffset}. * * @since 1.3.0 */ set effectOffset(offset: Readonly<NumberArray>); /** @overload */ getEffectOffset(): Float32Array; /** * Get text component effect offset. * * @param out Destination array, expected to have at least 2 elements. * @returns The `out` parameter. * * @since 1.3.0 */ getEffectOffset<T extends NumberArray>(out: T): T; /** * Set text component effect offset. * * The offset is given as X and Y factors for {@link Font.emHeight}. E.g. a * value of 2 in one axis offsets the effect by two font line heights. A * positive Y value moves the effect **upwards**. * * @param offset Array with new offset, expected to have at least 2 elements. * * @since 1.3.0 */ setEffectOffset(offset: Readonly<NumberArray>): void; /** * Text component line wrap mode. * @since 1.2.1 */ get wrapMode(): TextWrapMode; /** * Set text component line wrap mode. * * @param wrapMode Line wrap mode for the text component. * @since 1.2.1 */ set wrapMode(wrapMode: TextWrapMode); /** * Text component line wrap width, in object space. * @since 1.2.1 */ get wrapWidth(): number; /** * Set text component line wrap width. * * Only takes effect when {@link wrapMode} is something other than * {@link TextWrapMode.None}. * * @param width Line wrap width for the text component, in object space. * @since 1.2.1 */ set wrapWidth(width: number); /** Text component text. */ get text(): string; /** * Set text component text. * * @param text Text of the text component. */ set text(text: any); /** * Set material to render the text with. * * @param material New material. */ set material(material: Material | null | undefined); /** Material used to render the text. */ get material(): Material | null; /** @overload */ getBoundingBoxForText(text: string): Float32Array; /** * Axis-aligned bounding box for a given text, in object space. * * To calculate the size for the currently set text, use * {@link getBoundingBox}. * * Useful for calculating the text size before an update and potentially * adjusting the text: * * ```js * let updatedName = 'some very long name'; * const box = new Float32Array(4); * text.getBoundingBoxForText(updatedName, box); * const width = box[2] - box[0]; * if(width > 2.0) { * updatedName = updatedName.slice(0, 5) + '...'; * } * text.text = updatedName; * ``` * * @param text Text string to calculate the bounding box for. * @param out Preallocated array to write into, to avoid garbage, * otherwise will allocate a new Float32Array. * * @returns Bounding box - left, bottom, right, top. */ getBoundingBoxForText<T extends NumberArray>(text: string, out: T): T; /** @overload */ getBoundingBox(): Float32Array; /** * Axis-aligned bounding box, in object space. * * The bounding box is computed using the current component properties * that influence the position and size of the text. The bounding box is * affected by alignment, spacing, effect type and the font set in the * material. * * To calculate the size for a different text, use * {@link getBoundingBoxForText}. * * Useful for adjusting text position or scaling: * * ```js * const box = new Float32Array(4); * text.getBoundingBox(box); * const width = box[2] - box[0]; * // Make text 1m wide * text.object.setScalingLocal([1/width, 1, 1]); * ``` * * @param text Text string to calculate the bounding box for. * @param out Preallocated array to write into, to avoid garbage, * otherwise will allocate a new Float32Array. * * @returns Bounding box - left, bottom, right, top. */ getBoundingBox<T extends NumberArray>(out: T): T; } /** * Native view component. * * Provides access to a native view component instance. */ export declare class ViewComponent extends Component { /** @override */ static TypeName: string; /** * Projection type of the view. * * @since 1.2.2 */ get projectionType(): ProjectionType; /** * Set the projection type of the view. * * @param type New projection type. * @since 1.2.2 */ set projectionType(type: ProjectionType); /** @overload */ getProjectionMatrix(): Float32Array; /** * Projection matrix. * * A 4x4 matrix that transforms from view space to a WebGL-compatible clip * space (-1 to 1 on all axes, near plane at -1, far plane at 1). * * If an XR session is active and this is the left or right eye view, this * returns the projection matrix reported by the device. * * @note This is not necessarily the final projection matrix used for * rendering. You can use it for unprojecting from screen space coordinates * to view space. * * @param out Destination array/vector, expected to have at least 16 elements. * @returns The `out` parameter. */ getProjectionMatrix<T extends NumberArray>(out: T): T; /** * Equivalent to {@link ViewComponent.getProjectionMatrix}. * * @note Prefer to use {@link ViewComponent.getProjectionMatrix} for performance. */ get projectionMatrix(): Float32Array; /** * Override projection matrix for this view. * * Bypasses the generation of the projection matrix from viewport, fov, near, far. * * @hidden */ _setProjectionMatrix(v: Readonly<NumberArray>): void; /** * Generate projection matrix from viewport, fov, near, far. * * Overwrites any projection matrix set manually. * * @hidden */ _generateProjectionMatrix(): void; /** ViewComponent near clipping plane value. */ get near(): number; /** * Set near clipping plane distance for the view. * * If an XR session is active, the change will apply in the * following frame, otherwise the change is immediate. * * @param near Near depth value. */ set near(near: number); /** Far clipping plane value. */ get far(): number; /** * Set far clipping plane distance for the view. * * If an XR session is active, the change will apply in the * following frame, otherwise the change is immediate. * * @param far Near depth value. */ set far(far: number); /** * Get the horizontal field of view for the view, **in degrees**. * * If an XR session is active and this is the left or right eye view, this * returns the field of view reported by the device, regardless of the fov * that was set. */ get fov(): number; /** * Set the horizontal field of view for the view, **in degrees**. * * Only has an effect if {@link projectionType} is * {@link ProjectionType.Perspective}. * * If an XR session is active and this is the left or right eye view, the * field of view reported by the device is used and this value is ignored. * After the XR session ends, the new value is applied. * * @param fov Horizontal field of view, **in degrees**. */ set fov(fov: number); /** @overload */ getViewport(): Int32Array; /** * Get viewport of the view of the form: [x, y, width, height]. * * @param out Destination array/vector, expected to have at least 4 elements. * @returns The `out` parameter. */ getViewport<T extends NumberArray>(out: T): T; /** * Get viewport of the view of the form: [x, y, width, height]. */ get viewport(): Int32Array; /** * Set viewport. * * @hidden */ _setViewport(x: number, y: number, width: number, height: number): void; /** * Get the width of the orthographic viewing volume. * * @since 1.2.2 */ get extent(): number; /** * Set the width of the orthographic viewing volume. * * Only has an effect if {@link projectionType} is * {@link ProjectionType.Orthographic}. * * @param extent New extent. * @since 1.2.2 */ set extent(extent: number); } /** * Native input component. * * Provides access to a native input component instance. */ export declare class InputComponent extends Component { /** @override */ static TypeName: string; /** Input component type */ get inputType(): InputType; /** * Set input component type. * * @params New input component type. */ set inputType(type: InputType); /** * WebXR Device API input source associated with this input component, * if type {@link InputType.ControllerLeft} or {@link InputType.ControllerRight}. */ get xrInputSource(): XRInputSource | null; /** * 'left', 'right' or `null` depending on the {@link InputComponent#inputType}. */ get handedness(): 'left' | 'right' | null; } /** * Native light component. * * Provides access to a native light component instance. */ export declare class LightComponent extends Component { /** @override */ static TypeName: string; /** @overload */ getColor(): Float32Array; /** * Get light color. * * @param out Destination array/vector, expected to have at least 3 elements. * @returns The `out` parameter. * @since 1.0.0 */ getColor<T extends NumberArray>(out: T): T; /** * Set light color. * * @param c New color array/vector, expected to have at least 3 elements. * @since 1.0.0 */ setColor(c: Readonly<NumberArray>): void; /** * View on the light color. * * @note Prefer to use {@link getColor} in performance-critical code. */ get color(): Float32Array; /** * Set light color. * * @param c Color of the light component. * * @note Prefer to use {@link setColor} in performance-critical code. */ set color(c: Readonly<NumberArray>); /** Light type. */ get lightType(): LightType; /** * Set light type. * * @param lightType Type of the light component. */ set lightType(t: LightType); /** * Light intensity. * @since 1.0.0 */ get intensity(): number; /** * Set light intensity. * * @param intensity Intensity of the light component. * @since 1.0.0 */ set intensity(intensity: number); /** * Outer angle for spot lights, in degrees. * @since 1.0.0 */ get outerAngle(): number; /** * Set outer angle for spot lights. * * @param angle Outer angle, in degrees. * @since 1.0.0 */ set outerAngle(angle: number); /** * Inner angle for spot lights, in degrees. * @since 1.0.0 */ get innerAngle(): number; /** * Set inner angle for spot lights. * * @param angle Inner angle, in degrees. * @since 1.0.0 */ set innerAngle(angle: number); /** * Whether the light casts shadows. * @since 1.0.0 */ get shadows(): boolean; /** * Set whether the light casts shadows. * * @param b Whether the light casts shadows. * @since 1.0.0 */ set shadows(b: boolean); /** * Range for shadows. * @since 1.0.0 */ get shadowRange(): number; /** * Set range for shadows. * * @param range Range for shadows. * @since 1.0.0 */ set shadowRange(range: number); /** * Bias value for shadows. * @since 1.0.0 */ get shadowBias(): number; /** * Set bias value for shadows. * * @param bias Bias for shadows. * @since 1.0.0 */ set shadowBias(bias: number); /** * Normal bias value for shadows. * @since 1.0.0 */ get shadowNormalBias(): number; /** * Set normal bias value for shadows. * * @param bias Normal bias for shadows. * @since 1.0.0 */ set shadowNormalBias(bias: number); /** * Texel size for shadows. * @since 1.0.0 */ get shadowTexelSize(): number; /** * Set texel size for shadows. * * @param size Texel size for shadows. * @since 1.0.0 */ set shadowTexelSize(size: number); /** * Cascade count for {@link LightType.Sun} shadows. * @since 1.0.0 */ get cascadeCount(): number; /** * Set cascade count for {@link LightType.Sun} shadows. * * @param count Cascade count. * @since 1.0.0 */ set cascadeCount(count: number); } /** * Native animation component. * * Provides access to a native animation component instance. */ export declare class AnimationComponent extends Component { /** @override */ static TypeName: string; /** * Emitter for animation events triggered on this component. * * The first argument is the name of the event. */ readonly onEvent: Emitter<[string]>; /** * Set animation to play. * * Make sure to {@link Animation#retarget} the animation to affect the * right objects. * * @param anim Animation to play. */ set animation(anim: Animation | null | undefined); /** Animation set for this component */ get animation(): Animation | null; /** * Set play count. Set to `0` to loop indefinitely. * * @param playCount Number of times to repeat the animation. */ set playCount(playCount: number); /** Number of times the animation is played. */ get playCount(): number; /** * Set speed. Set to negative values to run the animation backwards. * * Setting speed has an immediate effect for the current frame's update * and will continue with the speed from the current point in the animation. * * @param speed New speed at which to play the animation. * @since 0.8.10 */ set speed(speed: number); /** * Speed factor at which the animation is played. * * @since 0.8.10 */ get speed(): number; /** Current playing state of the animation */ get state(): AnimationState; /** * How to handle root motion on this component. * * @since 1.2.2 */ get rootMotionMode(): RootMotionMode; /** * Set how to handle root motion. * * @param mode Mode to handle root motion, see {@link RootMotionMode}. * @since 1.2.2 */ set rootMotionMode(mode: RootMotionMode); /** * Current iteration of the animation. * * If {@link playCount} is not unlimited, the value is in the range from * `0` to `playCount`. * * @since 1.2.3 */ get iteration(): number; /** * Current playing position of the animation within the current iteration, * in seconds. * * The value is in the range from `0.0` to {@link AnimationComponent#duration}, * if playing in reverse, this range is reversed as well. * * @since 1.2.3 */ get position(): number; /** * Current duration to loop one iteration in seconds, offers a more accurate duration * than {@link Animation#duration} when blending multiple animations. * * @since 1.2.3 */ get duration(): number; /** * Play animation. * * If the animation is currently paused, resumes from that position. If the * animation is already playing, does nothing. * * To restart the animation, {@link AnimationComponent#stop} it first. */ play(): void; /** Stop animation. */ stop(): void; /** Pause animation. */ pause(): void; /** * Get the value of a float parameter in the attached graph. * Throws if the parameter is missing. * * @param name Name of the parameter. * @since 1.2.0 */ getFloatParameter(name: string): number | null; /** * Set the value of a float parameter in the attached graph * Throws if the parameter is missing. * * @param name Name of the parameter. * @param value Float value to set. * @returns 1 if the parameter was successfully set, 0 on fail. * @since 1.2.0 */ setFloatParameter(name: string, value: number): void; /** @overload */ getRootMotionTranslation(): Float32Array; /** * Get the root motion translation in **local space** calculated for the current frame. * * @note If {@link AnimationComponent.rootMotionMode} is not *