import { AnimationAction } from 'three'; import { AnimationClip } from 'three'; import { AnimationMixer } from 'three'; import { AnimationMixerEventMap } from 'three'; import { Audio as Audio_2 } from 'three'; import { AudioListener as AudioListener_3 } from 'three'; import { BatchedMesh } from 'three'; import { BloomEffect as BloomEffect_2 } from 'postprocessing'; import { Box3 } from 'three'; import { BufferGeometry } from 'three'; import { BufferGeometryEventMap } from 'three'; import { Camera as Camera_2 } from 'three'; import { Collider as Collider_2 } from '@dimforge/rapier3d-compat'; import { ColliderDesc } from '@dimforge/rapier3d-compat'; import { Color } from 'three'; import { ColorRepresentation } from 'three'; import { Curve } from 'three'; import { default as default_2 } from 'peerjs'; import { default as default_3 } from 'three/src/materials/nodes/MeshPhysicalNodeMaterial.js'; import { DepthOfFieldEffect } from 'postprocessing'; import { DepthTexture } from 'three'; import { dimforgeRapier3dCompat } from '@dimforge/rapier3d-compat'; import { DocumentedOptions } from '../../../node_modules/three-mesh-ui/build/types/core/elements/MeshUIBaseElement.js'; import { Effect } from 'postprocessing'; import { EffectComposer } from 'postprocessing'; import { EffectComposer as EffectComposer_2 } from 'three/examples/jsm/postprocessing/EffectComposer.js'; import { EmitterShape } from 'three.quarks'; import { Euler } from 'three'; import { EventDispatcher } from 'three'; import { Face } from 'three'; import * as fflate from 'three/examples/jsm/libs/fflate.module.js'; import * as flatbuffers from 'flatbuffers'; import { Fog as Fog_2 } from 'three'; import { Font } from 'three/examples/jsm/loaders/FontLoader.js'; import { Frustum } from 'three'; import { GLTF as GLTF_2 } from 'three/examples/jsm/loaders/GLTFLoader.js'; import { GLTFExporter } from 'three/examples/jsm/exporters/GLTFExporter.js'; import { GLTFExporterOptions } from 'three/examples/jsm/exporters/GLTFExporter.js'; import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'; import { GLTFLoaderPlugin } from 'three/examples/jsm/loaders/GLTFLoader.js'; import { GLTFParser } from 'three/examples/jsm/loaders/GLTFLoader.js'; import { Group } from 'three'; import { ImpulseJoint } from '@dimforge/rapier3d-compat'; import { InstancedMesh } from 'three'; import { Intersection } from 'three'; import { IParticleSystem as IParticleSystem_2 } from 'three.quarks'; import { KeyframeTrack } from 'three'; import { Layers } from 'three'; import { Light as Light_2 } from 'three'; import { LightProbe } from 'three'; import { Line2 } from 'three/examples/jsm/lines/Line2.js'; import { Loader } from 'three'; import { LoadingManager } from 'three'; import { LOD_Results } from '@needle-tools/gltf-progressive'; import { LODsManager as LODsManager_2 } from '@needle-tools/gltf-progressive'; import { Material } from 'three'; import { MaterialEventMap } from 'three'; import { Matrix4 } from 'three'; import { MediaConnection } from 'peerjs'; import { Mesh } from 'three'; import { MeshBasicMaterial } from 'three'; import { MeshPhysicalMaterial } from 'three'; import { MeshStandardMaterial } from 'three'; import { N8AOPostPass } from 'n8ao'; import { NEEDLE_progressive } from '@needle-tools/gltf-progressive'; import { NEEDLE_progressive_plugin } from '@needle-tools/gltf-progressive'; import { needleToolsMaterialx } from '@needle-tools/materialx'; import { NormalBufferAttributes } from 'three'; import { Object3D } from 'three'; import { Object3DEventMap } from 'three'; import { Options } from '../../../node_modules/three-mesh-ui/build/types/core/elements/MeshUIBaseElement.js'; import { OrbitControls as OrbitControls_2 } from 'three/examples/jsm/controls/OrbitControls.js'; import { OrthographicCamera } from 'three'; import { ParticleSystem as ParticleSystem_2 } from 'three.quarks'; import { Pass } from 'postprocessing'; import { peerjs } from 'peerjs'; import { PeerJSOption } from 'peerjs'; import { PerspectiveCamera } from 'three'; import { Plane } from 'three'; import { PositionalAudio } from 'three'; import { postprocessing } from 'postprocessing'; import { Particle as QParticle } from 'three.quarks'; import { Behavior as QParticleBehaviour } from 'three.quarks'; import { TrailParticle as QTrailParticle } from 'three.quarks'; import { Quaternion } from 'three'; import { QueryFilterFlags } from '@dimforge/rapier3d-compat'; import { RawShaderMaterial } from 'three'; import { Ray } from 'three'; import { Raycaster } from 'three'; import { Scene } from 'three'; import { SceneData } from 'needle-bindings'; import { ShaderMaterial } from 'three'; import { ShapeJSON } from 'three.quarks'; import { SkinnedMesh } from 'three'; import { SplatMesh } from '@sparkjsdev/spark'; import { Sprite as Sprite_2 } from 'three'; import { SpriteMaterial } from 'three'; import { Texture } from 'three'; import * as ThreeMeshUI from 'three-mesh-ui'; import { ToneMapping } from 'three'; import { TransformControls } from 'three/examples/jsm/controls/TransformControls.js'; import { Vector2 } from 'three'; import { Vector2Like } from 'three'; import { Vector3 } from 'three'; import { Vector3 as Vector3_2 } from 'three.quarks'; import { Vector3Like } from 'three'; import { Vector4 } from 'three'; import { Vector4 as Vector4_2 } from 'three.quarks'; import { Vector4Like } from 'three'; import { VideoTexture } from 'three'; import { WebGLCubeRenderTarget } from 'three'; import { WebGLRenderer } from 'three'; import { WebGLRendererParameters } from 'three'; import { WebGLRenderTarget } from 'three'; import { WebXRArrayCamera } from 'three'; import { World } from '@dimforge/rapier3d-compat'; import { XRControllerModelFactory } from 'three/examples/jsm/webxr/XRControllerModelFactory.js'; import { XRHandMeshModel } from 'three/examples/jsm/webxr/XRHandMeshModel.js'; import { XRHandSpace } from 'three'; export declare const $componentName: unique symbol; /* Excluded from this release type: _$CsMP */ /* Excluded from this release type: $GPtE */ export declare const $physicsKey: unique symbol; /* Excluded from this release type: _$WpMPwhP */ export declare class __Ignore { } export declare function __internalNotifyObjectDestroyed(obj: Object3D): void; /** Data describing the accessible semantics for a 3D object or component. */ declare type AccessibilityData = { /** ARIA role (e.g. `"button"`, `"img"`, `"region"`). */ role: string; /** Human-readable label announced by screen readers. */ label: string; /** When `true`, the element is hidden from the accessibility tree. */ hidden?: boolean; /** When `true`, indicates the element's content is being updated. */ busy?: boolean; }; /** * Manages an accessible, screen-reader-friendly overlay for a Needle Engine {@link Context}. * * The manager maintains a visually-hidden DOM tree that mirrors relevant 3D scene objects * with appropriate ARIA roles and labels. It also provides a live region so that hover * events in the 3D scene can be announced to assistive technology without stealing focus. * * ## Automatic integration * Several built-in components register accessible elements automatically: * - {@link DragControls} — announces draggable objects and drag state * - {@link Button} — exposes UI buttons to the accessibility tree * - {@link Text} — exposes UI text content to screen readers * - {@link ChangeTransformOnClick} — announces clickable transform actions * - {@link ChangeMaterialOnClick} — announces clickable material changes * - {@link EmphasizeOnClick} — announces clickable emphasis effects * - {@link PlayAudioOnClick} — announces clickable audio playback * - {@link PlayAnimationOnClick} — announces clickable animation triggers * * ## What this unlocks * - Hovering over buttons and interactive objects with the cursor announces them to screen readers via an ARIA live region — no focus steal required * - Screen readers can discover and navigate interactive 3D objects in the scene * - Drag operations update the accessibility state (busy, label changes) in real time * - Custom components can participate by calling {@link updateElement}, {@link focus}, and {@link hover} * * Access the manager via `this.context.accessibility` from any component. */ declare class AccessibilityManager { private readonly context; private static readonly _managers; /** Returns the {@link AccessibilityManager} associated with the given context or component. */ static get(obj: Context | IComponent): AccessibilityManager | undefined; constructor(context: Context); private _enabled; /** Enables or disables the accessibility overlay. When disabled, the overlay DOM is removed. */ set enabled(value: boolean); /** Removes all tracked accessibility elements, keeping only the live region. */ clear(): void; /** Removes the overlay from the DOM and unregisters this manager from the context. */ dispose(): void; private readonly root; private readonly liveRegion; private readonly treeElements; /** * Creates or updates the accessible DOM element for a 3D object or component. * @param obj - The scene object or component to represent. * @param data - Partial accessibility data (role, label, hidden, busy) to apply. */ updateElement(obj: T, data: Partial): void; /** Moves keyboard focus to the accessible element representing the given object. */ focus(obj: T): void; /** Removes keyboard focus from the accessible element representing the given object. */ unfocus(obj: T): void; /** * Announces a hover event to screen readers via the ARIA live region. * @param obj - The hovered object (used to look up its label if `text` is not provided). * @param text - Optional text to announce. Falls back to the element's `aria-label`. */ hover(obj: T, text?: string): void; /** Removes the accessible DOM element for the given object and stops tracking it. */ removeElement(obj: Object3D | IComponent): void; private set liveRegionMode(value); } export declare class ActionBuilder { static sequence(...params: IBehaviorElement[]): GroupActionModel; static parallel(...params: IBehaviorElement[]): GroupActionModel; static fadeAction(targetObject: Target, duration: number, show: boolean): ActionModel; /** * creates an action that plays an animation * @param start offset in seconds! * @param duration in seconds! 0 means play to end */ static startAnimationAction(targetObject: Target, anim: RegisteredAnimationInfo, reversed?: boolean, pingPong?: boolean): IBehaviorElement; static waitAction(duration: number): ActionModel; static lookAtCameraAction(targets: Target, duration?: number, front?: Vec3_2, up?: Vec3_2): ActionModel; static emphasize(targets: Target, duration: number, motionType?: EmphasizeActionMotionType, moveDistance?: number, style?: MotionStyle): ActionModel; static transformAction(targets: Target, transformTarget: Target, duration: number, transformType: Space, easeType?: EaseType): ActionModel; static playAudioAction(targets: Target, audio: string, type?: PlayAction, gain?: number, auralMode?: AuralMode): ActionModel; static impulseAction(targets: Target, velocity: Vec3_2): ActionModel; } export declare class ActionCollection { private actions; private sortedActions?; constructor(actions: DocumentAction[]); private organize; /** returns all document actions affecting the object passed in */ getActions(obj: Object3D): DocumentAction[] | null; } export declare class ActionModel implements IBehaviorElement { private static global_id; id: string; tokenId?: "ChangeScene" | "Visibility" | "StartAnimation" | "Wait" | "LookAtCamera" | "Emphasize" | "Transform" | "Audio" | "Impulse"; affectedObjects?: string | Target; easeType?: EaseType; motionType: EmphasizeActionMotionType | VisibilityActionMotionType | undefined; duration?: number; moveDistance?: number; style?: MotionStyle; type?: Space | PlayAction | VisibilityMode; front?: Vec3_2; up?: Vec3_2; start?: number; animationSpeed?: number; reversed?: boolean; pingPong?: boolean; xFormTarget?: Target | string; audio?: string; gain?: number; auralMode?: AuralMode; multiplePerformOperation?: MultiplePerformOperation; velocity?: Vec3_2; comment?: string; animationName?: string; clone(): ActionModel; constructor(affectedObjects?: string | Target, id?: string); writeTo(document: USDDocument, writer: USDWriter): void; } /** * Options for an activation clip in the timeline builder */ export declare type ActivationClipOptions = { /** Start time of the clip in seconds. If omitted, placed after the previous clip on this track. */ start?: number; /** Duration of the clip in seconds (required) */ duration: number; /** Ease-in duration in seconds (default: 0) */ easeIn?: number; /** Ease-out duration in seconds (default: 0) */ easeOut?: number; }; /* Excluded from this release type: ActivationTrackBuilder */ export declare const activeInHierarchyFieldName = "needle_isActiveInHierarchy"; /** * Register a callback when an {@link HTMLElement} attribute changes. * This is used, for example, by the Skybox component to watch for changes to the environment-* and skybox-* attributes. * Duplicate registrations of the same (element, name, callback) triple are * silently skipped — the callback is only added once and the returned * unsubscribe function still removes it correctly. * @returns A function that can be used to unregister the callback */ export declare function addAttributeChangeCallback(domElement: HTMLElement, name: string, callback: AttributeChangeCallback): () => void; export declare function addComponent(obj: Object3D, componentInstance: T | ConstructorConcrete, init?: ComponentInit, opts?: { callAwake: boolean; }): T; /** Register callbacks for registering custom gltf importer or exporter plugins */ export declare function addCustomExtensionPlugin(ext: INeedleGLTFExtensionPlugin): void; export declare function addNewComponent(obj: Object3D, componentInstance: T, callAwake?: boolean): T; /** * Use patcher for patching properties insteadof calling Object.defineProperty individually * since this will cause conflicts if multiple patches need to be applied to the same property */ export declare function addPatch(prototype: T, fieldName: string, beforeCallback?: Prefix | null, afterCallback?: Postfix | null): void; /** * The Addressables class is used to register and manage {@link AssetReference} types * It can be accessed from components via {@link Context.Current} or {@link Context.addressables} (e.g. `this.context.addressables`) */ export declare class Addressables { private _context; private _assetReferences; /* Excluded from this release type: __constructor */ /* Excluded from this release type: dispose */ private preUpdate; /** * Find a registered AssetReference by its URL */ findAssetReference(url: string): AssetReference | null; /* Excluded from this release type: registerAssetReference */ /* Excluded from this release type: unregisterAssetReference */ } /**[documentation](https://developer.apple.com/documentation/arkit/usdz_schemas_for_ar/preliminary_anchoringapi/preliminary_planeanchoring_alignment) */ declare type Alignment = "horizontal" | "vertical" | "any"; /** * The [AlignmentConstraint](https://engine.needle.tools/docs/api/AlignmentConstraint) positions and scales this GameObject to span between two target objects. * The object is rotated to face `to` and scaled along Z to match the distance. * * **Use cases:** * - Dynamic beams or laser effects between objects * - Stretchy connectors or ropes * - Visual links between UI elements * - Debug lines between transforms * * **How it works:** * - Position: Centered between `from` and `to` (or at `from` if not centered) * - Rotation: Looks at `to` from `from` * - Scale: Z-axis scales to match distance, X/Y use `width` * * @example Create a beam between two objects * ```ts * const beam = beamMesh.addComponent(AlignmentConstraint); * // Set targets via serialized properties in editor * // or via code if properties are exposed * ``` * * @summary Aligns and scales object between two targets * @category Constraints * @group Components * @see {@link SmoothFollow} for following with smoothing **/ export declare class AlignmentConstraint extends Component { private from; private to; private width; private centered; private _centerPos; awake(): void; update(): void; } declare type AlphaKey = { time: number; alpha: number; }; /* Excluded from this release type: AmbientMode */ /**[documentation](https://developer.apple.com/documentation/arkit/usdz_schemas_for_ar/preliminary_anchoringapi/preliminary_anchoring_type) */ declare type Anchoring = "plane" | "image" | "face" | "none"; /** * Animation component to play animations on a GameObject. * For simpler animation needs compared to {@link Animator}, this component directly * plays AnimationClips without state machine logic. * * **Key features:** * - Play animations by index, name, or clip reference * - Cross-fade between animations with `fadeDuration` * - Loop or play once with optional clamping * - Random start time and speed variation * - Promise-based completion handling * * * ![](https://cloud.needle.tools/-/media/zXQhLgtxr5ZaxLDTDb3MXA.gif) * * @example Play animation by name * ```ts * const anim = this.gameObject.getComponent(Animation); * await anim?.play("Walk", { loop: true, fadeDuration: 0.3 }); * ``` * * @example Play with options * ```ts * anim?.play(0, { * loop: false, * clampWhenFinished: true, * speed: 2 * }); * ``` * * @summary Plays animations from AnimationClips * @category Animation and Sequencing * @group Components * @see {@link Animator} for state machine-based animation * @see {@link PlayOptions} for all playback options * @link https://engine.needle.tools/samples/?overlay=samples&tag=animation * @link https://engine.needle.tools/samples/imunogard/ * * @link https://engine.needle.tools/docs/blender/animation.html * * ![](https://cloud.needle.tools/-/media/vAYv-kU-eMpICqQZHJktCA.gif) * */ declare class Animation_2 extends Component implements IAnimationComponent { get isAnimationComponent(): boolean; addClip(clip: AnimationClip): void; /** * If true, the animation will start playing when the component is enabled */ playAutomatically: boolean; /** * If true, the animation will start at a random time. This is used when the animation component is enabled * @default false */ randomStartTime: boolean; /** * The animation min-max speed range * @default undefined */ minMaxSpeed?: Vec2_2; /** * The normalized offset to start the animation at. This will override startTime * @default undefined */ minMaxOffsetNormalized?: Vec2_2; /** * Set to true to loop the animation * @default true */ loop: boolean; /** * If true, the animation will clamp when finished */ clampWhenFinished: boolean; /** * The time in seconds of the first running animation action * @default 0 */ get time(): number; set time(val: number); get duration(): number; private _tempAnimationClipBeforeGameObjectExisted; /** * Get the first animation clip in the animations array */ get clip(): AnimationClip | null; /** * Set the first animation clip in the animations array */ set clip(val: AnimationClip | null); set clips(animations: AnimationClip[]); private _tempAnimationsArray; set animations(animations: AnimationClip[]); get animations(): AnimationClip[]; private mixer; /** * The animation actions */ get actions(): Array; set actions(val: Array); private _actions; private _handles; /* Excluded from this release type: awake */ /* Excluded from this release type: onEnable */ /* Excluded from this release type: update */ /* Excluded from this release type: onDisable */ /* Excluded from this release type: onDestroy */ /** Get an animation action by the animation clip name */ getAction(name: string): AnimationAction | null; /** Is any animation playing? */ get isPlaying(): boolean; /** Stops all currently playing animations */ stopAll(opts?: Pick): void; /** * Stops a specific animation clip or index. If clip is undefined then all animations will be stopped */ stop(clip?: AnimationIdentifier, opts?: Pick): void; /** * Pause all animations or a specific animation clip or index * @param clip optional animation clip, index or name, if undefined all animations will be paused * @param unpause if true, the animation will be resumed */ pause(clip?: AnimationIdentifier, unpause?: boolean): void; /** * Resume all paused animations. * Note that this will not fade animations in or out and just unpause previous animations. If an animation was faded out which means it's not running anymore, it will not be resumed. */ resume(): void; /** * Play an animation clip or an clip at the specified index. * @param clipOrNumber the animation clip, index or name to play. If undefined, the first animation in the animations array will be played * @param options the play options. Use to set the fade duration, loop, speed, start time, end time, clampWhenFinished * @returns a promise that resolves when the animation is finished (note that it will not resolve if the animation is looping) */ play(clipOrNumber?: AnimationIdentifier, options?: PlayOptions): Promise | void; private internalOnPlay; private tryFindHandle; private ensureMixer; } export { Animation_2 as Animation } /** * A fluent builder for creating `AnimationClip` instances from code. * * Use {@link AnimationBuilder.create} to start a new builder, chain `.track()` calls * to add animation tracks, and call `.build()` to produce the clip. * * @example Single track * ```ts * const clip = AnimationBuilder.create() * .track(door, "position", { from: [0,0,0], to: [2,0,0], duration: 1 }) * .build(); * ``` * * @example Multiple tracks * ```ts * const clip = AnimationBuilder.create("DoorOpen") * .track(door, "position", { from: [0,0,0], to: [2,0,0], duration: 1 }) * .track(light, "intensity", { from: 0, to: 5, duration: 1 }) * .build(room); * ``` * * @category Animation and Sequencing * @group Utilities */ export declare class AnimationBuilder { private _name?; private _tracks; /** Creates a new AnimationBuilder instance */ static create(name?: string): AnimationBuilder; constructor(name?: string); /** Adds an animation track for an Object3D's position or scale */ track(target: Object3D, property: "position" | "scale", keyframes: KF_2, options?: TrackOptions): this; /** Adds an animation track for an Object3D's quaternion */ track(target: Object3D, property: "quaternion", keyframes: KF_2, options?: TrackOptions): this; /** Adds an animation track for an Object3D's rotation (Euler, converted to quaternion) */ track(target: Object3D, property: "rotation", keyframes: KF_2, options?: TrackOptions): this; /** Adds an animation track for an Object3D's visibility */ track(target: Object3D, property: "visible", keyframes: KF_2, options?: TrackOptions): this; /** Adds an animation track for a material's numeric property */ track(target: Material, property: "opacity" | "roughness" | "metalness" | "alphaTest" | "emissiveIntensity" | "envMapIntensity" | "bumpScale" | "displacementScale" | "displacementBias", keyframes: KF_2, options?: TrackOptions): this; /** Adds an animation track for a material's color property */ track(target: Material, property: "color" | "emissive", keyframes: KF_2, options?: TrackOptions): this; /** Adds an animation track for a light's numeric property */ track(target: Light_2, property: "intensity" | "distance" | "angle" | "penumbra" | "decay", keyframes: KF_2, options?: TrackOptions): this; /** Adds an animation track for a light's color */ track(target: Light_2, property: "color", keyframes: KF_2, options?: TrackOptions): this; /** Adds an animation track for a camera's numeric property */ track(target: PerspectiveCamera, property: "fov" | "near" | "far" | "zoom", keyframes: KF_2, options?: TrackOptions): this; /** * Builds and returns the `AnimationClip`. * @param root - Optional root Object3D for resolving track paths. * When provided, tracks targeting a different object use `target.name` for named resolution. */ build(root?: Object3D): AnimationClip; } /** * @category Animation and Sequencing * @see {@link PlayableDirector} for the main component to control timelines in Needle Engine. */ export declare type AnimationClipModel = { clip: string | number | AnimationClip; loop: boolean; duration: number; removeStartOffset: boolean; position?: Vec3_3 | Vector3; rotation?: Quat | Quaternion; }; /** * Options for an animation clip in the timeline builder */ export declare type AnimationClipOptions = { /** Start time of the clip in seconds. If omitted, placed after the previous clip on this track. */ start?: number; /** Duration of the clip in seconds. Defaults to the animation clip duration. */ duration?: number; /** Playback speed multiplier (default: 1) */ speed?: number; /** Whether the animation should loop within the clip (default: false) */ loop?: boolean; /** Ease-in duration in seconds (default: 0) */ easeIn?: number; /** Ease-out duration in seconds (default: 0) */ easeOut?: number; /** Offset into the source animation clip in seconds (default: 0) */ clipIn?: number; /** Whether to remove the start offset of the animation (default: false) */ removeStartOffset?: boolean; /** Pre-extrapolation mode (default: None) */ preExtrapolation?: ClipExtrapolation; /** Post-extrapolation mode (default: None) */ postExtrapolation?: ClipExtrapolation; /** Play the clip in reverse */ reversed?: boolean; }; /** * AnimationCurve is a representation of a curve that can be used to animate values over time. * * @category Animation and Sequencing * @group Utilities */ export declare class AnimationCurve { /** * Creates an animation curve that goes from the `from` value to the `to` value over the given `duration`. */ static linearFromTo(from: number, to: number, duration: number): AnimationCurve; /** Creates an animation curve with just one keyframe */ static constant(value: number): AnimationCurve; /** * The keyframes that define the curve. */ keys: Array; /** * Clones this AnimationCurve and returns a new instance with the same keyframes (the keyframes are also cloned). */ clone(): AnimationCurve; /** The duration of the curve, which is the time of the last keyframe. */ get duration(): number; /** Evaluates the curve at the given time and returns the value of the curve at that time. * @param time The time at which to evaluate the curve. * @returns The value of the curve at the given time. */ evaluate(time: number): number; static interpolateValue(time: number, keyframe1: Keyframe_2, keyframe2: Keyframe_2): number; } export declare class AnimationExtension implements IUSDExporterExtension { get extensionName(): string; get animationData(): Map, TransformData[]>; get registeredClips(): MapIterator; get animatedRoots(): MapIterator>; get holdClipMap(): Map; /** For each animated object, contains time/pos/rot/scale samples in the format that USD needs, * ready to be written to the .usda file. */ private dict; /** Map of all roots (Animation/Animator or scene) and all targets that they animate. * We need that info so that we can ensure that each target has the same number of TransformData entries * so that switching between animations doesn't result in data "leaking" to another clip. */ private rootTargetMap; private rootAndClipToRegisteredAnimationMap; /** Clips registered for each root */ private rootToRegisteredClip; private lastClipEndTime; private clipToStartTime; private clipToHoldClip; private serializers; /** Determines if we inject a rest pose clip for each root - only makes sense for QuickLook */ injectRestPoses: boolean; /** Determines if we inject a PlayAnimationOnClick component with "scenestart" trigger - only makes sense for QuickLook */ injectImplicitBehaviours: boolean; constructor(quickLookCompatible: boolean); getStartTimeCode(): number; /** Returns the end time code, based on 60 frames per second, for all registered animations. * This matches the highest time value in the USDZ file. */ getEndTimeCode(): number; getClipCount(root: Object3D): number; getStartTimeByClip(clip: AnimationClip | null): number; /** Register an AnimationClip for a specific root object. * @param root The root object that the animation clip is targeting. * @param clip The animation clip to register. If null, a rest pose is registered. * @returns The registered animation info, which contains the start time and duration of the clip. */ registerAnimation(root: Object3D, clip: AnimationClip | null): RegisteredAnimationInfo | null; onAfterHierarchy(_context: any): void; onAfterBuildDocument(_context: any): void; onExportObject(object: any, model: USDObject, _context: any): void; } declare type AnimationIdentifier = AnimationClip | number | string | undefined; /** User-friendly interpolation mode names */ export declare type AnimationInterpolation = "linear" | "smooth" | "step"; /** A single keyframe: a time and a value */ export declare type AnimationKeyframe = { /** Time in seconds */ time: number; /** The value at this time */ value: V; /** Interpolation mode for this track (default: `"linear"`). Note: Three.js applies one mode per track; the first keyframe's mode is used. */ interpolation?: AnimationInterpolation; }; /** * Registry for animation related data. Use {@link registerAnimationMixer} to register an animation mixer instance. * Can be accessed from {@link Context.animations} and is used internally e.g. when exporting GLTF files. * @category Animation */ declare class AnimationsRegistry { readonly context: Context; readonly mixers: AnimationMixer[]; constructor(context: Context); /* Excluded from this release type: onDestroy */ /** * Register an animation mixer instance. */ registerAnimationMixer(mixer: AnimationMixer): void; /** * Unregister an animation mixer instance. */ unregisterAnimationMixer(mixer: AnimationMixer | null | undefined): void; } /* Excluded from this release type: AnimationTrackBuilder */ declare class AnimationTriggers { disabledTrigger: string; highlightedTrigger: string; normalTrigger: string; pressedTrigger: string; selectedTrigger: string; } /** * Utility class for working with animations. */ export declare namespace AnimationUtils { /** * Tests if the root object of an AnimationAction can be animated. Objects where matrixAutoUpdate or matrixWorldAutoUpdate is set to false may not animate correctly. * @param action The AnimationAction to test * @param allowLog Whether to allow logging warnings. Default is false, which only allows logging in development environments. * @returns True if the root object can be animated, false otherwise */ export function testIfRootCanAnimate(action: AnimationAction, allowLog?: boolean): boolean; /** * Tries to get the animation actions from an animation mixer. * @param mixer The animation mixer to get the actions from * @returns The actions or null if the mixer is invalid */ export function tryGetActionsFromMixer(mixer: AnimationMixer): Array | null; export function tryGetAnimationClipsFromObjectHierarchy(obj: Object3D, target?: Array): Array; /** Internal method - This marks an object as being animated. Make sure to always call isAnimated=false if you stop animating the object * @param obj The object to mark * @param isAnimated Whether the object is animated or not */ export function setObjectAnimated(obj: Object3D, animatedBy: object, isAnimated: boolean): void; /** Get is the object is currently animated. Currently used by the Animator to check if a timeline animationtrack is actively animating an object */ export function getObjectAnimated(obj: Object3D): boolean; /** * Assigns animations from a GLTF file to the objects in the scene. * This method will look for objects in the scene that have animations and assign them to the correct objects. * @param file The GLTF file to assign the animations from */ export function autoplayAnimations(file: Object3D | Pick): Array | null; export function emptyClip(): AnimationClip; export function createScaleClip(options?: ScaleClipOptions): AnimationClip; } /** * Animator plays and manages state-machine based animations on a GameObject. * Uses an {@link AnimatorController} for state transitions, blending, and parameters. * * **State machine animations:** * Define animation states and transitions in Unity's Animator window or in [Blender's Animator Controller editor](https://engine.needle.tools/docs/blender/animation.html) * Control transitions via parameters (bool, int, float, trigger). * * ![](https://cloud.needle.tools/-/media/zXQhLgtxr5ZaxLDTDb3MXA.gif) * * **Creating at runtime:** * Use `AnimatorController.createFromClips()` to create controllers from code. * * **Parameters:** * - `setTrigger(name)` - Trigger a one-shot transition * - `setBool(name, value)` - Set boolean parameter * - `setFloat(name, value)` - Set float parameter * - `setInteger(name, value)` - Set integer parameter * * @example Trigger animation state * ```ts * const animator = myCharacter.getComponent(Animator); * animator.setTrigger("Jump"); * animator.setFloat("Speed", 5); * animator.setBool("IsRunning", true); * ``` * * @example Listen to animation events * ```ts * animator.onLoop(evt => console.log("Animation looped")); * animator.onFinished(evt => console.log("Animation finished")); * ``` * * @summary Plays and manages animations on a GameObject based on an AnimatorController * @category Animation and Sequencing * @group Components * @see {@link AnimatorController} for state machine configuration * @see {@link Animation} for simple clip playback * @see {@link PlayableDirector} for timeline-based animation * * @link https://engine.needle.tools/docs/blender/animation.html */ export declare class Animator extends Component implements IAnimationComponent { /** * Identifies this component as an animation component in the engine */ get isAnimationComponent(): boolean; /** * The current animator mixer, used for low-level control of animations. Owned by the AnimatorController * @returns The current AnimationMixer, or null if no controller is assigned * @see AnimatorController.mixer */ get mixer(): AnimationMixer | null; /** * When enabled, animation will affect the root transform position and rotation */ applyRootMotion: boolean; /** * Indicates whether this animator contains root motion data */ hasRootMotion: boolean; /** * When enabled, the animator will maintain its state when the component is disabled */ keepAnimatorControllerStateOnDisable: boolean; /** * Sets or replaces the animator controller for this component. * Handles binding the controller to this animator instance and ensures * proper initialization when the controller changes. * @param val The animator controller model or instance to use */ set runtimeAnimatorController(val: AnimatorControllerModel | AnimatorController | undefined | null); /** * Gets the current animator controller instance * @returns The current animator controller or null if none is assigned */ get runtimeAnimatorController(): AnimatorController | undefined | null; /** * Retrieves information about the current animation state * @returns The current state information, or undefined if no state is playing */ getCurrentStateInfo(): AnimatorStateInfo | null | undefined; /** * The currently playing animation action that can be used to modify animation properties * @returns The current animation action, or null if no animation is playing */ get currentAction(): AnimationAction | null; /** * Indicates whether animation parameters have been modified since the last update * @returns True if parameters have been changed */ get parametersAreDirty(): boolean; private _parametersAreDirty; /** * Indicates whether the animator state has changed since the last update * @returns True if the animator has been changed */ get isDirty(): boolean; private _isDirty; /**@deprecated use play() */ Play(name: string | number, layer?: number, normalizedTime?: number, transitionDurationInSec?: number): void; /** * Plays an animation on the animator * @param name The name or hash of the animation to play * @param layer The layer to play the animation on (-1 for default layer) * @param normalizedTime The time position to start playing (0-1 range, NEGATIVE_INFINITY for current position) * @param transitionDurationInSec The duration of the blend transition in seconds */ play(name: string | number, layer?: number, normalizedTime?: number, transitionDurationInSec?: number): void; /**@deprecated use reset */ Reset(): void; /** * Resets the animator controller to its initial state */ reset(): void; /**@deprecated use setBool */ SetBool(name: string | number, val: boolean): void; /** * Sets a boolean parameter in the animator * @param name The name or hash of the parameter * @param value The boolean value to set */ setBool(name: string | number, value: boolean): void; /**@deprecated use getBool */ GetBool(name: string | number): boolean; /** * Gets a boolean parameter from the animator * @param name The name or hash of the parameter * @returns The value of the boolean parameter, or false if not found */ getBool(name: string | number): boolean; /** * Toggles a boolean parameter between true and false * @param name The name or hash of the parameter */ toggleBool(name: string | number): void; /**@deprecated use setFloat */ SetFloat(name: string | number, val: number): void; /** * Sets a float parameter in the animator * @param name The name or hash of the parameter * @param val The float value to set */ setFloat(name: string | number, val: number): void; /**@deprecated use getFloat */ GetFloat(name: string | number): number; /** * Gets a float parameter from the animator * @param name The name or hash of the parameter * @returns The value of the float parameter, or -1 if not found */ getFloat(name: string | number): number; /**@deprecated use setInteger */ SetInteger(name: string | number, val: number): void; /** * Sets an integer parameter in the animator * @param name The name or hash of the parameter * @param val The integer value to set */ setInteger(name: string | number, val: number): void; /**@deprecated use getInteger */ GetInteger(name: string | number): number; /** * Gets an integer parameter from the animator * @param name The name or hash of the parameter * @returns The value of the integer parameter, or -1 if not found */ getInteger(name: string | number): number; /**@deprecated use setTrigger */ SetTrigger(name: string | number): void; /** * Activates a trigger parameter in the animator * @param name The name or hash of the trigger parameter */ setTrigger(name: string | number): void; /**@deprecated use resetTrigger */ ResetTrigger(name: string | number): void; /** * Resets a trigger parameter in the animator * @param name The name or hash of the trigger parameter */ resetTrigger(name: string | number): void; /**@deprecated use getTrigger */ GetTrigger(name: string | number): void; /** * Gets the state of a trigger parameter from the animator * @param name The name or hash of the trigger parameter * @returns The state of the trigger parameter */ getTrigger(name: string | number): boolean | undefined; /**@deprecated use isInTransition */ IsInTransition(): boolean; /** * Checks if the animator is currently in a transition between states * @returns True if the animator is currently blending between animations */ isInTransition(): boolean; /**@deprecated use setSpeed */ SetSpeed(speed: number): void; /** * Sets the playback speed of the animator * @param speed The new playback speed multiplier */ setSpeed(speed: number): void; /** * Sets a random playback speed between the min and max values * @param minMax Object with x (minimum) and y (maximum) speed values */ set minMaxSpeed(minMax: { x: number; y: number; }); /** * Sets a random normalized time offset for animations between min (x) and max (y) values * @param minMax Object with x (min) and y (max) values for the offset range */ set minMaxOffsetNormalized(minMax: { x: number; y: number; }); private _speed; private _normalizedStartOffset; private _animatorController?; awake(): void; private _initializeWithRuntimeAnimatorController?; initializeRuntimeAnimatorController(force?: boolean): void; onDisable(): void; onBeforeRender(): void; } export declare enum AnimatorConditionMode { If = 1, IfNot = 2, Greater = 3, Less = 4, Equals = 6, NotEqual = 7 } /** * Controls the playback of animations using a state machine architecture. * * The AnimatorController manages animation states, transitions between states, * and parameters that affect those transitions. It is used by the {@link Animator} * component to control animation behavior on 3D models. * * Use {@link AnimatorController.build} to fluently create a controller with parameters, * states, transitions, and conditions. For simple sequential playback, * use {@link AnimatorController.createFromClips}. * * @category Animation and Sequencing * @group Utilities */ export declare class AnimatorController { /** * Creates an AnimatorController from a set of animation clips. * Each clip becomes a state in the controller's state machine. * * @param clips - The animation clips to use for creating states * @param options - Configuration options for the controller including looping behavior and transitions * @returns A new AnimatorController instance */ static createFromClips(clips: AnimationClip[], options?: CreateAnimatorControllerOptions): AnimatorController; /** * Creates a new {@link AnimatorControllerBuilder} for fluently constructing a controller with * parameters, states, transitions, and conditions. * * @param name - Optional name for the controller * @returns A new builder instance * * @example * ```ts * const ctrl = AnimatorController.build("MyController") * .floatParameter("Speed") * .state("Idle", { clip: idleClip, loop: true }) * .state("Walk", { clip: walkClip, loop: true }) * .transition("Idle", "Walk", { duration: 0.25 }) * .condition("Speed", "greater", 0.1) * .transition("Walk", "Idle", { duration: 0.25 }) * .condition("Speed", "less", 0.1) * .build(); * ``` */ static build(name?: string): AnimatorControllerBuilder; /** * Plays an animation state by name or hash. * * @param name - The name or hash identifier of the state to play * @param layerIndex - The layer index (defaults to 0) * @param normalizedTime - The normalized time to start the animation from (0-1) * @param durationInSec - Transition duration in seconds */ play(name: string | number, layerIndex?: number, normalizedTime?: number, durationInSec?: number): void; /** * Resets the controller to its initial state. */ reset(): void; /** * Sets a boolean parameter value by name or hash. * * @param name - The name or hash identifier of the parameter * @param value - The boolean value to set */ setBool(name: string | number, value: boolean): void; /** * Gets a boolean parameter value by name or hash. * * @param name - The name or hash identifier of the parameter * @returns The boolean value of the parameter, or false if not found */ getBool(name: string | number): boolean; /** * Sets a float parameter value by name or hash. * * @param name - The name or hash identifier of the parameter * @param val - The float value to set * @returns True if the parameter was found and set, false otherwise */ setFloat(name: string | number, val: number): boolean; /** * Gets a float parameter value by name or hash. * * @param name - The name or hash identifier of the parameter * @returns The float value of the parameter, or 0 if not found */ getFloat(name: string | number): number; /** * Sets an integer parameter value by name or hash. * * @param name - The name or hash identifier of the parameter * @param val - The integer value to set */ setInteger(name: string | number, val: number): void; /** * Gets an integer parameter value by name or hash. * * @param name - The name or hash identifier of the parameter * @returns The integer value of the parameter, or 0 if not found */ getInteger(name: string | number): number; /** * Sets a trigger parameter to active (true). * Trigger parameters are automatically reset after they are consumed by a transition. * * @param name - The name or hash identifier of the trigger parameter */ setTrigger(name: string | number): void; /** * Resets a trigger parameter to inactive (false). * * @param name - The name or hash identifier of the trigger parameter */ resetTrigger(name: string | number): void; /** * Gets the current state of a trigger parameter. * * @param name - The name or hash identifier of the trigger parameter * @returns The boolean state of the trigger, or false if not found */ getTrigger(name: string | number): boolean; /** * Checks if the controller is currently in a transition between states. * * @returns True if a transition is in progress, false otherwise */ isInTransition(): boolean; /** Set the speed of the animator controller. Larger values will make the animation play faster. */ setSpeed(speed: number): void; private _speed; /** * Finds an animation state by name or hash. * @deprecated Use findState instead * * @param name - The name or hash identifier of the state to find * @returns The found state or null if not found */ FindState(name: string | number | undefined | null): State | null; /** * Finds an animation state by name or hash. * * @param name - The name or hash identifier of the state to find * @returns The found state or null if not found */ findState(name: string | number | undefined | null): State | null; /** * Gets information about the current playing animation state. * * @returns An AnimatorStateInfo object with data about the current state, or null if no state is active */ getCurrentStateInfo(): AnimatorStateInfo | null; /** * Gets the animation action currently playing. * * @returns The current animation action, or null if no action is playing */ get currentAction(): AnimationAction | null; /** * The normalized time (0-1) to start playing the first state at. * This affects the initial state when the animator is first enabled. */ normalizedStartOffset: number; /** * The Animator component this controller is bound to. */ animator?: Animator; /** * The data model describing the animation states and transitions. */ model: AnimatorControllerModel; /** * Gets the engine context from the bound animator. */ get context(): Context | undefined | null; /** * Gets the animation mixer used by this controller. */ get mixer(): AnimationMixer; /** * Cleans up resources used by this controller. * Stops all animations and unregisters the mixer from the animation system. */ dispose(): void; /** * Binds this controller to an animator component. * Creates a new animation mixer and sets up animation actions. * * @param animator - The animator to bind this controller to */ bind(animator: Animator): void; /** * Updates the controller's state machine and animations. * Called each frame by the animator component. * * @param weight - The weight to apply to the animations (for blending) */ update(weight: number): void; private _mixer; private _activeState?; /** * Gets the currently active animation state. * * @returns The active state or undefined if no state is active */ get activeState(): State | undefined; constructor(model: AnimatorControllerModel); private _activeStates; private updateActiveStates; private setStartTransition; private evaluateTransitions; private setTimescale; private getState; /** * These actions have been active previously but not faded out because we entered a state that has no real animation - no duration. In which case we hold the previously active actions until they are faded out. */ private readonly _heldActions; private releaseHeldActions; private transitionTo; private createAction; private evaluateCondition; private createActions; /** * Yields all animation actions managed by this controller. * Iterates through all states in all layers and returns their actions. */ enumerateActions(): Generator; private rootMotionHandler?; } /** * A fluent builder for creating {@link AnimatorController} instances from code. * * Use {@link AnimatorControllerBuilder.create} or {@link AnimatorController.build} to create a new builder. * * The builder tracks state names and parameter types through the fluent chain, * providing autocomplete for state names in `.transition()` and type-aware * `.condition()` calls (e.g., trigger parameters don't require a mode argument). * * @example With pre-built AnimationClips * ```ts * const controller = AnimatorControllerBuilder.create("CharacterController") * .floatParameter("Speed", 0) * .triggerParameter("Jump") * .state("Idle", { clip: idleClip, loop: true }) * .state("Walk", { clip: walkClip, loop: true }) * .state("Jump", { clip: jumpClip }) * .transition("Idle", "Walk", { duration: 0.25 }) * .condition("Speed", "greater", 0.1) * .transition("Walk", "Idle", { duration: 0.25 }) * .condition("Speed", "less", 0.1) * .transition("*", "Jump", { duration: 0.1 }) * .condition("Jump") * .transition("Jump", "Idle", { hasExitTime: true, exitTime: 0.9, duration: 0.25 }) * .build(); * ``` * * @example With inline tracks (no pre-built clips needed) * ```ts * const controller = AnimatorControllerBuilder.create("Door") * .boolParameter("Open", false) * .state("Closed", { loop: true }) * .track(door, "position", { from: [0, 0, 0], to: [0, 0, 0], duration: 1 }) * .state("Open", { loop: true }) * .track(door, "position", { from: [0, 0, 0], to: [2, 0, 0], duration: 1 }) * .track(light, "intensity", { from: 0, to: 5, duration: 1 }) * .transition("Closed", "Open", { duration: 0.25 }) * .condition("Open", "if") * .transition("Open", "Closed", { duration: 0.25 }) * .condition("Open", "ifNot") * .build(room); * ``` * * @typeParam TStates - Union of state names added via `.state()`. Used for autocomplete and validation in `.transition()` and `.defaultState()`. * @typeParam TParams - Record mapping parameter names to their types (`"trigger"`, `"bool"`, `"float"`, `"int"`). Used for type-aware `.condition()` overloads. * * @category Animation and Sequencing * @group Utilities */ export declare class AnimatorControllerBuilder = {}> { private _name; private _parameters; private _states; private _anyStateTransitions; private _defaultStateName; private _lastTransition; private _lastState; /** * Creates a new AnimatorControllerBuilder instance. * @param name - Optional name for the controller */ static create(name?: string): AnimatorControllerBuilder; constructor(name?: string); /** Adds a float parameter */ floatParameter(name: N, defaultValue?: number): AnimatorControllerBuilder>; /** Adds an integer parameter */ intParameter(name: N, defaultValue?: number): AnimatorControllerBuilder>; /** Adds a boolean parameter */ boolParameter(name: N, defaultValue?: boolean): AnimatorControllerBuilder>; /** Adds a trigger parameter */ triggerParameter(name: N): AnimatorControllerBuilder>; /** * Adds a state to the controller. The first state added becomes the default state. * * When `options.clip` is provided, the state uses that clip directly. * When omitted, chain `.track()` calls to define animation tracks inline: * ```ts * .state("Open", { loop: true }) * .track(door, "position", { from: [0,0,0], to: [2,0,0], duration: 1 }) * .track(light, "intensity", { from: 0, to: 5, duration: 1 }) * ``` * * @param name - Unique name for the state * @param options - State configuration including clip, loop, speed. When omitted, use `.track()` to add animation data. */ state(name: N, options?: StateOptions): AnimatorControllerBuilder; /** * Adds a transition between two states. * Use `"*"` as the source to create a transition from any state. * Chain `.condition()` calls after this to add conditions. * @param from - Source state name, or `"*"` for any-state transition * @param to - Destination state name * @param options - Transition configuration */ transition(from: TStates | "*", to: TStates, options?: TransitionOptions): AnimatorControllerBuilder; /** * Adds a condition to the most recently added transition. * Multiple conditions on the same transition are AND-ed together. * * The required arguments depend on the parameter type: * - **Trigger**: `.condition("Jump")` — mode defaults to `"if"`, no threshold needed * - **Bool**: `.condition("Open", "if")` or `.condition("Open", "ifNot")` * - **Float/Int**: `.condition("Speed", "greater", 0.1)` * * @param parameter - Name of the parameter to evaluate */ condition(parameter: ParamNamesOfType, mode?: "if" | "ifNot"): AnimatorControllerBuilder; condition(parameter: ParamNamesOfType, mode: "if" | "ifNot"): AnimatorControllerBuilder; condition(parameter: ParamNamesOfType, mode: "greater" | "less" | "equals" | "notEqual", threshold?: number): AnimatorControllerBuilder; /** Adds an animation track for an Object3D's position or scale to the current state */ track(target: Object3D, property: "position" | "scale", keyframes: KF, options?: TrackOptions): this; /** Adds an animation track for an Object3D's quaternion to the current state */ track(target: Object3D, property: "quaternion", keyframes: KF, options?: TrackOptions): this; /** Adds an animation track for an Object3D's rotation (Euler, converted to quaternion) to the current state */ track(target: Object3D, property: "rotation", keyframes: KF, options?: TrackOptions): this; /** Adds an animation track for an Object3D's visibility to the current state */ track(target: Object3D, property: "visible", keyframes: KF, options?: TrackOptions): this; /** Adds an animation track for a material's numeric property to the current state */ track(target: Material, property: "opacity" | "roughness" | "metalness" | "alphaTest" | "emissiveIntensity" | "envMapIntensity" | "bumpScale" | "displacementScale" | "displacementBias", keyframes: KF, options?: TrackOptions): this; /** Adds an animation track for a material's color property to the current state */ track(target: Material, property: "color" | "emissive", keyframes: KF, options?: TrackOptions): this; /** Adds an animation track for a light's numeric property to the current state */ track(target: Light_2, property: "intensity" | "distance" | "angle" | "penumbra" | "decay", keyframes: KF, options?: TrackOptions): this; /** Adds an animation track for a light's color to the current state */ track(target: Light_2, property: "color", keyframes: KF, options?: TrackOptions): this; /** Adds an animation track for a camera's numeric property to the current state */ track(target: PerspectiveCamera, property: "fov" | "near" | "far" | "zoom", keyframes: KF, options?: TrackOptions): this; /** * Sets which state is the default/entry state. * If not called, the first added state is used. * @param name - Name of the state */ defaultState(name: TStates): AnimatorControllerBuilder; /** * Builds and returns the {@link AnimatorController}. * Resolves all state name references to indices. * @param root - Optional root Object3D for resolving {@link TrackDescriptor} track paths. * When provided, tracks targeting a different object use `target.name` for named resolution. */ build(root?: Object3D): AnimatorController; } export declare type AnimatorControllerModel = { name: string; guid: string; parameters: Parameter[]; layers: Layer[]; }; export declare enum AnimatorControllerParameterType { Float = 1, Int = 3, Bool = 4, Trigger = 9 } export declare class AnimatorStateInfo { /** The name of the animation */ readonly name: string; /** The hash of the name */ readonly nameHash: number; /** The normalized time of the animation */ readonly normalizedTime: number; /** The length of the animation */ readonly length: number; /** The current speed of the animation */ readonly speed: number; /** The current action playing. It can be used to modify the action */ readonly action: AnimationAction | null; /** * If the state has any transitions */ readonly hasTransitions: boolean; constructor(state: State, normalizedTime: number, length: number, speed: number); } /** * [Antialiasing](https://engine.needle.tools/docs/api/Antialiasing) provides SMAA (Subpixel Morphological Antialiasing) post-processing effect to smooth edges in the rendered scene. * @summary Smooths jagged edges for a cleaner-looking image. * @category Effects * @group Components */ export declare class Antialiasing extends PostProcessingEffect { get typeName(): string; readonly preset: VolumeParameter; onCreateEffect(): EffectProviderResult; } declare type AnyString = string & { _brand?: never; }; /** * The Application class can be used to mute audio globally, and to check if the application (canvas) is currently visible (it's tab is active and not minimized). */ export declare class Application extends EventTarget { static get userInteractionRegistered(): boolean; /** @deprecated use Application.registerWaitForInteraction instead */ static readonly registerWaitForAllowAudio: typeof Application.registerWaitForInteraction; /** * Register a callback that will be called when the user interacts with the page (click, touch, keypress, etc). * If the user has already interacted with the page, the callback will be called immediately. * This can be used to wait for user interaction before playing audio, for example. */ static registerWaitForInteraction(cb: Function): void; /** * Unregister a callback that was previously registered with registerWaitForInteraction. */ static unregisterWaitForInteraction(cb: Function): void; private _mute; /** audio muted? */ get muted(): boolean; /** set global audio mute */ set muted(value: boolean); private readonly context; /** @returns true if the document is focused */ get hasFocus(): boolean; /** * @returns true if the application is currently visible (it's tab is active and not minimized) */ get isVisible(): boolean; private _isVisible; /* Excluded from this release type: __constructor */ private onVisiblityChanged; } /* Excluded from this release type: apply */ export declare function applyHMRChanges(newModule: any): boolean; /* Excluded from this release type: applyPrototypeExtensions */ declare enum AspectMode { None = 0, AdjustHeight = 1, AdjustWidth = 2 } export declare class AssetDatabase { constructor(); } /** ### AssetReferences can be used to load glTF or GLB assets * Use {@link AssetReference.getOrCreateFromUrl} to get an AssetReference for a URL to be easily loaded. When using the same URL multiple times the same AssetReference will be returned, this avoids loading or creating the same asset multiple times. * * **Important methods:** * - {@link preload} to load the asset binary without creating an instance yet. * - {@link loadAssetAsync} to load the asset and create an instance. * - {@link instantiate} to load the asset and create another instance. * - {@link unload} to dispose allocated memory and destroy the asset instance. * * @example Loading an asset from a URL * ```ts * import { AssetReference } from '@needle-tools/engine'; * const assetRef = AssetReference.getOrCreateFromUrl("https://example.com/myModel.glb"); * const instance = await assetRef.loadAssetAsync(); * scene.add(instance); * ``` * * @example Referencing an asset in a component and loading it on start * ```ts * import { Behaviour, serializable, AssetReference } from '@needle-tools/engine'; * * export class MyComponent extends Behaviour { * * @serializable(AssetReference) * myModel?: AssetReference; * * // Load the model on start. Start is called after awake and onEnable * start() { * if (this.myModel) { * this.myModel.loadAssetAsync().then(instance => { * if (instance) { * // add the loaded model to this component's game object * this.gameObject.add(instance); * } * }); * } * } * } * ``` * * ### Related: * - {@link ImageReference} to load external image URLs * - {@link FileReference} to load external file URLs * - {@link loadAsset} to load assets directly without using AssetReferences */ export declare class AssetReference { /** * Get an AssetReference for a URL to be easily loaded. * AssetReferences are cached so calling this method multiple times with the same arguments will always return the same AssetReference. * @param url The URL of the asset to load. The url can be relative or absolute. * @param context The context to use for loading the asset * @returns the AssetReference for the URL */ static getOrCreateFromUrl(url: string, context?: Context): AssetReference; /** * Get an AssetReference for a URL to be easily loaded. * AssetReferences are cached so calling this method multiple times with the same arguments will always return the same AssetReference. */ static getOrCreate(sourceId: SourceIdentifier | IComponent, url: string, context?: Context): AssetReference; readonly isAssetReference = true; /** * This is the loaded asset root object. If the asset is a glb/gltf file this will be the {@link three#Scene} object. */ get rawAsset(): any; /** The loaded asset root */ get asset(): Object3D | null; protected set asset(val: Object3D | null); /** The url of the loaded asset (or the asset to be loaded) * @deprecated use url */ get uri(): string; /** The url of the loaded asset (or the asset to be loaded) */ get url(): string; /** The name of the assigned url. This name is deduced from the url and might not reflect the actual name of the asset */ get urlName(): string; /** * @returns true if the uri is a valid URL (http, https, blob) */ get hasUrl(): boolean; private _rawAsset; private _glbRoot?; private _url; private _urlName; private _progressListeners; private _isLoadingRawBinary; private _rawBinary?; /* Excluded from this release type: __constructor */ constructor(uri: string, _hash?: string, asset?: any); private onResolvePrefab; private get mustLoad(); private _loadingPromise; /** * @returns `true` if the asset has been loaded (via preload) or if it exists already (assigned to `asset`) */ isLoaded(): boolean | ArrayBufferLike; /** frees previously allocated memory and destroys the current `asset` instance (if any) */ unload(): void; /** loads the asset binary without creating an instance */ preload(): Promise; /** Loads the asset and returns a single shared instance (assigned to {@link asset}). * Calling this multiple times will **not** create additional instances — it returns the same `Object3D`. * To create a new independent clone, use {@link instantiate} instead. * @param prog Optional progress callback invoked during download. * @returns The loaded root `Object3D`, or `null` if loading fails. */ loadAssetAsync(prog?: ProgressCallback | null): Promise; /** loads and returns a new instance of `asset` */ instantiate(parent?: Object3D | IInstantiateOptions | null): Promise | null>; /** loads and returns a new instance of `asset` - this call is networked so an instance will be created on all connected users */ instantiateSynced(parent?: Object3D | SyncInstantiateOptions, saveOnServer?: boolean): Promise | null>; beginListenDownload(evt: ProgressCallback): void; endListenDownload(evt: ProgressCallback): void; private raiseProgressEvent; private static readonly currentlyInstantiating; private onInstantiate; /** * try to ignore the intermediate created object * because it causes trouble if we instantiate an assetreference per player * and call destroy on the player marker root * @returns the scene root object if the asset was a glb/gltf */ private tryGetActualGameObjectRoot; } /** * Used to attract Rigidbodies towards the position of this component. * Add Rigidbodies to the `targets` array to have them be attracted. * You can use negative strength values to create a repulsion effect. * * @example Attractor component attracting a Rigidbody * ```ts * const attractor = object.addComponent(Attractor); * attractor.strength = 5; // positive value to attract * attractor.radius = 10; // only attract within 10 units * attractor.targets.push(rigidbody); // add the Rigidbody to be attracted * @summary Attract Rigidbodies towards the position of this component * @category Physics * @group Components */ export declare class Attractor extends Component { strength: number; radius: number; targets: Rigidbody[]; update(): void; } declare type AttributeChangeCallback = (value: string | null) => void; /** * Represents an audio clip that can be loaded and played independently. * The AudioClip class encapsulates the URL of the audio resource and provides * methods for playback control (play, pause, stop) and querying duration. */ export declare class AudioClip { readonly url: string; /** * Creates a new AudioClip instance with the specified URL. * @param url The URL of the audio resource to load. This can be a path to an audio file or a MediaStream URL. */ constructor(url: string); /** Whether the clip is currently playing. * @returns `true` if the clip is actively playing audio. */ get isPlaying(): boolean; /** * The total duration of the audio clip in seconds. * Loads the audio metadata if not already available. * @returns A promise that resolves with the duration in seconds. */ getDuration(): Promise; /** * Plays the audio clip from the current position. * @returns A promise that resolves when playback finishes, or rejects on error. * If the clip is looping, the promise will never resolve on its own – call {@link stop} or {@link pause} to end playback. */ play(): Promise; /** * Pauses playback at the current position. * Call {@link play} to resume. */ pause(): void; /** * Stops playback and resets the position to the beginning. */ stop(): void; /** Whether the clip should loop when reaching the end. */ get loop(): boolean; set loop(value: boolean); /** Playback volume from 0 (silent) to 1 (full). */ get volume(): number; set volume(value: number); /** Current playback position in seconds. */ get currentTime(): number; set currentTime(value: number); /** Normalized playback progress from 0 to 1. * @returns The current playback position as a value between 0 and 1, or 0 if the duration is unknown. */ get progress(): number; /** * Seeks to a normalized position (0–1) in the clip. * @param position A value between 0 (start) and 1 (end). */ seek(position: number): void; /** The underlying HTMLAudioElement, or `undefined` if not yet created. * Use this to connect the element to the Web Audio API via `createMediaElementSource()`. * @returns The HTMLAudioElement if the clip has been loaded or played, otherwise `undefined`. */ get audioElement(): HTMLAudioElement | undefined; private _audioElement?; private _duration?; private _loadPromise?; private _loop; private _volume; /** Lazily creates and loads the shared HTMLAudioElement. */ private ensureAudioElement; } /** * @category Animation and Sequencing * @see {@link PlayableDirector} for the main component to control timelines in Needle Engine. */ export declare type AudioClipModel = { clip: string; loop: boolean; volume: number; }; declare type AudioClipModel_2 = Models.ClipModel & { _didTriggerPlay: boolean; }; /** * Options for an audio clip in the timeline builder */ export declare type AudioClipOptions = { /** Start time of the clip in seconds. If omitted, placed after the previous clip on this track. */ start?: number; /** Duration of the clip in seconds (required for audio since we can't infer it) */ duration: number; /** Playback speed multiplier (default: 1) */ speed?: number; /** Volume multiplier for this clip (default: 1) */ volume?: number; /** Whether the audio should loop within the clip (default: false) */ loop?: boolean; /** Ease-in duration in seconds (default: 0) */ easeIn?: number; /** Ease-out duration in seconds (default: 0) */ easeOut?: number; }; export declare class AudioExtension implements IUSDExporterExtension { static getName(clip: string): string; get extensionName(): string; private files; onExportObject?(object: Object3D, model: USDObject, _context: USDZExporterContext): void; onAfterSerialize(context: USDZExporterContext): Promise; } /** * The [AudioListener](https://engine.needle.tools/docs/api/AudioListener) represents a listener that can hear audio sources in the scene. * This component creates and manages a Three.js {@link three#AudioListener}, automatically connecting it * to the main camera or a Camera in the parent hierarchy. * * @summary Receives audio in the scene and outputs it to speakers * @category Multimedia * @group Components */ declare class AudioListener_2 extends Component { /** * Gets the existing Three.js {@link three#AudioListener} instance or creates a new one if it doesn't exist. * This listener is responsible for capturing audio in the 3D scene. * @returns The {@link three#AudioListener} instance */ get listener(): AudioListener_3; private _listener; /* Excluded from this release type: onEnable */ /* Excluded from this release type: onDisable */ private onInteraction; private addListenerIfItExists; private removeListenerIfItExists; } export { AudioListener_2 as AudioListener } /** * Defines how audio volume attenuates over distance from the listener. */ export declare enum AudioRolloffMode { /** * Logarithmic rolloff provides a natural, real-world attenuation where volume decreases * exponentially with distance. */ Logarithmic = 0, /** * Linear rolloff provides a straightforward volume reduction that decreases at a constant * rate with distance. */ Linear = 1, /** * Custom rolloff allows for defining specialized distance-based attenuation curves. * Note: Custom rolloff is not fully implemented in this version. */ Custom = 2 } /** * Plays audio clips in the scene with support for spatial (3D) positioning. * * **Browser autoplay policies:** * Web browsers require user interaction before playing audio. Use * `AudioSource.userInteractionRegistered` to check if playback is allowed, * or `registerWaitForAllowAudio()` to queue playback until interaction occurs. * * **Spatial audio:** * Set `spatialBlend` to 1 for full 3D positioning, or 0 for 2D (non-spatial). * Requires an {@link AudioListener} in the scene (typically on the camera). * * **Visibility handling:** * Audio automatically pauses when the tab is hidden unless `playInBackground = true`. * On mobile, audio always pauses in background regardless of this setting. * * @example Play audio on button click * ```ts * onClick() { * const audio = this.getComponent(AudioSource); * audio.play(); * } * ``` * * @example Wait for user interaction * ```ts * AudioSource.registerWaitForAllowAudio(() => { * this.getComponent(AudioSource)?.play(); * }); * ``` * * @summary Plays audio clips from files or media streams * @category Multimedia * @group Components * @see {@link AudioListener} for the audio receiver component * @see {@link AudioRolloffMode} for distance attenuation options * @see {@link Voip} for voice communication * @see {@link PlayableDirector} for timeline-based audio * @link https://engine.needle.tools/samples/?overlay=samples&tag=audio * @link https://spatial-audio-zubckswmztj.needle.run/ */ export declare class AudioSource extends Component { /** * Checks if the user has interacted with the page to allow audio playback. * Audio playback often requires a user gesture first due to browser autoplay policies. * This is the same as calling {@link Application.userInteractionRegistered}. * * @returns Whether user interaction has been registered to allow audio playback */ static get userInteractionRegistered(): boolean; /** * Registers a callback that will be executed once the user has interacted with the page, * allowing audio playback to begin. * This is the same as calling {@link Application.registerWaitForInteraction}. * * @param cb - The callback function to execute when user interaction is registered */ static registerWaitForAllowAudio(cb: Function): void; /** * The audio clip to play. Can be a URL string pointing to an audio file or a {@link MediaStream} object. */ clip: string | MediaStream; /** * When true, the audio will automatically start playing when the component is enabled. * When false, you must call play() manually to start audio playback. * @default false */ playOnAwake: boolean; /** * When true, the audio clip will be loaded during initialization rather than when play() is called. * This can reduce playback delay but increases initial loading time. * @default true */ preload: boolean; /** * When true, audio will continue playing when the browser tab loses focus. * When false, audio will pause when the tab is minimized or not active. * @default true */ playInBackground: boolean; /** * Indicates whether the audio is currently playing. * * @returns True if the audio is playing, false otherwise */ get isPlaying(): boolean; /** * The total duration of the currently loaded audio clip in seconds. * * @returns Duration in seconds or undefined if no clip is loaded * @remarks For MediaStream clips, duration is not directly available and will return undefined. If the audio clip has not started loading or is still loading, duration may also be undefined until the audio buffer is ready. */ get duration(): number | undefined; /** * The current playback position as a normalized value between 0 and 1. * Can be set to seek to a specific position in the audio. */ get time01(): number; set time01(val: number); /** * The current playback position in seconds. * Can be set to seek to a specific time in the audio. */ get time(): number; set time(val: number); /** * When true, the audio will repeat after reaching the end. * When false, audio will play once and stop. * @default false */ get loop(): boolean; set loop(val: boolean); /** * Controls how the audio is positioned in space. * Values range from 0 (2D, non-positional) to 1 (fully 3D positioned). * Internally uses a dual-path audio graph to crossfade between a spatialized (PannerNode) * and a non-spatialized (direct) signal path. */ get spatialBlend(): number; set spatialBlend(val: number); /** * The minimum distance from the audio source at which the volume starts to attenuate. * Within this radius, the audio plays at full volume regardless of distance. */ get minDistance(): number; set minDistance(val: number); /** * The maximum distance from the audio source beyond which the volume no longer decreases. * This defines the outer limit of the attenuation curve. */ get maxDistance(): number; set maxDistance(val: number); private _spatialBlend; private _minDistance; private _maxDistance; /** * Controls the overall volume/loudness of the audio. * Values range from 0 (silent) to 1 (full volume). * @default 1 */ get volume(): number; set volume(val: number); private _volume; /** * Controls the playback rate (speed) of the audio. * Values greater than 1 increase speed, values less than 1 decrease it. * This affects both speed and pitch of the audio. * @default 1 */ set pitch(val: number); get pitch(): number; /** * Determines how audio volume decreases with distance from the listener. * @default AudioRolloffMode.Logarithmic * @see {@link AudioRolloffMode} */ rollOffMode: AudioRolloffMode; private _loop; private sound; private helper; private wasPlaying; private shouldPlay; private _loadedClip; private _audioElement; /** * True when {@link _audioElement} is a file-URL element routed through * `sound.setMediaElementSource()` (the iOS-survivable string-clip path). For this path ALL * playback control (play/pause/stop/loop/pitch/time/isPlaying) goes through the element, * because three.js sets `hasPlaybackControl = false` once a media source is attached. * It is `false` for the distinct MediaStream path (which uses an element with `srcObject` * plus `setMediaStreamSource()` and is controlled differently). */ private _usesMediaElementSource; private _entryNode; private _spatialGain; private _bypassGain; /** * Returns the underlying {@link PositionalAudio} object, creating it if necessary. * The audio source needs a user interaction to be initialized due to browser autoplay policies. * * @returns The three.js PositionalAudio object or null if unavailable */ get Sound(): PositionalAudio | null; /** * Indicates whether the audio source is queued to play when possible. * This may be true before user interaction has been registered. * * @returns Whether the audio source intends to play */ get ShouldPlay(): boolean; /** * Returns the Web Audio API context associated with this audio source. * * @returns The {@link AudioContext} or null if not available */ get audioContext(): AudioContext | undefined; /** * Resumes the shared AudioContext if it is currently suspended/interrupted and the * page is visible. Uses the same policy as the global resume handler so this never * triggers the iOS `InvalidStateError: Failed to start the audio device` (which * happens when resuming while the page is hidden). No-op when the context is already * running or when resuming is not currently allowed. */ private ensureContextResumed; /* Excluded from this release type: awake */ /* Excluded from this release type: onEnable */ /* Excluded from this release type: onDisable */ private onVisibilityChanged; private onApplicationMuteChanged; /** * Sets up playback of a string (file URL) clip through an `HTMLAudioElement` routed into the * Web Audio graph via `sound.setMediaElementSource()`. * * Why a media element instead of a decoded `AudioBuffer`: on iOS Safari an * `AudioBufferSourceNode` has its output torn down after a device lock / audio-session * interruption and cannot be reliably revived. A `MediaElementAudioSourceNode` survives the * lock because the playing `