/** * Copyright 2025 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @file xrblocks.js * @version v0.21.1 * @commitid bf149d6 * @builddate 2026-08-25T18:16:09.419Z * @description XR Blocks SDK, built from source with the above commit ID. * @agent When using with Gemini to create XR apps, use **Gemini Canvas** mode, * and follow rules below: * 1. Include the following importmap for maximum compatibility: "three": "https://cdn.jsdelivr.net/npm/three@0.184.0/build/three.module.js", "three/addons/": "https://cdn.jsdelivr.net/npm/three@0.184.0/examples/jsm/", "@pmndrs/uikit": "https://cdn.jsdelivr.net/npm/@pmndrs/uikit@1.0.64/dist/index.min.js", "@pmndrs/uikit-pub-sub": "https://cdn.jsdelivr.net/npm/@pmndrs/uikit-pub-sub@1.0.64/dist/index.min.js", "@pmndrs/msdfonts": "https://cdn.jsdelivr.net/npm/@pmndrs/msdfonts@1.0.64/dist/index.min.js", "@preact/signals-core": "https://cdn.jsdelivr.net/npm/@preact/signals-core@1.14.0/dist/signals-core.mjs", "yoga-layout/load": "https://cdn.jsdelivr.net/npm/yoga-layout@3.2.1/dist/src/load.js", "lit": "https://esm.sh/lit@3.3.1", "lit/": "https://esm.sh/lit@3.3.1/", "three-pathfinding": "https://cdn.jsdelivr.net/npm/three-pathfinding@1.3.0/dist/three-pathfinding.module.js", 2. If the app focus on standalone objects, spawn it in front of the user in WebXR and rescale to reasonable physical size. Wrap them with xb.ModelViewer and make sure users can drag the platform to move it around in XR. 3. When rendering a large scene, remember users may navigate the scene in a physical world space, also add locomotion methods like pinch to teleport. 4. Do not halluciate mode files --- use either public high-quality assets, or generate from primitive shapes of use vox formats for voxels or lego-styles. */ import * as GoogleGenAITypes from '@google/genai'; import * as _pmndrs_uikit_dist_panel from '@pmndrs/uikit/dist/panel'; import * as THREE from 'three'; import RAPIER_NS from 'rapier3d'; import OpenAIType from 'openai'; import { Pass, FullScreenQuad } from 'three/addons/postprocessing/Pass.js'; import { GLTFLoader, GLTF } from 'three/addons/loaders/GLTFLoader.js'; import * as _sparkjsdev_spark from '@sparkjsdev/spark'; import { SparkRenderer } from '@sparkjsdev/spark'; declare const GEMINI_DEFAULT_FLASH_MODEL = "gemini-3.7-flash"; declare const GEMINI_DEFAULT_LIVE_MODEL = "gemini-3.1-flash-live-preview"; declare const GEMINI_DEFAULT_IMAGE_MODEL = "gemini-3.1-flash-image"; declare class GeminiOptions { apiKey: string; urlParam: string; keyValid: boolean; enabled: boolean; model: string; liveModel: string; config: GoogleGenAITypes.GenerateContentConfig; } declare class OpenAIOptions { apiKey: string; urlParam: string; model: string; enabled: boolean; } type AIModel = 'gemini' | 'openai'; declare class AIOptions { enabled: boolean; model: AIModel; /** * Show a browser dialog before AI starts so a prototype user can provide, * replace, or remove an API key kept only for the current page. Disabled by * default. The dialog is skipped when the page URL or keys.json already * provides a key. */ promptForApiKey: boolean; gemini: GeminiOptions; openai: OpenAIOptions; globalUrlParams: { key: string; }; } /** * Misc collection of types not specific to any XR Blocks module. */ type Constructor = new (...args: any[]) => T; type ShaderUniforms = { [uniform: string]: THREE.IUniform; }; /** * Defines the structure for a shader object compatible with PanelMesh, * requiring uniforms, a vertex shader, and a fragment shader. */ interface Shader { uniforms: ShaderUniforms; vertexShader: string; fragmentShader: string; defines?: { [key: string]: unknown; }; } /** * A recursive readonly type. */ type DeepReadonly = T extends (...args: any[]) => any ? T : T extends object ? { readonly [P in keyof T]: DeepReadonly; } : T; /** * A recursive partial type. */ type DeepPartial = T extends (...args: any[]) => any ? T : T extends object ? { [P in keyof T]?: DeepPartial; } : T; /** * Parameters for RGB to depth UV mapping given different aspect ratios. * These parameters define the distortion model and affine transformations * required to align the RGB camera feed with the depth map. */ interface RgbToDepthParams { scale: number; scaleX: number; scaleY: number; translateU: number; translateV: number; k1: number; k2: number; k3: number; p1: number; p2: number; xc: number; yc: number; } /** * Default parameters for rgb to depth projection. * For RGB and depth, 4:3 and 1:1, respectively. */ declare const DEFAULT_RGB_TO_DEPTH_PARAMS: RgbToDepthParams; /** * Configuration options for the device camera. */ declare class DeviceCameraOptions { enabled: boolean; /** * Constraints for `getUserMedia`. This will guide the initial camera * selection. */ videoConstraints?: MediaTrackConstraints; /** * Hint for performance optimization on frequent captures. */ willCaptureFrequently: boolean; /** * Parameters for RGB to depth UV mapping given different aspect ratios. */ rgbToDepthParams: RgbToDepthParams; cameraLabel?: string; constructor(options?: DeepReadonly>); } declare const xrDeviceCameraEnvironmentOptions: { readonly enabled: boolean; readonly videoConstraints?: { readonly advanced?: readonly { readonly aspectRatio?: number | { readonly exact?: number | undefined; readonly ideal?: number | undefined; readonly max?: number | undefined; readonly min?: number | undefined; } | undefined; readonly autoGainControl?: boolean | { readonly exact?: boolean | undefined; readonly ideal?: boolean | undefined; } | undefined; readonly backgroundBlur?: boolean | { readonly exact?: boolean | undefined; readonly ideal?: boolean | undefined; } | undefined; readonly channelCount?: number | { readonly exact?: number | undefined; readonly ideal?: number | undefined; readonly max?: number | undefined; readonly min?: number | undefined; } | undefined; readonly deviceId?: string | readonly string[] | { readonly exact?: string | readonly string[] | undefined; readonly ideal?: string | readonly string[] | undefined; } | undefined; readonly displaySurface?: string | readonly string[] | { readonly exact?: string | readonly string[] | undefined; readonly ideal?: string | readonly string[] | undefined; } | undefined; readonly echoCancellation?: string | boolean | { readonly exact?: boolean | string | undefined; readonly ideal?: boolean | string | undefined; } | undefined; readonly facingMode?: string | readonly string[] | { readonly exact?: string | readonly string[] | undefined; readonly ideal?: string | readonly string[] | undefined; } | undefined; readonly frameRate?: number | { readonly exact?: number | undefined; readonly ideal?: number | undefined; readonly max?: number | undefined; readonly min?: number | undefined; } | undefined; readonly groupId?: string | readonly string[] | { readonly exact?: string | readonly string[] | undefined; readonly ideal?: string | readonly string[] | undefined; } | undefined; readonly height?: number | { readonly exact?: number | undefined; readonly ideal?: number | undefined; readonly max?: number | undefined; readonly min?: number | undefined; } | undefined; readonly noiseSuppression?: boolean | { readonly exact?: boolean | undefined; readonly ideal?: boolean | undefined; } | undefined; readonly sampleRate?: number | { readonly exact?: number | undefined; readonly ideal?: number | undefined; readonly max?: number | undefined; readonly min?: number | undefined; } | undefined; readonly sampleSize?: number | { readonly exact?: number | undefined; readonly ideal?: number | undefined; readonly max?: number | undefined; readonly min?: number | undefined; } | undefined; readonly width?: number | { readonly exact?: number | undefined; readonly ideal?: number | undefined; readonly max?: number | undefined; readonly min?: number | undefined; } | undefined; }[] | undefined; readonly aspectRatio?: number | { readonly exact?: number | undefined; readonly ideal?: number | undefined; readonly max?: number | undefined; readonly min?: number | undefined; } | undefined; readonly autoGainControl?: boolean | { readonly exact?: boolean | undefined; readonly ideal?: boolean | undefined; } | undefined; readonly backgroundBlur?: boolean | { readonly exact?: boolean | undefined; readonly ideal?: boolean | undefined; } | undefined; readonly channelCount?: number | { readonly exact?: number | undefined; readonly ideal?: number | undefined; readonly max?: number | undefined; readonly min?: number | undefined; } | undefined; readonly deviceId?: string | readonly string[] | { readonly exact?: string | readonly string[] | undefined; readonly ideal?: string | readonly string[] | undefined; } | undefined; readonly displaySurface?: string | readonly string[] | { readonly exact?: string | readonly string[] | undefined; readonly ideal?: string | readonly string[] | undefined; } | undefined; readonly echoCancellation?: string | boolean | { readonly exact?: boolean | string | undefined; readonly ideal?: boolean | string | undefined; } | undefined; readonly facingMode?: string | readonly string[] | { readonly exact?: string | readonly string[] | undefined; readonly ideal?: string | readonly string[] | undefined; } | undefined; readonly frameRate?: number | { readonly exact?: number | undefined; readonly ideal?: number | undefined; readonly max?: number | undefined; readonly min?: number | undefined; } | undefined; readonly groupId?: string | readonly string[] | { readonly exact?: string | readonly string[] | undefined; readonly ideal?: string | readonly string[] | undefined; } | undefined; readonly height?: number | { readonly exact?: number | undefined; readonly ideal?: number | undefined; readonly max?: number | undefined; readonly min?: number | undefined; } | undefined; readonly noiseSuppression?: boolean | { readonly exact?: boolean | undefined; readonly ideal?: boolean | undefined; } | undefined; readonly sampleRate?: number | { readonly exact?: number | undefined; readonly ideal?: number | undefined; readonly max?: number | undefined; readonly min?: number | undefined; } | undefined; readonly sampleSize?: number | { readonly exact?: number | undefined; readonly ideal?: number | undefined; readonly max?: number | undefined; readonly min?: number | undefined; } | undefined; readonly width?: number | { readonly exact?: number | undefined; readonly ideal?: number | undefined; readonly max?: number | undefined; readonly min?: number | undefined; } | undefined; } | undefined; readonly willCaptureFrequently: boolean; readonly rgbToDepthParams: { readonly scale: number; readonly scaleX: number; readonly scaleY: number; readonly translateU: number; readonly translateV: number; readonly k1: number; readonly k2: number; readonly k3: number; readonly p1: number; readonly p2: number; readonly xc: number; readonly yc: number; }; readonly cameraLabel?: string | undefined; }; declare const xrDeviceCameraUserOptions: { readonly enabled: boolean; readonly videoConstraints?: { readonly advanced?: readonly { readonly aspectRatio?: number | { readonly exact?: number | undefined; readonly ideal?: number | undefined; readonly max?: number | undefined; readonly min?: number | undefined; } | undefined; readonly autoGainControl?: boolean | { readonly exact?: boolean | undefined; readonly ideal?: boolean | undefined; } | undefined; readonly backgroundBlur?: boolean | { readonly exact?: boolean | undefined; readonly ideal?: boolean | undefined; } | undefined; readonly channelCount?: number | { readonly exact?: number | undefined; readonly ideal?: number | undefined; readonly max?: number | undefined; readonly min?: number | undefined; } | undefined; readonly deviceId?: string | readonly string[] | { readonly exact?: string | readonly string[] | undefined; readonly ideal?: string | readonly string[] | undefined; } | undefined; readonly displaySurface?: string | readonly string[] | { readonly exact?: string | readonly string[] | undefined; readonly ideal?: string | readonly string[] | undefined; } | undefined; readonly echoCancellation?: string | boolean | { readonly exact?: boolean | string | undefined; readonly ideal?: boolean | string | undefined; } | undefined; readonly facingMode?: string | readonly string[] | { readonly exact?: string | readonly string[] | undefined; readonly ideal?: string | readonly string[] | undefined; } | undefined; readonly frameRate?: number | { readonly exact?: number | undefined; readonly ideal?: number | undefined; readonly max?: number | undefined; readonly min?: number | undefined; } | undefined; readonly groupId?: string | readonly string[] | { readonly exact?: string | readonly string[] | undefined; readonly ideal?: string | readonly string[] | undefined; } | undefined; readonly height?: number | { readonly exact?: number | undefined; readonly ideal?: number | undefined; readonly max?: number | undefined; readonly min?: number | undefined; } | undefined; readonly noiseSuppression?: boolean | { readonly exact?: boolean | undefined; readonly ideal?: boolean | undefined; } | undefined; readonly sampleRate?: number | { readonly exact?: number | undefined; readonly ideal?: number | undefined; readonly max?: number | undefined; readonly min?: number | undefined; } | undefined; readonly sampleSize?: number | { readonly exact?: number | undefined; readonly ideal?: number | undefined; readonly max?: number | undefined; readonly min?: number | undefined; } | undefined; readonly width?: number | { readonly exact?: number | undefined; readonly ideal?: number | undefined; readonly max?: number | undefined; readonly min?: number | undefined; } | undefined; }[] | undefined; readonly aspectRatio?: number | { readonly exact?: number | undefined; readonly ideal?: number | undefined; readonly max?: number | undefined; readonly min?: number | undefined; } | undefined; readonly autoGainControl?: boolean | { readonly exact?: boolean | undefined; readonly ideal?: boolean | undefined; } | undefined; readonly backgroundBlur?: boolean | { readonly exact?: boolean | undefined; readonly ideal?: boolean | undefined; } | undefined; readonly channelCount?: number | { readonly exact?: number | undefined; readonly ideal?: number | undefined; readonly max?: number | undefined; readonly min?: number | undefined; } | undefined; readonly deviceId?: string | readonly string[] | { readonly exact?: string | readonly string[] | undefined; readonly ideal?: string | readonly string[] | undefined; } | undefined; readonly displaySurface?: string | readonly string[] | { readonly exact?: string | readonly string[] | undefined; readonly ideal?: string | readonly string[] | undefined; } | undefined; readonly echoCancellation?: string | boolean | { readonly exact?: boolean | string | undefined; readonly ideal?: boolean | string | undefined; } | undefined; readonly facingMode?: string | readonly string[] | { readonly exact?: string | readonly string[] | undefined; readonly ideal?: string | readonly string[] | undefined; } | undefined; readonly frameRate?: number | { readonly exact?: number | undefined; readonly ideal?: number | undefined; readonly max?: number | undefined; readonly min?: number | undefined; } | undefined; readonly groupId?: string | readonly string[] | { readonly exact?: string | readonly string[] | undefined; readonly ideal?: string | readonly string[] | undefined; } | undefined; readonly height?: number | { readonly exact?: number | undefined; readonly ideal?: number | undefined; readonly max?: number | undefined; readonly min?: number | undefined; } | undefined; readonly noiseSuppression?: boolean | { readonly exact?: boolean | undefined; readonly ideal?: boolean | undefined; } | undefined; readonly sampleRate?: number | { readonly exact?: number | undefined; readonly ideal?: number | undefined; readonly max?: number | undefined; readonly min?: number | undefined; } | undefined; readonly sampleSize?: number | { readonly exact?: number | undefined; readonly ideal?: number | undefined; readonly max?: number | undefined; readonly min?: number | undefined; } | undefined; readonly width?: number | { readonly exact?: number | undefined; readonly ideal?: number | undefined; readonly max?: number | undefined; readonly min?: number | undefined; } | undefined; } | undefined; readonly willCaptureFrequently: boolean; readonly rgbToDepthParams: { readonly scale: number; readonly scaleX: number; readonly scaleY: number; readonly translateU: number; readonly translateV: number; readonly k1: number; readonly k2: number; readonly k3: number; readonly p1: number; readonly p2: number; readonly xc: number; readonly yc: number; }; readonly cameraLabel?: string | undefined; }; declare const xrDeviceCameraEnvironmentContinuousOptions: { readonly enabled: boolean; readonly videoConstraints?: { readonly advanced?: readonly { readonly aspectRatio?: number | { readonly exact?: number | undefined; readonly ideal?: number | undefined; readonly max?: number | undefined; readonly min?: number | undefined; } | undefined; readonly autoGainControl?: boolean | { readonly exact?: boolean | undefined; readonly ideal?: boolean | undefined; } | undefined; readonly backgroundBlur?: boolean | { readonly exact?: boolean | undefined; readonly ideal?: boolean | undefined; } | undefined; readonly channelCount?: number | { readonly exact?: number | undefined; readonly ideal?: number | undefined; readonly max?: number | undefined; readonly min?: number | undefined; } | undefined; readonly deviceId?: string | readonly string[] | { readonly exact?: string | readonly string[] | undefined; readonly ideal?: string | readonly string[] | undefined; } | undefined; readonly displaySurface?: string | readonly string[] | { readonly exact?: string | readonly string[] | undefined; readonly ideal?: string | readonly string[] | undefined; } | undefined; readonly echoCancellation?: string | boolean | { readonly exact?: boolean | string | undefined; readonly ideal?: boolean | string | undefined; } | undefined; readonly facingMode?: string | readonly string[] | { readonly exact?: string | readonly string[] | undefined; readonly ideal?: string | readonly string[] | undefined; } | undefined; readonly frameRate?: number | { readonly exact?: number | undefined; readonly ideal?: number | undefined; readonly max?: number | undefined; readonly min?: number | undefined; } | undefined; readonly groupId?: string | readonly string[] | { readonly exact?: string | readonly string[] | undefined; readonly ideal?: string | readonly string[] | undefined; } | undefined; readonly height?: number | { readonly exact?: number | undefined; readonly ideal?: number | undefined; readonly max?: number | undefined; readonly min?: number | undefined; } | undefined; readonly noiseSuppression?: boolean | { readonly exact?: boolean | undefined; readonly ideal?: boolean | undefined; } | undefined; readonly sampleRate?: number | { readonly exact?: number | undefined; readonly ideal?: number | undefined; readonly max?: number | undefined; readonly min?: number | undefined; } | undefined; readonly sampleSize?: number | { readonly exact?: number | undefined; readonly ideal?: number | undefined; readonly max?: number | undefined; readonly min?: number | undefined; } | undefined; readonly width?: number | { readonly exact?: number | undefined; readonly ideal?: number | undefined; readonly max?: number | undefined; readonly min?: number | undefined; } | undefined; }[] | undefined; readonly aspectRatio?: number | { readonly exact?: number | undefined; readonly ideal?: number | undefined; readonly max?: number | undefined; readonly min?: number | undefined; } | undefined; readonly autoGainControl?: boolean | { readonly exact?: boolean | undefined; readonly ideal?: boolean | undefined; } | undefined; readonly backgroundBlur?: boolean | { readonly exact?: boolean | undefined; readonly ideal?: boolean | undefined; } | undefined; readonly channelCount?: number | { readonly exact?: number | undefined; readonly ideal?: number | undefined; readonly max?: number | undefined; readonly min?: number | undefined; } | undefined; readonly deviceId?: string | readonly string[] | { readonly exact?: string | readonly string[] | undefined; readonly ideal?: string | readonly string[] | undefined; } | undefined; readonly displaySurface?: string | readonly string[] | { readonly exact?: string | readonly string[] | undefined; readonly ideal?: string | readonly string[] | undefined; } | undefined; readonly echoCancellation?: string | boolean | { readonly exact?: boolean | string | undefined; readonly ideal?: boolean | string | undefined; } | undefined; readonly facingMode?: string | readonly string[] | { readonly exact?: string | readonly string[] | undefined; readonly ideal?: string | readonly string[] | undefined; } | undefined; readonly frameRate?: number | { readonly exact?: number | undefined; readonly ideal?: number | undefined; readonly max?: number | undefined; readonly min?: number | undefined; } | undefined; readonly groupId?: string | readonly string[] | { readonly exact?: string | readonly string[] | undefined; readonly ideal?: string | readonly string[] | undefined; } | undefined; readonly height?: number | { readonly exact?: number | undefined; readonly ideal?: number | undefined; readonly max?: number | undefined; readonly min?: number | undefined; } | undefined; readonly noiseSuppression?: boolean | { readonly exact?: boolean | undefined; readonly ideal?: boolean | undefined; } | undefined; readonly sampleRate?: number | { readonly exact?: number | undefined; readonly ideal?: number | undefined; readonly max?: number | undefined; readonly min?: number | undefined; } | undefined; readonly sampleSize?: number | { readonly exact?: number | undefined; readonly ideal?: number | undefined; readonly max?: number | undefined; readonly min?: number | undefined; } | undefined; readonly width?: number | { readonly exact?: number | undefined; readonly ideal?: number | undefined; readonly max?: number | undefined; readonly min?: number | undefined; } | undefined; } | undefined; readonly willCaptureFrequently: boolean; readonly rgbToDepthParams: { readonly scale: number; readonly scaleX: number; readonly scaleY: number; readonly translateU: number; readonly translateV: number; readonly k1: number; readonly k2: number; readonly k3: number; readonly p1: number; readonly p2: number; readonly xc: number; readonly yc: number; }; readonly cameraLabel?: string | undefined; }; declare const xrDeviceCameraUserContinuousOptions: { readonly enabled: boolean; readonly videoConstraints?: { readonly advanced?: readonly { readonly aspectRatio?: number | { readonly exact?: number | undefined; readonly ideal?: number | undefined; readonly max?: number | undefined; readonly min?: number | undefined; } | undefined; readonly autoGainControl?: boolean | { readonly exact?: boolean | undefined; readonly ideal?: boolean | undefined; } | undefined; readonly backgroundBlur?: boolean | { readonly exact?: boolean | undefined; readonly ideal?: boolean | undefined; } | undefined; readonly channelCount?: number | { readonly exact?: number | undefined; readonly ideal?: number | undefined; readonly max?: number | undefined; readonly min?: number | undefined; } | undefined; readonly deviceId?: string | readonly string[] | { readonly exact?: string | readonly string[] | undefined; readonly ideal?: string | readonly string[] | undefined; } | undefined; readonly displaySurface?: string | readonly string[] | { readonly exact?: string | readonly string[] | undefined; readonly ideal?: string | readonly string[] | undefined; } | undefined; readonly echoCancellation?: string | boolean | { readonly exact?: boolean | string | undefined; readonly ideal?: boolean | string | undefined; } | undefined; readonly facingMode?: string | readonly string[] | { readonly exact?: string | readonly string[] | undefined; readonly ideal?: string | readonly string[] | undefined; } | undefined; readonly frameRate?: number | { readonly exact?: number | undefined; readonly ideal?: number | undefined; readonly max?: number | undefined; readonly min?: number | undefined; } | undefined; readonly groupId?: string | readonly string[] | { readonly exact?: string | readonly string[] | undefined; readonly ideal?: string | readonly string[] | undefined; } | undefined; readonly height?: number | { readonly exact?: number | undefined; readonly ideal?: number | undefined; readonly max?: number | undefined; readonly min?: number | undefined; } | undefined; readonly noiseSuppression?: boolean | { readonly exact?: boolean | undefined; readonly ideal?: boolean | undefined; } | undefined; readonly sampleRate?: number | { readonly exact?: number | undefined; readonly ideal?: number | undefined; readonly max?: number | undefined; readonly min?: number | undefined; } | undefined; readonly sampleSize?: number | { readonly exact?: number | undefined; readonly ideal?: number | undefined; readonly max?: number | undefined; readonly min?: number | undefined; } | undefined; readonly width?: number | { readonly exact?: number | undefined; readonly ideal?: number | undefined; readonly max?: number | undefined; readonly min?: number | undefined; } | undefined; }[] | undefined; readonly aspectRatio?: number | { readonly exact?: number | undefined; readonly ideal?: number | undefined; readonly max?: number | undefined; readonly min?: number | undefined; } | undefined; readonly autoGainControl?: boolean | { readonly exact?: boolean | undefined; readonly ideal?: boolean | undefined; } | undefined; readonly backgroundBlur?: boolean | { readonly exact?: boolean | undefined; readonly ideal?: boolean | undefined; } | undefined; readonly channelCount?: number | { readonly exact?: number | undefined; readonly ideal?: number | undefined; readonly max?: number | undefined; readonly min?: number | undefined; } | undefined; readonly deviceId?: string | readonly string[] | { readonly exact?: string | readonly string[] | undefined; readonly ideal?: string | readonly string[] | undefined; } | undefined; readonly displaySurface?: string | readonly string[] | { readonly exact?: string | readonly string[] | undefined; readonly ideal?: string | readonly string[] | undefined; } | undefined; readonly echoCancellation?: string | boolean | { readonly exact?: boolean | string | undefined; readonly ideal?: boolean | string | undefined; } | undefined; readonly facingMode?: string | readonly string[] | { readonly exact?: string | readonly string[] | undefined; readonly ideal?: string | readonly string[] | undefined; } | undefined; readonly frameRate?: number | { readonly exact?: number | undefined; readonly ideal?: number | undefined; readonly max?: number | undefined; readonly min?: number | undefined; } | undefined; readonly groupId?: string | readonly string[] | { readonly exact?: string | readonly string[] | undefined; readonly ideal?: string | readonly string[] | undefined; } | undefined; readonly height?: number | { readonly exact?: number | undefined; readonly ideal?: number | undefined; readonly max?: number | undefined; readonly min?: number | undefined; } | undefined; readonly noiseSuppression?: boolean | { readonly exact?: boolean | undefined; readonly ideal?: boolean | undefined; } | undefined; readonly sampleRate?: number | { readonly exact?: number | undefined; readonly ideal?: number | undefined; readonly max?: number | undefined; readonly min?: number | undefined; } | undefined; readonly sampleSize?: number | { readonly exact?: number | undefined; readonly ideal?: number | undefined; readonly max?: number | undefined; readonly min?: number | undefined; } | undefined; readonly width?: number | { readonly exact?: number | undefined; readonly ideal?: number | undefined; readonly max?: number | undefined; readonly min?: number | undefined; } | undefined; } | undefined; readonly willCaptureFrequently: boolean; readonly rgbToDepthParams: { readonly scale: number; readonly scaleX: number; readonly scaleY: number; readonly translateU: number; readonly translateV: number; readonly k1: number; readonly k2: number; readonly k3: number; readonly p1: number; readonly p2: number; readonly xc: number; readonly yc: number; }; readonly cameraLabel?: string | undefined; }; declare class SceneDerivedContextOptions { enabled: boolean; constructor(options?: DeepPartial); enable(): this; } declare class SceneVisibilityOptions extends SceneDerivedContextOptions { /** * Raycast hits on materials with effective opacity less than or equal to this * threshold are ignored for line-of-sight occlusion. */ occlusionOpacityThreshold: number; } declare class SceneSetOfMarkOptions extends SceneDerivedContextOptions { } declare class SceneOptions { enabled: boolean; pollingIntervalMs: number; visibleObjects: SceneVisibilityOptions; som: SceneSetOfMarkOptions; constructor(options?: DeepPartial); enable(): this; enableVisibleObjects(): this; enableSetOfMark(): this; } declare class ContextOptions { debugging: boolean; enabled: boolean; scene: SceneOptions; constructor(options?: DeepPartial); enable(): this; enableScene(): this; enableVisibleObjects(): this; enableSetOfMark(): this; } declare class DepthMeshOptions { enabled: boolean; updateVertexNormals: boolean; showDebugTexture: boolean; useDepthTexture: boolean; renderShadow: boolean; shadowOpacity: number; patchHoles: boolean; patchHolesUpper: boolean; opacity: number; useDualCollider: boolean; useDownsampledGeometry: boolean; updateFullResolutionGeometry: boolean; colliderUpdateFps: number; /** FPS cap for depth mesh geometry updates. 0 = update every frame. */ depthMeshUpdateFps: number; depthFullResolution: number; ignoreEdgePixels: number; } declare class DepthOptions { debugging: boolean; enabled: boolean; depthMesh: DepthMeshOptions; depthTexture: { enabled: boolean; constantKernel: boolean; applyGaussianBlur: boolean; applyKawaseBlur: boolean; }; occlusion: { enabled: boolean; }; usagePreference: XRDepthUsage[]; dataFormatPreference: XRDepthDataFormat[]; depthTypeRequest: XRDepthType[]; matchDepthView: boolean; constructor(options?: DeepReadonly>); } declare const xrDepthMeshOptions: { readonly debugging: boolean; readonly enabled: boolean; readonly depthMesh: { readonly enabled: boolean; readonly updateVertexNormals: boolean; readonly showDebugTexture: boolean; readonly useDepthTexture: boolean; readonly renderShadow: boolean; readonly shadowOpacity: number; readonly patchHoles: boolean; readonly patchHolesUpper: boolean; readonly opacity: number; readonly useDualCollider: boolean; readonly useDownsampledGeometry: boolean; readonly updateFullResolutionGeometry: boolean; readonly colliderUpdateFps: number; readonly depthMeshUpdateFps: number; readonly depthFullResolution: number; readonly ignoreEdgePixels: number; }; readonly depthTexture: { readonly enabled: boolean; readonly constantKernel: boolean; readonly applyGaussianBlur: boolean; readonly applyKawaseBlur: boolean; }; readonly occlusion: { readonly enabled: boolean; }; readonly usagePreference: readonly XRDepthUsage[]; readonly dataFormatPreference: readonly XRDepthDataFormat[]; readonly depthTypeRequest: readonly XRDepthType[]; readonly matchDepthView: boolean; }; declare const xrDepthMeshVisualizationOptions: { readonly debugging: boolean; readonly enabled: boolean; readonly depthMesh: { readonly enabled: boolean; readonly updateVertexNormals: boolean; readonly showDebugTexture: boolean; readonly useDepthTexture: boolean; readonly renderShadow: boolean; readonly shadowOpacity: number; readonly patchHoles: boolean; readonly patchHolesUpper: boolean; readonly opacity: number; readonly useDualCollider: boolean; readonly useDownsampledGeometry: boolean; readonly updateFullResolutionGeometry: boolean; readonly colliderUpdateFps: number; readonly depthMeshUpdateFps: number; readonly depthFullResolution: number; readonly ignoreEdgePixels: number; }; readonly depthTexture: { readonly enabled: boolean; readonly constantKernel: boolean; readonly applyGaussianBlur: boolean; readonly applyKawaseBlur: boolean; }; readonly occlusion: { readonly enabled: boolean; }; readonly usagePreference: readonly XRDepthUsage[]; readonly dataFormatPreference: readonly XRDepthDataFormat[]; readonly depthTypeRequest: readonly XRDepthType[]; readonly matchDepthView: boolean; }; declare const xrDepthMeshPhysicsOptions: { readonly debugging: boolean; readonly enabled: boolean; readonly depthMesh: { readonly enabled: boolean; readonly updateVertexNormals: boolean; readonly showDebugTexture: boolean; readonly useDepthTexture: boolean; readonly renderShadow: boolean; readonly shadowOpacity: number; readonly patchHoles: boolean; readonly patchHolesUpper: boolean; readonly opacity: number; readonly useDualCollider: boolean; readonly useDownsampledGeometry: boolean; readonly updateFullResolutionGeometry: boolean; readonly colliderUpdateFps: number; readonly depthMeshUpdateFps: number; readonly depthFullResolution: number; readonly ignoreEdgePixels: number; }; readonly depthTexture: { readonly enabled: boolean; readonly constantKernel: boolean; readonly applyGaussianBlur: boolean; readonly applyKawaseBlur: boolean; }; readonly occlusion: { readonly enabled: boolean; }; readonly usagePreference: readonly XRDepthUsage[]; readonly dataFormatPreference: readonly XRDepthDataFormat[]; readonly depthTypeRequest: readonly XRDepthType[]; readonly matchDepthView: boolean; }; declare class HandsOptions { /** Whether hand tracking is enabled. */ enabled: boolean; /** Whether to show any hand visualization. */ visualization: boolean; /** Whether to show the tracked hand joints. */ visualizeJoints: boolean; /** Whether to show the virtual hand meshes. */ visualizeMeshes: boolean; debugging: boolean; constructor(options?: DeepReadonly>); /** * Enables hands tracking. * @returns The instance for chaining. */ enableHands(): this; enableHandsVisualization(): this; } declare const HAND_JOINT_NAMES: readonly ["wrist", "thumb-metacarpal", "thumb-phalanx-proximal", "thumb-phalanx-distal", "thumb-tip", "index-finger-metacarpal", "index-finger-phalanx-proximal", "index-finger-phalanx-intermediate", "index-finger-phalanx-distal", "index-finger-tip", "middle-finger-metacarpal", "middle-finger-phalanx-proximal", "middle-finger-phalanx-intermediate", "middle-finger-phalanx-distal", "middle-finger-tip", "ring-finger-metacarpal", "ring-finger-phalanx-proximal", "ring-finger-phalanx-intermediate", "ring-finger-phalanx-distal", "ring-finger-tip", "pinky-finger-metacarpal", "pinky-finger-phalanx-proximal", "pinky-finger-phalanx-intermediate", "pinky-finger-phalanx-distal", "pinky-finger-tip"]; type JointName = (typeof HAND_JOINT_NAMES)[number]; /** * Utility class for managing WebXR hand tracking data based on * reported Handedness. */ /** * Enum for handedness, using WebXR standard strings. */ declare enum Handedness { NONE = -1,// Represents unknown or unspecified handedness LEFT = 0, RIGHT = 1 } /** * Represents and provides access to WebXR hand tracking data. * Uses the 'handedness' property of input hands for identification. */ declare class Hands { hands: THREE.XRHandSpace[]; dominant: Handedness; /** * @param hands - An array containing XRHandSpace objects from Three.js. */ constructor(hands: THREE.XRHandSpace[]); /** * Retrieves a specific joint object for a given hand. * @param jointName - The name of the joint to retrieve (e.g., * 'index-finger-tip'). * @param targetHandednessEnum - The hand enum value * (Handedness.LEFT or Handedness.RIGHT) * to retrieve the joint from. If Handedness.NONE, uses the dominant * hand. * @returns The requested joint object, or null if not * found or invalid input. */ getJoint(jointName: JointName, targetHandednessEnum: Handedness): THREE.XRJointSpace | undefined; /** * Gets the index finger tip joint. * @param handedness - Optional handedness * ('left'/'right'), * defaults to NONE (uses dominant hand). * @returns The joint object or null. */ getIndexTip(handedness?: Handedness): THREE.XRJointSpace | undefined; /** * Gets the thumb tip joint. * @param handedness - Optional handedness * ('left'/'right'), * defaults to NONE (uses dominant hand). * @returns The joint object or null. */ getThumbTip(handedness?: Handedness): THREE.XRJointSpace | undefined; /** * Gets the middle finger tip joint. * @param handedness - Optional handedness * ('left'/'right'), * defaults to NONE (uses dominant hand). * @returns The joint object or null. */ getMiddleTip(handedness?: Handedness): THREE.XRJointSpace | undefined; /** * Gets the ring finger tip joint. * @param handedness - Optional handedness * ('left'/'right'), * defaults to NONE (uses dominant hand). * @returns The joint object or null. */ getRingTip(handedness?: Handedness): THREE.XRJointSpace | undefined; /** * Gets the pinky finger tip joint. * @param handedness - Optional handedness * ('left'/'right'), * defaults to NONE (uses dominant hand). * @returns The joint object or null. */ getPinkyTip(handedness?: Handedness): THREE.XRJointSpace | undefined; /** * Gets the wrist joint. * @param handedness - Optional handedness enum value * (LEFT/RIGHT/NONE), * defaults to NONE (uses dominant hand). * @returns The joint object or null. */ getWrist(handedness?: Handedness): THREE.XRJointSpace | undefined; /** * Generates a string representation of the hand joint data for both hands. * Always lists LEFT hand data first, then RIGHT hand data, if available. * @returns A string containing position data for all available * joints. */ toString(): string; /** * Converts the pose data (position and quaternion) of all joints for both * hands into a single flat array. Each joint is represented by 7 numbers * (3 for position, 4 for quaternion). Missing joints or hands are represented * by zeros. Ensures a consistent output order: all left hand joints first, * then all right hand joints. * @returns A flat array containing position (x, y, z) and * quaternion (x, y, z, w) data for all joints, ordered [left..., * right...]. Size is always 2 * HAND_JOINT_NAMES.length * 7. */ toPositionQuaternionArray(): number[]; /** * Checks for the availability of hand data. * If an integer (0 for LEFT, 1 for RIGHT) is provided, it checks for that * specific hand. If no integer is provided, it checks that data for *both* * hands is available. * @param handIndex - Optional. The index of the hand to validate * (0 or 1). * @returns `true` if the specified hand(s) have data, `false` * otherwise. */ isValid(handIndex?: number): boolean; } /** * A 3D visual marker used to indicate a user's aim or interaction * point in an XR scene. It orients itself to surfaces it intersects with and * provides visual feedback for states like "pressed". */ declare class Reticle extends THREE.Mesh { /** Text description of the PanelMesh */ name: string; editorIcon: string; /** The world-space direction vector of the ray that hit the target. */ direction: THREE.Vector3; /** Ensures the reticle is drawn on top of other transparent objects. */ renderOrder: number; /** The smoothing factor for rotational slerp interpolation. */ rotationSmoothing: number; /** The z-offset to prevent visual artifacts (z-fighting). */ offset: number; /** The most recent intersection data that positioned this reticle. */ intersection?: THREE.Intersection; /** Object on which the reticle is hovering. */ targetObject?: THREE.Object3D; /** Ring shown when the reticle is over an interactable object. */ private readonly hoverRing; private readonly originalNormal; private readonly newRotation; private readonly objectRotation; private readonly normalVector; /** * Creates an instance of Reticle. * @param rotationSmoothing - A factor between 0.0 (no smoothing) and * 1.0 (no movement) to smoothly animate orientation changes. * @param offset - A small z-axis offset to prevent z-fighting. * @param size - The radius of the reticle's circle geometry. * @param depthTest - Determines if the reticle should be occluded by other * objects. Defaults to `false` to ensure it is always visible. */ constructor(rotationSmoothing?: number, offset?: number, size?: number, depthTest?: boolean); /** * Orients the reticle to be flush with a surface, based on the surface * normal. It smoothly interpolates the rotation for a polished visual effect. * @param normal - The world-space normal of the surface. */ setRotationFromNormalVector(normal: THREE.Vector3): void; /** * Updates the reticle's complete pose (position and rotation) from a * raycaster intersection object. * @param intersection - The intersection data from a raycast. */ setPoseFromIntersection(intersection: THREE.Intersection): void; /** * Sets the color of the reticle via its shader uniform. * @param color - The color to apply. */ setColor(color: THREE.Color | number | string): void; /** * Gets the current color of the reticle. * @returns The current color from the shader uniform. */ getColor(): THREE.Color; /** * Sets the visual state of the reticle to "pressed" or "unpressed". * This provides visual feedback to the user during interaction. * @param pressed - True to show the pressed state, false otherwise. */ setPressed(pressed: boolean): void; /** * Sets the pressed state as a continuous value for smooth animations. * @param pressedAmount - A value from 0.0 (unpressed) to 1.0 (fully * pressed). */ setPressedAmount(pressedAmount: number): void; /** * Shows a ring around the reticle while it hovers over an interactable * object. */ setHovering(hovering: boolean): void; /** Releases the GPU resources owned by this Reticle. */ dispose(): void; /** * Overrides the default raycast method to make the reticle ignored by * raycasters. */ raycast(): void; } interface ControllerEventMap extends THREE.Object3DEventMap { connected: { target: Controller; data?: XRInputSource; }; disconnected: { target: Controller; data?: XRInputSource; }; select: { target: Controller; data?: XRInputSource; }; selectstart: { target: Controller; data?: XRInputSource; }; selectend: { target: Controller; data?: XRInputSource; }; squeeze: { target: Controller; data?: XRInputSource; }; squeezestart: { target: Controller; data?: XRInputSource; }; squeezeend: { target: Controller; data?: XRInputSource; }; } interface Controller extends THREE.Object3D { reticle?: Reticle; gamepad?: Gamepad; inputSource?: Partial; updatePose?(): void; } interface ControllerEvent { type: keyof ControllerEventMap; target: Controller; data?: Partial; } type GamepadAction = 'select' | 'cycleHandPoseLeft' | 'cycleHandPoseRight' | 'cycleSimulatorMode' | 'toggleUI' | 'toggleHand' | 'moveDown' | 'moveUp' | 'openSettings'; /** * Manages gamepad button-to-action mappings with localStorage persistence. * One button per action — assigning a button removes it from any previous action. */ declare class GamepadBindings { private bindings; constructor(); getBinding(action: GamepadAction): number; getAllBindings(): Record; setBinding(action: GamepadAction, buttonIndex: number): void; resetDefaults(): void; private load; private save; } /** Defines the event map for the GamepadController's custom events. */ interface GamepadControllerEventMap extends THREE.Object3DEventMap { connected: { target: GamepadController; }; disconnected: { target: GamepadController; }; selectstart: { target: GamepadController; }; selectend: { target: GamepadController; }; } /** * Simulates an XR controller using a connected gamepad (Xbox/PS). * The controller ray always points forward from the camera center, * similar to GazeController but with button-driven selection. */ declare class GamepadController extends Script implements Controller { static dependencies: { camera: typeof THREE.Camera; }; type: string; name: string; userData: { id: number; connected: boolean; selected: boolean; }; camera?: THREE.Camera; bindings: GamepadBindings; /** The browser Gamepad object, refreshed each frame. */ activeGamepad?: Gamepad | null; gamepad?: Gamepad; /** True if the toast has been shown this session. */ hasShownToast: boolean; /** Callback set by SimulatorInterface for opening settings. */ onOpenSettings?: () => void; /** When true, normal gamepad UI/select actions are suppressed (modal menu). */ menuActive: boolean; private _prevButtons; private _risingEdges; private _captureCallback; constructor(); init({ camera }: { camera: THREE.Camera; }): void; /** * Enters capture mode — the next button press will invoke the callback * instead of triggering normal actions, then exit capture mode. */ captureNextButtonPress(callback: (buttonIndex: number) => void): void; cancelCapture(): void; get captureActive(): boolean; updatePose(): void; update(): void; callSelectStart(): void; callSelectEnd(): void; connect(): void; disconnect(): void; /** * Returns the axes of the active gamepad with deadzone applied. * [leftX, leftY, rightX, rightY] */ getAxes(): [number, number, number, number]; static applyDeadzone(value: number): number; /** * Returns the analog value (0..1) of the given button index, or 0 if * unbound or no gamepad. Useful for triggers (which expose .value). */ getButtonValue(index: number): number; /** * Returns the analog values of the left and right triggers (LT, RT) on a * standard-mapped gamepad, in [0, 1]. Returns [0, 0] when no gamepad. */ getTriggers(): [number, number]; /** * Returns true if the given button index had a rising edge this frame. * Safe to call from any update order — uses pre-computed edges. */ isButtonJustPressed(buttonIndex: number): boolean; private _updatePrevButtons; private _pollGamepad; private _onDisconnect; } interface GazeControllerEventMap extends THREE.Object3DEventMap { connected: { target: GazeController; }; disconnected: { target: GazeController; }; } /** * Supplies a camera-aligned gaze ray for XR interactions. Interaction owns * target resolution and dwell selection. * WebXR Eye Tracking is not yet available. This API simulates a reticle * at the center of the field of view for simulating gaze-based interaction. */ declare class GazeController extends Script implements Controller { static dependencies: { camera: typeof THREE.Camera; }; /** * User data for the controller, including its connection status, unique ID, * and selection state. */ userData: { connected: boolean; id: number; selected: boolean; }; /** * The visual indicator for where the user is looking. */ reticle: Reticle | undefined; camera: THREE.Camera; init({ camera }: { camera: THREE.Camera; }): void; /** * Syncs the controller with the camera before Input samples its ray. */ updatePose(): void; /** * Connects the gaze controller to the input system. */ connect(): void; /** * Disconnects the gaze controller from the input system. */ disconnect(): void; } type HeadGestureEventDetail = { name: string; confidence: number; data?: Record; }; type HeadGestureEvent = THREE.Event & { type: 'gesture'; target: HeadGestureRecognition; detail: HeadGestureEventDetail; }; interface HeadGestureEventMap extends THREE.Object3DEventMap { gesture: HeadGestureEvent; } type HeadGestureConfiguration = { enabled: boolean; /** Detector-specific sensitivity. Built-in heuristics interpret this as radians. */ threshold?: number; }; type HeadPoseSample = { timestamp: number; position: THREE.Vector3; orientation: THREE.Quaternion; }; interface HeadGestureContext { readonly samples: readonly HeadPoseSample[]; } type HeadGestureDetectionResult = { confidence: number; data?: Record; }; type HeadGestureScoreMap = Record; type HeuristicHeadGestureDetector = (context: HeadGestureContext, config: HeadGestureConfiguration) => HeadGestureDetectionResult | undefined; interface HeadGestureRecognizer { init?(): Promise; recognize(context: HeadGestureContext): HeadGestureScoreMap | Promise; getGestureConfigurations?(): Record; setGestureConfig?(name: string, config: HeadGestureConfiguration): void; dispose?(): void; } declare class HeadGestureRecognitionOptions { enabled: boolean; minimumConfidence: number; releaseConfidence: number; updateIntervalMs: number; historyDurationMs: number; warmupDurationMs: number; maximumSampleGapMs: number; maximumSampleAngleRadians: number; gestureRecognizer: HeadGestureRecognizer; gestures: Record; constructor(options?: DeepReadonly>); enable(): this; setGestureEnabled(name: string, enabled: boolean): this; setGestureRecognizer(gestureRecognizer: HeadGestureRecognizer): this; setGestureConfig(name: string, config: Partial): this; private applyGestureRecognizerConfigurations; } declare class HeadGestureRecognition extends Script { static dependencies: { camera: typeof THREE.Camera; options: typeof HeadGestureRecognitionOptions; }; private camera; private options; private samples; private latchedGestures; private lastEvaluation; private latestTimestamp; private pendingRecognition; private generation; init({ camera, options, }: { camera: THREE.Camera; options: HeadGestureRecognitionOptions; }): Promise; update(time?: number): void; private captureSample; private isDiscontinuity; private pruneSamples; private evaluate; private emitFromScores; private emitGesture; private resetRecognitionState; dispose(): void; } /** Defines the event map for the MouseController's custom events. */ interface MouseControllerEventMap extends THREE.Object3DEventMap { connected: { target: MouseController; }; disconnected: { target: MouseController; }; selectstart: { target: MouseController; }; selectend: { target: MouseController; }; } /** * Simulates an XR controller using the mouse for desktop * environments. This class translates 2D mouse movements on the screen into a * 3D ray in the scene, allowing for point-and-click interactions in a * non-immersive context. It functions as a virtual controller that is always * aligned with the user's pointer. */ declare class MouseController extends Script implements Controller { static dependencies: { camera: typeof THREE.Camera; }; type: string; name: string; editorIcon: string; /** * User data for the controller, including its connection status, unique ID, * and selection state (mouse button pressed). */ userData: { id: number; connected: boolean; selected: boolean; }; /** A THREE.Raycaster used to determine the 3D direction of the mouse. */ raycaster: THREE.Raycaster; /** A normalized vector representing the default forward direction. */ forwardVector: THREE.Vector3; /** A reference to the main scene camera. */ camera?: THREE.Camera; private lastNormalizedMouse; constructor(); /** * Initialize the MouseController */ init({ camera }: { camera: THREE.Camera; }): void; /** Updates the mouse position/rotation using camera state. */ updatePose(): void; /** * The main update loop, called every frame. * If connected, it syncs the controller's origin point with the camera's * position. */ update(): void; /** * Updates the controller's transform based on the mouse's position on the * screen. This method sets both the position and rotation, ensuring the * object has a valid world matrix for raycasting. * @param event - The mouse event containing clientX and clientY coordinates. */ updateMousePositionFromEvent(event: MouseEvent): void; /** * Dispatches a 'selectstart' event, simulating the start of a controller * press (e.g., mouse down). */ callSelectStart(): void; /** * Dispatches a 'selectend' event, simulating the end of a controller press * (e.g., mouse up). */ callSelectEnd(): void; /** * "Connects" the virtual controller, notifying the input system that it is * active. */ connect(): void; /** * "Disconnects" the virtual controller. */ disconnect(): void; } /** * A node to hold all XR Blocks Systems. */ declare class XRSystems extends THREE.Group { type: string; name: string; } declare class ActiveControllers extends THREE.Group { type: string; name: string; } declare class Reticles extends THREE.Group { type: string; name: string; } /** * Holds physical input sources and samples their current state each frame. */ declare class Input { options: Options; controllers: Controller[]; controllerGrips: THREE.Group[]; hands: THREE.XRHandSpace[]; /** Completed head gestures, when enabled before initialization. */ headGestures?: HeadGestureRecognition; pivotsEnabled: boolean; gazeController: GazeController; mouseController: MouseController; gamepadController: GamepadController; controllersEnabled: boolean; listeners: Map; private dispatchControllerEvent; private pinchFilter; private releasedControllers; private keyDownListeners; private keyUpListeners; activeControllers: ActiveControllers; leftController?: Controller; rightController?: Controller; reticles: Reticles; private ownedReticles; private readonly raySourceInputs; private readonly raySourceSlots; private readonly directTouchInputs; private readonly directTouchSlots; private readonly interactionFrame; /** * Initializes physical input sources. Only called by Core. */ init({ systemsGroup, options, renderer, }: { systemsGroup: XRSystems; options: Options; renderer: THREE.WebGLRenderer; }): void; /** * Retrieves the controller object by its ID. * @param id - The ID of the controller. * @returns The controller with the specified ID. */ get(id: number): THREE.Object3D; /** * Adds an object to both controllers by creating a new group and cloning it. * @param obj - The object to add to each controller. */ addObject(obj: THREE.Object3D): void; /** * Creates a pivot point for each hand, primarily used as a reference * point. */ enablePivots(): void; /** * Adds reticles to the controllers and scene, with initial visibility set to * false. */ addReticles(): void; /** * Default action to handle the start of a selection, setting the selecting * state to true. */ defaultOnSelectStart(event: ControllerEvent): void; /** * Default action to handle the end of a selection, setting the selecting * state to false. */ defaultOnSelectEnd(event: ControllerEvent): void; defaultOnSqueezeStart(event: ControllerEvent): void; defaultOnSqueezeEnd(event: ControllerEvent): void; defaultOnConnected(event: ControllerEvent): void; defaultOnDisconnected(event: ControllerEvent): void; /** * Binds a listener to both controllers. * @param listenerName - Event name * @param listener - Function to call */ bindListener(listenerName: keyof ControllerEventMap, listener: (event: ControllerEvent) => void): void; unbindListener(listenerName: keyof ControllerEventMap, listener: (event: ControllerEvent) => void): void; dispatchEvent(event: ControllerEvent): void; /** * Binds an event listener to handle 'selectstart' events for both * controllers. * @param event - The event listener function. */ bindSelectStart(event: (event: ControllerEvent) => void): void; /** * Binds an event listener to handle 'selectend' events for both controllers. * @param event - The event listener function. */ bindSelectEnd(event: (event: ControllerEvent) => void): void; /** * Binds an event listener to handle 'select' events for both controllers. * @param event - The event listener function. */ bindSelect(event: (event: ControllerEvent) => void): void; /** * Binds an event listener to handle 'squeezestart' events for both * controllers. * @param event - The event listener function. */ bindSqueezeStart(event: (event: ControllerEvent) => void): void; /** * Binds an event listener to handle 'squeezeend' events for both controllers. * @param event - The event listener function. */ bindSqueezeEnd(event: (event: ControllerEvent) => void): void; bindSqueeze(event: (event: ControllerEvent) => void): void; bindKeyDown(event: (event: KeyEvent) => void): void; bindKeyUp(event: (event: KeyEvent) => void): void; unbindKeyDown(event: (event: KeyEvent) => void): void; unbindKeyUp(event: (event: KeyEvent) => void): void; /** Samples current controller, button, and direct-touch state. */ sampleSources(): void; /** Returns the complete physical source state sampled this frame. */ getFrame(): InteractionFrameInput; private getRaySourceType; private updateDirectTouchInputs; enableGazeController(): void; disableGazeController(): void; private registerController; enableController(controller: Controller): void; disableController(controller: Controller): void; disableControllers(): void; enableControllers(): void; dispose(): void; } /** Owns all logical target, hover, capture, completion, and cancellation state. */ declare class Interaction { private readonly callbacks; private readonly manipulation; private readonly reticle; private readonly reticleOptions; private readonly scene?; private readonly registry; private readonly resolver; private readonly directTouch; private longSelectDuration; private readonly gazeDwell; private readonly sourceStates; private readonly frameSnapshots; private readonly rawIntersections; private readonly resolvedRays; private readonly hoverPaths; private readonly captures; private readonly exclusiveControls; private readonly touches; private readonly suppressedUntilRelease; private readonly scaleIntents; private raycastMode; private frameSources; private nextFrameSources; constructor(dependencies: InteractionDependencies); setLongSelectDuration(seconds: number): void; setRaycastMode(mode: RaycastMode): void; /** Replaces all sampled physical interaction state for one engine frame. */ update(frame: InteractionFrameInput, deltaSeconds?: number): void; clear(): void; registerHitSurface(physical: THREE.Object3D, logical: THREE.Object3D): () => void; /** Refreshes bounded direct-touch candidates found by the lifecycle pass. */ syncTouchCandidates(candidates: Iterable): void; /** Cancels captures that belong to an object before its Script is disposed. */ cancelObject(object: THREE.Object3D, reason?: SelectionEndReason): void; removeSource(controller: Controller, reason?: SelectionEndReason): void; getSourceSnapshot(controller: Controller): InteractionSourceState | undefined; getResolvedRay(controller: Controller): ResolvedRay | undefined; isPointingAt(object: THREE.Object3D): boolean; isSelectingAt(object: THREE.Object3D): boolean; isHovered(object: THREE.Object3D): boolean; getIntersectionAt(object: THREE.Object3D, controller?: Controller): THREE.Intersection | null; /** Writes up to two internal cursor points in controller order. */ writeCursorPointsAt(object: THREE.Object3D, first: THREE.Vector3, second: THREE.Vector3): 0 | 1 | 2; isManipulating(object: THREE.Object3D): boolean; queueScaleIntent(controller: Controller, factor: number): boolean; private applyScaleIntent; private updateRay; private collectIntersections; private beginSelection; private startTargetCapture; private endSelection; private cancelCapture; private processTouchContact; private updateTouch; private finishTouch; private dispatchTouchStart; private dispatchTouch; private createTouchEvent; private updateGrab; private startGrabManipulation; private finishGrab; private createGrabEvent; private updateSemantic; private updateLongSelect; private setResolvedRay; private clearResolvedRay; private updateHoverPath; private updateRaySnapshot; private updateTouchSnapshot; private getSourceState; private createSelection; private createSelectEvent; private hasDeliberateInput; private installCapture; private detachCapture; private runCaptureTransition; private cancelFailedCapture; private cancelFailedManipulations; private runManipulationTransition; private invokeSemantic; } /** * User is an embodied instance to manage hands, controllers, speech, and * avatars. It extends Script to update human-world interaction. * * In the long run, User is to manages avatars, hands, and everything of Human * I/O. In third-person view simulation, it should come with an low-poly avatar. * To support multi-user social XR planned for future iterations. */ declare class User extends Script { private static readonly dependencies; /** * Whether to represent a local user, or another user in a multi-user session. */ local: boolean; /** * The number of hands associated with the XR user. */ numHands: number; /** * The height of the user in meters. */ height: number; /** * The default distance of a UI panel from the user in meters. */ panelDistance: number; /** * The handedness (primary hand) of the user (0 for left, 1 for right, 2 for * both). */ handedness: number; /** * The radius of the safe space around the user in meters. */ safeSpaceRadius: number; /** * The distance of a newly spawned object from the user in meters. */ objectDistance: number; /** * The angle of a newly spawned object from the user in radians. */ objectAngle: number; /** * An array of pivot objects. Pivot are sphere at the **starting** tip of * user's hand / controller / mouse rays for debugging / drawing applications. */ pivots: THREE.Object3D[]; /** * Public data for user interactions, typically holding references to XRHand. */ hands?: Hands; input: Input; private interaction; controllers: Controller[]; /** * Initializes the User. */ init({ input, interaction }: { input: Input; interaction: Interaction; }): void; /** * Sets the user's height on the first frame. * @param camera - */ setHeight(camera: THREE.Camera): void; /** * Adds pivots at the starting tip of user's hand / controller / mouse rays. */ enablePivots(): void; /** * Gets the pivot object for a given controller id. * @param id - The controller id. * @returns The pivot object. */ getPivot(id: number): THREE.Object3D | undefined; /** * Gets the world position of the pivot for a given controller id. * @param id - The controller id. * @returns The world position of the pivot. */ getPivotPosition(id: number): THREE.Vector3 | undefined; getRay(controllerId: number, target?: THREE.Ray): THREE.Ray; getRayIntersection(controllerId: number): THREE.Intersection> | null; /** * Checks if any controller is pointing at the given object or its children. * @param obj - The object to check against. * @returns True if a controller is pointing at the object. */ isPointingAt(obj: THREE.Object3D): boolean; /** * Checks if any controller is selecting the given object or its children. * @param obj - The object to check against. * @returns True if a controller is selecting the object. */ isSelectingAt(obj: THREE.Object3D): boolean; isManipulating(obj: THREE.Object3D): boolean; /** * Gets the intersection point on a specific object. * @param obj - The object to check for intersection. * @param id - The controller ID, or -1 for any controller. * @returns The intersection details, or null if no intersection. */ getIntersectionAt(obj: THREE.Object3D, id?: number): THREE.Intersection> | null; /** * Gets the world position of a controller. * @param id - The controller id. * @param target - The target vector to * store the result. * @returns The world position of the controller. */ getControllerPosition(id: number, target?: THREE.Vector3): THREE.Vector3; /** * Calculates the distance between a controller and an object. * @param id - The controller id. * @param object - The object to measure the distance to. * @returns The distance between the controller and the object. */ getControllerObjectDistance(id: number, object: THREE.Object3D): number; /** * Checks if either controller is selecting. * @param id - The controller id. If -1, check both controllers. * @returns True if selecting, false otherwise. */ isSelecting(id?: number): any; /** * Checks if either controller is squeezing. * @param id - The controller id. If -1, check both controllers. * @returns True if squeezing, false otherwise. */ isSqueezing(id?: number): any; } type HandLabel = 'left' | 'right'; declare const HAND_INDEX_TO_LABEL: Partial>; type JointPositions = Map; interface HandContext { handedness: Handedness; handLabel: HandLabel; joints: JointPositions; getJoint(jointName: JointName): THREE.Vector3 | undefined; } type GestureDetectionResult = { confidence: number; data?: Record; }; type GestureScoreMap = Record; type HeuristicGestureDetector = (context: HandContext, config: GestureConfiguration) => GestureDetectionResult | undefined; interface GestureRecognizer { init?(): Promise; recognize(context: HandContext): GestureScoreMap | Promise; getGestureConfigurations?(): Record; dispose?(): void; } interface PoseEstimator { init?(dependencies?: { user?: User; }): Promise; getHandContext(handedness: Handedness): HandContext | null; getHandContexts(): Partial>; dispose?(): void; } type GestureConfiguration = { enabled: boolean; threshold?: number; }; declare class GestureRecognitionOptions { enabled: boolean; minimumConfidence: number; updateIntervalMs: number; poseEstimator: PoseEstimator; gestureRecognizer: GestureRecognizer; gestures: Record; constructor(options?: DeepReadonly>); enable(): this; setGestureEnabled(name: string, enabled: boolean): this; setPoseEstimator(poseEstimator: PoseEstimator): this; setGestureRecognizer(gestureRecognizer: GestureRecognizer): this; setGestureConfig(name: string, config: Partial): this; private applyGestureRecognizerConfigurations; } type StrokeProvider = 'onedollar'; declare class StrokeRecognitionOptions { /** Master switch for the stroke recognition block. */ enabled: boolean; /** * Configuration for the stroke recognition provider. */ providerConfig: { /** * Backing provider that recognizes strokes. * - 'onedollar': $1 Unistroke recognizer. */ provider: StrokeProvider; /** * Options specific to the 'onedollar' provider. */ onedollar: { supportedShapes: string[]; }; }; /** * Delay in seconds after gesture start before recording points. */ startDelay: number; /** * Delay in seconds to ignore points before gesture end. */ endDelay: number; /** * The hand joint to track for stroke recognition. */ joint: JointName; /** * Maximum number of points to capture in a single stroke. */ maxPoints: number; constructor(options?: DeepReadonly>); enable(): this; } /** * Default options for controlling Lighting module features. */ declare class LightingOptions { /** Enables debugging renders and logs. */ debugging: boolean; /** Enables XR lighting. */ enabled: boolean; /** Add ambient spherical harmonics to lighting. */ useAmbientSH: boolean; /** Add main diredtional light to lighting. */ useDirectionalLight: boolean; /** Cast shadows using diretional light. */ castDirectionalLightShadow: boolean; /** * Adjust hardness of shadows according to relative brightness of main light. */ useDynamicSoftShadow: boolean; constructor(options?: DeepReadonly>); } type RAPIERCompat = typeof RAPIER_NS & { init?: () => Promise; }; declare class PhysicsOptions { /** * The target frames per second for the physics simulation loop. */ fps: number; /** * The global gravity vector applied to the physics world. */ gravity: { x: number; y: number; z: number; }; /** * If true, the `Physics` manager will automatically call `world.step()` * on its fixed interval. Set to false if you want to control the * simulation step manually. */ worldStep: boolean; /** * If true, an event queue will be created and passed to `world.step()`, * enabling the handling of collision and contact events. */ useEventQueue: boolean; /** * Instance of RAPIER. */ RAPIER?: RAPIERCompat; } /** * A frozen object containing standardized string values for `event.code`. * Used for desktop simulation. */ declare enum Keycodes { W_CODE = "KeyW", A_CODE = "KeyA", S_CODE = "KeyS", D_CODE = "KeyD", UP = "ArrowUp", DOWN = "ArrowDown", LEFT = "ArrowLeft", RIGHT = "ArrowRight", Q_CODE = "KeyQ",// Often used for 'down' or 'strafe left' E_CODE = "KeyE",// Often used for 'up' or 'strafe right' PAGE_UP = "PageUp", PAGE_DOWN = "PageDown", SPACE_CODE = "Space", ENTER_CODE = "Enter", T_CODE = "KeyT",// General purpose 'toggle' or 'tool' key LEFT_SHIFT_CODE = "ShiftLeft", RIGHT_SHIFT_CODE = "ShiftRight", LEFT_CTRL_CODE = "ControlLeft", RIGHT_CTRL_CODE = "ControlRight", LEFT_ALT_CODE = "AltLeft", RIGHT_ALT_CODE = "AltRight", CAPS_LOCK_CODE = "CapsLock", ESCAPE_CODE = "Escape", TAB_CODE = "Tab", B_CODE = "KeyB", C_CODE = "KeyC", F_CODE = "KeyF", G_CODE = "KeyG", H_CODE = "KeyH", I_CODE = "KeyI", J_CODE = "KeyJ", K_CODE = "KeyK", L_CODE = "KeyL", M_CODE = "KeyM", N_CODE = "KeyN", O_CODE = "KeyO", P_CODE = "KeyP", R_CODE = "KeyR", U_CODE = "KeyU", V_CODE = "KeyV", X_CODE = "KeyX", Y_CODE = "KeyY", Z_CODE = "KeyZ", DIGIT_0 = "Digit0", DIGIT_1 = "Digit1", DIGIT_2 = "Digit2", DIGIT_3 = "Digit3", DIGIT_4 = "Digit4", DIGIT_5 = "Digit5", DIGIT_6 = "Digit6", DIGIT_7 = "Digit7", DIGIT_8 = "Digit8", DIGIT_9 = "Digit9", BACKQUOTE = "Backquote" } declare enum SimulatorMode { USER = "User", POSE = "Navigation", CONTROLLER = "Hands", POINTER_LOCK = "PointerLock", EDITOR = "Editor" } interface SimulatorCustomInstruction { header: string; videoSrc?: string; description: string; } interface SimulatorEnvironment { /** Optional display name; otherwise the manifest name is used. */ name?: string; manifestPath: string; } interface SimulatorHandPhysicsOptions { enabled: boolean; radius: number; mass: number; contactOffset: number; friction: number; restitution: number; } declare class SimulatorOptions { initialCameraPosition: { x: number; y: number; z: number; }; environments: { /** Optional display name; otherwise the manifest name is used. */ name?: string; manifestPath: string; }[]; activeEnvironmentIndex: number; defaultMode: SimulatorMode; defaultHand: Handedness; modeToggle: { enabled: boolean; toggleKey: Keycodes | null; toggleOrder: { User: SimulatorMode; Navigation: SimulatorMode; Hands: SimulatorMode; PointerLock: SimulatorMode; Editor: SimulatorMode; }; }; simulatorSettingsPanel: { enabled: boolean; element: string; }; instructions: { enabled: boolean; showAutomatically: boolean; element: string; customInstructions: SimulatorCustomInstruction[]; }; handPosePanel: { enabled: boolean; element: string; }; geminiLivePanel: { enabled: boolean; element: string; }; stereo: { enabled: boolean; }; navMesh: { enabled: boolean; showDebugVisualizations: boolean; eyeHeight: number; }; /** Controls the isolated physics world used by the desktop simulator. */ physics: { enabled: boolean; }; deviceCamera: { enabled: boolean; }; renderToRenderTexture: boolean; blendingMode: 'normal' | 'screen'; /** Shoulder/chest origin of the left hand in local camera space. */ leftHandOrigin: { x: number; y: number; z: number; }; /** Shoulder/chest origin of the right hand in local camera space. */ rightHandOrigin: { x: number; y: number; z: number; }; /** Optional physical constraints for simulated hands. Requires Rapier. */ handPhysics: SimulatorHandPhysicsOptions; /** Limits how far each hand controller can travel from the user's shoulder origin. */ reachDistance: { enabled: boolean; /** The maximum distance in meters a controller can move from its origin point. */ radius: number; }; /** Limits the angular cone in front of the user within which controllers can move. */ reachAngle: { enabled: boolean; /** The maximum full cone angle in radians around the camera's forward direction (default is Math.PI, a front hemisphere). */ angle: number; }; constructor(options?: DeepReadonly>); } declare class SpeechSynthesizerOptions { enabled: boolean; /** If true, a new call to speak() will interrupt any ongoing speech. */ allowInterruptions: boolean; } declare class SpeechRecognizerOptions { enabled: boolean; /** Recognition language (e.g., 'en-US'). */ lang: string; /** If true, recognition continues after a pause. */ continuous: boolean; /** Keywords to detect as commands. */ commands: string[]; /** If true, provides interim results. */ interimResults: boolean; /** Minimum confidence (0-1) for a command. */ commandConfidenceThreshold: number; /** If true, play activation sounds in simulator. */ playSimulatorActivationSounds: boolean; } declare class SoundOptions { speechSynthesizer: SpeechSynthesizerOptions; speechRecognizer: SpeechRecognizerOptions; } declare class MeshDetectionOptions { showDebugVisualizations: boolean; enabled: boolean; constructor(options?: DeepPartial); /** * Enables the mesh detector. */ enable(): this; } /** * Configuration options for the ObjectDetector. */ declare class ObjectsOptions { debugging: boolean; enabled: boolean; showDebugVisualizations: boolean; /** Use simulator ground truth instead of a camera detector on desktop. */ simulatorOverride: boolean; /** * Minimum delay in milliseconds between continuous object detection runs. * A value of 0 runs again as soon as the previous detection finishes. */ pollingIntervalMs: number; /** * Margin to add when cropping the object image, as a percentage of image * size. */ objectImageMargin: number; /** * Configuration for the detection backends. */ backendConfig: { /** The active backend to use for detection. */ activeBackend: "gemini" | "mediapipe"; gemini: { systemInstruction: string; /** * Extra Gemini generation config merged into the per-call config (over * the SDK defaults). Use to pin sampling parameters such as * `temperature: 0` for deterministic detections. */ generationConfig: Record; responseSchema: { type: string; items: { type: string; required: string[]; properties: { objectName: { type: string; }; ymin: { type: string; }; xmin: { type: string; }; ymax: { type: string; }; xmax: { type: string; }; }; }; }; }; /** Configuration for MediaPipe backend. */ mediapipe: { wasmFilesUrl: string; modelAssetPath: string; scoreThreshold: number; }; }; constructor(options?: DeepPartial); /** * Enables the object detector. */ enable(): this; } declare class PlanesOptions { debugging: boolean; enabled: boolean; showDebugVisualizations: boolean; constructor(options?: DeepPartial); enable(): this; } declare class SoundsOptions { enabled: boolean; showDebugInfo: boolean; backendConfig: { activeBackend: string; mediapipe: { wasmFilesUrl: string; modelAssetPath: string; chunkSamples: number; }; }; constructor(options?: DeepPartial); /** * Enables sound detection. */ enable(): this; } /** * Configuration options for the Human Pose Detection system. */ declare class HumansOptions { enabled: boolean; /** * Minimum delay in milliseconds between continuous pose detection runs. * A value of 0 runs again as soon as the previous detection finishes. */ pollingIntervalMs: number; /** * Project each landmark onto the depth mesh to find its world position. * * This is what you want when the people being detected are physically in * front of you, since the ray lands on their actual body. Turn it off when * the camera is showing someone who is not part of the depth scene, such as a * webcam feed on the desktop simulator: every ray would then hit the * surrounding geometry instead and the skeleton would be smeared across it. * With projection off, landmarks are placed along the view ray at a fixed * distance, which keeps the body correctly proportioned. */ useDepthProjection: boolean; /** * Configuration options for the active pose detection backend. */ backendConfig: { activeBackend: string; mediapipe: { wasmFilesUrl: string; modelAssetPath: string; /** * Run inference in a web worker so a detection pass does not stall the * render loop. The worker is limited to the CPU delegate because * MediaPipe only creates a GPU surface for a real DOM canvas, so set * this to false to trade a blocked main thread for GPU inference. * Falls back to the main thread automatically when workers are * unavailable. */ useWorker: boolean; /** * The maximum number of simultaneous human poses/bodies to track. */ numPoses: number; /** * The minimum confidence score [0.0, 1.0] required for a pose to be detected. */ minPoseDetectionConfidence: number; /** * The minimum confidence score [0.0, 1.0] required to confirm a pose is still present. */ minPosePresenceConfidence: number; /** * The minimum confidence score [0.0, 1.0] required for tracking landmarks between frames. */ minTrackingConfidence: number; }; }; constructor(options?: DeepPartial); enable(): this; } /** * Configuration options for the Face Landmark Detection system. */ declare class FacesOptions { enabled: boolean; /** * Minimum delay in milliseconds between continuous face detection runs. * A value of 0 runs again as soon as the previous detection finishes. */ pollingIntervalMs: number; /** * Configuration options for the active face detection backend. */ backendConfig: { activeBackend: string; mediapipe: { wasmFilesUrl: string; modelAssetPath: string; /** * The maximum number of simultaneous faces to track. */ numFaces: number; /** * The minimum confidence score [0.0, 1.0] required for a face to be * detected. */ minFaceDetectionConfidence: number; /** * The minimum confidence score [0.0, 1.0] required to confirm a face is * still present. */ minFacePresenceConfidence: number; /** * The minimum confidence score [0.0, 1.0] required for tracking * landmarks between frames. */ minTrackingConfidence: number; /** * Whether to compute and emit per-face blendshape weights (52 * ARKit-compatible categories). Required for facial expression * mirroring, lipsync feeds, and avatar animation. */ outputFaceBlendshapes: boolean; /** * Whether to compute and emit the 4x4 facial transformation matrix * for each face. Provides a stable rigid head pose for parenting * objects to the head (glasses, masks, hats). */ outputFacialTransformationMatrixes: boolean; }; }; constructor(options?: DeepPartial); enable(): this; } /** * Configuration options for the semantic segmentation system. Mirrors the * other `world/*` perception options (humans, faces, objects). */ declare class SegmentationOptions { enabled: boolean; /** * Minimum delay in milliseconds between continuous segmentation runs. * A value of 0 runs again as soon as the previous inference finishes. * Defaults to 66 (~15 fps), the rate the magic_window grab loop used before * segmentation moved onto its own polling loop. */ pollingIntervalMs: number; /** * Configuration options for the active segmentation backend. */ backendConfig: { activeBackend: string; mediapipe: { wasmFilesUrl: string; modelAssetPath: string; /** * Output the per-pixel category mask. Required to produce a * {@link SegmentationMask}. */ outputCategoryMask: boolean; }; }; constructor(options?: DeepPartial); enable(): this; } /** * Builds the default storage key for a page. * * Scoped to the path because anchors are stored per origin: two apps served * from one host would otherwise restore each other's anchors, which reads as * mysterious content appearing on first run rather than as a shared store. * * @param pathname - Page path; omit when there is no document. * @returns The storage key to default to. */ declare function defaultAnchorStorageKey(pathname?: string): string; /** * Configuration for the spatial anchor subsystem. * * Anchors pin content to a real place so the platform keeps it there as its * understanding of the room improves. With {@link AnchorsOptions.persistent} * enabled, anchor handles are saved so the same content can be restored in a * later session. */ declare class AnchorsOptions { /** Logs anchor lifecycle transitions. */ debugging: boolean; /** Whether the anchor subsystem is created at all. */ enabled: boolean; /** * Whether anchor handles are saved so they can be restored in a later * session. Requires platform support for persistent handles; when the * platform only offers session-scoped anchors this degrades to in-session * behaviour rather than failing. */ persistent: boolean; /** * Whether to hold poses locally when the platform has no anchor support. * * Off by default: on a real headset a silent stand-in would look like * working anchors while nothing is actually pinned. Demos and desktop * development opt in deliberately. */ simulatorFallback: boolean; /** * Storage key used when persistence is enabled. * * Defaults to a page-scoped key. Set it explicitly to share anchors between * pages, or to keep a stable key if the app might move path. */ storageKey: string; /** * Upper bound on saved handles. Persistent handles accumulate across * sessions and would otherwise grow without limit; the oldest are evicted * first once the cap is reached. */ maxStoredAnchors: number; constructor(options?: DeepPartial); /** * Enables anchors. * @returns This options object, for chaining. */ enable(): this; /** * Enables anchors and saves handles for restoration in later sessions. * @returns This options object, for chaining. */ enablePersistence(): this; } declare class WorldOptions { debugging: boolean; enabled: boolean; initiateRoomCapture: boolean; planes: PlanesOptions; objects: ObjectsOptions; meshes: MeshDetectionOptions; sounds: SoundsOptions; humans: HumansOptions; faces: FacesOptions; segmentation: SegmentationOptions; anchors: AnchorsOptions; constructor(options?: DeepPartial); /** * Enables plane detection. */ enablePlaneDetection(): this; /** * Enables object detection. */ enableObjectDetection(): this; /** * Enables mesh detection. */ enableMeshDetection(): this; /** * Enables spatial anchors. */ enableAnchors(): this; /** * Enables spatial anchors and saves their handles so anchored content can be * restored in a later session. */ enableAnchorPersistence(): this; /** * Enables sound detection. */ enableSoundDetection(): this; /** * Enables human detection. */ enableHumanDetection(): this; /** * Enables face landmark detection. */ enableFaceDetection(): this; /** * Enables semantic segmentation (person / background category masks). */ enableSegmentation(): this; } /** * Default options for XR controllers, which encompass hands by default in * Android XR, mouse input on desktop, tracked controllers, and gamepads. */ declare class InputOptions { /** Whether controller input is enabled. */ enabled: boolean; /** Whether mouse input should act as a controller on desktop. */ enabledMouse: boolean; /** Whether to enable debugging features for controllers. */ debug: boolean; /** Whether to show controller models. */ visualization: boolean; /** Whether to show the ray lines extending from the controllers. */ visualizeRays: boolean; } /** * Default options for the reticle (pointing cursor). */ declare class ReticleOptions { enabled: boolean; /** Whether reticles use the real-world depth mesh as a surface. */ projectOnDepthMesh: boolean; /** * Maximum reticle drawing distance in meters. It does not limit targeting. */ maxDistance?: number; /** * Distance in meters at which to render the reticle when no valid hit is * found. Set to 0 to hide the reticle on a miss. */ defaultRenderDistance: number; } type RaycastMode = 'continuous' | 'select'; declare class InteractionOptions { /** When to sample ray intersections for interaction. */ raycastMode: RaycastMode; /** Seconds a stable object selection must be held before long-select. */ longSelectDuration: number; } /** * Options for the XR transition effect. */ declare class XRTransitionOptions { /** Whether the transition effect is enabled. */ enabled: boolean; /** The duration of the transition in seconds. */ transitionTime: number; /** The default background color for VR transitions. */ defaultBackgroundColor: number; } declare const FORM_FACTORS: readonly ["auto", "xr", "hud", "vr", "desktop", "mobile"]; type FormFactor = (typeof FORM_FACTORS)[number]; type AutomationModeOptions = { hideSimulatorUi?: boolean; defaultHand?: Handedness; defaultMode?: SimulatorMode; enableHands?: boolean; enableCamera?: boolean; }; /** * A central configuration class for the entire XR Blocks system. It aggregates * all settings and provides chainable methods for enabling common features. */ declare class Options { /** * Whether to use antialiasing. */ antialias: boolean; /** * Whether to use a logarithmic depth buffer. Useful for depth-aware * occlusions. */ logarithmicDepthBuffer: boolean; /** * Global flag for enabling various debugging features. */ debugging: boolean; /** * Whether to request a stencil buffer. */ stencil: boolean; /** * Canvas element to use for rendering. * If not defined, a new element will be added to document body. */ canvas?: HTMLCanvasElement; /** * Any additional required features when initializing webxr. */ webxrRequiredFeatures: string[]; /** * Any additional optional features when initializing webxr. */ webxrOptionalFeatures: string[]; referenceSpaceType: XRReferenceSpaceType; controllers: InputOptions; depth: DepthOptions; lighting: LightingOptions; deviceCamera: DeviceCameraOptions; hands: HandsOptions; gestures: GestureRecognitionOptions; headGestures: HeadGestureRecognitionOptions; strokes: StrokeRecognitionOptions; reticles: ReticleOptions; interaction: InteractionOptions; sound: SoundOptions; ai: AIOptions; simulator: SimulatorOptions; world: WorldOptions; context: ContextOptions; physics: PhysicsOptions; transition: XRTransitionOptions; camera: { near: number; far: number; }; /** * Whether to use post-processing effects. */ usePostprocessing: boolean; enableSimulator: boolean; /** * Whether to catch all exceptions thrown by developer scripts in the main update loop * and physics step, and log them using console.error instead of crashing the application. * When enabled, exceptions in one script will not prevent other scripts or subsystems from updating. */ catchScriptExceptions: boolean; /** * Configuration for the XR session button. */ xrButton: { appTitle: string; appDescription: string; enabled: boolean; startText: string; endText: string; invalidText: string; startSimulatorText: string; showEnterSimulatorButton: boolean; alwaysAutostartSimulator: boolean; }; /** * Which permissions to request before entering the XR session. */ permissions: { geolocation: boolean; camera: boolean; microphone: boolean; }; xrSessionMode: XRSessionMode; private _formFactor; get formFactor(): FormFactor; /** * Form factor is a preset that configures the experience for a specific * device type. Currently it only controls whether the simulator is enabled * and should always be autostarted. */ set formFactor(formFactor: FormFactor); /** * Constructs the Options object by merging default values with provided * custom options. * @param options - A custom options object to override the defaults. */ constructor(options?: DeepReadonly>); protected parseUrlParams(): void; /** * Sets the session mode to VR and disables the simulator passthrough scene. */ enableVR(): this; /** * Enables a standard simulator-driven setup for automation and external test * harnesses. * @returns The instance for chaining. */ enableAutomationMode(config?: AutomationModeOptions): this; /** * Enables reticles for visualizing targets of hand rays in WebXR. * @returns The instance for chaining. */ enableReticles(): this; /** * Enables depth sensing in WebXR with default options. * @returns The instance for chaining. */ enableDepth(): this; /** * Enables plane detection. * @returns The instance for chaining. */ enablePlaneDetection(): this; /** * Enables object detection. * @returns The instance for chaining. */ enableObjectDetection(): this; /** * Enables human pose detection. * @returns The instance for chaining. */ enableHumanDetection(): this; /** * Enables face landmark detection. Provides 478 per-face landmarks in * world space, optional 52 ARKit-style blendshape weights, and an * optional rigid 4x4 facial transformation matrix per detected face. * @returns The instance for chaining. */ enableFaceDetection(): this; /** * Enables semantic segmentation. Produces per-pixel person / background * category masks from the device camera (MediaPipe, on-device). Unlike face * and human detection it does not require depth. * @returns The instance for chaining. */ enableSegmentation(): this; /** * Enables device camera (passthrough) with a specific facing mode. * @param facingMode - The desired camera facing mode, either 'environment' or * 'user'. * @returns The instance for chaining. */ enableCamera(facingMode?: 'environment' | 'user'): this; /** * Enables hand tracking. * @returns The instance for chaining. */ enableHands(): this; /** * Enables the gesture recognition block and ensures hands are available. * @returns The instance for chaining. */ enableGestures(): this; /** * Enables completed nod and shake recognition from the user's head pose. * @returns The instance for chaining. */ enableHeadGestures(): this; /** * Enables the stroke recognition block and ensures gestures are available. * @returns The instance for chaining. */ enableStrokes(): this; /** * Enables the visualization of rays for hand tracking. * @returns The instance for chaining. */ enableHandRays(): this; /** * Enables a standard set of AI features, including Gemini Live. * @returns The instance for chaining. */ enableAI(): this; /** * Enables agent-facing context detectors such as semantic trees, * view visibility, and Set-of-Mark observations. * @returns The instance for chaining. */ enableContext(): this; /** * Enables agent-facing scene context. * @returns The instance for chaining. */ enableSceneContext(): this; /** * Enables agent-facing visible objects context. * @returns The instance for chaining. */ enableVisibleObjectsContext(): this; /** * Enables agent-facing Set-of-Mark context. * @returns The instance for chaining. */ enableSetOfMarkContext(): this; /** * Enables the XR transition component for toggling VR. * @returns The instance for chaining. */ enableXRTransitions(): this; /** * Enables input from hands and controllers. * Note that this is enabled by default and can also be changed at runtime with * xb.core.input.enableControllers() and xb.core.input.disableControllers(). * @returns The instance for chaining. */ enableControllers(): this; /** * Sets the title of the app to be displayed above the XR button. * @param title - The title of the app. * @returns The instance for chaining. */ setAppTitle(title: string): this; /** * Sets the description of the app to be displayed above the XR button. * @param description - The description of the app. * @returns The instance for chaining. */ setAppDescription(description: string): this; } type FaceCameraMode = 'capsule' | 'cylindrical' | 'spherical'; declare const ManipulationAction: { readonly Translate: "translate"; readonly Rotate: "rotate"; readonly Scale: "scale"; readonly None: "none"; }; type ManipulationAction = (typeof ManipulationAction)[keyof typeof ManipulationAction]; interface TranslateOptions { faceCamera?: boolean; /** Camera-facing rotation mode used while translating. */ mode?: FaceCameraMode; /** Half-height of the upright region used by capsule mode, in meters. */ capsuleHalfHeight?: number; /** Camera-facing rotation smoothing, matching `FaceCamera`. */ smoothing?: number; } interface RotateOptions { axis?: 'x' | 'y' | 'z' | THREE.Vector3Like; space?: 'local' | 'world'; sensitivity?: number; } interface ScaleOptions { minScale?: number | THREE.Vector3Like; maxScale?: number | THREE.Vector3Like; } interface ManipulationHandleOptions { action?: typeof ManipulationAction.Translate | typeof ManipulationAction.Rotate | typeof ManipulationAction.Scale | typeof ManipulationAction.None; } interface ManipulationOptions { actions?: { translate?: boolean | TranslateOptions; rotate?: boolean | RotateOptions; scale?: boolean | ScaleOptions; }; handle?: ManipulationHandleOptions; } type ManipulationPhase = 'start' | 'update' | 'end' | 'cancel'; interface BaseManipulationEvent { readonly phase: ManipulationPhase; readonly action: ManipulationAction; readonly source: InteractionSource; readonly sources: readonly InteractionSource[]; readonly target: THREE.Object3D; readonly surface: THREE.Object3D; readonly owner: THREE.Object3D; readonly currentTarget: Script; readonly defaultPrevented: boolean; preventDefault(): void; stopPropagation(): void; } interface TranslateManipulationEvent extends BaseManipulationEvent { readonly action: typeof ManipulationAction.Translate; readonly point: THREE.Vector3; readonly delta: THREE.Vector3; readonly position: THREE.Vector3; readonly worldPosition: THREE.Vector3; } interface RotateManipulationEvent extends BaseManipulationEvent { readonly action: typeof ManipulationAction.Rotate; readonly angle: number; readonly quaternion: THREE.Quaternion; } interface ScaleManipulationEvent extends BaseManipulationEvent { readonly action: typeof ManipulationAction.Scale; readonly factor: number; readonly center: THREE.Vector3; readonly scale: THREE.Vector3; } type ManipulationEvent = TranslateManipulationEvent | RotateManipulationEvent | ScaleManipulationEvent; type PointerEvents = 'auto' | 'none'; type ReticleMode = 'auto' | 'surface' | 'hidden'; interface XBObjectOptions { /** Whether this object and its descendants participate in pointer hits. */ pointerEvents?: PointerEvents; interactionEnabled?: boolean; reticleMode?: ReticleMode; manipulation?: boolean | ManipulationOptions; manipulationHandle?: ManipulationHandleOptions | 'none'; } declare module 'three' { interface Object3D { xb?: XBObjectOptions; } } type InteractionSourceType = 'mouse' | 'controller-ray' | 'hand-ray' | 'direct-touch' | 'gaze' | 'simulator'; type RaySourceType = Exclude; interface InteractionSource { readonly type: InteractionSourceType; readonly handedness: 'left' | 'right' | 'none'; readonly controller: Controller; } interface RaySourceInput { controller: Controller; sourceType: RaySourceType; ray: THREE.Ray; /** Optional raw hits supplied by an isolated Interaction adapter. */ intersections?: readonly THREE.Intersection[]; selected: boolean; released?: boolean; position?: THREE.Vector3; orientation?: THREE.Quaternion; } interface DirectTouchInput { controller: Controller; handIndex: number; hand?: THREE.Object3D; point: THREE.Vector3; selected: boolean; orientation?: THREE.Quaternion; } /** All physical interaction input sampled for one engine frame. */ interface InteractionFrameInput { readonly raySources: readonly RaySourceInput[]; readonly directTouches: readonly DirectTouchInput[]; } /** Mutable internal storage for one controller's current logical source. */ declare class InteractionSourceState { readonly controller: Controller; source: InteractionSource; sourceType: InteractionSourceType; readonly position: THREE.Vector3; readonly orientation: THREE.Quaternion; private readonly rayValue; ray?: THREE.Ray; selected: boolean; selectionProgress?: number; constructor(controller: Controller); updateRay(input: RaySourceInput): this; updateTouch(point: THREE.Vector3, orientation?: THREE.Quaternion): this; copyFrom(source: InteractionSourceState): this; } interface ResolvedRay { readonly intersection: THREE.Intersection; /** Physical object that supplied the hit geometry. */ readonly hitObject: THREE.Object3D; /** Public object that owns the hit. */ readonly surface: THREE.Object3D; readonly target?: THREE.Object3D; readonly scriptPath: readonly Script[]; readonly objectPath: readonly THREE.Object3D[]; readonly reticleMode: ReticleMode; readonly semanticControl?: THREE.Object3D; readonly manipulation?: ManipulationResolution; } type ResolvedManipulationAction = Exclude; interface ManipulationResolution { readonly owner: THREE.Object3D; readonly action?: ResolvedManipulationAction; readonly handle?: THREE.Object3D; } type TargetedInteractionHook = 'onObjectSelectStart' | 'onObjectSelectEnd' | 'onObjectLongSelect' | 'onObjectTouchStart' | 'onObjectTouching' | 'onObjectTouchEnd' | 'onObjectGrabStart' | 'onObjectGrabbing' | 'onObjectGrabEnd' | 'onHoverEnter' | 'onHovering' | 'onHoverExit'; type GlobalInteractionHook = 'onSelectStart' | 'onSelecting' | 'onSelect' | 'onSelectEnd' | 'onLongSelect'; type GlobalInteractionEvent = Hook extends 'onSelectEnd' ? SelectEndEvent : Hook extends 'onLongSelect' ? LongSelectEvent : SelectEvent; /** * The only Script-facing seam. The implementation applies the existing Script * exception policy to each invocation. */ interface InteractionCallbackDispatch { isScript(object: THREE.Object3D): boolean; hasTargetHandler(object: THREE.Object3D, sourceType: InteractionSourceType): boolean; hasTargetHook(object: THREE.Object3D, hook: TargetedInteractionHook): boolean; invokeTarget(script: THREE.Object3D, hook: TargetedInteractionHook, argument: unknown): void; invokeSemantic(object: THREE.Object3D, callback: () => void): void; invokeGlobal(hook: Hook, event: GlobalInteractionEvent): void; invokeManipulation(script: Script, event: ManipulationEvent): void; } interface ReticlePresentationObserver { present(snapshot: InteractionSourceState, resolved: ResolvedRay | undefined): void; clear(controller: Controller): void; } interface InteractionDependencies { callbacks: InteractionCallbackDispatch; scene?: THREE.Scene; raycastMode?: RaycastMode; camera?: THREE.Camera; timer?: THREE.Timer; reticle?: ReticlePresentationObserver; reticleOptions?: ReticleOptions; longSelectDuration?: number; } /** * Integrates the RAPIER physics engine into the XRCore lifecycle. * It sets up the physics in a blended world that combines virtual and physical * objects, steps the simulation forward in sync with the application's * framerate, and manages the lifecycle of physics-related objects. */ declare class Physics { initialized: boolean; options?: PhysicsOptions; RAPIER: RAPIERCompat; fps: number; blendedWorld: RAPIER_NS.World; eventQueue: RAPIER_NS.EventQueue; get timestep(): number; /** * Asynchronously initializes the RAPIER physics engine and creates the * blendedWorld. This is called in Core before the physics simulation starts. */ init({ physicsOptions }: { physicsOptions: PhysicsOptions; }): Promise; /** * Advances the physics simulation by one step. */ physicsStep(): void; /** * Frees the memory allocated by the RAPIER physics blendedWorld and event * queue. This is crucial for preventing memory leaks when the XR session * ends. */ dispose(): void; } interface SelectEvent { readonly source: InteractionSource; readonly target?: THREE.Object3D; readonly currentTarget?: Script; /** Public hit surface. Private renderer meshes are normalized to their owner. */ readonly surface?: THREE.Object3D; /** Current ray intersection on `surface`, when the source still hits it. */ readonly intersection?: THREE.Intersection; stopPropagation(): void; } type SelectionEndReason = 'released' | 'released-outside' | 'source-lost' | 'pointer-cancel' | 'removed' | 'hidden' | 'disabled'; interface SelectEndEvent extends SelectEvent { readonly completed: boolean; readonly reason: SelectionEndReason; } /** Event sent after a captured selection is held past the long-select delay. */ interface LongSelectEvent extends SelectEvent { /** How long the selection has been held, in seconds. */ duration: number; } interface ObjectTouchEvent { readonly source: InteractionSource; readonly target: THREE.Object3D; readonly currentTarget?: Script; /** Public contact surface. Private renderer meshes are normalized to it. */ readonly surface: THREE.Object3D; readonly handIndex: number; readonly hand?: THREE.Object3D; readonly touchPosition: THREE.Vector3; stopPropagation(): void; } interface ObjectTouchStartEvent extends ObjectTouchEvent { readonly defaultPrevented: boolean; preventDefault(): void; } interface ObjectGrabEvent { readonly source: InteractionSource; readonly target: THREE.Object3D; readonly currentTarget?: Script; /** Public contact surface. Private renderer meshes are normalized to it. */ readonly surface: THREE.Object3D; readonly handIndex: number; readonly hand: THREE.Object3D; readonly touchPosition: THREE.Vector3; stopPropagation(): void; } interface HoverEvent extends SelectEvent { readonly intersection?: THREE.Intersection; } interface KeyEvent { code: string; } /** * The Script class facilities development by providing useful life cycle * functions similar to MonoBehaviors in Unity. * * Each Script object is an independent THREE.Object3D entity within the * scene graph. * * See /docs/manual/Scripts.md for the full documentation. * * It manages user, objects, and interaction between user and objects. * See `/templates/00_basic/` for an example to start with. * # Supported interaction functions to extend: * * onSelectStart(event) * onSelectEnd(event) * */ declare function ScriptMixin>(base: TBase): { new (...args: any[]): { isXRScript: boolean; /** * Initializes an instance with XR controllers, grips, hands, and default * options. We allow all scripts to quickly access its user (e.g., * user.isSelecting(), user.hands), world (e.g., physical depth mesh, * lighting estimation, and recognized objects), and scene (the root of * three.js's scene graph). If this returns a promise, we will wait for it. */ init(_?: object): void | Promise; /** * Runs per frame. */ update(_time?: number, _frame?: XRFrame): void; /** * Enables depth-aware interactions with physics. See /samples/advanced/ballpit */ initPhysics(_physics: Physics): void | Promise; physicsStep(): void; onXRSessionStarted(_session?: XRSession): void; onXRSessionEnded(): void; onSimulatorStarted(): void; /** * Called whenever pinch / mouse click starts, globally. * @param _event - The interaction source and optional captured target. */ onSelectStart(_event: SelectEvent): void; /** * Called whenever pinch / mouse click discontinues, globally. * @param _event - The completed state and end reason. */ onSelectEnd(_event: SelectEndEvent): void; /** * Called whenever pinch / mouse click successfully completes, globally. * @param _event - The interaction source and completed target. */ onSelect(_event: SelectEvent): void; /** * Called whenever pinch / mouse click is happening, globally. */ onSelecting(_event: SelectEvent): void; /** Called when an object selection reaches the long-select delay. */ onLongSelect(_event: LongSelectEvent): void; /** * Called on keyboard keypress. * @param _event - Event containing `.code` to read the keyboard key. */ onKeyDown(_event: KeyEvent): void; onKeyUp(_event: KeyEvent): void; /** * Called whenever gamepad trigger starts, globally. * @param _event - `event.source.controller` identifies the controller. */ onSqueezeStart(_event: SelectEvent): void; /** * Called whenever gamepad trigger stops, globally. * @param _event - `event.source.controller` identifies the controller. */ onSqueezeEnd(_event: SelectEvent): void; /** * Called whenever gamepad is being triggered, globally. */ onSqueezing(_event: SelectEvent): void; /** * Called whenever gamepad trigger successfully completes, globally. * @param _event - `event.source.controller` identifies the controller. */ onSqueeze(_event: SelectEvent): void; /** * Called when a source starts selecting the object this Script represents. * @param _event - `event.target` is the logical object and * `event.source.controller` identifies the controller. * Call `event.stopPropagation()` to stop bubbling to ancestor Scripts. */ onObjectSelectStart(_event: SelectEvent): void; /** * Called when a source stops selecting the object this Script represents. * @param _event - The completed state and end reason. * Call `event.stopPropagation()` to stop bubbling to ancestor Scripts. */ onObjectSelectEnd(_event: SelectEndEvent): void; /** * Called once when a captured selection is held for the long-select delay. * Manipulation captures do not emit this callback. * @param _event - The controller and completed hold duration. * Call `event.stopPropagation()` to stop bubbling to ancestor Scripts. */ onObjectLongSelect(_event: LongSelectEvent): void; /** * Called for each phase of an automatic object manipulation. Call * `event.stopPropagation()` to stop bubbling. Calling `preventDefault()` * on a start event suppresses the automatic action. */ onObjectManipulate(_event: ManipulationEvent): void; /** * Called when a source starts hovering over this object. * @param _event - The hover source, target, surface, and intersection. * Call `event.stopPropagation()` to stop bubbling to ancestor Scripts. */ onHoverEnter(_event: HoverEvent): void; /** * Called when a source stops hovering over this object. * @param _event - The hover source, target, surface, and intersection. * Call `event.stopPropagation()` to stop bubbling to ancestor Scripts. */ onHoverExit(_event: HoverEvent): void; /** * Called while a source hovers over this object. * @param _event - The hover source, target, surface, and intersection. * Call `event.stopPropagation()` to stop bubbling to ancestor Scripts. */ onHovering(_event: HoverEvent): void; /** * Called when a hand's index finger starts touching this object. * Direct touch starts the object's selection lifecycle by default. Call * `event.preventDefault()` to handle contact without selecting. */ onObjectTouchStart(_event: ObjectTouchStartEvent): void; /** * Called every frame that a hand's index finger is touching this object. * The object remains selected during these frames unless touch selection * was prevented when contact started. */ onObjectTouching(_event: ObjectTouchEvent): void; /** * Called when a hand's index finger stops touching this object. * This ends the default selection lifecycle after the touch callback. */ onObjectTouchEnd(_event: ObjectTouchEvent): void; /** * Called when a hand starts grabbing this object (touching + pinching). * A grab starts built-in direct-touch manipulation when enabled. */ onObjectGrabStart(_event: ObjectGrabEvent): void; /** * Called every frame a hand is grabbing this object. */ onObjectGrabbing(_event: ObjectGrabEvent): void; /** * Called when a hand stops grabbing this object. * This ends built-in direct-touch manipulation without ending contact. */ onObjectGrabEnd(_event: ObjectGrabEvent): void; /** * Called when the script is removed from the scene. Opposite of init. */ dispose(): void; readonly isObject3D: true; readonly id: number; uuid: string; name: string; readonly type: string; parent: THREE.Object3D | null; children: THREE.Object3D[]; up: THREE.Vector3; readonly position: THREE.Vector3; readonly rotation: THREE.Euler; readonly quaternion: THREE.Quaternion; readonly scale: THREE.Vector3; readonly modelViewMatrix: THREE.Matrix4; readonly normalMatrix: THREE.Matrix3; matrix: THREE.Matrix4; matrixWorld: THREE.Matrix4; matrixAutoUpdate: boolean; matrixWorldAutoUpdate: boolean; matrixWorldNeedsUpdate: boolean; layers: THREE.Layers; visible: boolean; castShadow: boolean; receiveShadow: boolean; frustumCulled: boolean; renderOrder: number; animations: THREE.AnimationClip[]; customDepthMaterial?: THREE.Material | undefined; customDistanceMaterial?: THREE.Material | undefined; static: boolean; userData: Record; pivot: THREE.Vector3 | null; onBeforeShadow(renderer: THREE.WebGLRenderer, scene: THREE.Scene, camera: THREE.Camera, shadowCamera: THREE.Camera, geometry: THREE.BufferGeometry, depthMaterial: THREE.Material, group: THREE.Group): void; onAfterShadow(renderer: THREE.WebGLRenderer, scene: THREE.Scene, camera: THREE.Camera, shadowCamera: THREE.Camera, geometry: THREE.BufferGeometry, depthMaterial: THREE.Material, group: THREE.Group): void; onBeforeRender(renderer: THREE.WebGLRenderer, scene: THREE.Scene, camera: THREE.Camera, geometry: THREE.BufferGeometry, material: THREE.Material, group: THREE.Group): void; onAfterRender(renderer: THREE.WebGLRenderer, scene: THREE.Scene, camera: THREE.Camera, geometry: THREE.BufferGeometry, material: THREE.Material, group: THREE.Group): void; applyMatrix4(matrix: THREE.Matrix4): void; applyQuaternion(quaternion: THREE.Quaternion): /*elided*/ any; setRotationFromAxisAngle(axis: THREE.Vector3, angle: number): void; setRotationFromEuler(euler: THREE.Euler): void; setRotationFromMatrix(m: THREE.Matrix4): void; setRotationFromQuaternion(q: THREE.Quaternion): void; rotateOnAxis(axis: THREE.Vector3, angle: number): /*elided*/ any; rotateOnWorldAxis(axis: THREE.Vector3, angle: number): /*elided*/ any; rotateX(angle: number): /*elided*/ any; rotateY(angle: number): /*elided*/ any; rotateZ(angle: number): /*elided*/ any; translateOnAxis(axis: THREE.Vector3, distance: number): /*elided*/ any; translateX(distance: number): /*elided*/ any; translateY(distance: number): /*elided*/ any; translateZ(distance: number): /*elided*/ any; localToWorld(vector: THREE.Vector3): THREE.Vector3; worldToLocal(vector: THREE.Vector3): THREE.Vector3; lookAt(vector: THREE.Vector3): void; lookAt(x: number, y: number, z: number): void; add(...object: THREE.Object3D[]): /*elided*/ any; remove(...object: THREE.Object3D[]): /*elided*/ any; removeFromParent(): /*elided*/ any; clear(): /*elided*/ any; attach(object: THREE.Object3D): /*elided*/ any; getObjectById(id: number): THREE.Object3D | undefined; getObjectByName(name: string): THREE.Object3D | undefined; getObjectByProperty(name: string, value: any): THREE.Object3D | undefined; getObjectsByProperty(name: string, value: any, optionalTarget?: THREE.Object3D[]): THREE.Object3D[]; getWorldPosition(target: THREE.Vector3): THREE.Vector3; getWorldQuaternion(target: THREE.Quaternion): THREE.Quaternion; getWorldScale(target: THREE.Vector3): THREE.Vector3; getWorldDirection(target: THREE.Vector3): THREE.Vector3; raycast(raycaster: THREE.Raycaster, intersects: THREE.Intersection[]): void; traverse(callback: (object: THREE.Object3D) => any): void; traverseVisible(callback: (object: THREE.Object3D) => any): void; traverseAncestors(callback: (object: THREE.Object3D) => any): void; updateMatrix(): void; updateMatrixWorld(force?: boolean): void; updateWorldMatrix(updateParents: boolean, updateChildren: boolean): void; toJSON(meta?: THREE.JSONMeta): THREE.Object3DJSON; clone(recursive?: boolean): /*elided*/ any; copy(object: THREE.Object3D, recursive?: boolean): /*elided*/ any; count?: number | undefined; occlusionTest?: boolean | undefined; xb?: XBObjectOptions; spherecast?(sphere: THREE.Sphere, intersects: Array): void; intersectChildren?: boolean; interactableDescendants?: Array; ancestorsHaveListeners?: boolean; defaultPointerEvents?: _pmndrs_uikit_dist_panel.PointerEventsProperties["pointerEvents"]; addEventListener(type: T, listener: THREE.EventListener): void; hasEventListener(type: T, listener: THREE.EventListener): boolean; removeEventListener(type: T, listener: THREE.EventListener): void; dispatchEvent(event: THREE.BaseEvent & THREE.Object3DEventMap[T]): void; pointerEvents?: "none" | "auto" | "listener"; pointerEventsType?: _pmndrs_uikit_dist_panel.AllowedPointerEventsType; pointerEventsOrder?: number; }; } & TBase; /** * Script manages app logic or interaction between user and objects. */ declare const ScriptMixinObject3D: { new (...args: any[]): { isXRScript: boolean; /** * Initializes an instance with XR controllers, grips, hands, and default * options. We allow all scripts to quickly access its user (e.g., * user.isSelecting(), user.hands), world (e.g., physical depth mesh, * lighting estimation, and recognized objects), and scene (the root of * three.js's scene graph). If this returns a promise, we will wait for it. */ init(_?: object): void | Promise; /** * Runs per frame. */ update(_time?: number, _frame?: XRFrame): void; /** * Enables depth-aware interactions with physics. See /samples/advanced/ballpit */ initPhysics(_physics: Physics): void | Promise; physicsStep(): void; onXRSessionStarted(_session?: XRSession): void; onXRSessionEnded(): void; onSimulatorStarted(): void; /** * Called whenever pinch / mouse click starts, globally. * @param _event - The interaction source and optional captured target. */ onSelectStart(_event: SelectEvent): void; /** * Called whenever pinch / mouse click discontinues, globally. * @param _event - The completed state and end reason. */ onSelectEnd(_event: SelectEndEvent): void; /** * Called whenever pinch / mouse click successfully completes, globally. * @param _event - The interaction source and completed target. */ onSelect(_event: SelectEvent): void; /** * Called whenever pinch / mouse click is happening, globally. */ onSelecting(_event: SelectEvent): void; /** Called when an object selection reaches the long-select delay. */ onLongSelect(_event: LongSelectEvent): void; /** * Called on keyboard keypress. * @param _event - Event containing `.code` to read the keyboard key. */ onKeyDown(_event: KeyEvent): void; onKeyUp(_event: KeyEvent): void; /** * Called whenever gamepad trigger starts, globally. * @param _event - `event.source.controller` identifies the controller. */ onSqueezeStart(_event: SelectEvent): void; /** * Called whenever gamepad trigger stops, globally. * @param _event - `event.source.controller` identifies the controller. */ onSqueezeEnd(_event: SelectEvent): void; /** * Called whenever gamepad is being triggered, globally. */ onSqueezing(_event: SelectEvent): void; /** * Called whenever gamepad trigger successfully completes, globally. * @param _event - `event.source.controller` identifies the controller. */ onSqueeze(_event: SelectEvent): void; /** * Called when a source starts selecting the object this Script represents. * @param _event - `event.target` is the logical object and * `event.source.controller` identifies the controller. * Call `event.stopPropagation()` to stop bubbling to ancestor Scripts. */ onObjectSelectStart(_event: SelectEvent): void; /** * Called when a source stops selecting the object this Script represents. * @param _event - The completed state and end reason. * Call `event.stopPropagation()` to stop bubbling to ancestor Scripts. */ onObjectSelectEnd(_event: SelectEndEvent): void; /** * Called once when a captured selection is held for the long-select delay. * Manipulation captures do not emit this callback. * @param _event - The controller and completed hold duration. * Call `event.stopPropagation()` to stop bubbling to ancestor Scripts. */ onObjectLongSelect(_event: LongSelectEvent): void; /** * Called for each phase of an automatic object manipulation. Call * `event.stopPropagation()` to stop bubbling. Calling `preventDefault()` * on a start event suppresses the automatic action. */ onObjectManipulate(_event: ManipulationEvent): void; /** * Called when a source starts hovering over this object. * @param _event - The hover source, target, surface, and intersection. * Call `event.stopPropagation()` to stop bubbling to ancestor Scripts. */ onHoverEnter(_event: HoverEvent): void; /** * Called when a source stops hovering over this object. * @param _event - The hover source, target, surface, and intersection. * Call `event.stopPropagation()` to stop bubbling to ancestor Scripts. */ onHoverExit(_event: HoverEvent): void; /** * Called while a source hovers over this object. * @param _event - The hover source, target, surface, and intersection. * Call `event.stopPropagation()` to stop bubbling to ancestor Scripts. */ onHovering(_event: HoverEvent): void; /** * Called when a hand's index finger starts touching this object. * Direct touch starts the object's selection lifecycle by default. Call * `event.preventDefault()` to handle contact without selecting. */ onObjectTouchStart(_event: ObjectTouchStartEvent): void; /** * Called every frame that a hand's index finger is touching this object. * The object remains selected during these frames unless touch selection * was prevented when contact started. */ onObjectTouching(_event: ObjectTouchEvent): void; /** * Called when a hand's index finger stops touching this object. * This ends the default selection lifecycle after the touch callback. */ onObjectTouchEnd(_event: ObjectTouchEvent): void; /** * Called when a hand starts grabbing this object (touching + pinching). * A grab starts built-in direct-touch manipulation when enabled. */ onObjectGrabStart(_event: ObjectGrabEvent): void; /** * Called every frame a hand is grabbing this object. */ onObjectGrabbing(_event: ObjectGrabEvent): void; /** * Called when a hand stops grabbing this object. * This ends built-in direct-touch manipulation without ending contact. */ onObjectGrabEnd(_event: ObjectGrabEvent): void; /** * Called when the script is removed from the scene. Opposite of init. */ dispose(): void; readonly isObject3D: true; readonly id: number; uuid: string; name: string; readonly type: string; parent: THREE.Object3D | null; children: THREE.Object3D[]; up: THREE.Vector3; readonly position: THREE.Vector3; readonly rotation: THREE.Euler; readonly quaternion: THREE.Quaternion; readonly scale: THREE.Vector3; readonly modelViewMatrix: THREE.Matrix4; readonly normalMatrix: THREE.Matrix3; matrix: THREE.Matrix4; matrixWorld: THREE.Matrix4; matrixAutoUpdate: boolean; matrixWorldAutoUpdate: boolean; matrixWorldNeedsUpdate: boolean; layers: THREE.Layers; visible: boolean; castShadow: boolean; receiveShadow: boolean; frustumCulled: boolean; renderOrder: number; animations: THREE.AnimationClip[]; customDepthMaterial?: THREE.Material | undefined; customDistanceMaterial?: THREE.Material | undefined; static: boolean; userData: Record; pivot: THREE.Vector3 | null; onBeforeShadow(renderer: THREE.WebGLRenderer, scene: THREE.Scene, camera: THREE.Camera, shadowCamera: THREE.Camera, geometry: THREE.BufferGeometry, depthMaterial: THREE.Material, group: THREE.Group): void; onAfterShadow(renderer: THREE.WebGLRenderer, scene: THREE.Scene, camera: THREE.Camera, shadowCamera: THREE.Camera, geometry: THREE.BufferGeometry, depthMaterial: THREE.Material, group: THREE.Group): void; onBeforeRender(renderer: THREE.WebGLRenderer, scene: THREE.Scene, camera: THREE.Camera, geometry: THREE.BufferGeometry, material: THREE.Material, group: THREE.Group): void; onAfterRender(renderer: THREE.WebGLRenderer, scene: THREE.Scene, camera: THREE.Camera, geometry: THREE.BufferGeometry, material: THREE.Material, group: THREE.Group): void; applyMatrix4(matrix: THREE.Matrix4): void; applyQuaternion(quaternion: THREE.Quaternion): /*elided*/ any; setRotationFromAxisAngle(axis: THREE.Vector3, angle: number): void; setRotationFromEuler(euler: THREE.Euler): void; setRotationFromMatrix(m: THREE.Matrix4): void; setRotationFromQuaternion(q: THREE.Quaternion): void; rotateOnAxis(axis: THREE.Vector3, angle: number): /*elided*/ any; rotateOnWorldAxis(axis: THREE.Vector3, angle: number): /*elided*/ any; rotateX(angle: number): /*elided*/ any; rotateY(angle: number): /*elided*/ any; rotateZ(angle: number): /*elided*/ any; translateOnAxis(axis: THREE.Vector3, distance: number): /*elided*/ any; translateX(distance: number): /*elided*/ any; translateY(distance: number): /*elided*/ any; translateZ(distance: number): /*elided*/ any; localToWorld(vector: THREE.Vector3): THREE.Vector3; worldToLocal(vector: THREE.Vector3): THREE.Vector3; lookAt(vector: THREE.Vector3): void; lookAt(x: number, y: number, z: number): void; add(...object: THREE.Object3D[]): /*elided*/ any; remove(...object: THREE.Object3D[]): /*elided*/ any; removeFromParent(): /*elided*/ any; clear(): /*elided*/ any; attach(object: THREE.Object3D): /*elided*/ any; getObjectById(id: number): THREE.Object3D | undefined; getObjectByName(name: string): THREE.Object3D | undefined; getObjectByProperty(name: string, value: any): THREE.Object3D | undefined; getObjectsByProperty(name: string, value: any, optionalTarget?: THREE.Object3D[]): THREE.Object3D[]; getWorldPosition(target: THREE.Vector3): THREE.Vector3; getWorldQuaternion(target: THREE.Quaternion): THREE.Quaternion; getWorldScale(target: THREE.Vector3): THREE.Vector3; getWorldDirection(target: THREE.Vector3): THREE.Vector3; raycast(raycaster: THREE.Raycaster, intersects: THREE.Intersection[]): void; traverse(callback: (object: THREE.Object3D) => any): void; traverseVisible(callback: (object: THREE.Object3D) => any): void; traverseAncestors(callback: (object: THREE.Object3D) => any): void; updateMatrix(): void; updateMatrixWorld(force?: boolean): void; updateWorldMatrix(updateParents: boolean, updateChildren: boolean): void; toJSON(meta?: THREE.JSONMeta): THREE.Object3DJSON; clone(recursive?: boolean): /*elided*/ any; copy(object: THREE.Object3D, recursive?: boolean): /*elided*/ any; count?: number | undefined; occlusionTest?: boolean | undefined; xb?: XBObjectOptions; spherecast?(sphere: THREE.Sphere, intersects: Array): void; intersectChildren?: boolean; interactableDescendants?: Array; ancestorsHaveListeners?: boolean; defaultPointerEvents?: _pmndrs_uikit_dist_panel.PointerEventsProperties["pointerEvents"]; addEventListener(type: T, listener: THREE.EventListener): void; hasEventListener(type: T, listener: THREE.EventListener): boolean; removeEventListener(type: T, listener: THREE.EventListener): void; dispatchEvent(event: THREE.BaseEvent & THREE.Object3DEventMap[T]): void; pointerEvents?: "none" | "auto" | "listener"; pointerEventsType?: _pmndrs_uikit_dist_panel.AllowedPointerEventsType; pointerEventsOrder?: number; }; } & typeof THREE.Object3D; declare class Script extends ScriptMixinObject3D { } /** * MeshScript can be constructed with geometry and materials, with * `super(geometry, material)`; for direct access to its geometry. * MeshScripts hold geometry and materials while using the Script lifecycle. */ declare const ScriptMixinMeshScript: { new (...args: any[]): { isXRScript: boolean; /** * Initializes an instance with XR controllers, grips, hands, and default * options. We allow all scripts to quickly access its user (e.g., * user.isSelecting(), user.hands), world (e.g., physical depth mesh, * lighting estimation, and recognized objects), and scene (the root of * three.js's scene graph). If this returns a promise, we will wait for it. */ init(_?: object): void | Promise; /** * Runs per frame. */ update(_time?: number, _frame?: XRFrame): void; /** * Enables depth-aware interactions with physics. See /samples/advanced/ballpit */ initPhysics(_physics: Physics): void | Promise; physicsStep(): void; onXRSessionStarted(_session?: XRSession): void; onXRSessionEnded(): void; onSimulatorStarted(): void; /** * Called whenever pinch / mouse click starts, globally. * @param _event - The interaction source and optional captured target. */ onSelectStart(_event: SelectEvent): void; /** * Called whenever pinch / mouse click discontinues, globally. * @param _event - The completed state and end reason. */ onSelectEnd(_event: SelectEndEvent): void; /** * Called whenever pinch / mouse click successfully completes, globally. * @param _event - The interaction source and completed target. */ onSelect(_event: SelectEvent): void; /** * Called whenever pinch / mouse click is happening, globally. */ onSelecting(_event: SelectEvent): void; /** Called when an object selection reaches the long-select delay. */ onLongSelect(_event: LongSelectEvent): void; /** * Called on keyboard keypress. * @param _event - Event containing `.code` to read the keyboard key. */ onKeyDown(_event: KeyEvent): void; onKeyUp(_event: KeyEvent): void; /** * Called whenever gamepad trigger starts, globally. * @param _event - `event.source.controller` identifies the controller. */ onSqueezeStart(_event: SelectEvent): void; /** * Called whenever gamepad trigger stops, globally. * @param _event - `event.source.controller` identifies the controller. */ onSqueezeEnd(_event: SelectEvent): void; /** * Called whenever gamepad is being triggered, globally. */ onSqueezing(_event: SelectEvent): void; /** * Called whenever gamepad trigger successfully completes, globally. * @param _event - `event.source.controller` identifies the controller. */ onSqueeze(_event: SelectEvent): void; /** * Called when a source starts selecting the object this Script represents. * @param _event - `event.target` is the logical object and * `event.source.controller` identifies the controller. * Call `event.stopPropagation()` to stop bubbling to ancestor Scripts. */ onObjectSelectStart(_event: SelectEvent): void; /** * Called when a source stops selecting the object this Script represents. * @param _event - The completed state and end reason. * Call `event.stopPropagation()` to stop bubbling to ancestor Scripts. */ onObjectSelectEnd(_event: SelectEndEvent): void; /** * Called once when a captured selection is held for the long-select delay. * Manipulation captures do not emit this callback. * @param _event - The controller and completed hold duration. * Call `event.stopPropagation()` to stop bubbling to ancestor Scripts. */ onObjectLongSelect(_event: LongSelectEvent): void; /** * Called for each phase of an automatic object manipulation. Call * `event.stopPropagation()` to stop bubbling. Calling `preventDefault()` * on a start event suppresses the automatic action. */ onObjectManipulate(_event: ManipulationEvent): void; /** * Called when a source starts hovering over this object. * @param _event - The hover source, target, surface, and intersection. * Call `event.stopPropagation()` to stop bubbling to ancestor Scripts. */ onHoverEnter(_event: HoverEvent): void; /** * Called when a source stops hovering over this object. * @param _event - The hover source, target, surface, and intersection. * Call `event.stopPropagation()` to stop bubbling to ancestor Scripts. */ onHoverExit(_event: HoverEvent): void; /** * Called while a source hovers over this object. * @param _event - The hover source, target, surface, and intersection. * Call `event.stopPropagation()` to stop bubbling to ancestor Scripts. */ onHovering(_event: HoverEvent): void; /** * Called when a hand's index finger starts touching this object. * Direct touch starts the object's selection lifecycle by default. Call * `event.preventDefault()` to handle contact without selecting. */ onObjectTouchStart(_event: ObjectTouchStartEvent): void; /** * Called every frame that a hand's index finger is touching this object. * The object remains selected during these frames unless touch selection * was prevented when contact started. */ onObjectTouching(_event: ObjectTouchEvent): void; /** * Called when a hand's index finger stops touching this object. * This ends the default selection lifecycle after the touch callback. */ onObjectTouchEnd(_event: ObjectTouchEvent): void; /** * Called when a hand starts grabbing this object (touching + pinching). * A grab starts built-in direct-touch manipulation when enabled. */ onObjectGrabStart(_event: ObjectGrabEvent): void; /** * Called every frame a hand is grabbing this object. */ onObjectGrabbing(_event: ObjectGrabEvent): void; /** * Called when a hand stops grabbing this object. * This ends built-in direct-touch manipulation without ending contact. */ onObjectGrabEnd(_event: ObjectGrabEvent): void; /** * Called when the script is removed from the scene. Opposite of init. */ dispose(): void; readonly isObject3D: true; readonly id: number; uuid: string; name: string; readonly type: string; parent: THREE.Object3D | null; children: THREE.Object3D[]; up: THREE.Vector3; readonly position: THREE.Vector3; readonly rotation: THREE.Euler; readonly quaternion: THREE.Quaternion; readonly scale: THREE.Vector3; readonly modelViewMatrix: THREE.Matrix4; readonly normalMatrix: THREE.Matrix3; matrix: THREE.Matrix4; matrixWorld: THREE.Matrix4; matrixAutoUpdate: boolean; matrixWorldAutoUpdate: boolean; matrixWorldNeedsUpdate: boolean; layers: THREE.Layers; visible: boolean; castShadow: boolean; receiveShadow: boolean; frustumCulled: boolean; renderOrder: number; animations: THREE.AnimationClip[]; customDepthMaterial?: THREE.Material | undefined; customDistanceMaterial?: THREE.Material | undefined; static: boolean; userData: Record; pivot: THREE.Vector3 | null; onBeforeShadow(renderer: THREE.WebGLRenderer, scene: THREE.Scene, camera: THREE.Camera, shadowCamera: THREE.Camera, geometry: THREE.BufferGeometry, depthMaterial: THREE.Material, group: THREE.Group): void; onAfterShadow(renderer: THREE.WebGLRenderer, scene: THREE.Scene, camera: THREE.Camera, shadowCamera: THREE.Camera, geometry: THREE.BufferGeometry, depthMaterial: THREE.Material, group: THREE.Group): void; onBeforeRender(renderer: THREE.WebGLRenderer, scene: THREE.Scene, camera: THREE.Camera, geometry: THREE.BufferGeometry, material: THREE.Material, group: THREE.Group): void; onAfterRender(renderer: THREE.WebGLRenderer, scene: THREE.Scene, camera: THREE.Camera, geometry: THREE.BufferGeometry, material: THREE.Material, group: THREE.Group): void; applyMatrix4(matrix: THREE.Matrix4): void; applyQuaternion(quaternion: THREE.Quaternion): /*elided*/ any; setRotationFromAxisAngle(axis: THREE.Vector3, angle: number): void; setRotationFromEuler(euler: THREE.Euler): void; setRotationFromMatrix(m: THREE.Matrix4): void; setRotationFromQuaternion(q: THREE.Quaternion): void; rotateOnAxis(axis: THREE.Vector3, angle: number): /*elided*/ any; rotateOnWorldAxis(axis: THREE.Vector3, angle: number): /*elided*/ any; rotateX(angle: number): /*elided*/ any; rotateY(angle: number): /*elided*/ any; rotateZ(angle: number): /*elided*/ any; translateOnAxis(axis: THREE.Vector3, distance: number): /*elided*/ any; translateX(distance: number): /*elided*/ any; translateY(distance: number): /*elided*/ any; translateZ(distance: number): /*elided*/ any; localToWorld(vector: THREE.Vector3): THREE.Vector3; worldToLocal(vector: THREE.Vector3): THREE.Vector3; lookAt(vector: THREE.Vector3): void; lookAt(x: number, y: number, z: number): void; add(...object: THREE.Object3D[]): /*elided*/ any; remove(...object: THREE.Object3D[]): /*elided*/ any; removeFromParent(): /*elided*/ any; clear(): /*elided*/ any; attach(object: THREE.Object3D): /*elided*/ any; getObjectById(id: number): THREE.Object3D | undefined; getObjectByName(name: string): THREE.Object3D | undefined; getObjectByProperty(name: string, value: any): THREE.Object3D | undefined; getObjectsByProperty(name: string, value: any, optionalTarget?: THREE.Object3D[]): THREE.Object3D[]; getWorldPosition(target: THREE.Vector3): THREE.Vector3; getWorldQuaternion(target: THREE.Quaternion): THREE.Quaternion; getWorldScale(target: THREE.Vector3): THREE.Vector3; getWorldDirection(target: THREE.Vector3): THREE.Vector3; raycast(raycaster: THREE.Raycaster, intersects: THREE.Intersection[]): void; traverse(callback: (object: THREE.Object3D) => any): void; traverseVisible(callback: (object: THREE.Object3D) => any): void; traverseAncestors(callback: (object: THREE.Object3D) => any): void; updateMatrix(): void; updateMatrixWorld(force?: boolean): void; updateWorldMatrix(updateParents: boolean, updateChildren: boolean): void; toJSON(meta?: THREE.JSONMeta): THREE.Object3DJSON; clone(recursive?: boolean): /*elided*/ any; copy(object: THREE.Object3D, recursive?: boolean): /*elided*/ any; count?: number | undefined; occlusionTest?: boolean | undefined; xb?: XBObjectOptions; spherecast?(sphere: THREE.Sphere, intersects: Array): void; intersectChildren?: boolean; interactableDescendants?: Array; ancestorsHaveListeners?: boolean; defaultPointerEvents?: _pmndrs_uikit_dist_panel.PointerEventsProperties["pointerEvents"]; addEventListener(type: T, listener: THREE.EventListener): void; hasEventListener(type: T, listener: THREE.EventListener): boolean; removeEventListener(type: T, listener: THREE.EventListener): void; dispatchEvent(event: THREE.BaseEvent & THREE.Object3DEventMap[T]): void; pointerEvents?: "none" | "auto" | "listener"; pointerEventsType?: _pmndrs_uikit_dist_panel.AllowedPointerEventsType; pointerEventsOrder?: number; }; } & typeof THREE.Mesh; declare class MeshScript extends ScriptMixinMeshScript { /** * {@inheritDoc} */ constructor(geometry?: TGeometry, material?: TMaterial); } interface ToolCall { name: string; args: unknown; } /** * Standardized result type for tool execution. * @typeParam T - The type of data returned on success. */ interface ToolResult { /** Whether the tool execution succeeded */ success: boolean; /** The result data if successful */ data?: T; /** Error message if execution failed */ error?: string; /** Additional metadata about the execution */ metadata?: Record; } type ToolSchema = Omit & { properties?: Record; items?: ToolSchema; type?: keyof typeof GoogleGenAITypes.Type; }; type ToolOptions = { /** The name of the tool. */ name: string; /** A description of what the tool does. */ description: string; /** The parameters of the tool */ parameters?: ToolSchema; /** A callback to execute when the tool is triggered */ onTriggered?: (args: unknown) => unknown | Promise; behavior?: 'BLOCKING' | 'NON_BLOCKING' | GoogleGenAITypes.Behavior; }; /** * A base class for tools that the agent can use. */ declare class Tool { name: string; description?: string; parameters?: ToolSchema; onTriggered?: (args: unknown) => unknown; behavior?: 'BLOCKING' | 'NON_BLOCKING'; /** * @param options - The options for the tool. */ constructor(options: ToolOptions); /** * Executes the tool's action with standardized error handling. * @param args - The arguments for the tool. * @returns A promise that resolves with a ToolResult containing success/error information. */ execute(args: unknown): Promise; /** * Returns a JSON representation of the tool. * @returns A valid FunctionDeclaration object. */ toJSON(): GoogleGenAITypes.FunctionDeclaration; } interface GeminiResponse { toolCall?: ToolCall; text?: string | null; } declare abstract class BaseAIModel { constructor(); abstract init(): Promise; abstract isAvailable(): boolean; abstract query(_input: object, _tools: []): Promise; hasApiKey(): Promise; } interface GeminiQueryInput { type: 'live' | 'text' | 'uri' | 'base64' | 'multiPart'; action?: 'start' | 'stop' | 'send'; text?: string; uri?: string; base64?: string; mimeType?: string; parts?: GoogleGenAITypes.Part[]; config?: GoogleGenAITypes.LiveConnectConfig; data?: GoogleGenAITypes.LiveSendRealtimeInputParameters; useExponentialBackoff?: boolean; } declare class Gemini extends BaseAIModel { protected options: GeminiOptions; inited: boolean; liveSession?: GoogleGenAITypes.Session; isLiveMode: boolean; liveCallbacks: Partial; ai?: GoogleGenAITypes.GoogleGenAI; constructor(options: GeminiOptions); init(): Promise; isAvailable(): boolean; isLiveAvailable(): false | typeof GoogleGenAITypes.Modality | undefined; startLiveSession(params?: GoogleGenAITypes.LiveConnectConfig, model?: string): Promise; stopLiveSession(): Promise; setLiveCallbacks(callbacks: GoogleGenAITypes.LiveCallbacks): void; sendToolResponse(response: GoogleGenAITypes.LiveSendToolResponseParameters): void; sendRealtimeInput(input: GoogleGenAITypes.LiveSendRealtimeInputParameters): void; getLiveSessionStatus(): { isActive: boolean; hasSession: boolean; isAvailable: boolean | typeof GoogleGenAITypes.Modality | undefined; }; query(input: GeminiQueryInput | { prompt: string; }): Promise; protected queryOnce(input: GeminiQueryInput | { prompt: string; }): Promise; protected queryWithExponentialFalloff(input: GeminiQueryInput | { prompt: string; }): Promise; generate(prompt: string | string[], type?: 'image', systemInstruction?: string, model?: string): Promise; hasApiKey(): Promise; } declare class OpenAI extends BaseAIModel { protected options: OpenAIOptions; openai?: OpenAIType; constructor(options: OpenAIOptions); init(): Promise; isAvailable(): boolean; query(input: { prompt: string; }, _tools?: never[]): Promise<{ text: string; } | null>; generate(): Promise; } type ModelClass = Gemini | OpenAI; type ModelOptions = GeminiOptions | OpenAIOptions; type KeysJson = { gemini?: { apiKey?: string; }; openai?: { apiKey?: string; }; }; /** * AI Interface to wrap different AI models (primarily Gemini) * Handles both traditional query-based AI interactions and real-time live * sessions * * Features: * - Text and multimodal queries * - Real-time audio/video AI sessions (Gemini Live) * - Advanced API key management with multiple sources * - Session locking to prevent concurrent operations * * The URL param and key.json shortcut is only for demonstration and prototyping * practice and we strongly suggest not using it for production or deployment * purposes. One should set up a proper server to converse with AI servers in * deployment. * * API Key Management Features: * * 1. Multiple Key Sources (Priority Order): * - Model option * - Generic and model-specific URL parameters * - Current-page memory * - keys.json file * 2. keys.json Support: * - Structure: \{"gemini": \{"apiKey": "YOUR_KEY_HERE"\}\} * - Automatically loads if present */ declare class AI extends Script { static dependencies: { aiOptions: typeof AIOptions; }; editorIcon: string; model?: ModelClass; lock: boolean; options: AIOptions; keysCache?: KeysJson; /** * Load API keys from keys.json file if available * Parsed keys object or null if not found */ loadKeysFromFile(): Promise; init({ aiOptions }: { aiOptions: AIOptions; }): Promise; initializeModel(ModelClass: typeof Gemini | typeof OpenAI, modelOptions: ModelOptions): Promise; resolveApiKey(modelOptions: ModelOptions): Promise; private resolveApiKeyWithSource; private getUrlApiKey; isValidApiKey(key: string): boolean | ""; isAvailable(): boolean | undefined; query(input: GeminiQueryInput | { prompt: string; }, tools?: never[]): Promise; startLiveSession(config?: GoogleGenAITypes.LiveConnectConfig, model?: string): Promise; stopLiveSession(): Promise; setLiveCallbacks(callbacks: GoogleGenAITypes.LiveCallbacks): Promise; sendToolResponse(response: GoogleGenAITypes.LiveSendToolResponseParameters): void; sendRealtimeInput(input: GoogleGenAITypes.LiveSendRealtimeInputParameters): false | void; getLiveSessionStatus(): { isActive: boolean; hasSession: boolean; isAvailable: boolean | typeof GoogleGenAITypes.Modality | undefined; }; isLiveAvailable(): false | typeof GoogleGenAITypes.Modality | undefined; generate(prompt: string | string[], type?: 'image', systemInstruction?: string, model?: undefined): Promise; /** * Create a sample keys.json file structure for reference * @returns Sample keys.json structure */ static createSampleKeysStructure(): { gemini: { apiKey: string; }; openai: { apiKey: string; }; }; /** * Check if the current model has an API key available from any source * @returns True if API key is available */ hasApiKey(): Promise; } interface MemoryEntry { role: 'user' | 'ai' | 'tool'; content: string; } /** * Manages the agent's memory, including short-term, long-term, and working * memory. */ declare class Memory { private shortTermMemory; /** * Adds a new entry to the short-term memory. * @param entry - The memory entry to add. */ addShortTerm(entry: MemoryEntry): void; /** * Retrieves the short-term memory. * @returns An array of all short-term memory entries. */ getShortTerm(): MemoryEntry[]; /** * Clears all memory components. */ clear(): void; } /** * Builds the context to be sent to the AI for reasoning. */ declare class Context$1 { private instructions; constructor(instructions?: string); get instruction(): string; /** * Constructs a formatted prompt from memory and available tools. * @param memory - The agent's memory. * @param tools - The list of available tools. * @returns A string representing the full context for the AI. */ build(memory: Memory, tools: Tool[]): string; private formatEntry; } /** * Lifecycle callbacks for agent events. */ interface AgentLifecycleCallbacks { /** Called when a session starts */ onSessionStart?: () => void | Promise; /** Called when a session ends */ onSessionEnd?: () => void | Promise; /** Called after a tool is executed */ onToolExecuted?: (toolName: string, result: unknown) => void; /** Called when an error occurs */ onError?: (error: Error) => void; } /** * An agent that can use an AI to reason and execute tools. */ declare class Agent { static dependencies: {}; ai: AI; tools: Tool[]; memory: Memory; contextBuilder: Context$1; lifecycleCallbacks?: AgentLifecycleCallbacks; isSessionActive: boolean; constructor(ai: AI, tools?: Tool[], instruction?: string, callbacks?: AgentLifecycleCallbacks); /** * Starts the agent's reasoning loop with an initial prompt. * @param prompt - The initial prompt from the user. * @returns The final text response from the agent. */ start(prompt: string): Promise; /** * The main reasoning and action loop of the agent for non-live mode. * It repeatedly builds context, queries the AI, and executes tools * until a final text response is generated. */ private run; findTool(name: string): Tool | undefined; /** * Get the current session state. * @returns Object containing session information */ getSessionState(): { isActive: boolean; toolCount: number; memorySize: number; }; } declare class Registry { private instances; /** * Registers an new instanceof a given type. * If an existing instance of the same type is already registered, it will be * overwritten. * @param instance - The instance to register. * @param type - Type to register the instance as. Will default to * `instance.constructor` if not defined. */ register(instance: T, type?: Constructor): void; /** * Gets an existing instance of a registered type. * @param type - The constructor function of the type to retrieve. * @returns The instance of the requested type. */ get(type: Constructor): T | undefined; /** * Gets an existing instance of a registered type, or creates a new one if it * doesn't exist. * @param type - The constructor function of the type to retrieve. * @param factory - A function that creates a new instance of the type if it * doesn't already exist. * @returns The instance of the requested type. */ getOrCreate(type: Constructor, factory: () => T): T; /** * Unregisters an instance of a given type. * @param type - The type to unregister. */ unregister(type: Constructor): void; } interface AudioListenerOptions { sampleRate?: number; channelCount?: number; echoCancellation?: boolean; noiseSuppression?: boolean; autoGainControl?: boolean; } declare class AudioListener extends Script { static dependencies: { registry: typeof Registry; }; private options; private audioStream?; audioContext?: AudioContext; private sourceNode?; private processorNode?; private isCapturing; private latestAudioBuffer; private accumulatedChunks; private isAccumulating; private registry; aiService?: AI; private onAudioData?; private onError?; constructor(options?: AudioListenerOptions); /** * Init the AudioListener. */ init({ registry }: { registry: Registry; }): void; startCapture(callbacks?: { onAudioData?: (audioBuffer: ArrayBuffer) => void; onError?: (error: Error) => void; accumulate?: boolean; }): Promise; stopCapture(): void; setupAudioCapture(): Promise; private setupAudioWorklet; streamToAI(audioBuffer: ArrayBuffer): void; setAIStreaming(enabled: boolean): void; cleanup(): void; static isSupported(): boolean; getIsCapturing(): boolean; getLatestAudioBuffer(): ArrayBuffer | null; clearLatestAudioBuffer(): void; /** * Gets all accumulated audio chunks as a single combined buffer */ getAccumulatedBuffer(): ArrayBuffer | null; /** * Clears accumulated chunks */ clearAccumulatedBuffer(): void; /** * Gets the number of accumulated chunks */ getAccumulatedChunkCount(): number; dispose(): void; } declare enum VolumeCategory { music = "music", sfx = "sfx", speech = "speech", ui = "ui" } declare class CategoryVolumes { isMuted: boolean; masterVolume: number; volumes: Record; getCategoryVolume(category: string): number; getEffectiveVolume(category: string, specificVolume?: number): number; } interface AudioPlayerOptions { sampleRate?: number; channelCount?: number; category?: string; } declare class AudioPlayer extends Script { private options; private audioContext?; private audioQueue; private nextStartTime; private gainNode?; private categoryVolumes?; private volume; private category; scheduleAheadTime: number; constructor(options?: AudioPlayerOptions); /** * Sets the CategoryVolumes instance for this player to respect * master/category volumes */ setCategoryVolumes(categoryVolumes: CategoryVolumes): void; /** * Sets the specific volume for this player (0.0 to 1.0) */ setVolume(level: number): void; /** * Updates the gain node volume based on category volumes * Public so CoreSound can update it when master volume changes */ updateGainNodeVolume(): void; initializeAudioContext(): Promise; playAudioChunk(base64AudioData: string): Promise; private scheduleAudioBuffers; clearQueue(): void; getIsPlaying(): boolean; getQueueLength(): number; base64ToArrayBuffer(base64: string): ArrayBuffer; stop(): void; static isSupported(): boolean; dispose(): void; } declare const musicLibrary: { readonly ambient: string; readonly background: string; readonly buttonHover: string; readonly buttonPress: string; readonly menuDismiss: string; }; declare class BackgroundMusic extends Script { private listener; private categoryVolumes; private audioLoader; private currentAudio; private isPlaying; private musicLibrary; private specificVolume; private musicCategory; constructor(listener: THREE.AudioListener, categoryVolumes: CategoryVolumes); setVolume(level: number): void; playMusic(musicKey: keyof typeof musicLibrary, category?: string): void; stopMusic(): void; destroy(): void; } /** * Defines common UI sound presets with their default parameters. * Each preset specifies frequency, duration, and waveform type. */ declare const SOUND_PRESETS: { readonly BEEP: { readonly frequency: 1000; readonly duration: 0.07; readonly waveformType: "sine"; }; readonly CLICK: readonly [{ readonly frequency: 1500; readonly duration: 0.02; readonly waveformType: "triangle"; readonly delay: 0; }]; readonly ACTIVATE: readonly [{ readonly frequency: 800; readonly duration: 0.05; readonly waveformType: "sine"; readonly delay: 0; }, { readonly frequency: 1200; readonly duration: 0.07; readonly waveformType: "sine"; readonly delay: 50; }]; readonly DEACTIVATE: readonly [{ readonly frequency: 1200; readonly duration: 0.05; readonly waveformType: "sine"; readonly delay: 0; }, { readonly frequency: 800; readonly duration: 0.07; readonly waveformType: "sine"; readonly delay: 50; }]; }; declare class SoundSynthesizer extends Script { audioContext?: AudioContext; isInitialized: boolean; debug: boolean; /** * Initializes the AudioContext. */ private _initAudioContext; /** * Plays a single tone with specified parameters. * @param frequency - The frequency of the tone in Hz. * @param duration - The duration of the tone in seconds. * @param volume - The volume of the tone (0.0 to 1.0). * @param waveformType - The type of waveform ('sine', 'square', 'sawtooth', * 'triangle'). */ playTone(frequency: number, duration: number, volume: number, waveformType: OscillatorType): void; /** * Plays a predefined sound preset. * @param presetName - The name of the preset (e.g., 'BEEP', 'CLICK', * 'ACTIVATE', 'DEACTIVATE'). * @param volume - The volume for the preset (overrides default * if present, otherwise uses this). */ playPresetTone(presetName: keyof typeof SOUND_PRESETS, volume?: number): void; } declare const spatialSoundLibrary: { readonly ambient: "musicLibrary/AmbientLoop.opus"; readonly buttonHover: "musicLibrary/ButtonHover.opus"; readonly paintOneShot1: "musicLibrary/PaintOneShot1.opus"; }; interface PlaySoundOptions { loop?: boolean; volume?: number; refDistance?: number; rolloffFactor?: number; onEnded?: () => void; } declare class SpatialAudio extends Script { private listener; private categoryVolumes; private audioLoader; private soundLibrary; private activeSounds; private specificVolume; private category; private defaultRefDistance; private defaultRolloffFactor; constructor(listener: THREE.AudioListener, categoryVolumes: CategoryVolumes); /** * Plays a sound attached to a specific 3D object. * @param soundKey - Key from the soundLibrary. * @param targetObject - The object the sound should emanate * from. * @param options - Optional settings \{ loop: boolean, volume: * number, refDistance: number, rolloffFactor: number, onEnded: function * \}. * @returns A unique ID for the playing sound instance, or null * if failed. */ playSoundAtObject(soundKey: keyof typeof spatialSoundLibrary, targetObject: THREE.Object3D, options?: PlaySoundOptions): number | null; /** * Stops a specific sound instance by its ID. * @param soundId - The ID returned by playSoundAtObject. */ stopSound(soundId: number): void; /** * Internal method to remove sound from object and map. * @param soundId - id */ private _cleanupSound; /** * Sets the base specific volume for subsequently played spatial sounds. * Does NOT affect currently playing sounds (use updateAllVolumes for that). * @param level - Volume level (0.0 to 1.0). */ setVolume(level: number): void; /** * Updates the volume of all currently playing spatial sounds managed by this * instance. */ updateAllVolumes(): void; destroy(): void; } interface SpeechRecognizerEventMap extends THREE.Object3DEventMap { start: object; error: { error: string; }; end: object; result: { originalEvent: SpeechRecognitionEvent; transcript: string; confidence: number; command?: string; isFinal: boolean; }; } declare class SpeechRecognizer extends Script { private soundSynthesizer; static dependencies: { soundOptions: typeof SoundOptions; }; options: SpeechRecognizerOptions; recognition?: SpeechRecognition; isListening: boolean; lastTranscript: string; lastCommand?: string; lastConfidence: number; error?: string; playActivationSounds: boolean; constructor(soundSynthesizer: SoundSynthesizer); init({ soundOptions }: { soundOptions: SoundOptions; }): void; onSimulatorStarted(): void; start(): void; stop(): void; getLastTranscript(): string; getLastCommand(): string | undefined; getLastConfidence(): number; private _handleStart; private _handleResult; private _handleEnd; private _handleError; destroy(): void; } declare class SpeechSynthesizer extends Script { private categoryVolumes; private onStartCallback; private onEndCallback; private onErrorCallback; static dependencies: { soundOptions: typeof SoundOptions; }; private synth; private voices; private selectedVoice?; private isSpeaking; private debug; private specificVolume; private speechCategory; private options; /** * Optional callback invoked on each word boundary while speaking, with the * character index into the spoken text. Lets callers sync visuals (e.g. * gestures) to the actual spoken words. */ onBoundaryCallback?: (charIndex: number) => void; constructor(categoryVolumes: CategoryVolumes, onStartCallback?: () => void, onEndCallback?: () => void, onErrorCallback?: (_: Error) => void); init({ soundOptions }: { soundOptions: SoundOptions; }): void; loadVoices: () => void; setVolume(level: number): void; speak(text: string, lang?: string, pitch?: number, rate?: number): Promise; tts(text: string, lang?: string, pitch?: number, rate?: number): void; cancel(): void; destroy(): void; } declare class CoreSound extends Script { static dependencies: { camera: typeof THREE.Camera; soundOptions: typeof SoundOptions; }; type: string; name: string; categoryVolumes: CategoryVolumes; soundSynthesizer: SoundSynthesizer; listener: THREE.AudioListener; backgroundMusic: BackgroundMusic; spatialAudio: SpatialAudio; speechRecognizer?: SpeechRecognizer; speechSynthesizer?: SpeechSynthesizer; audioListener: AudioListener; audioPlayer: AudioPlayer; options: SoundOptions; init({ camera, soundOptions, }: { camera: THREE.Camera; soundOptions: SoundOptions; }): void; getAudioListener(): THREE.AudioListener; setMasterVolume(level: number): void; getMasterVolume(): number; setCategoryVolume(category: VolumeCategory, level: number): void; getCategoryVolume(category: VolumeCategory): number; enableAudio(options?: { streamToAI?: boolean; accumulate?: boolean; }): Promise; disableAudio(): void; /** * Starts recording audio with chunk accumulation */ startRecording(): Promise; /** * Stops recording and returns the accumulated audio buffer */ stopRecording(): ArrayBuffer | null; /** * Gets the accumulated recording buffer without stopping */ getRecordedBuffer(): ArrayBuffer | null; /** * Clears the accumulated recording buffer */ clearRecordedBuffer(): void; /** * Gets the sample rate being used for recording */ getRecordingSampleRate(): number; setAIStreaming(enabled: boolean): void; isAIStreamingEnabled(): boolean; playAIAudio(base64AudioData: string): Promise; stopAIAudio(): void; isAIAudioPlaying(): boolean; /** * Plays a raw audio buffer (Int16 PCM data) with proper sample rate */ playRecordedAudio(audioBuffer: ArrayBuffer, sampleRate?: number): Promise; isAudioEnabled(): boolean; getLatestAudioBuffer(): ArrayBuffer | null; clearLatestAudioBuffer(): void; getEffectiveVolume(category: VolumeCategory, specificVolume?: number): number; muteAll(): void; unmuteAll(): void; destroy(): void; } /** * State information for a live session. */ interface LiveSessionState { /** Whether the session is currently active */ isActive: boolean; /** Timestamp when session started */ startTime?: number; /** Timestamp when session ended */ endTime?: number; /** Number of messages received */ messageCount: number; /** Number of tool calls executed */ toolCallCount: number; /** Last error message if any */ lastError?: string; } /** * Skybox Agent for generating 360-degree equirectangular backgrounds through conversation. * * @example Basic usage * ```typescript * // 1. Enable audio (required for live sessions) * await xb.core.sound.enableAudio(); * * // 2. Create agent * const agent = new xb.SkyboxAgent(xb.core.ai, xb.core.sound, xb.core.scene); * * // 3. Start session * await agent.startLiveSession({ * onopen: () => console.log('Session ready'), * onmessage: (msg) => handleMessage(msg), * onclose: () => console.log('Session closed') * }); * * // 4. Clean up when done * await agent.stopLiveSession(); * xb.core.sound.disableAudio(); * ``` * * @example With lifecycle callbacks * ```typescript * const agent = new xb.SkyboxAgent( * xb.core.ai, * xb.core.sound, * xb.core.scene, * { * onSessionStart: () => updateUI('active'), * onSessionEnd: () => updateUI('inactive'), * onError: (error) => showError(error) * } * ); * ``` * * @remarks * - Audio must be enabled BEFORE starting live session using `xb.core.sound.enableAudio()` * - Users are responsible for managing audio lifecycle * - Always call `stopLiveSession()` before disabling audio * - Session state can be checked using `getSessionState()` and `getLiveSessionState()` */ declare class SkyboxAgent extends Agent { private sound; private sessionState; constructor(ai: AI, sound: CoreSound, scene: THREE.Scene, callbacks?: AgentLifecycleCallbacks); /** * Starts a live AI session for real-time conversation. * * @param callbacks - Optional callbacks for session events. Can also be set using ai.setLiveCallbacks() * @throws If AI model is not initialized or live session is not available * * @remarks * Audio must be enabled separately using `xb.core.sound.enableAudio()` before starting the session. * This gives users control over when microphone permissions are requested. */ startLiveSession(callbacks?: GoogleGenAITypes.LiveCallbacks): Promise; /** * Stops the live AI session. * * @remarks * Audio must be disabled separately using `xb.core.sound.disableAudio()` after stopping the session. */ stopLiveSession(): Promise; /** * Wraps user callbacks to track session state and trigger lifecycle events. * @param callbacks - The callbacks to wrap. * @returns The wrapped callbacks. */ private wrapCallbacks; /** * Sends tool execution results back to the AI. * * @param response - The tool response containing function results */ sendToolResponse(response: GoogleGenAITypes.LiveSendToolResponseParameters): Promise; /** * Validates that a tool response has the correct format. * @param response - The tool response to validate. * @returns True if the response is valid, false otherwise. */ private validateToolResponse; /** * Helper to create a properly formatted tool response from a ToolResult. * * @param id - The function call ID * @param name - The function name * @param result - The ToolResult from tool execution * @returns A properly formatted FunctionResponse */ static createToolResponse(id: string, name: string, result: ToolResult): GoogleGenAITypes.FunctionResponse; /** * Gets the current live session state. * * @returns Read-only session state information */ getLiveSessionState(): Readonly; /** * Gets the duration of the session in milliseconds. * * @returns Duration in ms, or null if session hasn't started */ getSessionDuration(): number | null; } interface GetWeatherArgs { latitude: number; longitude: number; } interface WeatherData { temperature: number; weathercode: number; } /** * A tool that gets the current weather for a specific location. */ declare class GetWeatherTool extends Tool { constructor(); /** * Executes the tool's action. * @param args - The arguments for the tool. * @returns A promise that resolves with a ToolResult containing weather information. */ execute(args: GetWeatherArgs): Promise>; } /** * A tool that generates a 360-degree equirectangular skybox image * based on a given prompt using an AI service. */ declare class GenerateSkyboxTool extends Tool { private ai; private scene; constructor(ai: AI, scene: THREE.Scene); /** * Executes the tool's action. * @param args - The prompt to use to generate the skybox. * @returns A promise that resolves with a ToolResult containing success/error information. */ execute(args: { prompt: string; }): Promise>; } /** * Enum for video stream states. */ declare enum StreamState { IDLE = "idle", INITIALIZING = "initializing", STREAMING = "streaming", ERROR = "error", NO_DEVICES_FOUND = "no_devices_found" } type VideoStreamDetails = { force?: boolean; error?: Error; }; interface VideoStreamEventMap extends THREE.Object3DEventMap { statechange: { state: StreamState; details?: T; }; } type VideoStreamGetSnapshotImageDataOptionsBase = { /** The target width, defaults to the video width. */ width?: number; /** The target height, defaults to the video height. */ height?: number; }; type VideoStreamGetSnapshotImageDataOptions = VideoStreamGetSnapshotImageDataOptionsBase & { outputFormat: 'imageData'; }; type VideoStreamGetSnapshotBase64Options = VideoStreamGetSnapshotImageDataOptionsBase & { outputFormat: 'base64'; mimeType?: string; quality?: number; }; type VideoStreamGetSnapshotBlobOptions = VideoStreamGetSnapshotImageDataOptionsBase & { outputFormat: 'blob'; mimeType?: string; quality?: number; }; type VideoStreamGetSnapshotTextureOptions = VideoStreamGetSnapshotImageDataOptionsBase & { outputFormat?: 'texture'; }; type VideoStreamGetSnapshotOptions = VideoStreamGetSnapshotImageDataOptions | VideoStreamGetSnapshotBase64Options | VideoStreamGetSnapshotTextureOptions | VideoStreamGetSnapshotBlobOptions; type VideoStreamOptions = { /** Hint for performance optimization for frequent captures. */ willCaptureFrequently?: boolean; }; /** * The base class for handling video streams (from camera or file), managing * the underlying