xrblocks 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +107 -22
- package/build/addons/ai/GeminiManager.d.ts +7 -4
- package/build/addons/ai/GeminiManager.js +43 -22
- package/build/agent/Agent.d.ts +25 -1
- package/build/agent/SkyboxAgent.d.ts +119 -3
- package/build/agent/Tool.d.ts +18 -4
- package/build/agent/index.d.ts +1 -0
- package/build/agent/tools/GenerateSkyboxTool.d.ts +3 -3
- package/build/agent/tools/GetWeatherTool.d.ts +7 -8
- package/build/ai/AI.d.ts +2 -2
- package/build/ai/Gemini.d.ts +5 -4
- package/build/core/Core.d.ts +1 -0
- package/build/core/Options.d.ts +10 -0
- package/build/core/components/ScreenshotSynthesizer.d.ts +4 -2
- package/build/depth/Depth.d.ts +5 -3
- package/build/depth/DepthMesh.d.ts +7 -0
- package/build/depth/DepthTextures.d.ts +6 -4
- package/build/depth/occlusion/OcclusionPass.d.ts +6 -5
- package/build/simulator/SimulatorOptions.d.ts +1 -0
- package/build/sound/AudioListener.d.ts +16 -1
- package/build/sound/AudioPlayer.d.ts +21 -2
- package/build/sound/CoreSound.d.ts +25 -0
- package/build/ui/components/IconButton.d.ts +6 -2
- package/build/ui/components/TextButton.d.ts +0 -1
- package/build/xrblocks.js +773 -151
- package/build/xrblocks.js.map +1 -1
- package/build/xrblocks.min.js +1 -1
- package/build/xrblocks.min.js.map +1 -1
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"xrblocks.min.js","sources":["../src/agent/Context.ts","../src/agent/Memory.ts","../src/agent/Agent.ts","../src/agent/Tool.ts","../src/agent/tools/GenerateSkyboxTool.ts","../src/agent/SkyboxAgent.ts","../src/agent/tools/GetWeatherTool.ts","../src/ux/UX.ts","../src/core/Script.ts","../src/utils/utils.ts","../src/ai/AIOptions.ts","../src/ai/BaseAIModel.ts","../src/ai/Gemini.ts","../src/ai/OpenAI.ts","../src/ai/AI.ts","../src/constants.ts","../src/utils/OptionsUtils.ts","../src/camera/CameraOptions.ts","../src/utils/BrowserUtils.ts","../src/depth/DepthMeshTexturedShader.ts","../src/depth/DepthMesh.ts","../src/depth/DepthOptions.ts","../src/depth/DepthTextures.ts","../src/depth/occlusion/kawaseblur.glsl.ts","../src/depth/occlusion/occlusion.glsl.ts","../src/depth/occlusion/occlusion_map.glsl.ts","../src/depth/occlusion/OcclusionMapMeshMaterial.ts","../src/depth/occlusion/OcclusionPass.ts","../src/depth/Depth.ts","../src/camera/CameraUtils.ts","../src/video/VideoStream.ts","../src/camera/XRDeviceCamera.ts","../src/core/components/Registry.ts","../src/core/components/ScreenshotSynthesizer.ts","../src/core/components/ScriptsManager.ts","../src/core/components/WaitFrame.ts","../src/core/components/WebXRSessionManager.ts","../src/core/components/XRButton.ts","../src/core/components/XREffects.ts","../src/input/components/HandJointNames.ts","../src/input/Hands.ts","../src/ui/shaders/ReticleShader.ts","../src/ui/core/Reticle.ts","../src/input/components/ControllerRayVisual.ts","../src/ui/interaction/AnimatableNumber.ts","../src/input/GazeController.ts","../src/input/MouseController.ts","../src/input/Input.ts","../src/lighting/Lighting.ts","../src/physics/Physics.ts","../src/input/HandsOptions.ts","../src/lighting/LightingOptions.ts","../src/physics/PhysicsOptions.ts","../src/simulator/SimulatorOptions.ts","../src/sound/SoundOptions.ts","../src/world/objects/ObjectsOptions.ts","../src/world/planes/PlanesOptions.ts","../src/world/WorldOptions.ts","../src/core/Options.ts","../src/simulator/SimulatorMediaDeviceInfo.ts","../src/simulator/utils/CameraUtils.ts","../src/simulator/SimulatorCamera.ts","../src/simulator/SimulatorConstants.ts","../src/utils/Keycodes.ts","../src/simulator/SimulatorControllerState.ts","../src/simulator/controlModes/SimulatorControlMode.ts","../src/simulator/controlModes/SimulatorControllerMode.ts","../src/simulator/controlModes/SimulatorPoseMode.ts","../src/simulator/controlModes/SimulatorUserMode.ts","../src/simulator/events/SimulatorModeEvents.ts","../src/simulator/SimulatorControls.ts","../src/simulator/SimulatorDepthMaterial.ts","../src/simulator/SimulatorDepth.ts","../src/simulator/events/SimulatorHandEvents.ts","../src/simulator/handPoses/HandPoses.ts","../src/simulator/handPoses/RelaxedHandPoses.ts","../src/simulator/handPoses/PinchingHandPoses.ts","../src/simulator/handPoses/FistHandPoses.ts","../src/simulator/handPoses/ThumbsUpPoses.ts","../src/simulator/handPoses/PointingHandPoses.ts","../src/simulator/handPoses/RockHandPoses.ts","../src/simulator/handPoses/ThumbsDownPoses.ts","../src/simulator/handPoses/VictoryHandPoses.ts","../src/simulator/SimulatorXRHand.ts","../src/simulator/SimulatorHands.ts","../src/simulator/SimulatorInterface.ts","../src/simulator/SimulatorScene.ts","../src/utils/DependencyInjection.ts","../src/simulator/SimulatorUser.ts","../src/simulator/Simulator.ts","../src/sound/AudioListener.ts","../src/sound/AudioPlayer.ts","../src/sound/BackgroundMusic.ts","../src/sound/CategoryVolumes.ts","../src/sound/SoundSynthesizer.ts","../src/sound/SpatialAudio.ts","../src/sound/SpeechRecognizer.ts","../src/sound/SpeechSynthesizer.ts","../src/sound/CoreSound.ts","../src/ui/constants.ts","../src/ui/core/View.ts","../src/ui/components/utils/FontFamilies.ts","../src/ui/components/TextView.ts","../src/ui/components/IconButton.ts","../src/ui/components/IconView.ts","../src/ui/components/ImageView.ts","../src/ui/components/LabelView.ts","../src/ui/shaders/SquircleShader.ts","../src/ui/components/TextButton.ts","../src/ui/components/VideoView.ts","../src/utils/SceneGraphUtils.ts","../src/core/User.ts","../src/utils/HelperConstants.ts","../src/ux/DragManager.ts","../src/ui/components/ExitButton.ts","../src/ui/layouts/Grid.ts","../src/ui/shaders/SpatialPanelShader.ts","../src/ui/core/PanelMesh.ts","../src/ui/core/Panel.ts","../src/ui/layouts/Col.ts","../src/ui/layouts/Orbiter.ts","../src/ui/layouts/Row.ts","../src/ui/layouts/SpatialPanel.ts","../src/ui/UI.ts","../src/utils/CreateLoadingSpinner.ts","../src/utils/LoadingSpinnerManager.ts","../src/utils/ObjectPlacement.ts","../src/world/objects/DetectedObject.ts","../src/world/objects/ObjectDetector.ts","../src/world/planes/DetectedPlane.ts","../src/world/planes/PlaneDetector.ts","../src/world/World.ts","../src/core/components/XRTransition.ts","../src/core/Core.ts","../src/depth/occlusion/OcclusionUtils.ts","../src/utils/RotationUtils.ts","../src/simulator/userActions/SimulatorUserAction.ts","../src/simulator/userActions/PinchOnButtonAction.ts","../src/simulator/userActions/ShowHandsAction.ts","../src/simulator/userActions/WalkTowardsPanelAction.ts","../src/singletons.ts","../src/stereo/utils.ts","../src/ui/components/MaterialSymbolsView.ts","../src/ui/layouts/TextScrollerState.ts","../src/ui/layouts/Page.ts","../src/ui/layouts/PagerState.ts","../src/ui/layouts/Pager.ts","../src/ui/layouts/VerticalPager.ts","../src/ui/components/ScrollingTroikaTextView.ts","../src/ui/interaction/FreestandingSlider.ts","../src/utils/ModelLoader.ts","../src/ui/interaction/ModelViewerPlatformCornerGeometry.ts","../src/ui/interaction/ModelViewerPlatformGeometry.ts","../src/ui/interaction/ModelViewerPlatform.ts","../src/ui/interaction/ModelViewer.ts","../src/utils/ModelUtils.ts","../src/ui/interaction/SketchPanel.ts","../src/ui/layouts/HorizontalPager.ts","../src/ui/layouts/PageIndicator.ts","../src/video/VideoFileStream.ts"],"sourcesContent":["import {Memory, MemoryEntry} from './Memory';\nimport {Tool} from './Tool';\n\n/**\n * Builds the context to be sent to the AI for reasoning.\n */\nexport class Context {\n private instructions: string;\n\n constructor(instructions = 'You are a helpful assistant.') {\n this.instructions = instructions;\n }\n\n get instruction(): string {\n return this.instructions;\n }\n\n /**\n * Constructs a formatted prompt from memory and available tools.\n * @param memory - The agent's memory.\n * @param tools - The list of available tools.\n * @returns A string representing the full context for the AI.\n */\n build(memory: Memory, tools: Tool[]): string {\n const history = memory.getShortTerm();\n const formattedHistory =\n history.map(entry => this.formatEntry(entry)).join('\\n');\n\n const toolDescriptions =\n tools.map(tool => `- ${tool.name}: ${tool.description}`).join('\\n');\n\n return `${this.instructions} You have access to the following tools: ${\n toolDescriptions}\n Current Conversation history: ${\n formattedHistory}. You should reply to the user or call a tool as needed.`;\n }\n\n private formatEntry(entry: MemoryEntry): string {\n switch (entry.role) {\n case 'user':\n return `User: ${entry.content}`;\n case 'ai':\n return `AI: ${entry.content}`;\n case 'tool':\n return `Tool Output: ${entry.content}`;\n }\n }\n}\n","export interface MemoryEntry {\n role: 'user'|'ai'|'tool';\n content: string;\n}\n\n/**\n * Manages the agent's memory, including short-term, long-term, and working\n * memory.\n */\nexport class Memory {\n private shortTermMemory: MemoryEntry[] = [];\n\n /**\n * Adds a new entry to the short-term memory.\n * @param entry - The memory entry to add.\n */\n addShortTerm(entry: MemoryEntry): void {\n this.shortTermMemory.push(entry);\n }\n\n /**\n * Retrieves the short-term memory.\n * @returns An array of all short-term memory entries.\n */\n getShortTerm(): MemoryEntry[] {\n return [...this.shortTermMemory];\n }\n\n /**\n * Clears all memory components.\n */\n clear(): void {\n this.shortTermMemory.length = 0;\n }\n}\n","import {AI} from '../ai/AI';\nimport {GeminiResponse} from '../ai/AITypes';\nimport {Gemini} from '../ai/Gemini';\n\nimport {Context} from './Context';\nimport {Memory} from './Memory';\nimport {Tool} from './Tool';\n\n/**\n * An agent that can use an AI to reason and execute tools.\n */\nexport class Agent {\n static dependencies = {};\n ai: AI;\n tools: Tool[];\n memory: Memory;\n contextBuilder: Context;\n\n constructor(ai: AI, tools: Tool[] = [], instruction: string = '') {\n this.ai = ai;\n this.tools = tools;\n this.memory = new Memory();\n this.contextBuilder = new Context(instruction);\n }\n\n /**\n * Starts the agent's reasoning loop with an initial prompt.\n * @param prompt - The initial prompt from the user.\n * @returns The final text response from the agent.\n */\n async start(prompt: string): Promise<string> {\n this.memory.addShortTerm({role: 'user', content: prompt});\n\n if (!this.ai.isAvailable()) {\n await this.ai.init({aiOptions: this.ai.options});\n }\n\n return this.run();\n }\n\n /**\n * The main reasoning and action loop of the agent for non-live mode.\n * It repeatedly builds context, queries the AI, and executes tools\n * until a final text response is generated.\n */\n private async run(): Promise<string> {\n while (true) {\n const context = this.contextBuilder.build(this.memory, this.tools);\n\n const response: GeminiResponse|null =\n await (this.ai.model as Gemini)\n .query({type: 'text', text: context}, this.tools);\n\n this.memory.addShortTerm({role: 'ai', content: JSON.stringify(response)});\n\n if (response?.toolCall) {\n console.log(`Executing tool: ${response.toolCall.name}`);\n const tool = this.findTool(response.toolCall.name);\n\n if (tool) {\n const result = await tool.execute(response.toolCall.args);\n this.memory.addShortTerm(\n {role: 'tool', content: JSON.stringify(result)});\n } else {\n const errorMsg = `Error: Tool \"${response.toolCall.name}\" not found.`;\n console.error(errorMsg);\n this.memory.addShortTerm({role: 'tool', content: errorMsg});\n }\n } else if (response?.text) {\n console.log(`Final Response: ${response.text}`);\n return response.text;\n } else {\n const finalResponse = 'The AI did not provide a valid response.';\n console.error(finalResponse);\n return finalResponse;\n }\n }\n }\n\n findTool(name: string): Tool|undefined {\n return this.tools.find(tool => tool.name === name);\n }\n}\n","import type * as GoogleGenAITypes from '@google/genai';\n\nexport interface ToolCall {\n name: string;\n args: unknown;\n}\n\n// Identical to GoogleGenAITypes.Schema but replaces the Type enum with actual\n// strings so tools don't need to import the types from @google/genai.\nexport type ToolSchema = Omit<GoogleGenAITypes.Schema, 'type'|'properties'>&{\n properties?: Record<string, ToolSchema>;\n type?: keyof typeof GoogleGenAITypes.Type;\n};\n\nexport type ToolOptions = {\n /** The name of the tool. */\n name: string;\n /** A description of what the tool does. */\n description: string;\n /** The parameters of the tool */\n parameters?: ToolSchema;\n /** A callback to execute when the tool is triggered */\n onTriggered?: (args: unknown) => unknown;\n};\n\n/**\n * A base class for tools that the agent can use.\n */\nexport class Tool {\n name: string;\n description?: string;\n parameters?: ToolSchema;\n onTriggered?: (args: unknown) => unknown;\n\n /**\n * @param options - The options for the tool.\n */\n constructor(options: ToolOptions) {\n this.name = options.name;\n this.description = options.description;\n this.parameters = options.parameters || {};\n this.onTriggered = options.onTriggered;\n }\n\n /**\n * Executes the tool's action.\n * @param args - The arguments for the tool.\n * @returns The result of the tool's action.\n */\n execute(args: unknown): unknown {\n if (this.onTriggered) {\n return this.onTriggered(args);\n }\n throw new Error(\n 'The execute method must be implemented by a subclass or onTriggered must be provided.');\n }\n\n /**\n * Returns a JSON representation of the tool.\n * @returns A valid FunctionDeclaration object.\n */\n toJSON(): GoogleGenAITypes.FunctionDeclaration {\n const result: GoogleGenAITypes.FunctionDeclaration = {name: this.name};\n if (this.description) {\n result.description = this.description;\n }\n if (this.parameters && this.parameters.required) {\n result.parameters = this.parameters as GoogleGenAITypes.Schema;\n }\n return result;\n }\n}\n","import * as THREE from 'three';\n\nimport {AI} from '../../ai/AI';\nimport {Tool} from '../Tool';\n\n/**\n * A tool that generates a 360-degree equirectangular skybox image\n * based on a given prompt using an AI service.\n */\nexport class GenerateSkyboxTool extends Tool {\n constructor(private ai: AI, private scene: THREE.Scene) {\n super({\n name: 'generateSkybox',\n description:\n 'Generate a 360 equirectangular skybox image for the given prompt.',\n parameters: {\n type: 'OBJECT',\n properties: {\n prompt: {\n type: 'STRING',\n description:\n 'A description of the skybox to generate, e.g. \"a sunny beach with palm trees\"',\n },\n },\n required: ['prompt'],\n },\n });\n }\n\n /**\n * Executes the tool's action.\n * @param args - The prompt to use to generate the skybox.\n * @returns A promise that resolves with the result of the skybox generation.\n */\n override async execute(args: {prompt: string}): Promise<string> {\n try {\n const image = await this.ai.generate(\n 'Generate a 360 equirectangular skybox image for the prompt of:' +\n args.prompt,\n 'image', 'Generate a 360 equirectangular skybox image for the prompt',\n 'gemini-2.5-flash-image-preview');\n if (image) {\n console.log('Applying texture...');\n this.scene.background = new THREE.TextureLoader().load(image);\n this.scene.background.mapping = THREE.EquirectangularReflectionMapping;\n return 'Skybox generated successfully.';\n } else {\n return 'Sorry, I had trouble creating that skybox.';\n }\n } catch (e) {\n console.error('error:', e);\n return 'Sorry, I encountered an error while creating the skybox.';\n }\n }\n}\n","import type * as GoogleGenAITypes from '@google/genai';\nimport * as THREE from 'three';\n\nimport {AI} from '../ai/AI';\nimport {CoreSound} from '../sound/CoreSound';\n\nimport {Agent} from './Agent';\nimport {GenerateSkyboxTool} from './tools/GenerateSkyboxTool';\n\nexport class SkyboxAgent extends Agent {\n constructor(ai: AI, private sound: CoreSound, scene: THREE.Scene) {\n super(\n ai, [new GenerateSkyboxTool(ai, scene)],\n `You are a friendly and helpful skybox designer. The response should be short. Your only capability\n is to generate a 360-degree equirectangular skybox image based on\n a user's description. You will generate a default skybox if the user\n does not provide any description. You will use the tool 'generateSkybox'\n with the summarized description as the 'prompt' argument to create the skybox.`);\n }\n\n async startLiveSession(callbacks: GoogleGenAITypes.LiveCallbacks) {\n this.ai.setLiveCallbacks(callbacks);\n const functionDeclarations: GoogleGenAITypes.FunctionDeclaration[] =\n this.tools.map(tool => tool.toJSON());\n const systemInstruction: GoogleGenAITypes.ContentUnion = {\n parts: [{text: this.contextBuilder.instruction}]\n };\n await this.ai.startLiveSession({\n tools: functionDeclarations,\n systemInstruction: systemInstruction,\n });\n\n this.sound.enableAudio();\n }\n\n async stopLiveSession() {\n await this.ai.stopLiveSession();\n this.sound.disableAudio();\n }\n\n async sendToolResponse(\n response: GoogleGenAITypes.LiveSendToolResponseParameters) {\n console.log('Sending tool response:', response);\n this.ai.sendToolResponse(response);\n }\n}\n","import {Tool} from '../Tool';\n\nexport interface GetWeatherArgs {\n latitude: number;\n longitude: number;\n}\n\nexport type GetWeatherToolResults = {\n error?: string;\n temperature?: number;\n weathercode?: number;\n};\n\n/**\n * A tool that gets the current weather for a specific location.\n */\nexport class GetWeatherTool extends Tool {\n constructor() {\n super({\n name: 'get_weather',\n description: 'Gets the current weather for a specific location.',\n parameters: {\n type: 'OBJECT',\n properties: {\n location: {\n type: 'STRING',\n description: 'The city and state, e.g. San Francisco, CA',\n },\n unit: {\n type: 'STRING',\n enum: ['celsius', 'fahrenheit'],\n },\n },\n required: ['location'],\n }\n });\n }\n\n /**\n * Executes the tool's action.\n * @param args - The arguments for the tool.\n * @returns A promise that resolves with the weather information.\n */\n override async execute(args: GetWeatherArgs): Promise<GetWeatherToolResults> {\n if (!args.latitude || !args.longitude) {\n args.latitude = 37.7749; // Default to San Francisco\n args.longitude = -122.4194;\n }\n const url = `https://api.open-meteo.com/v1/forecast?latitude=${\n args.latitude}&longitude=${\n args.longitude}¤t=weather_code,temperature_2m&temperature_unit=fahrenheit`;\n\n try {\n const response = await fetch(url);\n const data = await response.json();\n\n if (response.ok) {\n return {\n temperature: data.current.temperature_2m,\n weathercode: data.current.weather_code,\n };\n } else {\n return {\n error: 'Could not retrieve weather for the specified location.'\n };\n }\n } catch (error) {\n console.error('Error fetching weather:', error);\n return {\n error: 'There was an error fetching the weather.'\n };\n }\n }\n}\n","import * as THREE from 'three';\n\nimport {View} from '../ui/core/View';\n\n/**\n * UX manages the user experience (UX) state for an interactive object in\n * the scene. It tracks interaction states like hover,\n * selection, and dragging for multiple controllers.\n */\nexport class UX {\n /**\n * The object this UX state manager is attached to.\n */\n parent;\n\n /**\n * Indicates if the parent object can be dragged.\n */\n draggable = false;\n\n /**\n * Indicates if the parent object can be selected.\n */\n selectable = false;\n\n /**\n * Indicates if the parent object can be touched.\n */\n touchable = false;\n\n\n // --- Interaction States ---\n\n /**\n * An array tracking the selection state for each controller.\n * `selected[i]` is true if controller `i` is selecting the object.\n */\n selected: boolean[] = [];\n\n /**\n * An array tracking the hover state for each controller.\n * `hovered[i]` is true if controller `i` is hovering over the object.\n */\n hovered: boolean[] = [];\n\n /**\n * An array tracking the touch state for each controller.\n * `touched[i]` is true if controller `i` is touching over the object.\n */\n touched: boolean[] = [];\n\n /**\n * An array tracking the drag state for each controller.\n */\n activeDragged: boolean[] = [];\n\n\n // --- Intersection Data ---\n\n /**\n * An array storing the 3D position of the last intersection for each\n * controller.\n */\n positions: THREE.Vector3[] = [];\n\n /**\n * An array storing the distance of the last intersection for each controller.\n */\n distances: number[] = [];\n\n /**\n * An array storing the UV coordinates of the last intersection for each\n * controller.\n */\n uvs: THREE.Vector2[] = [];\n\n\n // --- Drag Management State ---\n\n /**\n * The initial position of the object when a drag operation begins.\n */\n initialPosition = new THREE.Vector3();\n\n /**\n * The initial distance from the controller to the object at the start of a\n * drag for computing the relative dragging distances and angles.\n */\n initialDistance?: number;\n\n /**\n * @param parent - The script or object that owns this UX instance.\n */\n constructor(parent: THREE.Object3D) {\n this.parent = parent;\n }\n\n /**\n * Checks if the object is currently being hovered by any controller.\n */\n isHovered() {\n return this.hovered.includes(true);\n }\n\n /**\n * Checks if the object is currently being selected by any controller.\n */\n isSelected() {\n return this.selected.includes(true);\n }\n\n /**\n * Checks if the object is currently being dragged by any controller.\n */\n isDragging() {\n return this.activeDragged.includes(true);\n }\n\n /**\n * Updates the interaction state for a specific controller based on a new\n * intersection. This is internally called by the core input system when a\n * raycast hits the parent object.\n * @param controller - The controller performing the\n * interaction.\n * @param intersection - The raycast intersection data.\n */\n update(controller: THREE.Object3D, intersection: THREE.Intersection) {\n const id = controller.userData.id;\n this.initializeVariablesForId(id);\n\n if (intersection.object === this.parent ||\n intersection.object === (this.parent as Partial<View>).mesh) {\n this.hovered[id] = true;\n this.selected[id] = controller.userData.selected;\n if (intersection.uv) {\n this.uvs[id].copy(intersection.uv);\n }\n this.positions[id].copy(intersection.point);\n this.distances[id] = intersection.distance;\n\n if (!this.selected[id]) {\n this.activeDragged[id] = false;\n }\n }\n }\n\n /**\n * Ensures that the internal arrays for tracking states are large enough to\n * accommodate a given controller ID.\n * @param id - The controller ID to ensure exists.\n */\n initializeVariablesForId(id: number) {\n while (this.selected.length <= id) {\n this.selected.push(false);\n this.hovered.push(false);\n this.activeDragged.push(false);\n this.positions.push(new THREE.Vector3());\n this.distances.push(1);\n this.uvs.push(new THREE.Vector2());\n }\n }\n\n /**\n * Resets the hover and selection states for all controllers. This is\n * typically called at the beginning of each frame.\n */\n reset() {\n for (const i in this.selected) {\n this.selected[i] = false;\n this.hovered[i] = false;\n }\n }\n\n\n /**\n * Gets the IDs of up to two controllers that are currently hovering over the\n * parent object, always returning a two-element array. This is useful for\n * shaders or components like Panels that expect a fixed number of interaction\n * points.\n *\n * @returns A fixed-size two-element array. Each element is either a\n * controller ID (e.g., 0, 1) or null.\n */\n getPrimaryTwoControllerIds() {\n const activeControllerIds = [];\n // this.hovered is an array of booleans, indexed by controller ID.\n if (this.hovered) {\n for (let i = 0; i < this.hovered.length && activeControllerIds.length < 2;\n ++i) {\n if (this.hovered[i]) {\n activeControllerIds.push(i);\n }\n }\n }\n\n // Ensures the returned array always has two elements.\n const controllerId1 = activeControllerIds[0] ?? null;\n const controllerId2 = activeControllerIds[1] ?? null;\n return [controllerId1, controllerId2];\n }\n}\n","import * as THREE from 'three';\n\nimport type {Controller} from '../input/Controller';\nimport type {Physics} from '../physics/Physics';\nimport type {Injectable} from '../utils/DependencyInjection';\nimport type {Constructor} from '../utils/Types';\nimport {UX} from '../ux/UX';\n\nexport interface SelectEvent {\n target: Controller;\n}\n\nexport interface ObjectTouchEvent {\n handIndex: number;\n touchPosition: THREE.Vector3;\n}\n\nexport interface ObjectGrabEvent {\n handIndex: number;\n hand: THREE.Object3D;\n}\n\nexport interface KeyEvent {\n code: string;\n}\n\n/**\n * The Script class facilities development by providing useful life cycle\n * functions similar to MonoBehaviors in Unity.\n *\n * Each Script object is an independent THREE.Object3D entity within the\n * scene graph.\n *\n * See /docs/manual/Scripts.md for the full documentation.\n *\n * It manages user, objects, and interaction between user and objects.\n * See `/templates/0_basic/` for an example to start with.\n *\n *\n * If the class does not extends View, it can still bind the above three\n * function, where the engine ignores whether reticle exists.\n *\n * # Supported (native WebXR) functions to extend:\n *\n * onSelectStart(event)\n * onSelectEnd(event)\n *\n */\nexport function ScriptMixin<TBase extends Constructor<THREE.Object3D>>(\n base: TBase) {\n return class extends base implements Injectable {\n ux = new UX(this);\n isXRScript = true;\n\n /**\n * Initializes an instance with XR controllers, grips, hands, raycaster, and\n * default options. We allow all scripts to quickly access its user (e.g.,\n * user.isSelecting(), user.hands), world (e.g., physical depth mesh,\n * lighting estimation, and recognized objects), and scene (the root of\n * three.js's scene graph). If this returns a promise, we will wait for it.\n */\n init(_?: object): void|Promise<void> {}\n\n /**\n * Runs per frame.\n */\n update(_time?: number, _frame?: XRFrame) {}\n\n /**\n * Enables depth-aware interactions with physics. See /demos/ballpit\n */\n initPhysics(_physics: Physics): void|Promise<void> {}\n physicsStep() {}\n\n onXRSessionStarted(_session?: XRSession) {}\n onXRSessionEnded() {}\n\n onSimulatorStarted() {}\n\n // Global controller callbacks.\n // See https://developer.mozilla.org/en-US/docs/Web/API/XRInputSourceEvent\n /**\n * Called whenever pinch / mouse click starts, globally.\n * @param _event - event.target holds its controller\n */\n onSelectStart(_event: SelectEvent) {}\n\n /**\n * Called whenever pinch / mouse click discontinues, globally.\n * @param _event - event.target holds its controller\n */\n onSelectEnd(_event: SelectEvent) {}\n\n /**\n * Called whenever pinch / mouse click successfully completes, globally.\n * @param _event - event.target holds its controller.\n */\n onSelect(_event: SelectEvent) {}\n\n /**\n * Called whenever pinch / mouse click is happening, globally.\n */\n onSelecting(_event: SelectEvent) {}\n\n /**\n * Called on keyboard keypress.\n * @param _event - Event containing `.code` to read the keyboard key.\n */\n onKeyDown(_event: KeyEvent) {}\n onKeyUp(_event: KeyEvent) {}\n\n /**\n * Called whenever gamepad trigger starts, globally.\n * @param _event - event.target holds its controller.\n */\n onSqueezeStart(_event: SelectEvent) {}\n /**\n * Called whenever gamepad trigger stops, globally.\n * @param _event - event.target holds its controller.\n */\n onSqueezeEnd(_event: SelectEvent) {}\n\n /**\n * Called whenever gamepad is being triggered, globally.\n */\n onSqueezing(_event: SelectEvent) {}\n\n /**\n * Called whenever gamepad trigger successfully completes, globally.\n * @param _event - event.target holds its controller.\n */\n onSqueeze(_event: SelectEvent) {}\n\n // Object-specific controller callbacks.\n /**\n * Called when the controller starts selecting this object the script\n * represents, e.g. View, ModelView.\n * @param _event - event.target holds its controller.\n * @returns Whether the event was handled\n */\n onObjectSelectStart(_event: SelectEvent) {\n return false;\n }\n /**\n * Called when the controller stops selecting this object the script\n * represents, e.g. View, ModelView.\n * @param _event - event.target holds its controller.\n * @returns Whether the event was handled\n */\n onObjectSelectEnd(_event: SelectEvent) {\n return false; // Whether the event was handled\n }\n /**\n * Called when the controller starts hovering over this object with reticle.\n * @param _controller - An XR controller.\n */\n onHoverEnter(_controller: THREE.Object3D) {}\n /**\n * Called when the controller hovers over this object with reticle.\n * @param _controller - An XR controller.\n */\n onHoverExit(_controller: THREE.Object3D) {}\n /**\n * Called when the controller hovers over this object with reticle.\n * @param _controller - An XR controller.\n */\n onHovering(_controller: THREE.Object3D) {}\n /**\n * Called when a hand's index finger starts touching this object.\n */\n onObjectTouchStart(_event: ObjectTouchEvent) {}\n /**\n * Called every frame that a hand's index finger is touching this object.\n */\n onObjectTouching(_event: ObjectTouchEvent) {}\n /**\n * Called when a hand's index finger stops touching this object.\n */\n onObjectTouchEnd(_event: ObjectTouchEvent) {}\n /**\n * Called when a hand starts grabbing this object (touching + pinching).\n */\n onObjectGrabStart(_event: ObjectGrabEvent) {}\n /**\n * Called every frame a hand is grabbing this object.\n */\n onObjectGrabbing(_event: ObjectGrabEvent) {}\n /**\n * Called when a hand stops grabbing this object.\n */\n onObjectGrabEnd(_event: ObjectGrabEvent) {}\n\n /**\n * Called when the script is removed from the scene. Opposite of init.\n */\n dispose() {}\n };\n}\n\n/**\n * Script manages app logic or interaction between user and objects.\n */\nconst ScriptMixinObject3D = ScriptMixin(THREE.Object3D);\nexport class Script<TEventMap extends THREE.Object3DEventMap =\n THREE.Object3DEventMap> extends\n ScriptMixinObject3D<TEventMap> {}\n\n\n/**\n * MeshScript can be constructed with geometry and materials, with\n * `super(geometry, material)`; for direct access to its geometry.\n * MeshScripts hold a UX object that contains its interaction information such\n * as which controller is selecting or touching this object, as well as the\n * exact selected UV / xyz of the reticle, or touched point.\n */\nconst ScriptMixinMeshScript = ScriptMixin(THREE.Mesh);\nexport class MeshScript<\n TGeometry extends THREE.BufferGeometry = THREE.BufferGeometry,\n TMaterial extends\n THREE.Material | THREE.Material[] = THREE.Material | THREE.Material[],\n TEventMap extends THREE.Object3DEventMap =\n THREE.Object3DEventMap> extends\n ScriptMixinMeshScript<TGeometry, TMaterial, TEventMap> {\n /**\n * {@inheritDoc}\n */\n constructor(geometry?: TGeometry, material?: TMaterial) {\n super(geometry, material);\n }\n}\n","import * as THREE from 'three';\n\n/**\n * Clamps a value between a minimum and maximum value.\n */\nexport function clamp(value: number, min: number, max: number) {\n return Math.min(Math.max(value, min), max);\n}\n\n/**\n * Linearly interpolates between two numbers `x` and `y` by a given amount `t`.\n */\nexport function lerp(x: number, y: number, t: number) {\n return x + (y - x) * t;\n}\n\n/**\n * Python-style print function for debugging.\n */\nexport function print(...args: unknown[]) {\n console.log('*', ...args);\n}\n\n// Parses URL parameters using the URLSearchParams API.\nexport const urlParams = new URLSearchParams(window.location.search);\n\n/**\n * Function to get the value of a URL parameter.\n * @param name - The name of the URL parameter.\n * @returns The value of the URL parameter or null if not found.\n */\nexport function getUrlParameter(name: string) {\n const urlParams = new URLSearchParams(window.location.search);\n return urlParams.get(name);\n}\n\n/**\n * Retrieves a boolean URL parameter. Returns true for 'true' or '1', false for\n * 'false' or '0'. If the parameter is not found, returns the specified default\n * boolean value.\n * @param name - The name of the URL parameter.\n * @param defaultBool - The default boolean value if the\n * parameter is not present.\n * @returns The boolean value of the URL parameter.\n */\nexport function getUrlParamBool(name: string, defaultBool = false) {\n const inputString = urlParams.get(name)?.toLowerCase();\n // Convert the parameter value to a boolean. Returns true for 'true' or '1'.\n if (inputString === 'true' || inputString === '1') {\n return true;\n }\n // Returns false for 'false' or '0'.\n if (inputString === 'false' || inputString === '0') {\n return false;\n }\n // If the parameter is not found, returns the default boolean value.\n return defaultBool;\n}\n\n/**\n * Retrieves an integer URL parameter. If the parameter is not found or is not a\n * valid number, returns the specified default integer value.\n * @param name - The name of the URL parameter.\n * @param defaultNumber - The default integer value if the\n * parameter is not present.\n * @returns The integer value of the URL parameter.\n */\nexport function getUrlParamInt(name: string, defaultNumber = 0) {\n const inputNumber = urlParams.get(name);\n if (inputNumber) {\n // Convert the parameter value to an integer. If valid, returns it.\n const num = parseInt(inputNumber, 10);\n if (!isNaN(num)) {\n return num;\n }\n }\n // If the parameter is not found or invalid, returns the default integer\n // value.\n return defaultNumber;\n}\n\n/**\n * Retrieves a float URL parameter. If the parameter is not found or is not a\n * valid number, returns the specified default float value.\n * @param name - The name of the URL parameter.\n * @param defaultNumber - The default float value if the parameter\n * is not present.\n * @returns The float value of the URL parameter.\n */\nexport function getUrlParamFloat(name: string, defaultNumber = 0) {\n const inputNumber = urlParams.get(name);\n if (inputNumber) {\n // Convert the parameter value to a float. If valid, returns it.\n const num = parseFloat(inputNumber);\n if (!isNaN(num)) {\n return num;\n }\n }\n // If the parameter is not found or invalid, returns the default float value.\n return defaultNumber;\n}\n\n/**\n * Parses a color string (hexadecimal with optional alpha) into a THREE.Vector4.\n * Supports:\n * - #rgb (shorthand, alpha defaults to 1)\n * - #rrggbb (alpha defaults to 1)\n * - #rgba (shorthand)\n * - #rrggbbaa\n *\n * @param colorString - The color string to parse (e.g., '#66ccff',\n * '#6cf5', '#66ccff55', '#6cf').\n * @returns The parsed color as a THREE.Vector4 (r, g, b, a), with components in\n * the 0-1 range.\n * @throws If the input is not a string or if the hex string is invalid.\n */\nexport function getVec4ByColorString(colorString: string) {\n if (typeof colorString !== 'string') {\n throw new Error('colorString must be a string');\n }\n\n // Remove the '#' if it exists.\n const hex = colorString.startsWith('#') ? colorString.slice(1) : colorString;\n const len = hex.length;\n let alpha = 1.0; // Default alpha to 1\n\n let expandedHex = hex;\n if (len === 3 || len === 4) {\n // Expand shorthand: rgb -> rrgbbaa or rgba -> rrggbbaa\n expandedHex = hex.split('').map((char) => char + char).join('');\n }\n\n if (expandedHex.length === 8) {\n alpha = parseInt(expandedHex.slice(6, 8), 16) / 255;\n expandedHex = expandedHex.slice(0, 6);\n } else if (expandedHex.length === 6) {\n // Alpha is already 1.0\n } else {\n throw new Error(`Invalid hex color string format: ${colorString}`);\n }\n\n const r = parseInt(expandedHex.slice(0, 2), 16) / 255;\n const g = parseInt(expandedHex.slice(2, 4), 16) / 255;\n const b = parseInt(expandedHex.slice(4, 6), 16) / 255;\n\n if (isNaN(r) || isNaN(g) || isNaN(b) || isNaN(alpha)) {\n throw new Error(`Invalid hex values in color string: ${colorString}`);\n }\n\n return new THREE.Vector4(r, g, b, alpha);\n}\n\nexport function getColorHex(fontColor: string|number) {\n if (typeof fontColor === 'string') {\n const vec4 = getVec4ByColorString(fontColor);\n const r = Math.round(vec4.x * 255);\n const g = Math.round(vec4.y * 255);\n const b = Math.round(vec4.z * 255);\n return (r << 16) + (g << 8) + b;\n } else if (typeof fontColor === 'number') {\n return fontColor;\n } else {\n // Default to white if fontColor is invalid.\n return 0xffffff;\n }\n}\n\n/**\n * Parses a data URL (e.g., \"data:image/png;base64,...\") into its\n * stripped base64 string and MIME type.\n * This function handles common image MIME types.\n * @param dataURL - The data URL string.\n * @returns An object containing the stripped base64 string and the extracted\n * MIME type.\n */\nexport function parseBase64DataURL(dataURL: string) {\n const mimeTypeRegex = /^data:(image\\/[a-zA-Z0-9\\-+.]+);base64,/;\n const match = dataURL.match(mimeTypeRegex);\n\n if (match) {\n const mimeType = match[1];\n const strippedBase64 = dataURL.substring(match[0].length);\n return {strippedBase64, mimeType};\n } else {\n return {strippedBase64: dataURL, mimeType: null};\n }\n}\n","export interface GeminiLiveOptions {\n enabled?: boolean;\n model?: string;\n startOfSpeechSensitivity?: 'LOW'|'HIGH';\n endOfSpeechSensitivity?: 'LOW'|'HIGH';\n voiceName?: string;\n screenshotInterval?: number;\n audioConfig?: {\n sampleRate?: number;\n channelCount?: number;\n echoCancellation?: boolean;\n noiseSuppression?: boolean;\n autoGainControl?: boolean;\n };\n}\n\nexport class GeminiOptions {\n apiKey = '';\n urlParam = 'geminiKey';\n keyValid = false;\n enabled = false;\n model = 'gemini-2.0-flash';\n config = {};\n live: GeminiLiveOptions = {\n enabled: false,\n model: 'gemini-live-2.5-flash-preview',\n voiceName: 'Aoede',\n screenshotInterval: 3000,\n audioConfig: {\n sampleRate: 16000,\n channelCount: 1,\n echoCancellation: true,\n noiseSuppression: true,\n autoGainControl: true\n }\n };\n}\n\nexport class OpenAIOptions {\n apiKey = '';\n urlParam = 'openaiKey';\n model = 'gpt-4.1';\n enabled = false;\n}\n\nexport type AIModel = 'gemini'|'openai';\n\nexport class AIOptions {\n enabled = false;\n model: AIModel = 'gemini';\n gemini = new GeminiOptions();\n openai = new OpenAIOptions();\n globalUrlParams = {\n key: 'key', // Generic key parameter\n }\n}\n","import {GeminiResponse} from './AITypes';\n\nexport abstract class BaseAIModel {\n constructor() {}\n\n abstract init(): Promise<void>;\n\n abstract isAvailable(): boolean;\n\n abstract query(_input: object, _tools: []):\n Promise<GeminiResponse|string|null>;\n}\n","import * as GoogleGenAITypes from '@google/genai';\n\nimport type {Tool} from '../agent/Tool';\n\nimport {GeminiOptions} from './AIOptions';\nimport {GeminiResponse} from './AITypes';\nimport {BaseAIModel} from './BaseAIModel';\n\nlet createPartFromUri:\n ((uri: string, mimeType: string) => GoogleGenAITypes.Part);\nlet createUserContent: (\n (partOrString: GoogleGenAITypes.PartListUnion) => GoogleGenAITypes.Content)|\n undefined;\nlet GoogleGenAI: typeof GoogleGenAITypes.GoogleGenAI|undefined;\nlet EndSensitivity: typeof GoogleGenAITypes.EndSensitivity|undefined;\nlet StartSensitivity: typeof GoogleGenAITypes.StartSensitivity|undefined;\nlet Modality: typeof GoogleGenAITypes.Modality|undefined;\n\n// --- Attempt Dynamic Import ---\nasync function loadGoogleGenAIModule() {\n if (GoogleGenAI) {\n return;\n }\n try {\n const genAIModule = await import('@google/genai');\n if (genAIModule && genAIModule.GoogleGenAI) {\n createPartFromUri = genAIModule.createPartFromUri;\n createUserContent = genAIModule.createUserContent;\n GoogleGenAI = genAIModule.GoogleGenAI;\n EndSensitivity = genAIModule.EndSensitivity;\n StartSensitivity = genAIModule.StartSensitivity;\n Modality = genAIModule.Modality;\n console.log('\\'@google/genai\\' module loaded successfully.');\n } else {\n throw new Error('\\'@google/genai\\' module loaded but is not valid.');\n }\n } catch (error) {\n const errorMessage =\n `The '@google/genai' module is required for Gemini but failed to load. Error: ${\n error}`;\n console.error(errorMessage);\n throw new Error(errorMessage);\n }\n}\n\nexport interface GeminiQueryInput {\n type: 'live'|'text'|'uri'|'base64'|'multiPart';\n action?: 'start'|'stop'|'send';\n text?: string;\n uri?: string;\n base64?: string;\n mimeType?: string;\n parts?: GoogleGenAITypes.Part[];\n config?: GoogleGenAITypes.LiveConnectConfig;\n data?: GoogleGenAITypes.LiveSendRealtimeInputParameters;\n}\n\nexport class Gemini extends BaseAIModel {\n inited = false;\n liveSession?: GoogleGenAITypes.Session;\n isLiveMode = false;\n liveCallbacks: Partial<GoogleGenAITypes.LiveCallbacks> = {};\n ai?: GoogleGenAITypes.GoogleGenAI;\n\n constructor(protected options: GeminiOptions) {\n super();\n }\n\n async init() {\n await loadGoogleGenAIModule();\n }\n\n isAvailable() {\n if (!GoogleGenAI) {\n return false;\n }\n if (!this.inited) {\n this.ai = new GoogleGenAI({apiKey: this.options.apiKey});\n this.inited = true;\n }\n return true;\n }\n\n isLiveAvailable() {\n return this.isAvailable() && EndSensitivity && StartSensitivity && Modality;\n }\n\n async startLiveSession(params: {\n tools?: GoogleGenAITypes.FunctionDeclaration[];\n systemInstruction?: GoogleGenAITypes.ContentUnion | string;\n } = {}) {\n if (!this.isLiveAvailable()) {\n throw new Error(\n 'Live API not available. Make sure @google/genai module is loaded.');\n }\n\n if (this.liveSession) {\n return this.liveSession;\n }\n\n const defaultConfig: GoogleGenAITypes.LiveConnectConfig = {\n responseModalities: [Modality!.AUDIO],\n speechConfig: {\n voiceConfig: {prebuiltVoiceConfig: {voiceName: 'Aoede'}},\n },\n outputAudioTranscription: {},\n inputAudioTranscription: {}\n };\n\n if (params.tools && params.tools.length > 0) {\n defaultConfig.tools = [{functionDeclarations: params.tools}];\n }\n if (params.systemInstruction) {\n if (typeof params.systemInstruction === 'string') {\n defaultConfig.systemInstruction =\n createUserContent!(params.systemInstruction);\n } else {\n defaultConfig.systemInstruction = params.systemInstruction;\n }\n }\n\n const callbacks: GoogleGenAITypes.LiveCallbacks = {\n onopen: () => {\n this.isLiveMode = true;\n console.log('🔓 Live session opened.');\n if (this.liveCallbacks?.onopen) {\n this.liveCallbacks.onopen();\n }\n },\n onmessage: (e: GoogleGenAITypes.LiveServerMessage) => {\n if (this.liveCallbacks?.onmessage) {\n this.liveCallbacks.onmessage(e);\n }\n },\n onerror: (e: ErrorEvent) => {\n console.error('❌ Live session error:', e);\n if (this.liveCallbacks?.onerror) {\n this.liveCallbacks.onerror(e);\n }\n },\n onclose: (event: CloseEvent) => {\n this.isLiveMode = false;\n this.liveSession = undefined;\n if (event.reason) {\n console.warn('🔒 Live session closed:', event);\n } else {\n console.warn('🔒 Live session closed without reason.');\n }\n if (this.liveCallbacks?.onclose) {\n this.liveCallbacks.onclose(event);\n }\n },\n };\n try {\n const connectParams: GoogleGenAITypes.LiveConnectParameters = {\n model: 'gemini-2.5-flash-preview-native-audio-dialog',\n callbacks: callbacks,\n config: defaultConfig,\n };\n console.log('Connecting with params:', connectParams);\n this.liveSession = await this.ai!.live.connect(connectParams);\n return this.liveSession;\n } catch (error) {\n console.error('❌ Failed to start live session:', error);\n throw error;\n }\n }\n\n async stopLiveSession() {\n if (!this.liveSession) {\n return;\n }\n this.liveSession.close();\n this.liveSession = undefined;\n this.isLiveMode = false;\n }\n\n // Set Live session callbacks\n setLiveCallbacks(callbacks: GoogleGenAITypes.LiveCallbacks) {\n this.liveCallbacks = callbacks;\n }\n\n sendToolResponse(response: GoogleGenAITypes.LiveSendToolResponseParameters) {\n if (this.liveSession) {\n console.log('Sending tool response from gemini:', response);\n this.liveSession.sendToolResponse(response);\n }\n }\n\n sendRealtimeInput(input: GoogleGenAITypes.LiveSendRealtimeInputParameters) {\n if (!this.liveSession) {\n return;\n }\n\n try {\n this.liveSession.sendRealtimeInput(input);\n } catch (error) {\n console.error('❌ Error sending realtime input:', error);\n throw error;\n }\n }\n\n getLiveSessionStatus() {\n return {\n isActive: this.isLiveMode,\n hasSession: !!this.liveSession,\n isAvailable: this.isLiveAvailable()\n };\n }\n\n async query(input: GeminiQueryInput|{prompt: string}, _tools: Tool[] = []):\n Promise<GeminiResponse|null> {\n if (!this.inited) {\n console.warn('Gemini not inited.');\n return null;\n }\n\n const options = this.options;\n const config = options.config || {};\n\n if (!('type' in input)) {\n const response = await this.ai!.models.generateContent(\n {model: options.model, contents: input.prompt!, config: config});\n return {text: response.text || null};\n }\n\n const model = this.ai!.models;\n const modelParams: GoogleGenAITypes.GenerateContentParameters = {\n model: this.options.model,\n contents: [],\n config: this.options.config || {},\n };\n\n let response = null;\n switch (input.type) {\n case 'text':\n modelParams.contents = input.text!;\n response = await model.generateContent(modelParams);\n break;\n\n case 'base64':\n if (!input.mimeType) {\n input.mimeType = 'image/png';\n }\n modelParams.contents = {\n inlineData: {\n mimeType: input.mimeType,\n data: input.base64,\n },\n };\n response = await model.generateContent(modelParams);\n break;\n\n case 'uri':\n modelParams.contents = createUserContent!([\n createPartFromUri(input.uri!, input.mimeType!),\n input.text!,\n ]);\n response = await model.generateContent(modelParams);\n break;\n\n case 'multiPart':\n modelParams.contents = [{role: 'user', parts: input.parts}];\n response = await model.generateContent(modelParams);\n break;\n }\n\n if (!response) {\n return {text: null};\n }\n\n const toolCall = response.functionCalls?.[0];\n if (toolCall && toolCall.name) {\n return {toolCall: {name: toolCall.name, args: toolCall.args}};\n }\n return {text: response.text || null};\n }\n\n async generate(\n prompt: string|string[], type: 'image' = 'image',\n systemInstruction = 'Generate an image',\n model = 'gemini-2.5-flash-image-preview') {\n if (!this.isAvailable()) return;\n\n let contents: GoogleGenAITypes.ContentListUnion;\n\n if (Array.isArray(prompt)) {\n contents = prompt.map(item => {\n if (typeof item === 'string') {\n if (item.startsWith('data:image/')) {\n const [header, data] = item.split(',');\n const mimeType = header.split(';')[0].split(':')[1];\n return {inlineData: {mimeType, data}};\n } else {\n return {text: item};\n }\n }\n // Assumes other items are already valid Part objects\n return item;\n });\n } else {\n contents = prompt;\n }\n\n const response = await this.ai!.models.generateContent(\n {model: model, contents: contents, config: {systemInstruction}});\n if (response.candidates && response.candidates.length > 0) {\n const firstCandidate = response.candidates[0];\n for (const part of firstCandidate?.content?.parts || []) {\n if (type === 'image' && part.inlineData) {\n return 'data:image/png;base64,' + part.inlineData.data;\n }\n }\n }\n }\n};\n","import type OpenAIType from 'openai';\n\nimport {OpenAIOptions} from './AIOptions';\nimport {BaseAIModel} from './BaseAIModel';\n\nlet OpenAIApi: typeof OpenAIType|null = null;\n\nasync function loadOpenAIModule() {\n if (OpenAIApi) {\n return;\n }\n try {\n const openAIModule = await import('openai');\n OpenAIApi = openAIModule.default;\n console.log('\\'openai\\' module loaded successfully.');\n } catch (error) {\n console.warn(\n '\\'openai\\' module not found. Using fallback implementations.',\n 'Error details:', error);\n }\n}\n\nexport class OpenAI extends BaseAIModel {\n openai?: OpenAIType;\n\n constructor(protected options: OpenAIOptions) {\n super();\n }\n\n async init() {\n await loadOpenAIModule();\n if (this.options.apiKey && OpenAIApi) {\n this.openai = new OpenAIApi(\n {apiKey: this.options.apiKey, dangerouslyAllowBrowser: true});\n console.log('OpenAI model initialized');\n } else {\n console.error('OpenAI API key is missing or module failed to load.');\n }\n }\n\n isAvailable() {\n return !!this.openai;\n }\n\n async query(input: {prompt: string}, _tools?: never[]) {\n if (!this.isAvailable()) {\n throw new Error('OpenAI model is not initialized.');\n }\n\n try {\n const completion = await this.openai!.chat.completions.create({\n messages: [{role: 'user', content: input.prompt}],\n model: this.options.model,\n });\n const content = completion.choices[0].message.content;\n if (content) {\n return {text: content};\n }\n return null;\n } catch (error) {\n console.error('Error querying OpenAI:', error);\n throw error;\n }\n }\n\n async generate() {\n throw new Error('Wrapper not implemented');\n }\n}\n","import type * as GoogleGenAITypes from '@google/genai';\n\nimport {Script} from '../core/Script';\nimport {getUrlParameter} from '../utils/utils';\n\nimport {AIOptions, GeminiOptions, OpenAIOptions} from './AIOptions';\nimport {GeminiResponse} from './AITypes';\nimport {Gemini} from './Gemini';\nimport {OpenAI} from './OpenAI';\n\nexport type ModelClass = Gemini|OpenAI;\nexport type ModelOptions = GeminiOptions|OpenAIOptions;\n\nexport type KeysJson = {\n [key: string]:\n string|{\n apiKey?: string;\n }\n};\n\nconst SUPPORTED_MODELS = {\n gemini: Gemini,\n openai: OpenAI,\n} as const;\n\n/**\n * AI Interface to wrap different AI models (primarily Gemini)\n * Handles both traditional query-based AI interactions and real-time live\n * sessions\n *\n * Features:\n * - Text and multimodal queries\n * - Real-time audio/video AI sessions (Gemini Live)\n * - Advanced API key management with multiple sources\n * - Session locking to prevent concurrent operations\n *\n * The URL param and key.json shortcut is only for demonstration and prototyping\n * practice and we strongly suggest not using it for production or deployment\n * purposes. One should set up a proper server to converse with AI servers in\n * deployment.\n *\n * API Key Management Features:\n *\n * 1. Multiple Key Sources (Priority Order):\n * - URL Parameter: ?key=\\<api_key\\>\n * - keys.json file: Local configuration file\n * - User Prompt: Interactive fallback\n * 2. keys.json Support:\n * - Structure: \\{\"gemini\": \\{\"apiKey\": \"YOUR_KEY_HERE\"\\}\\}\n * - Automatically loads if present\n */\nexport class AI extends Script {\n static dependencies = {aiOptions: AIOptions};\n\n model?: ModelClass;\n lock = false;\n options!: AIOptions;\n keysCache?: KeysJson; // Cache for loaded keys.json\n\n /**\n * Load API keys from keys.json file if available\n * Parsed keys object or null if not found\n */\n async loadKeysFromFile(): Promise<KeysJson|null> {\n if (this.keysCache) return this.keysCache;\n\n try {\n const response = await fetch('./keys.json');\n if (response.ok) {\n this.keysCache = await response.json() as KeysJson;\n console.log('🔑 Loaded keys.json');\n return this.keysCache;\n }\n } catch {\n // Silent fail - keys.json is optional\n }\n return null;\n }\n\n async init({aiOptions}: {aiOptions: AIOptions}) {\n this.lock = false;\n this.options = aiOptions;\n\n if (!aiOptions.enabled) {\n console.log('AI is disabled in options');\n return;\n }\n\n const modelName = aiOptions.model;\n const ModelClass = SUPPORTED_MODELS[modelName];\n\n if (ModelClass) {\n const modelOptions = aiOptions[modelName];\n if (modelOptions && modelOptions.enabled) {\n await this.initializeModel(ModelClass, modelOptions);\n } else {\n console.log(`${modelName} is disabled in AI options`);\n }\n } else {\n console.error(`Unsupported AI model: ${modelName}`);\n }\n }\n\n async initializeModel(\n ModelClass: typeof Gemini|typeof OpenAI, modelOptions: ModelOptions) {\n const apiKey = await this.resolveApiKey(modelOptions);\n if (!apiKey || !this.isValidApiKey(apiKey)) {\n console.error(`No valid API key found for ${this.options.model}`);\n return;\n }\n modelOptions.apiKey = apiKey;\n this.model = new ModelClass(modelOptions as GeminiOptions & OpenAIOptions);\n try {\n await this.model.init();\n console.log(`${this.options.model} initialized`);\n } catch (error) {\n console.error(`Failed to initialize ${this.options.model}:`, error);\n this.model = undefined;\n }\n }\n\n async resolveApiKey(modelOptions: ModelOptions): Promise<string|null> {\n const modelName = this.options.model;\n\n // 1. Check options\n if (modelOptions.apiKey) {\n return modelOptions.apiKey;\n }\n\n // 2. Check URL parameters for 'key'\n const genericKey = getUrlParameter('key');\n if (genericKey) {\n return genericKey;\n }\n\n // 3. Check URL parameters for model-specific key\n const modelKey = getUrlParameter(modelOptions.urlParam);\n if (modelKey) return modelKey;\n\n // Temporary fallback to geminiKey64 for teamfood.\n const geminiKey64 = getUrlParameter('geminiKey64');\n if (geminiKey64) {\n return window.atob(geminiKey64);\n }\n\n // 3. Check keys.json file\n const keysFromFile = await this.loadKeysFromFile();\n if (keysFromFile) {\n const modelNameWithApiKeySuffix = modelName + `ApiKey`;\n let keyFromFile: string|null|undefined = null;\n if (typeof keysFromFile[modelName] === 'object') {\n keyFromFile = keysFromFile[modelName]?.apiKey;\n } else if (typeof keysFromFile[modelNameWithApiKeySuffix] === 'string') {\n keyFromFile = keysFromFile[modelNameWithApiKeySuffix];\n } else if (typeof keysFromFile[modelName] === 'string') {\n keyFromFile = keysFromFile[modelName];\n }\n if (keyFromFile) {\n console.log(`🔑 Using ${modelName} key from keys.json`);\n return keyFromFile;\n }\n }\n\n return null;\n }\n\n isValidApiKey(key: string) {\n return key && typeof key === 'string' && key.length > 0;\n }\n\n isAvailable() {\n return this.model && this.model.isAvailable() && !this.lock;\n }\n\n async query(input: {prompt: string}, tools?: never[]):\n Promise<GeminiResponse|string|null> {\n if (!this.isAvailable()) {\n throw new Error(\n 'AI is not available. Check if it\\'s enabled and properly initialized.');\n }\n return await this.model!.query(input, tools);\n }\n\n async startLiveSession(config = {}) {\n if (!this.model) {\n throw new Error('AI model is not initialized.');\n }\n if (!('isLiveAvailable' in this.model) || !this.model.isLiveAvailable()) {\n throw new Error('Live session is not available for the current model.');\n }\n this.lock = true;\n try {\n const session = await this.model.startLiveSession(config);\n return session;\n } catch (error) {\n this.lock = false;\n console.error('❌ Failed to start Live session:', error);\n throw error;\n }\n }\n\n async stopLiveSession() {\n if (!this.model) return;\n try {\n await ('stopLiveSession' in this.model && this.model.stopLiveSession());\n } catch (error) {\n console.error('❌ Error stopping Live session:', error);\n } finally {\n this.lock = false;\n }\n }\n\n async setLiveCallbacks(callbacks: GoogleGenAITypes.LiveCallbacks) {\n if (this.model && 'setLiveCallbacks' in this.model) {\n this.model.setLiveCallbacks(callbacks);\n }\n }\n\n sendToolResponse(response: GoogleGenAITypes.LiveSendToolResponseParameters) {\n if (this.model && 'sendToolResponse' in this.model) {\n this.model.sendToolResponse(response);\n }\n }\n\n sendRealtimeInput(input: GoogleGenAITypes.LiveSendRealtimeInputParameters) {\n if (!this.model || !('sendRealtimeInput' in this.model)) return false;\n return this.model.sendRealtimeInput(input);\n }\n\n getLiveSessionStatus() {\n if (!this.model || !('getLiveSessionStatus' in this.model)) {\n return {isActive: false, hasSession: false, isAvailable: false};\n }\n return this.model.getLiveSessionStatus();\n }\n\n isLiveAvailable() {\n return this.model && 'isLiveAvailable' in this.model &&\n this.model.isLiveAvailable();\n }\n\n /**\n * In simulator mode, pop up a 2D UI to request Gemini key;\n * In XR mode, show a 3D UI to instruct users to get an API key.\n */\n triggerKeyPopup() {}\n\n async generate(\n prompt: string|string[], type: 'image' = 'image',\n systemInstruction = 'Generate an image',\n model = 'gemini-2.5-flash-image-preview') {\n return this.model!.generate(prompt, type, systemInstruction, model);\n }\n\n /**\n * Create a sample keys.json file structure for reference\n * @returns Sample keys.json structure\n */\n static createSampleKeysStructure() {\n return {\n 'gemini': {'apiKey': 'YOUR_GEMINI_API_KEY_HERE'},\n 'openai': {'apiKey': 'YOUR_OPENAI_API_KEY_HERE'},\n };\n }\n\n /**\n * Check if the current model has an API key available from any source\n * @returns True if API key is available\n */\n async hasApiKey() {\n if (!this.options) return false;\n const modelOptions = this.options[this.options.model];\n if (!modelOptions) return false;\n\n const apiKey = await this.resolveApiKey(modelOptions);\n return apiKey && this.isValidApiKey(apiKey);\n }\n}\n","// --- Hands ---\n/**\n * The number of hands tracked in a typical XR session (left and right).\n */\nexport const NUM_HANDS = 2;\n\n/**\n * The number of joints per hand tracked in a typical XR session.\n */\nexport const HAND_JOINT_COUNT = 25;\n\n/**\n * The pairs of joints as an adjcent list.\n */\nexport const HAND_JOINT_IDX_CONNECTION_MAP = [\n [1, 2], [2, 3], [3, 4], // Thumb has 3 bones\n [5, 6], [6, 7], [7, 8], [8, 9], // Index finger has 4 bones\n [10, 11], [11, 12], [12, 13], [13, 14], // Middle finger has 4 bones\n [15, 16], [16, 17], [17, 18], [18, 19], // Ring finger has 4 bones\n [20, 21], [21, 22], [22, 23], [23, 24], // Little finger has 4 bones\n];\n\n/**\n * The pairs of bones' ids per angle as an adjcent list.\n */\n// clang-format off\nexport const HAND_BONE_IDX_CONNECTION_MAP = [\n [0, 1], [1, 2], // Thumb has 2 angles\n [3, 4], [4, 5], [5, 6], // Index finger has 3 angles\n [7, 8], [8, 9], [9, 10], // Middle finger has 3 angles\n [11, 12], [12, 13], [13, 14], // Ring finger has 3 angles\n [15, 16], [16, 17], [17, 18], // Little finger has 3 angles\n];\n// clang-format on\n\n// --- UI ---\n/**\n * A small depth offset (in meters) applied between layered UI elements to\n * prevent Z-fighting, which is a visual artifact where surfaces at similar\n * depths appear to flicker.\n */\nexport const VIEW_DEPTH_GAP = 0.002;\n\n// --- Renderer Layer ---\n/**\n * The THREE.js rendering layer used exclusively for objects that should only be\n * visible to the left eye's camera in stereoscopic rendering.\n */\nexport const LEFT_VIEW_ONLY_LAYER = 1;\n\n/**\n * The THREE.js rendering layer used exclusively for objects that should only be\n * visible to the right eye's camera in stereoscopic rendering.\n */\nexport const RIGHT_VIEW_ONLY_LAYER = 2;\n\n/**\n * The THREE.js rendering layer for virtual objects that should be realistically\n * occluded by real-world objects when depth sensing is active.\n */\nexport const OCCLUDABLE_ITEMS_LAYER = 3;\n\n/**\n * Layer used for rendering overlaid UI text. Currently only used for LabelView.\n */\nexport const UI_OVERLAY_LAYER = 4;\n\n// --- Camera ---\n\n/**\n * The default ideal width in pixels for requesting the device camera stream.\n * Corresponds to a 720p resolution.\n */\nexport const DEFAULT_DEVICE_CAMERA_WIDTH = 1280;\n\n/**\n * The default ideal height in pixels for requesting the device camera stream.\n * Corresponds to a 720p resolution.\n */\nexport const DEFAULT_DEVICE_CAMERA_HEIGHT = 720;\n\nexport const XR_BLOCKS_ASSETS_PATH = 'https://cdn.jsdelivr.net/gh/xrblocks/assets@34228db7ec7cef66fd65ef3250ef6f4a930fe373/';\n","import type {DeepReadonly} from './Types';\n\n/**\n * Recursively freezes an object and all its nested properties, making them\n * immutable. This prevents any future changes to the object or its sub-objects.\n * @param obj - The object to freeze deeply.\n * @returns The same object that was passed in, now deeply frozen.\n */\nexport function deepFreeze<T extends object>(obj: T): DeepReadonly<T> {\n Object.freeze(obj);\n Object.getOwnPropertyNames(obj).forEach(name => {\n // We use `any` here because `T` is a generic and we can't be sure\n // what properties it has without more complex type manipulation.\n // The function's signature provides the necessary type safety for\n // consumers.\n const prop = obj[name as keyof T];\n if (prop && typeof prop === 'object' && !Object.isFrozen(prop)) {\n deepFreeze(prop);\n }\n });\n return obj as DeepReadonly<T>;\n}\n\n/**\n * Recursively merges properties from `obj2` into `obj1`.\n * If a property exists in both objects and is an object itself, it will be\n * recursively merged. Otherwise, the value from `obj2` will overwrite the\n * value in `obj1`.\n * @param obj1 - The target object to merge into.\n * @param obj2 - The source object to merge from.\n */\nexport function deepMerge<T extends object, U extends object>(\n obj1: T, obj2?: U) {\n if (obj2 == null) {\n return obj1 as T & U;\n }\n\n const merged = obj1 as Record<string, unknown>;\n\n for (const key in obj2) {\n // Ensure the key is actually on obj2, not its prototype chain.\n if (Object.prototype.hasOwnProperty.call(obj2, key)) {\n const val1 = merged[key];\n const val2 = obj2[key];\n\n if (val1 && typeof val1 === 'object' && val2 &&\n typeof val2 === 'object') {\n // If both values are objects, recurse\n deepMerge(val1, val2);\n } else {\n // Otherwise, overwrite\n merged[key] = val2;\n }\n }\n }\n}\n","\nimport {DEFAULT_DEVICE_CAMERA_HEIGHT, DEFAULT_DEVICE_CAMERA_WIDTH} from '../constants';\nimport {deepFreeze, deepMerge} from '../utils/OptionsUtils';\nimport {DeepPartial, DeepReadonly} from '../utils/Types';\n\nexport class DeviceCameraOptions {\n enabled = false;\n /**\n * Constraints for `getUserMedia`. This will guide the initial camera\n * selection. *\n */\n videoConstraints?: MediaTrackConstraints;\n /**\n * Hint for performance optimization on frequent captures.\n */\n willCaptureFrequently = false;\n\n constructor(options?: DeepReadonly<DeepPartial<DeviceCameraOptions>>) {\n deepMerge(this, options);\n }\n}\n\n// Base configuration for all common capture settings\nconst baseCaptureOptions = {\n enabled: true,\n videoConstraints: {\n width: {ideal: DEFAULT_DEVICE_CAMERA_WIDTH},\n height: {ideal: DEFAULT_DEVICE_CAMERA_HEIGHT},\n }\n};\n\nexport const xrDeviceCameraEnvironmentOptions =\n deepFreeze(new DeviceCameraOptions({\n ...baseCaptureOptions,\n videoConstraints:\n {...baseCaptureOptions.videoConstraints, facingMode: 'environment'}\n }));\n\nexport const xrDeviceCameraUserOptions = deepFreeze(new DeviceCameraOptions({\n ...baseCaptureOptions,\n videoConstraints: {...baseCaptureOptions.videoConstraints, facingMode: 'user'}\n}));\n\nexport const xrDeviceCameraEnvironmentContinuousOptions =\n deepFreeze(new DeviceCameraOptions({\n ...xrDeviceCameraEnvironmentOptions,\n willCaptureFrequently: true,\n }));\n\nexport const xrDeviceCameraUserContinuousOptions =\n deepFreeze(new DeviceCameraOptions({\n ...xrDeviceCameraUserOptions,\n willCaptureFrequently: true,\n }));\n","export function onDesktopUserAgent() {\n return !(/Mobi|Linux|Android|iPhone/i.test(navigator.userAgent));\n}\n","export const DepthMeshTexturedShader = {\n name: 'DepthMeshTexturedShader',\n vertexShader: /* glsl */ `\nvarying vec3 vNormal;\nvarying vec3 vViewPosition;\nvarying vec2 vUv;\n\nvoid main() {\n vUv = uv;\n vNormal = normal;\n\n // Computes the view position.\n vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);\n vViewPosition = -mvPosition.xyz;\n\n gl_Position = projectionMatrix * mvPosition;\n}\n`,\n fragmentShader: /* glsl */ `\n#include <packing>\n\nuniform vec3 uColor;\nuniform sampler2D uDepthTexture;\nuniform vec3 uLightDirection;\nuniform vec2 uResolution;\nuniform float uRawValueToMeters;\n\nvarying vec3 vNormal;\nvarying vec3 vViewPosition;\nvarying vec2 vUv;\n\nconst highp float kMaxDepthInMeters = 8.0;\nconst float kInvalidDepthThreshold = 0.01;\nuniform float uMinDepth;\nuniform float uMaxDepth;\nuniform float uDebug;\nuniform float uOpacity;\nuniform bool uUsingFloatDepth;\n\nfloat saturate(in float x) {\n return clamp(x, 0.0, 1.0);\n}\n\nvec3 TurboColormap(in float x) {\n const vec4 kRedVec4 = vec4(0.55305649, 3.00913185, -5.46192616, -11.11819092);\n const vec4 kGreenVec4 = vec4(0.16207513, 0.17712472, 15.24091500, -36.50657960);\n const vec4 kBlueVec4 = vec4(-0.05195877, 5.18000081, -30.94853351, 81.96403246);\n const vec2 kRedVec2 = vec2(27.81927491, -14.87899417);\n const vec2 kGreenVec2 = vec2(25.95549545, -5.02738237);\n const vec2 kBlueVec2 = vec2(-86.53476570, 30.23299484);\n\n // Adjusts color space via 6 degree poly interpolation to avoid pure red.\n vec4 v4 = vec4( 1.0, x, x * x, x * x * x);\n vec2 v2 = v4.zw * v4.z;\n return vec3(\n dot(v4, kRedVec4) + dot(v2, kRedVec2),\n dot(v4, kGreenVec4) + dot(v2, kGreenVec2),\n dot(v4, kBlueVec4) + dot(v2, kBlueVec2)\n );\n}\n\n// Depth is packed into the luminance and alpha components of its texture.\n// The texture is in a normalized format, storing raw values that need to be\n// converted to meters.\nfloat DepthGetMeters(in sampler2D depth_texture, in vec2 depth_uv) {\n if (uUsingFloatDepth) {\n return texture2D(depth_texture, depth_uv).r * uRawValueToMeters;\n }\n vec2 packedDepthAndVisibility = texture2D(depth_texture, depth_uv).rg;\n return dot(packedDepthAndVisibility, vec2(255.0, 256.0 * 255.0)) * uRawValueToMeters;\n}\n\nvec3 DepthGetColorVisualization(in float x) {\n return step(kInvalidDepthThreshold, x) * TurboColormap(x);\n}\n\nvoid main() {\n vec3 lightDirection = normalize(uLightDirection);\n\n // Compute UV coordinates relative to resolution\n // vec2 uv = gl_FragCoord.xy / uResolution;\n vec2 uv = vUv;\n\n // Ambient, diffuse, and specular terms\n vec3 ambient = 0.1 * uColor;\n float diff = max(dot(vNormal, lightDirection), 0.0);\n vec3 diffuse = diff * uColor;\n\n vec3 viewDir = normalize(vViewPosition);\n vec3 reflectDir = reflect(-lightDirection, vNormal);\n float spec = pow(max(dot(viewDir, reflectDir), 0.0), 16.0);\n vec3 specular = vec3(0.5) * spec; // Adjust specular color/strength\n\n // Combine Phong lighting\n vec3 finalColor = ambient + diffuse + specular;\n // finalColor = vec3(vNormal);\n\n // Output color\n gl_FragColor = uOpacity * vec4(finalColor, 1.0);\n\n if (uDebug > 0.5) {\n return;\n }\n\n vec2 depth_uv = uv;\n depth_uv.y = 1.0 - depth_uv.y;\n\n float depth = DepthGetMeters(uDepthTexture, depth_uv) * 8.0;\n float normalized_depth =\n saturate((depth - uMinDepth) / (uMaxDepth - uMinDepth));\n gl_FragColor = uOpacity * vec4(TurboColormap(normalized_depth), 1.0);\n}\n`\n};\n","import type RAPIER_NS from '@dimforge/rapier3d';\nimport * as THREE from 'three';\n\nimport {MeshScript} from '../core/Script';\nimport {clamp} from '../utils/utils';\n\nimport {DepthMeshTexturedShader} from './DepthMeshTexturedShader';\nimport {DepthMeshOptions, DepthOptions} from './DepthOptions';\nimport {DepthTextures} from './DepthTextures';\n\nexport class DepthMesh extends MeshScript {\n static dependencies = {\n camera: THREE.Camera,\n renderer: THREE.WebGLRenderer,\n };\n static isDepthMesh = true;\n ignoreReticleRaycast = false;\n private worldPosition = new THREE.Vector3();\n private worldQuaternion = new THREE.Quaternion();\n private updateVertexNormals = false;\n\n private minDepth = 8;\n private maxDepth = 0;\n private minDepthPrev = 8;\n private maxDepthPrev = 0;\n\n private downsampledGeometry?: THREE.BufferGeometry;\n private downsampledMesh?: THREE.Mesh;\n\n private collider?: RAPIER_NS.Collider;\n private colliders: RAPIER_NS.Collider[] = [];\n private colliderUpdateFps: number;\n\n private renderer!: THREE.WebGLRenderer;\n private camera!: THREE.Camera;\n private projectionMatrixInverse = new THREE.Matrix4();\n private lastColliderUpdateTime = 0;\n private options: DepthMeshOptions;\n private depthTextureMaterialUniforms?;\n\n private RAPIER?: typeof RAPIER_NS;\n private blendedWorld?: RAPIER_NS.World;\n private rigidBody?: RAPIER_NS.RigidBody;\n private colliderId = 0;\n\n constructor(\n private depthOptions: DepthOptions, width: number, height: number,\n private depthTextures?: DepthTextures) {\n const options = depthOptions.depthMesh;\n const geometry = new THREE.PlaneGeometry(1, 1, 159, 159);\n let material: THREE.Material;\n let uniforms;\n if (options.useDepthTexture || options.showDebugTexture) {\n uniforms = {\n uDepthTexture: {value: (null as THREE.Texture | null)},\n uColor: {value: new THREE.Color(0xaaaaaa)},\n uResolution: {value: new THREE.Vector2(width, height)},\n uRawValueToMeters: {value: 1.0},\n uMinDepth: {value: 0.0},\n uMaxDepth: {value: 8.0},\n uOpacity: {value: options.opacity},\n uDebug: {value: options.showDebugTexture ? 1.0 : 0.0},\n uLightDirection: {value: new THREE.Vector3(1.0, 1.0, 1.0).normalize()},\n uUsingFloatDepth: {value: depthOptions.useFloat32}\n };\n material = new THREE.ShaderMaterial({\n uniforms: uniforms,\n vertexShader: DepthMeshTexturedShader.vertexShader,\n fragmentShader: DepthMeshTexturedShader.fragmentShader,\n side: THREE.FrontSide,\n transparent: true\n });\n } else {\n material = new THREE.ShadowMaterial({opacity: options.shadowOpacity});\n material.depthWrite = false;\n }\n\n super(geometry, material);\n\n this.visible = options.showDebugTexture || options.renderShadow;\n this.options = options;\n this.projectionMatrixInverse = new THREE.Matrix4();\n this.lastColliderUpdateTime = performance.now();\n this.updateVertexNormals = options.updateVertexNormals;\n this.colliderUpdateFps = options.colliderUpdateFps;\n this.depthTextureMaterialUniforms = uniforms;\n if (options.renderShadow) {\n this.receiveShadow = true;\n this.castShadow = false;\n }\n\n // Create a downsampled geometry for raycasts and physics.\n if (options.useDownsampledGeometry) {\n this.downsampledGeometry = new THREE.PlaneGeometry(1, 1, 39, 39);\n this.downsampledMesh = new THREE.Mesh(this.downsampledGeometry, material);\n this.downsampledMesh.visible = false;\n this.add(this.downsampledMesh);\n }\n }\n\n /**\n * Initialize the depth mesh.\n */\n init({camera, renderer}:\n {camera: THREE.Camera, renderer: THREE.WebGLRenderer}) {\n this.camera = camera;\n this.renderer = renderer;\n }\n\n /**\n * Updates the depth data and geometry positions based on the provided camera\n * and depth data.\n */\n updateDepth(depthData: XRCPUDepthInformation) {\n const camera = this.renderer.xr?.getCamera?.()?.cameras?.[0] || this.camera;\n if (!camera) return;\n\n // Inverts the projection matrix.\n this.projectionMatrixInverse.copy(camera.projectionMatrix).invert();\n\n this.minDepth = 8;\n this.maxDepth = 0;\n\n if (this.options.updateFullResolutionGeometry) {\n this.updateFullResolutionGeometry(depthData);\n }\n if (this.downsampledGeometry) {\n this.updateGeometry(depthData, this.downsampledGeometry);\n }\n\n this.minDepthPrev = this.minDepth;\n this.maxDepthPrev = this.maxDepth;\n this.geometry.attributes.position.needsUpdate = true;\n\n const depthTextureLeft = this.depthTextures?.get(0);\n if (depthTextureLeft && this.depthTextureMaterialUniforms) {\n this.depthTextureMaterialUniforms.uDepthTexture.value = depthTextureLeft;\n this.depthTextureMaterialUniforms.uMinDepth.value = this.minDepth;\n this.depthTextureMaterialUniforms.uMaxDepth.value = this.maxDepth;\n this.depthTextureMaterialUniforms.uRawValueToMeters.value =\n this.depthTextures!.depthData[0].rawValueToMeters;\n (this.material as THREE.Material).needsUpdate = true;\n }\n\n if (this.options.updateVertexNormals) {\n this.geometry.computeVertexNormals();\n }\n\n this.updateColliderIfNeeded();\n }\n\n /**\n * Method to manually update the full resolution geometry.\n * Only needed if options.updateFullResolutionGeometry is false.\n */\n updateFullResolutionGeometry(depthData: XRCPUDepthInformation) {\n this.updateGeometry(depthData, this.geometry);\n }\n\n /**\n * Internal method to update the geometry of the depth mesh.\n */\n private updateGeometry(\n depthData: XRCPUDepthInformation, geometry: THREE.BufferGeometry) {\n const width = depthData.width;\n const height = depthData.height;\n const depthArray = this.depthOptions.useFloat32 ?\n new Float32Array(depthData.data) :\n new Uint16Array(depthData.data);\n const vertexPosition = new THREE.Vector3();\n for (let i = 0; i < geometry.attributes.position.count; ++i) {\n const u = geometry.attributes.uv.array[2 * i];\n const v = geometry.attributes.uv.array[2 * i + 1];\n\n // Grabs the nearest for now.\n const depthX = Math.round(clamp(u * width, 0, width - 1));\n const depthY = Math.round(clamp((1.0 - v) * height, 0, height - 1));\n const rawDepth = depthArray[depthY * width + depthX];\n let depth = depthData.rawValueToMeters * rawDepth;\n // Workaround for b/382679381.\n if (this.depthOptions.useFloat32) {\n depth = rawDepth;\n }\n\n // Finds global min/max.\n if (depth > 0) {\n if (depth < this.minDepth) {\n this.minDepth = depth;\n } else if (depth > this.maxDepth) {\n this.maxDepth = depth;\n }\n }\n\n // This is a wrong algorithm to patch holes but working amazingly well.\n // Per-row maximum may work better but haven't tried here.\n // A proper local maximum takes another pass.\n if (depth == 0 && this.options.patchHoles) {\n depth = this.maxDepthPrev;\n }\n\n if (this.options.patchHolesUpper && v > 0.9) {\n depth = this.minDepthPrev;\n }\n\n vertexPosition.set(2.0 * (u - 0.5), 2.0 * (v - 0.5), -1);\n\n // This relates to camera.near\n vertexPosition.applyMatrix4(this.projectionMatrixInverse);\n\n vertexPosition.multiplyScalar(-depth / vertexPosition.z);\n\n geometry.attributes.position.array[3 * i + 0] = vertexPosition.x;\n geometry.attributes.position.array[3 * i + 1] = vertexPosition.y;\n geometry.attributes.position.array[3 * i + 2] = vertexPosition.z;\n }\n }\n\n /**\n * Optimizes collider updates to run periodically based on the specified FPS.\n */\n updateColliderIfNeeded() {\n const timeSinceLastUpdate = performance.now() - this.lastColliderUpdateTime;\n if (this.RAPIER && timeSinceLastUpdate > 1000 / this.colliderUpdateFps) {\n this.getWorldPosition(this.worldPosition);\n this.getWorldQuaternion(this.worldQuaternion);\n this.rigidBody!.setTranslation(this.worldPosition, false);\n this.rigidBody!.setRotation(this.worldQuaternion, false);\n\n const geometry =\n this.downsampledGeometry ? this.downsampledGeometry : this.geometry;\n const vertices = geometry.attributes.position.array as Float32Array;\n const indices = geometry.getIndex()!.array as Uint32Array;\n // Changing the density does not fix the issue.\n const shape =\n this.RAPIER.ColliderDesc.trimesh(vertices, indices).setDensity(1.0);\n // const convextHull = this.RAPIER.ColliderDesc.convexHull(vertices);\n\n if (this.options.useDualCollider) {\n this.colliderId = (this.colliderId + 1) % 2;\n this.blendedWorld!.removeCollider(\n this.colliders[this.colliderId], false);\n this.colliders[this.colliderId] =\n this.blendedWorld!.createCollider(shape, this.rigidBody);\n } else {\n const newCollider =\n this.blendedWorld!.createCollider(shape, this.rigidBody);\n this.blendedWorld!.removeCollider(this.collider!, /*wakeUp=*/ false);\n this.collider = newCollider;\n }\n\n this.lastColliderUpdateTime = performance.now();\n }\n }\n\n initRapierPhysics(RAPIER: typeof RAPIER_NS, blendedWorld: RAPIER_NS.World) {\n this.getWorldPosition(this.worldPosition);\n this.getWorldQuaternion(this.worldQuaternion);\n const desc = RAPIER.RigidBodyDesc.fixed()\n .setTranslation(\n this.worldPosition.x, this.worldPosition.y,\n this.worldPosition.z)\n .setRotation(this.worldQuaternion);\n this.rigidBody = blendedWorld.createRigidBody(desc);\n const vertices = this.geometry.attributes.position.array as Float32Array;\n const indices = this.geometry.getIndex()!.array as Uint32Array;\n const shape = RAPIER.ColliderDesc.trimesh(vertices, indices);\n\n if (this.options.useDualCollider) {\n this.colliders = [];\n this.colliders.push(\n blendedWorld.createCollider(shape, this.rigidBody),\n blendedWorld.createCollider(shape, this.rigidBody));\n this.colliderId = 0;\n } else {\n this.collider = blendedWorld.createCollider(shape, this.rigidBody);\n }\n\n this.RAPIER = RAPIER;\n this.blendedWorld = blendedWorld;\n this.lastColliderUpdateTime = performance.now();\n }\n\n getDepth(\n raycaster: THREE.Raycaster, ndc: THREE.Vector2, camera: THREE.Camera) {\n // Convert the point from blendedWorld space to normalized device\n // coordinates (NDC) const ndc = point.clone().project(camera);\n\n // Create a Vector2 for the NDC x, y coordinates (used by the Raycaster)\n const ndc2D = new THREE.Vector2(ndc.x, ndc.y);\n\n // Set up the Raycaster to cast a ray from the camera through the NDC point\n raycaster.setFromCamera(ndc2D, camera);\n\n // Check for intersections with the mesh\n const intersects = raycaster.intersectObject(this);\n\n // If an intersection is found, calculate the distance from the point to the\n // intersection\n if (intersects.length > 0) {\n const distance = intersects[0].distance;\n return distance;\n } else {\n return -1;\n }\n }\n\n /**\n * Customizes raycasting to compute normals for intersections.\n * @param raycaster - The raycaster object.\n * @param intersects - Array to store intersections.\n * @returns - True if intersections are found.\n */\n raycast(raycaster: THREE.Raycaster, intersects: THREE.Intersection[]) {\n const intersections: THREE.Intersection[] = [];\n if (this.downsampledMesh) {\n this.downsampledMesh.raycast(raycaster, intersections)\n } else {\n super.raycast(raycaster, intersections);\n }\n\n intersections.forEach(intersect => {\n intersect.object = this;\n });\n if (!this.updateVertexNormals) {\n // Use the face normals instead of attribute normals.\n intersections.forEach(intersect => {\n if (intersect.normal && intersect.face) {\n intersect.normal.copy(intersect.face.normal);\n }\n });\n }\n\n intersects.push(...intersections);\n return true;\n }\n\n getColliderFromHandle(handle: RAPIER_NS.ColliderHandle) {\n if (this.collider?.handle == handle) {\n return this.collider;\n }\n for (const collider of this.colliders) {\n if (collider?.handle == handle) {\n return collider;\n }\n }\n return undefined;\n }\n};\n","import {deepFreeze, deepMerge} from '../utils/OptionsUtils.js';\nimport {DeepPartial, DeepReadonly} from '../utils/Types';\n\nexport class DepthMeshOptions {\n enabled = false;\n updateVertexNormals = false;\n showDebugTexture = false;\n useDepthTexture = false;\n renderShadow = false;\n shadowOpacity = 0.25;\n patchHoles = false;\n patchHolesUpper = false;\n // Opacity of the debug material.\n opacity = 1.0;\n useDualCollider = false\n // Use downsampled geometry for raycast and collisions\n useDownsampledGeometry = true;\n // Whether to always update the full resolution geometry.\n updateFullResolutionGeometry = false;\n colliderUpdateFps = 5;\n}\n\nexport class DepthOptions {\n debugging = false;\n enabled = false;\n depthMesh = new DepthMeshOptions();\n depthTexture = {\n enabled: false,\n constantKernel: false,\n applyGaussianBlur: false,\n applyKawaseBlur: false,\n };\n // Occlusion pass.\n occlusion = {enabled: false};\n useFloat32 = true;\n\n constructor(options?: DeepReadonly<DeepPartial<DepthOptions>>) {\n deepMerge(this, options);\n }\n}\n\nexport const xrDepthMeshOptions = deepFreeze(new DepthOptions({\n enabled: true,\n depthMesh: {\n enabled: true,\n updateVertexNormals: false,\n showDebugTexture: false,\n useDepthTexture: false,\n renderShadow: false,\n shadowOpacity: 0.25,\n patchHoles: true,\n // Use downsampled geometry for raycast and collisions\n useDownsampledGeometry: true,\n // Whether to always update the full resolution geometry.\n updateFullResolutionGeometry: false,\n colliderUpdateFps: 5,\n }\n}));\n\n\nexport const xrDepthMeshVisualizationOptions = deepFreeze(new DepthOptions({\n enabled: true,\n depthMesh: {\n enabled: true,\n updateVertexNormals: true,\n showDebugTexture: true,\n useDepthTexture: true,\n renderShadow: false,\n shadowOpacity: 0.25,\n patchHoles: true,\n opacity: 0.1,\n // Use downsampled geometry for raycast and collisions\n useDownsampledGeometry: true,\n // Whether to always update the full resolution geometry.\n updateFullResolutionGeometry: true,\n colliderUpdateFps: 5,\n },\n depthTexture: {\n enabled: true,\n constantKernel: true,\n applyGaussianBlur: true,\n applyKawaseBlur: true,\n },\n}));\n\nexport const xrDepthMeshPhysicsOptions = deepFreeze(new DepthOptions({\n enabled: true,\n depthMesh: {\n enabled: true,\n updateVertexNormals: false,\n showDebugTexture: false,\n useDepthTexture: false,\n renderShadow: true,\n shadowOpacity: 0.25,\n patchHoles: true,\n patchHolesUpper: true,\n useDualCollider: false,\n // Use downsampled geometry for raycast and collisions\n useDownsampledGeometry: true,\n // Whether to always update the full resolution geometry.\n updateFullResolutionGeometry: false,\n colliderUpdateFps: 5,\n },\n}));\n","import * as THREE from 'three';\n\nimport {DepthOptions} from './DepthOptions';\n\nexport class DepthTextures {\n private uint16Arrays: Uint16Array[] = [];\n private uint8Arrays: Uint8Array[] = [];\n private textures: THREE.DataTexture[] = [];\n public depthData: XRCPUDepthInformation[] = [];\n\n constructor(private options: DepthOptions) {}\n\n private createDepthTextures(\n depthData: XRCPUDepthInformation, view_id: number) {\n if (this.textures[view_id]) {\n this.textures[view_id].dispose();\n }\n if (this.options.useFloat32) {\n const typedArray = new Uint16Array(depthData.width * depthData.height);\n const format = THREE.RedFormat;\n const type = THREE.HalfFloatType;\n this.uint16Arrays[view_id] = typedArray;\n this.textures[view_id] = new THREE.DataTexture(\n typedArray, depthData.width, depthData.height, format, type);\n } else {\n const typedArray = new Uint8Array(depthData.width * depthData.height * 2);\n const format = THREE.RGFormat;\n const type = THREE.UnsignedByteType;\n this.uint8Arrays[view_id] = typedArray;\n this.textures[view_id] = new THREE.DataTexture(\n typedArray, depthData.width, depthData.height, format, type);\n }\n }\n\n update(depthData: XRCPUDepthInformation, view_id: number) {\n if (this.textures.length < view_id + 1 ||\n this.textures[view_id].image.width !== depthData.width ||\n this.textures[view_id].image.height !== depthData.height) {\n this.createDepthTextures(depthData, view_id);\n }\n if (this.options.useFloat32) {\n const float32Data = new Float32Array(depthData.data);\n const float16Data = new Uint16Array(float32Data.length);\n for (let i = 0; i < float16Data.length; i++) {\n float16Data[i] = THREE.DataUtils.toHalfFloat(float32Data[i]);\n }\n this.uint16Arrays[view_id].set(float16Data);\n } else {\n this.uint8Arrays[view_id].set(new Uint8Array(depthData.data));\n }\n this.textures[view_id].needsUpdate = true;\n this.depthData[view_id] = depthData;\n }\n\n get(view_id: number) {\n return this.textures[view_id];\n }\n};\n","export const KawaseBlurShader = {\n name: 'KawaseBlurShader',\n defines: {\n MODE: \"0\"\n },\n vertexShader: /* glsl */ `\n uniform float uBlurSize;\n uniform vec2 uTexelSize;\n varying vec2 vTexCoord;\n varying vec4 uv1;\n varying vec4 uv2;\n varying vec4 uv3;\n varying vec4 uv4;\n\n void vertCopy(vec2 uv) {}\n\n void vertUpsample(vec2 uv) {\n vec2 halfPixel = uTexelSize * 0.5;\n vec2 offset = vec2(uBlurSize);\n uv1.xy = uv + vec2(-halfPixel.x * 2.0, 0.0) * offset;\n uv1.zw = uv + vec2(-halfPixel.x, halfPixel.y) * offset;\n uv2.xy = uv + vec2(0.0, halfPixel.y * 2.0) * offset;\n uv2.zw = uv + halfPixel * offset;\n uv3.xy = uv + vec2(halfPixel.x * 2.0, 0.0) * offset;\n uv3.zw = uv + vec2(halfPixel.x, -halfPixel.y) * offset;\n uv4.xy = uv + vec2(0.0, -halfPixel.y * 2.0) * offset;\n uv4.zw = uv - halfPixel * offset;\n }\n\n void vertDownsample(vec2 uv) {\n vec2 halfPixel = uTexelSize * 0.5;\n vec2 offset = vec2(uBlurSize);\n uv1.xy = uv - halfPixel * offset;\n uv1.zw = uv + halfPixel * offset;\n uv2.xy = uv - vec2(halfPixel.x, -halfPixel.y) * offset;\n uv2.zw = uv + vec2(halfPixel.x, -halfPixel.y) * offset;\n }\n\n void main() {\n vTexCoord = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n if (MODE == 0) {\n vertCopy(uv);\n } else if (MODE == 1) {\n vertDownsample(uv);\n } else {\n vertUpsample(uv);\n }\n }\n`,\n fragmentShader: /* glsl */ `\n uniform sampler2D tDiffuse;\n varying vec2 vTexCoord;\n varying vec4 uv1;\n varying vec4 uv2;\n varying vec4 uv3;\n varying vec4 uv4;\n\n vec2 getUV0() {\n return vTexCoord;\n }\n\n vec4 fragCopy() {\n return texture2D(tDiffuse, getUV0());\n }\n\n vec4 fragDownsample() {\n vec4 sum = texture2D(tDiffuse, getUV0()) * 4.0;\n sum += texture2D(tDiffuse, uv1.xy);\n sum += texture2D(tDiffuse, uv1.zw);\n sum += texture2D(tDiffuse, uv2.xy);\n sum += texture2D(tDiffuse, uv2.zw);\n return sum * 0.125;\n }\n\n vec4 fragUpsample() {\n vec4 sum = texture2D(tDiffuse, uv1.xy);\n sum += texture2D(tDiffuse, uv1.zw) * 2.0;\n sum += texture2D(tDiffuse, uv2.xy);\n sum += texture2D(tDiffuse, uv2.zw) * 2.0;\n sum += texture2D(tDiffuse, uv3.xy);\n sum += texture2D(tDiffuse, uv3.zw) * 2.0;\n sum += texture2D(tDiffuse, uv4.xy);\n sum += texture2D(tDiffuse, uv4.zw) * 2.0;\n return sum * 0.0833;\n }\n\n void main(void) {\n if (MODE == 0) {\n gl_FragColor = fragCopy();\n } else if (MODE == 1) {\n gl_FragColor = fragDownsample();\n } else {\n gl_FragColor = fragUpsample();\n }\n }\n`\n};\n","// Postprocessing shader which applies occlusion onto the entire rendered frame.\nexport const OcclusionShader = {\n name: 'OcclusionShader',\n defines: {},\n vertexShader: /* glsl */ `\nvarying vec2 vTexCoord;\n\nvoid main() {\n vTexCoord = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}\n `,\n fragmentShader: /* glsl */ `\nprecision mediump float;\n\nuniform sampler2D tDiffuse;\nuniform sampler2D tOcclusionMap;\n\nvarying vec2 vTexCoord;\n\nvoid main(void) {\n vec4 diffuse = texture2D(tDiffuse, vTexCoord);\n vec4 occlusion = texture2D(tOcclusionMap, vTexCoord);\n float occlusionValue = occlusion.r / max(0.0001, occlusion.g);\n occlusionValue = clamp(occlusionValue, 0.0, 1.0);\n gl_FragColor = occlusionValue * diffuse;\n\n gl_FragColor = sRGBTransferOETF( gl_FragColor );\n}\n`\n};\n","// Postprocessing to convert a render texture + depth map into an occlusion map.\nexport const OcclusionMapShader = {\n name: 'OcclusionMapShader',\n defines: {},\n\n vertexShader: /* glsl */ `\nvarying vec2 vTexCoord;\n\nvoid main() {\n vTexCoord = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}\n `,\n\n fragmentShader: /* glsl */ `\n#include <packing>\n\nprecision mediump float;\n\nuniform sampler2D uDepthTexture;\nuniform mat4 uUvTransform;\nuniform float uRawValueToMeters;\nuniform float uAlpha;\nuniform float uViewId;\nuniform bool uFloatDepth;\n\nuniform sampler2D tDiffuse;\nuniform sampler2D tDepth;\nuniform float cameraNear;\nuniform float cameraFar;\n\nvarying vec2 vTexCoord;\n\nfloat DepthGetMeters(in sampler2D depth_texture, in vec2 depth_uv) {\n // Depth is packed into the luminance and alpha components of its texture.\n // The texture is in a normalized format, storing raw values that need to be\n // converted to meters.\n vec2 packedDepthAndVisibility = texture2D(depth_texture, depth_uv).rg;\n if (uFloatDepth) {\n return packedDepthAndVisibility.r * uRawValueToMeters;\n }\n return dot(packedDepthAndVisibility, vec2(255.0, 256.0 * 255.0)) * uRawValueToMeters;\n}\n\nfloat readOrthographicDepth( sampler2D depthSampler, vec2 coord ) {\n float fragCoordZ = texture2D( depthSampler, coord ).x;\n // See https://github.com/mrdoob/three.js/issues/23072.\n #ifdef USE_LOGDEPTHBUF\n float viewZ = 1.0 - exp2(fragCoordZ * log(cameraFar + 1.0) / log(2.0));\n #else\n float viewZ = perspectiveDepthToViewZ(fragCoordZ, cameraNear, cameraFar);\n #endif\n return viewZToOrthographicDepth( viewZ, cameraNear, cameraFar );\n}\n\nvoid main(void) {\n vec4 texCoord = vec4(vTexCoord, 0, 1);\n vec2 uv = texCoord.xy;\n uv.y = 1.0 - uv.y;\n\n vec4 diffuse = texture2D( tDiffuse, texCoord.xy );\n highp float real_depth = DepthGetMeters(uDepthTexture, uv);\n highp float virtual_depth =\n (readOrthographicDepth(tDepth, texCoord.xy ) *\n (cameraFar - cameraNear) + cameraNear);\n gl_FragColor = vec4(step(virtual_depth, real_depth), step(0.001, diffuse.a), 0.0, 0.0);\n}\n`\n\n};\n","\nimport * as THREE from 'three';\n\nexport class OcclusionMapMeshMaterial extends THREE.MeshBasicMaterial {\n uniforms: {[uniform: string]: THREE.IUniform};\n\n constructor(camera: THREE.PerspectiveCamera, useFloatDepth: boolean) {\n super();\n this.uniforms = {\n uDepthTexture: {value: null},\n uRawValueToMeters: {value: 8.0 / 65536.0},\n cameraFar: {value: camera.far},\n cameraNear: {value: camera.near},\n uFloatDepth: {value: useFloatDepth},\n };\n this.onBeforeCompile = (shader) => {\n Object.assign(shader.uniforms, this.uniforms);\n this.uniforms = shader.uniforms;\n shader.vertexShader =\n shader.vertexShader\n .replace(\n '#include <common>',\n [\n 'varying vec2 vTexCoord;', 'varying float vVirtualDepth;',\n '#include <common>'\n ].join('\\n'))\n .replace('#include <fog_vertex>', [\n '#include <fog_vertex>',\n 'vec4 view_position = modelViewMatrix * vec4( position, 1.0 );',\n 'vVirtualDepth = -view_position.z;',\n 'gl_Position = gl_Position / gl_Position.w;',\n 'vTexCoord = 0.5 + 0.5 * gl_Position.xy;'\n ].join('\\n'));\n shader.fragmentShader =\n shader.fragmentShader\n .replace(\n 'uniform vec3 diffuse;',\n [\n 'uniform vec3 diffuse;', 'uniform sampler2D uDepthTexture;',\n 'uniform float uRawValueToMeters;',\n 'uniform float cameraNear;', 'uniform float cameraFar;',\n 'uniform bool uFloatDepth;', 'varying vec2 vTexCoord;',\n 'varying float vVirtualDepth;'\n ].join('\\n'))\n .replace(\n '#include <clipping_planes_pars_fragment>',\n [\n '#include <clipping_planes_pars_fragment>', `\n float DepthGetMeters(in sampler2D depth_texture, in vec2 depth_uv) {\n // Depth is packed into the luminance and alpha components of its texture.\n // The texture is in a normalized format, storing raw values that need to be\n // converted to meters.\n vec2 packedDepthAndVisibility = texture2D(depth_texture, depth_uv).rg;\n if (uFloatDepth) {\n return packedDepthAndVisibility.r * uRawValueToMeters;\n }\n return dot(packedDepthAndVisibility, vec2(255.0, 256.0 * 255.0)) * uRawValueToMeters;\n }\n`\n ].join('\\n'))\n .replace('#include <dithering_fragment>', [\n '#include <dithering_fragment>',\n 'vec4 texCoord = vec4(vTexCoord, 0, 1);',\n 'vec2 uv = vec2(texCoord.x, 1.0 - texCoord.y);',\n 'highp float real_depth = DepthGetMeters(uDepthTexture, uv);',\n 'gl_FragColor = vec4(step(vVirtualDepth, real_depth), 1.0, 0.0, 1.0);'\n ].join('\\n'));\n };\n }\n}\n","import * as THREE from 'three';\nimport {FullScreenQuad, Pass} from 'three/addons/postprocessing/Pass.js';\n\nimport {OCCLUDABLE_ITEMS_LAYER} from '../../constants';\nimport type {ShaderUniforms} from '../../utils/Types';\n\nimport {KawaseBlurShader} from './kawaseblur.glsl';\nimport {OcclusionShader} from './occlusion.glsl';\nimport {OcclusionMapShader} from './occlusion_map.glsl';\nimport {OcclusionMapMeshMaterial} from './OcclusionMapMeshMaterial';\n\nenum KawaseBlurMode {\n COPY = 0,\n DOWN = 1,\n UP = 2\n}\n\n/**\n * Occlusion postprocessing shader pass.\n * This is used to generate an occlusion map.\n * There are two modes:\n * Mode A: Generate an occlusion map for individual materials to use.\n * Mode B: Given a rendered frame, run as a postprocessing pass, occluding all\n * items in the frame. The steps are\n * 1. Compute an occlusion map between the real and virtual depth.\n * 2. Blur the occlusion map using Kawase blur.\n * 3. (Mode B only) Apply the occlusion map to the rendered frame.\n */\nexport class OcclusionPass extends Pass {\n private depthTextures: THREE.Texture[] = [];\n private occlusionMeshMaterial: OcclusionMapMeshMaterial;\n private occlusionMapUniforms: ShaderUniforms;\n private occlusionMapQuad: FullScreenQuad;\n private occlusionMapTexture: THREE.WebGLRenderTarget;\n private kawaseBlurQuads: FullScreenQuad[];\n private kawaseBlurTargets: THREE.WebGLRenderTarget[];\n private occlusionUniforms: ShaderUniforms;\n private occlusionQuad: FullScreenQuad;\n\n constructor(\n private scene: THREE.Scene, private camera: THREE.PerspectiveCamera,\n useFloatDepth = true, public renderToScreen = false,\n private occludableItemsLayer = OCCLUDABLE_ITEMS_LAYER) {\n super();\n\n this.occlusionMeshMaterial =\n new OcclusionMapMeshMaterial(camera, useFloatDepth);\n\n this.occlusionMapUniforms = {\n uDepthTexture: {value: null},\n uUvTransform: {value: new THREE.Matrix4()},\n uRawValueToMeters: {value: 8.0 / 65536.0},\n uAlpha: {value: 0.75},\n tDiffuse: {value: null},\n tDepth: {value: null},\n uFloatDepth: {value: useFloatDepth},\n cameraFar: {value: camera.far},\n cameraNear: {value: camera.near},\n };\n this.occlusionMapQuad = new FullScreenQuad(new THREE.ShaderMaterial({\n name: 'OcclusionMapShader',\n uniforms: this.occlusionMapUniforms,\n vertexShader: OcclusionMapShader.vertexShader,\n fragmentShader: OcclusionMapShader.fragmentShader,\n }));\n this.occlusionMapTexture = new THREE.WebGLRenderTarget();\n\n this.kawaseBlurTargets = [\n new THREE.WebGLRenderTarget(), // 1/2 resolution\n new THREE.WebGLRenderTarget(), // 1/4 resolution\n new THREE.WebGLRenderTarget(), // 1/8 resolution\n ];\n this.kawaseBlurQuads = [\n this.setupKawaseBlur(\n KawaseBlurMode.DOWN, this.occlusionMapTexture.texture),\n this.setupKawaseBlur(\n KawaseBlurMode.DOWN, this.kawaseBlurTargets[0].texture),\n this.setupKawaseBlur(\n KawaseBlurMode.DOWN, this.kawaseBlurTargets[1].texture),\n this.setupKawaseBlur(\n KawaseBlurMode.UP, this.kawaseBlurTargets[2].texture),\n this.setupKawaseBlur(\n KawaseBlurMode.UP, this.kawaseBlurTargets[1].texture),\n this.setupKawaseBlur(\n KawaseBlurMode.UP, this.kawaseBlurTargets[0].texture),\n ];\n\n this.occlusionUniforms = {\n tDiffuse: {value: null},\n tOcclusionMap: {value: this.occlusionMapTexture.texture},\n };\n this.occlusionQuad = new FullScreenQuad(new THREE.ShaderMaterial({\n name: 'OcclusionShader',\n uniforms: this.occlusionUniforms,\n vertexShader: OcclusionShader.vertexShader,\n fragmentShader: OcclusionShader.fragmentShader,\n }));\n\n this.occludableItemsLayer = occludableItemsLayer;\n }\n\n private setupKawaseBlur(mode: KawaseBlurMode, inputTexture: THREE.Texture) {\n const uniforms = {\n uBlurSize: {value: 7.0},\n uTexelSize: {value: new THREE.Vector2()},\n tDiffuse: {value: inputTexture}\n };\n const kawase1Material = new THREE.ShaderMaterial({\n name: 'Kawase',\n uniforms: uniforms,\n vertexShader: KawaseBlurShader.vertexShader,\n fragmentShader: KawaseBlurShader.fragmentShader,\n defines: {MODE: mode}\n });\n return new FullScreenQuad(kawase1Material);\n }\n\n setDepthTexture(\n depthTexture: THREE.Texture, rawValueToMeters: number, view_id: number) {\n if (view_id > 1) {\n return;\n }\n this.depthTextures[view_id] = depthTexture;\n this.occlusionMapUniforms.uRawValueToMeters.value = rawValueToMeters;\n this.occlusionMeshMaterial.uniforms.uRawValueToMeters.value =\n rawValueToMeters;\n depthTexture.needsUpdate = true;\n }\n\n /**\n * Render the occlusion map.\n * @param renderer - The three.js renderer.\n * @param writeBuffer - The buffer to write the final result.\n * @param readBuffer - The buffer for the current of virtual depth.\n * @param view_id - The view to render.\n */\n render(\n renderer: THREE.WebGLRenderer, writeBuffer?: THREE.WebGLRenderTarget,\n readBuffer?: THREE.WebGLRenderTarget, view_id = 0) {\n const originalRenderTarget = renderer.getRenderTarget();\n const dimensions = new THREE.Vector2();\n if (readBuffer == null) {\n this.renderOcclusionMapFromScene(renderer, dimensions, view_id);\n } else {\n this.renderOcclusionMapFromReadBuffer(\n renderer, readBuffer, dimensions, view_id);\n }\n\n // Blur the occlusion map\n this.blurOcclusionMap(renderer, dimensions);\n\n // Fuse the rendered image and the occlusion map.\n this.applyOcclusionMapToRenderedImage(renderer, readBuffer, writeBuffer);\n renderer.setRenderTarget(originalRenderTarget);\n }\n\n renderOcclusionMapFromScene(\n renderer: THREE.WebGLRenderer, dimensions: THREE.Vector2,\n view_id: number) {\n // Compute our own read buffer.\n this.occlusionMeshMaterial.uniforms.uDepthTexture.value =\n this.depthTextures[view_id];\n this.scene.overrideMaterial = this.occlusionMeshMaterial;\n renderer.getDrawingBufferSize(dimensions);\n this.occlusionMapTexture.setSize(dimensions.x, dimensions.y);\n const renderTarget = this.occlusionMapTexture;\n renderer.setRenderTarget(renderTarget);\n const camera = renderer.xr.getCamera().cameras[view_id] || this.camera;\n const originalCameraLayers =\n Array.from(Array(32).keys())\n .filter(element => camera.layers.isEnabled(element));\n camera.layers.set(this.occludableItemsLayer);\n renderer.render(this.scene, camera);\n camera.layers.disableAll();\n originalCameraLayers.forEach(element => {\n camera.layers.enable(element);\n });\n this.scene.overrideMaterial = null;\n }\n\n renderOcclusionMapFromReadBuffer(\n renderer: THREE.WebGLRenderer, readBuffer: THREE.RenderTarget,\n dimensions: THREE.Vector2, view_id: number) {\n // Convert the readBuffer into an occlusion map.\n // Render depth into texture\n this.occlusionMapUniforms.tDiffuse.value = readBuffer.texture;\n this.occlusionMapUniforms.tDepth.value = readBuffer.depthTexture;\n this.occlusionMapUniforms.uDepthTexture.value = this.depthTextures[view_id];\n\n // First render the occlusion map to an intermediate buffer.\n renderer.getDrawingBufferSize(dimensions);\n this.occlusionMapTexture.setSize(dimensions.x, dimensions.y);\n renderer.setRenderTarget(this.occlusionMapTexture);\n this.occlusionMapQuad.render(renderer);\n }\n\n blurOcclusionMap(renderer: THREE.WebGLRenderer, dimensions: THREE.Vector2) {\n for (let i = 0; i < 3; i++) {\n this.kawaseBlurTargets[i].setSize(\n dimensions.x / (2 ** i), dimensions.y / (2 ** i));\n }\n for (let i = 0; i < 3; i++) {\n (this.kawaseBlurQuads[i].material as THREE.ShaderMaterial)\n .uniforms.uTexelSize.value.set(\n 1 / (dimensions.x / (2 ** i)), 1 / (dimensions.y / (2 ** i)));\n (this.kawaseBlurQuads[this.kawaseBlurQuads.length - 1 - i].material as\n THREE.ShaderMaterial)\n .uniforms.uTexelSize.value.set(\n 1 / (dimensions.x / (2 ** (i - 1))),\n 1 / (dimensions.y / (2 ** (i - 1))));\n }\n renderer.setRenderTarget(this.kawaseBlurTargets[0]);\n this.kawaseBlurQuads[0].render(renderer);\n renderer.setRenderTarget(this.kawaseBlurTargets[1]);\n this.kawaseBlurQuads[1].render(renderer);\n renderer.setRenderTarget(this.kawaseBlurTargets[2]);\n this.kawaseBlurQuads[2].render(renderer);\n renderer.setRenderTarget(this.kawaseBlurTargets[1]);\n this.kawaseBlurQuads[3].render(renderer);\n renderer.setRenderTarget(this.kawaseBlurTargets[0]);\n this.kawaseBlurQuads[4].render(renderer);\n renderer.setRenderTarget(this.occlusionMapTexture);\n this.kawaseBlurQuads[5].render(renderer);\n }\n\n applyOcclusionMapToRenderedImage(\n renderer: THREE.WebGLRenderer, readBuffer?: THREE.WebGLRenderTarget,\n writeBuffer?: THREE.WebGLRenderTarget) {\n if (readBuffer && (this.renderToScreen || writeBuffer)) {\n this.occlusionUniforms.tDiffuse.value = readBuffer.texture;\n renderer.setRenderTarget(\n writeBuffer && !this.renderToScreen ? writeBuffer : null);\n this.occlusionQuad.render(renderer);\n }\n }\n\n dispose() {\n this.occlusionMeshMaterial.dispose();\n this.occlusionMapTexture.dispose();\n for (let i = 0; i < this.kawaseBlurQuads.length; i++) {\n this.kawaseBlurQuads[i].dispose();\n }\n }\n\n updateOcclusionMapUniforms(\n uniforms: ShaderUniforms, renderer: THREE.WebGLRenderer) {\n const camera = renderer.xr.getCamera().cameras[0] || this.camera;\n uniforms.tOcclusionMap.value = this.occlusionMapTexture.texture;\n uniforms.uOcclusionClipFromWorld.value.copy(camera.projectionMatrix)\n .multiply(camera.matrixWorldInverse);\n }\n}\n","import * as THREE from 'three';\n\nimport {Registry} from '../core/components/Registry';\nimport {onDesktopUserAgent} from '../utils/BrowserUtils';\nimport type {Shader} from '../utils/Types';\nimport {clamp} from '../utils/utils';\n\nimport {DepthMesh} from './DepthMesh';\nimport {DepthOptions} from './DepthOptions';\nimport {DepthTextures} from './DepthTextures';\nimport {OcclusionPass} from './occlusion/OcclusionPass';\n\nconst DEFAULT_DEPTH_WIDTH = 160;\nconst DEFAULT_DEPTH_HEIGHT = DEFAULT_DEPTH_WIDTH;\nconst clipSpacePosition = new THREE.Vector3();\n\nexport type DepthArray = Float32Array|Uint16Array;\n\nexport class Depth {\n static instance?: Depth;\n\n // The main camera.\n private camera!: THREE.Camera;\n private renderer!: THREE.WebGLRenderer;\n private scene!: THREE.Scene;\n private projectionMatrixInverse = new THREE.Matrix4();\n private xrRefSpace?: XRReferenceSpace|XRBoundedReferenceSpace;\n\n view: XRView[] = [];\n depthData: XRCPUDepthInformation[] = [];\n depthArray: DepthArray[] = [];\n depthMesh?: DepthMesh;\n private depthTextures?: DepthTextures;\n options = new DepthOptions();\n width = DEFAULT_DEPTH_WIDTH;\n height = DEFAULT_DEPTH_HEIGHT;\n rawValueToMeters = 0.0010000000474974513;\n occludableShaders = new Set<Shader>();\n private occlusionPass?: OcclusionPass;\n\n\n // Whether we're counting the number of depth clients.\n private depthClientsInitialized = false;\n private depthClients = new Set<object>();\n\n /**\n * Depth is a lightweight manager based on three.js to simply prototyping\n * with Depth in WebXR.\n */\n constructor() {\n if (Depth.instance) {\n return Depth.instance;\n }\n Depth.instance = this;\n }\n\n /**\n * Initialize Depth manager.\n */\n init(\n camera: THREE.PerspectiveCamera, options: DepthOptions,\n renderer: THREE.WebGLRenderer, registry: Registry, scene: THREE.Scene) {\n this.camera = camera;\n this.options = options;\n this.renderer = renderer;\n this.scene = scene;\n\n if (this.options.depthTexture.enabled) {\n this.depthTextures = new DepthTextures(options);\n registry.register(this.depthTextures);\n }\n\n if (this.options.depthMesh.enabled) {\n this.depthMesh =\n new DepthMesh(options, this.width, this.height, this.depthTextures);\n registry.register(this.depthMesh);\n if (this.options.depthMesh.renderShadow) {\n this.renderer.shadowMap.enabled = true;\n this.renderer.shadowMap.type = THREE.PCFShadowMap;\n }\n camera.add(this.depthMesh);\n scene.add(camera);\n }\n\n if (this.options.occlusion.enabled) {\n this.occlusionPass = new OcclusionPass(scene, camera);\n }\n }\n\n /**\n * Retrieves the depth at normalized coordinates (u, v).\n * @param u - Normalized horizontal coordinate.\n * @param v - Normalized vertical coordinate.\n * @returns Depth value at the specified coordinates.\n */\n getDepth(u: number, v: number) {\n if (!this.depthArray[0]) return 0.0;\n const depthX = Math.round(clamp(u * this.width, 0, this.width - 1));\n const depthY =\n Math.round(clamp((1.0 - v) * this.height, 0, this.height - 1));\n const rawDepth = this.depthArray[0][depthY * this.width + depthX];\n return this.rawValueToMeters * rawDepth;\n }\n\n /**\n * Projects the given world position to clip space and then to view\n * space using the depth.\n * @param position - The world position to project.\n */\n getProjectedDepthViewPositionFromWorldPosition(\n position: THREE.Vector3, target = new THREE.Vector3()) {\n const camera = this.renderer.xr?.getCamera?.()?.cameras?.[0] || this.camera;\n clipSpacePosition.copy(position)\n .applyMatrix4(camera.matrixWorldInverse)\n .applyMatrix4(camera.projectionMatrix);\n const u = 0.5 * (clipSpacePosition.x + 1.0);\n const v = 0.5 * (clipSpacePosition.y + 1.0);\n const depth = this.getDepth(u, v);\n target.set(2.0 * (u - 0.5), 2.0 * (v - 0.5), -1);\n target.applyMatrix4(camera.projectionMatrixInverse);\n target.multiplyScalar((target.z - depth) / target.z);\n return target;\n }\n\n /**\n * Retrieves the depth at normalized coordinates (u, v).\n * @param u - Normalized horizontal coordinate.\n * @param v - Normalized vertical coordinate.\n * @returns Vertex at (u, v)\n */\n getVertex(u: number, v: number) {\n if (!this.depthArray[0]) return null;\n\n const depthX = Math.round(clamp(u * this.width, 0, this.width - 1));\n const depthY =\n Math.round(clamp((1.0 - v) * this.height, 0, this.height - 1));\n const rawDepth = this.depthArray[0][depthY * this.width + depthX];\n const depth = this.rawValueToMeters * rawDepth;\n const vertexPosition =\n new THREE.Vector3(2.0 * (u - 0.5), 2.0 * (v - 0.5), -1);\n vertexPosition.applyMatrix4(this.projectionMatrixInverse);\n vertexPosition.multiplyScalar(-depth / vertexPosition.z);\n return vertexPosition;\n }\n\n updateDepthData(depthData: XRCPUDepthInformation, view_id = 0) {\n this.depthData[view_id] = depthData;\n // Workaround for b/382679381.\n this.rawValueToMeters = depthData.rawValueToMeters;\n if (this.options.useFloat32) {\n this.rawValueToMeters = 1.0;\n }\n\n // Updates Depth Array.\n if (this.depthArray[view_id] == null) {\n this.depthArray[view_id] = this.options.useFloat32 ?\n new Float32Array(depthData.data) :\n new Uint16Array(depthData.data);\n this.width = depthData.width;\n this.height = depthData.height;\n } else {\n // Copies the data from an ArrayBuffer to the existing TypedArray.\n this.depthArray[view_id].set(\n this.options.useFloat32 ? new Float32Array(depthData.data) :\n new Uint16Array(depthData.data));\n }\n\n // Updates Depth Texture.\n if (this.options.depthTexture.enabled && this.depthTextures) {\n this.depthTextures.update(depthData, view_id);\n }\n\n if (this.options.depthMesh.enabled && this.depthMesh && view_id == 0) {\n this.depthMesh.updateDepth(depthData)\n }\n }\n\n getTexture(view_id: number) {\n if (!this.options.depthTexture.enabled) return undefined;\n return this.depthTextures?.get(view_id);\n }\n\n update(frame: XRFrame) {\n if (!this.options.enabled) return;\n\n this.updateLocalDepth(frame);\n if (this.options.occlusion.enabled) {\n this.renderOcclusionPass();\n }\n }\n\n updateLocalDepth(frame: XRFrame) {\n if (onDesktopUserAgent()) {\n return;\n }\n\n const leftCamera = this.renderer.xr?.getCamera?.()?.cameras?.[0];\n if (leftCamera && this.depthMesh && this.depthMesh.parent != leftCamera) {\n leftCamera.add(this.depthMesh);\n this.scene.add(leftCamera);\n }\n\n if (!frame) return;\n const session = frame.session;\n\n // Enable or disable depth based on the number of clients.\n const pausingDepthSupported = session.depthActive !== undefined;\n if (pausingDepthSupported && this.depthClientsInitialized) {\n const needsDepth = this.depthClients.size > 0;\n if (session.depthActive && !needsDepth) {\n session.pauseDepthSensing?.();\n } else if (!session.depthActive && needsDepth) {\n session.resumeDepthSensing?.();\n }\n if (this.depthClients.size == 0) {\n return;\n }\n }\n\n if (this.xrRefSpace == null) {\n session.requestReferenceSpace('local').then((refSpace) => {\n this.xrRefSpace = refSpace;\n });\n session.addEventListener('end', () => {\n this.xrRefSpace = undefined;\n });\n } else {\n const pose = frame.getViewerPose(this.xrRefSpace);\n if (pose) {\n for (let view_id = 0; view_id < pose.views.length; ++view_id) {\n const view = pose.views[view_id];\n this.view[view_id] = view;\n const depthData = frame.getDepthInformation(view);\n if (!depthData) {\n return;\n }\n this.updateDepthData(depthData, view_id);\n }\n } else {\n console.error('Pose unavailable in the current frame.');\n }\n }\n }\n\n renderOcclusionPass() {\n const leftDepthTexture = this.getTexture(0);\n if (leftDepthTexture) {\n this.occlusionPass!.setDepthTexture(\n leftDepthTexture, this.rawValueToMeters, 0);\n }\n const rightDepthTexture = this.getTexture(1);\n if (rightDepthTexture) {\n this.occlusionPass!.setDepthTexture(\n rightDepthTexture, this.rawValueToMeters, 1);\n }\n const xrIsPresenting = this.renderer.xr.isPresenting;\n this.renderer.xr.isPresenting = false;\n this.occlusionPass!.render(this.renderer, undefined, undefined, 0);\n this.renderer.xr.isPresenting = xrIsPresenting;\n for (const shader of this.occludableShaders) {\n this.occlusionPass!.updateOcclusionMapUniforms(\n shader.uniforms, this.renderer);\n }\n }\n\n debugLog() {\n const arrayBuffer = this.depthData[0].data;\n const uint8Array = new Uint8Array(arrayBuffer);\n // Convert Uint8Array to a string where each character represents a byte\n const binaryString =\n Array.from(uint8Array, byte => String.fromCharCode(byte)).join('');\n // Convert binary string to base64\n const data_str = btoa(binaryString);\n console.log(data_str);\n }\n\n resumeDepth(client: object) {\n this.depthClientsInitialized = true;\n this.depthClients.add(client);\n }\n\n pauseDepth(client: object) {\n this.depthClientsInitialized = true;\n this.depthClients.delete(client);\n }\n};\n","import * as THREE from 'three';\n\nimport {Depth} from '../depth/Depth';\nimport {clamp} from '../utils/utils';\n\nimport {XRDeviceCamera} from './XRDeviceCamera';\n\nexport const aspectRatios = {\n depth: 1.0,\n RGB: 4 / 3\n};\n\n/**\n * Parameters for RGB to depth UV mapping (manually calibrated for aspect\n * ratios. For RGB and depth, 4:3 and 1:1, respectively.\n */\nexport const rgbToDepthParams = {\n scale: 1,\n scaleX: 0.75,\n scaleY: 0.63,\n translateU: 0.2,\n translateV: -0.02,\n k1: -0.046,\n k2: 0,\n k3: 0,\n p1: 0,\n p2: 0,\n xc: 0,\n yc: 0,\n};\n\n/**\n * Maps a UV coordinate from a RGB space to a destination depth space,\n * applying Brown-Conrady distortion and affine transformations based on\n * aspect ratios. If the simulator camera is used, no transformation is applied.\n *\n * @param rgbUv - The RGB UV coordinate, e.g., \\{ u: 0.5, v: 0.5 \\}.\n * @param xrDeviceCamera - The device camera instance.\n * @returns The transformed UV coordinate in the depth image space, or null if\n * inputs are invalid.\n */\nexport function transformRgbToDepthUv(\n rgbUv: {u: number, v: number}, xrDeviceCamera?: XRDeviceCamera) {\n if (xrDeviceCamera?.simulatorCamera) {\n // The simulator camera crops the viewport image to match its aspect ratio,\n // while the depth map covers the entire viewport, so we adjust for this.\n const viewportAspect = window.innerWidth / window.innerHeight;\n const cameraAspect = xrDeviceCamera.simulatorCamera.width /\n xrDeviceCamera.simulatorCamera.height;\n let {u, v} = rgbUv;\n\n if (viewportAspect > cameraAspect) {\n // The camera image is a centered vertical slice of the full render.\n const relativeWidth = cameraAspect / viewportAspect;\n u = u * relativeWidth + (1.0 - relativeWidth) / 2.0;\n } else {\n // The camera image is a centered horizontal slice of the full render.\n const relativeHeight = viewportAspect / cameraAspect;\n v = v * relativeHeight + (1.0 - relativeHeight) / 2.0;\n }\n return {u, v: 1.0 - v};\n }\n\n if (!aspectRatios || !aspectRatios.depth || !aspectRatios.RGB) {\n console.error('Invalid aspect ratios provided.');\n return null;\n }\n\n // Determine the relative scaling required to fit the overlay within the base\n let relativeScaleX, relativeScaleY;\n if (aspectRatios.depth > aspectRatios.RGB) {\n // Base is wider than overlay (\"letterboxing\")\n relativeScaleY = 1.0;\n relativeScaleX = aspectRatios.RGB / aspectRatios.depth;\n } else {\n // Base is narrower than overlay (\"pillarboxing\")\n relativeScaleX = 1.0;\n relativeScaleY = aspectRatios.depth / aspectRatios.RGB;\n }\n\n // Convert input source UV [0, 1] to a normalized coordinate space [-0.5, 0.5]\n const u_norm = rgbUv.u - 0.5;\n const v_norm = rgbUv.v - 0.5;\n\n // Apply the FORWARD Brown-Conrady distortion model\n const u_centered = u_norm - rgbToDepthParams.xc;\n const v_centered = v_norm - rgbToDepthParams.yc;\n const r2 = u_centered * u_centered + v_centered * v_centered;\n const radial = 1 + rgbToDepthParams.k1 * r2 + rgbToDepthParams.k2 * r2 * r2 +\n rgbToDepthParams.k3 * r2 * r2 * r2;\n const tanX = 2 * rgbToDepthParams.p1 * u_centered * v_centered +\n rgbToDepthParams.p2 * (r2 + 2 * u_centered * u_centered);\n const tanY = rgbToDepthParams.p1 * (r2 + 2 * v_centered * v_centered) +\n 2 * rgbToDepthParams.p2 * u_centered * v_centered;\n const u_distorted = u_centered * radial + tanX + rgbToDepthParams.xc;\n const v_distorted = v_centered * radial + tanY + rgbToDepthParams.yc;\n\n // Apply initial aspect ratio scaling and translation\n const u_fitted = u_distorted * relativeScaleX + rgbToDepthParams.translateU;\n const v_fitted = v_distorted * relativeScaleY + rgbToDepthParams.translateV;\n\n // Apply the final user-controlled scaling (zoom and stretch)\n const finalNormX =\n u_fitted * rgbToDepthParams.scale * rgbToDepthParams.scaleX;\n const finalNormY =\n v_fitted * rgbToDepthParams.scale * rgbToDepthParams.scaleY;\n\n // Convert the final normalized coordinate back to a UV coordinate [0, 1]\n const finalU = finalNormX + 0.5;\n const finalV = finalNormY + 0.5;\n\n return {u: finalU, v: 1.0 - finalV};\n}\n\n/**\n * Retrieves the world space position of a given RGB UV coordinate.\n * Note: it is essential that the coordinates, depth array, and projection\n * matrix all correspond to the same view ID (e.g., 0 for left). It is also\n * advised that all of these are obtained at the same time.\n *\n * @param rgbUv - The RGB UV coordinate, e.g., \\{ u: 0.5, v: 0.5 \\}.\n * @param depthArray - Array containing depth data.\n * @param viewProjectionMatrix - XRView object with corresponding\n * projection matrix.\n * @param matrixWorld - Matrix for view-to-world translation.\n * @param xrDeviceCamera - The device camera instance.\n * @param xrDepth - The SDK's Depth module.\n * @returns Vertex at (u, v) in world space.\n */\nexport function transformRgbUvToWorld(\n rgbUv: {u: number, v: number},\n depthArray: number[]|Uint16Array|Float32Array,\n viewProjectionMatrix: THREE.Matrix4, matrixWorld: THREE.Matrix4,\n xrDeviceCamera?: XRDeviceCamera, xrDepth = Depth.instance) {\n if (!depthArray || !viewProjectionMatrix || !matrixWorld || !xrDepth)\n return null;\n const depthUV = transformRgbToDepthUv(rgbUv, xrDeviceCamera);\n if (!depthUV) {\n return null;\n }\n\n const {u: depthU, v: depthV} = depthUV;\n const depthX =\n Math.round(clamp(depthU * xrDepth.width, 0, xrDepth.width - 1));\n\n // Invert depthV for array access, as image arrays are indexed from top-left.\n const depthY =\n Math.round(clamp((1.0 - depthV) * xrDepth.height, 0, xrDepth.height - 1));\n const rawDepthValue = depthArray[depthY * xrDepth.width + depthX];\n const depthInMeters = xrDepth.rawValueToMeters * rawDepthValue;\n\n // Convert UV to normalized device coordinates and create a point on the near\n // plane.\n const viewSpacePosition =\n new THREE.Vector3(2.0 * (depthU - 0.5), 2.0 * (depthV - 0.5), -1);\n\n const viewProjectionMatrixInverse = viewProjectionMatrix.clone().invert();\n\n // Unproject the point from clip space to view space and scale it along the\n // ray from the camera to the correct depth. Camera looks down -Z axis.\n viewSpacePosition.applyMatrix4(viewProjectionMatrixInverse);\n viewSpacePosition.multiplyScalar(-depthInMeters / viewSpacePosition.z);\n\n const worldPosition = viewSpacePosition.clone().applyMatrix4(matrixWorld);\n return worldPosition;\n}\n\n/**\n * Asynchronously crops a base64 encoded image using a THREE.Box2 bounding box.\n * This function creates an in-memory image, draws a specified portion of it to\n * a canvas, and then returns the canvas content as a new base64 string.\n * @param base64Image - The base64 string of the source image. Can be a raw\n * string or a full data URI.\n * @param boundingBox - The bounding box with relative coordinates (0-1) for\n * cropping.\n * @returns A promise that resolves with the base64 string of the cropped image.\n */\nexport async function cropImage(base64Image: string, boundingBox: THREE.Box2) {\n if (!base64Image) {\n throw new Error('No image data provided for cropping.');\n }\n\n const img = new Image();\n await new Promise((resolve, reject) => {\n img.onload = resolve;\n img.onerror = (err) => {\n console.error('Error loading image for cropping:', err);\n reject(new Error('Failed to load image for cropping.'));\n };\n img.src = base64Image.startsWith('data:image') ?\n base64Image :\n `data:image/png;base64,${base64Image}`;\n });\n\n const canvas = document.createElement('canvas');\n const ctx = canvas.getContext('2d')!;\n\n // Create a unit box and find the intersection to clamp coordinates.\n const unitBox =\n new THREE.Box2(new THREE.Vector2(0, 0), new THREE.Vector2(1, 1));\n const clampedBox = boundingBox.clone().intersect(unitBox);\n\n const cropSize = new THREE.Vector2();\n clampedBox.getSize(cropSize);\n\n // If the resulting crop area has no size, return an empty image.\n if (cropSize.x === 0 || cropSize.y === 0) {\n return 'data:image/png;base64,';\n }\n\n // Calculate absolute pixel values from relative coordinates.\n const sourceX = img.width * clampedBox.min.x;\n const sourceY = img.height * clampedBox.min.y;\n const sourceWidth = img.width * cropSize.x;\n const sourceHeight = img.height * cropSize.y;\n\n // Set canvas size to the cropped image size.\n canvas.width = sourceWidth;\n canvas.height = sourceHeight;\n\n // Draw the cropped portion of the source image onto the canvas.\n ctx.drawImage(\n img, sourceX, sourceY, sourceWidth, sourceHeight, // Source rectangle\n 0, 0, sourceWidth, sourceHeight // Destination rectangle\n );\n\n return canvas.toDataURL('image/png');\n}\n","import * as THREE from 'three';\n\nimport {Script} from '../core/Script';\n\n/**\n * Enum for video stream states.\n */\nexport enum StreamState {\n IDLE = 'idle',\n INITIALIZING = 'initializing',\n STREAMING = 'streaming',\n ERROR = 'error',\n NO_DEVICES_FOUND = 'no_devices_found',\n}\n\nexport type VideoStreamDetails = {\n force?: boolean;\n error?: Error;\n}\n\nexport interface VideoStreamEventMap<T> extends THREE.Object3DEventMap {\n statechange: {state: StreamState, details?: T};\n}\n\nexport type VideoStreamGetSnapshotOptions = {\n /** The target width, defaults to the video width. */\n width?: number;\n /** The target height, defaults to the video height. */\n height?: number;\n /** The output format, defaults to 'texture'. */\n outputFormat?: 'texture' | 'base64' | 'imageData';\n /** The MIME type for base64 output. */\n mimeType?: string;\n /** The quality for base64 output. */\n quality?: number;\n};\n\nexport type VideoStreamOptions = {\n /** Hint for performance optimization for frequent captures. */\n willCaptureFrequently?: boolean;\n};\n\n/**\n * The base class for handling video streams (from camera or file), managing\n * the underlying <video> element, streaming state, and snapshot logic.\n */\nexport class VideoStream<T extends VideoStreamDetails =\n VideoStreamDetails> extends\n Script<VideoStreamEventMap<T>> {\n loaded = false;\n width?: number;\n height?: number;\n aspectRatio?: number;\n texture: THREE.VideoTexture;\n state = StreamState.IDLE;\n\n protected stream_: MediaStream|null = null;\n protected video_ = document.createElement('video');\n\n private willCaptureFrequently_: boolean;\n private frozenTexture_: THREE.Texture|null = null;\n private canvas_: HTMLCanvasElement|null = null;\n private context_: CanvasRenderingContext2D|null = null;\n\n\n /**\n * @param options - The configuration options.\n */\n constructor({willCaptureFrequently = false}: VideoStreamOptions = {}) {\n super();\n\n this.willCaptureFrequently_ = willCaptureFrequently;\n this.video_.autoplay = true;\n this.video_.muted = true;\n this.video_.playsInline = true;\n\n this.texture = new THREE.VideoTexture(this.video_);\n this.texture.colorSpace = THREE.SRGBColorSpace;\n this.texture.minFilter = THREE.LinearFilter;\n this.texture.magFilter = THREE.LinearFilter;\n }\n\n /**\n * Sets the stream's state and dispatches a 'statechange' event.\n * @param state - The new state.\n * @param details - Additional data for the event payload.\n */\n protected setState_(state: StreamState, details: VideoStreamDetails|T = {}) {\n if (this.state === state && !details.force) return;\n this.state = state;\n this.dispatchEvent({type: 'statechange', state: this.state, ...details});\n console.debug(\n `VideoStream state changed to ${state} with details:`, details);\n }\n\n /**\n * Processes video metadata, sets dimensions, and resolves a promise.\n * @param resolve - The resolve function of the wrapping Promise.\n * @param reject - The reject function of the wrapping Promise.\n * @param allowRetry - Whether to allow a retry attempt on failure.\n */\n protected handleVideoStreamLoadedMetadata(\n resolve: () => void, reject: (_: Error) => void, allowRetry = false) {\n try {\n if (this.video_.videoWidth > 0 && this.video_.videoHeight > 0) {\n this.width = this.video_.videoWidth;\n this.height = this.video_.videoHeight;\n this.aspectRatio = this.width / this.height;\n this.loaded = true;\n resolve();\n } else if (allowRetry) {\n setTimeout(() => {\n this.handleVideoStreamLoadedMetadata(resolve, reject, false);\n }, 500);\n } else {\n const error = new Error('Failed to get valid video dimensions.');\n this.setState_(StreamState.ERROR, {error});\n reject(error);\n }\n } catch (error) {\n if (error instanceof Error) {\n this.setState_(StreamState.ERROR, {error});\n reject(error);\n }\n }\n }\n\n /**\n * Captures the current video frame.\n * @param options - The options for the snapshot.\n * @returns The captured data.\n */\n getSnapshot({\n width = this.width,\n height = this.height,\n outputFormat = 'texture',\n mimeType = 'image/jpeg',\n quality = 0.9\n }: VideoStreamGetSnapshotOptions = {}) {\n if (!this.loaded || !width || !height ||\n this.video_.readyState < this.video_.HAVE_CURRENT_DATA) {\n return null;\n }\n\n if (width > this.width! || height > this.height!) {\n console.warn(`The requested snapshot width (${width}px x ${\n height}px) is larger than the source video width (${this.width}px x ${\n this.height}px). The snapshot will be upscaled.`);\n }\n\n try {\n // Re-initialize canvas only if dimensions have changed.\n if (!this.canvas_ || this.canvas_.width !== width ||\n this.canvas_.height !== height) {\n this.canvas_ = document.createElement('canvas');\n this.canvas_.width = width;\n this.canvas_.height = height;\n this.context_ =\n this.canvas_.getContext(\n '2d', {willCaptureFrequently: this.willCaptureFrequently_}) as\n CanvasRenderingContext2D;\n }\n\n this.context_!.drawImage(this.video_, 0, 0, width, height);\n switch (outputFormat) {\n case 'imageData':\n return this.context_!.getImageData(0, 0, width, height);\n case 'base64':\n return this.canvas_.toDataURL(mimeType, quality);\n case 'texture':\n default: {\n const frozenTexture = new THREE.Texture(this.canvas_);\n frozenTexture.needsUpdate = true;\n frozenTexture.colorSpace = THREE.SRGBColorSpace;\n this.frozenTexture_ = frozenTexture;\n return this.frozenTexture_;\n }\n }\n } catch (error) {\n console.error('Error capturing snapshot:', error);\n return null;\n }\n }\n\n /**\n * Stops the current video stream tracks.\n */\n protected stop_() {\n if (this.stream_) {\n this.stream_.getTracks().forEach(track => track.stop());\n this.stream_ = null;\n }\n if (this.video_.srcObject) {\n this.video_.srcObject = null;\n }\n if (this.video_.src && this.video_.src.startsWith('blob:')) {\n URL.revokeObjectURL(this.video_.src);\n }\n this.video_.src = '';\n this.loaded = false;\n this.setState_(StreamState.IDLE);\n }\n\n /**\n * Disposes of all resources used by this stream.\n */\n override dispose() {\n this.stop_();\n this.texture?.dispose();\n this.frozenTexture_?.dispose();\n this.canvas_ = null;\n this.context_ = null;\n super.dispose();\n }\n}\n","import {SimulatorCamera} from '../simulator/SimulatorCamera';\nimport {SimulatorMediaDeviceInfo} from '../simulator/SimulatorMediaDeviceInfo';\nimport {StreamState, VideoStream, VideoStreamDetails} from '../video/VideoStream';\n\nimport {DeviceCameraOptions} from './CameraOptions';\n\nexport type MediaOrSimulatorMediaDeviceInfo =\n MediaDeviceInfo|SimulatorMediaDeviceInfo;\n\ntype XRDeviceCameraDetails = VideoStreamDetails&{\n width?: number;\n height?: number;\n aspectRatio?: number;\n device?: MediaOrSimulatorMediaDeviceInfo;\n}\n\n/**\n * Handles video capture from a device camera, manages the device list,\n * and reports its state using VideoStream's event model.\n */\nexport class XRDeviceCamera extends VideoStream<XRDeviceCameraDetails> {\n simulatorCamera?: SimulatorCamera;\n protected videoConstraints_: MediaTrackConstraints;\n private isInitializing_ = false;\n private availableDevices_: MediaOrSimulatorMediaDeviceInfo[] = [];\n private currentDeviceIndex_ = -1;\n private currentTrackSettings_?: MediaTrackSettings;\n\n /**\n * @param options - The configuration options.\n */\n constructor({\n videoConstraints = {facingMode: 'environment'},\n willCaptureFrequently = false\n }: Partial<DeviceCameraOptions> = {}) {\n super({willCaptureFrequently});\n this.videoConstraints_ = {...videoConstraints};\n }\n\n /**\n * Retrieves the list of available video input devices.\n * @returns A promise that resolves with an\n * array of video devices.\n */\n async getAvailableVideoDevices() {\n if (!navigator.mediaDevices?.enumerateDevices) {\n console.warn(\n 'navigator.mediaDevices.enumerateDevices() is not supported.');\n return [];\n }\n const devices: MediaOrSimulatorMediaDeviceInfo[] =\n [...await navigator.mediaDevices.enumerateDevices()];\n if (this.simulatorCamera) {\n const simulatorDevices = await this.simulatorCamera.enumerateDevices();\n devices.push(...simulatorDevices);\n }\n return devices.filter(device => device.kind === 'videoinput');\n }\n\n /**\n * Initializes the camera based on the initial constraints.\n */\n async init() {\n this.setState_(StreamState.INITIALIZING);\n try {\n this.availableDevices_ = await this.getAvailableVideoDevices();\n\n if (this.availableDevices_.length > 0) {\n await this.initStream_();\n } else {\n this.setState_(StreamState.NO_DEVICES_FOUND);\n console.warn('No video devices found.');\n }\n } catch (error) {\n this.setState_(StreamState.ERROR, {error: error as Error});\n console.error('Error initializing XRDeviceCamera:', error);\n throw error;\n }\n }\n\n /**\n * Initializes the media stream from the user's camera. After the stream\n * starts, it updates the current device index based on the stream's active\n * track.\n */\n protected async initStream_() {\n if (this.isInitializing_) return;\n this.isInitializing_ = true;\n this.setState_(StreamState.INITIALIZING);\n\n // Reset state for the new stream\n this.currentTrackSettings_ = undefined;\n this.currentDeviceIndex_ = -1;\n try {\n console.debug(\n 'Requesting media stream with constraints:', this.videoConstraints_);\n let stream = null;\n\n const deviceIdConstraint = this.videoConstraints_.deviceId;\n const targetDeviceId = typeof deviceIdConstraint === 'string' ?\n deviceIdConstraint :\n Array.isArray(deviceIdConstraint) ? deviceIdConstraint[0] :\n deviceIdConstraint?.exact;\n\n const useSimulatorCamera = !!this.simulatorCamera &&\n ((targetDeviceId &&\n this.availableDevices_.find(d => d.deviceId === targetDeviceId)\n ?.groupId === 'simulator') ||\n (!targetDeviceId &&\n this.videoConstraints_.facingMode === 'environment'));\n\n if (useSimulatorCamera) {\n stream = this.simulatorCamera!.getMedia(this.videoConstraints_);\n if (!stream) {\n throw new Error('Simulator camera failed to provide a media stream.');\n }\n } else {\n // Otherwise, request the stream from the browser.\n stream = await navigator.mediaDevices.getUserMedia(\n {video: this.videoConstraints_});\n }\n\n const videoTracks = stream?.getVideoTracks() || [];\n\n if (!videoTracks.length) {\n throw new Error('MediaStream has no video tracks.');\n }\n\n // After the stream is active, we can get the ID of the track\n const activeTrack = videoTracks[0];\n this.currentTrackSettings_ = activeTrack.getSettings();\n console.debug('Active track settings:', this.currentTrackSettings_);\n\n if (this.currentTrackSettings_.deviceId) {\n this.currentDeviceIndex_ = this.availableDevices_.findIndex(\n device => device.deviceId === this.currentTrackSettings_!.deviceId);\n } else {\n console.warn('Stream started without deviceId as it was unavailable');\n }\n\n this.stop_(); // Stop any previous stream before starting new one\n this.stream_ = stream;\n this.video_.srcObject = stream;\n this.video_.src = ''; // Required for some browsers to reset the src\n\n await new Promise<void>((resolve, reject) => {\n this.video_.onloadedmetadata = () => {\n this.handleVideoStreamLoadedMetadata(resolve, reject, true);\n };\n this.video_.onerror = () => {\n const error = new Error('Error playing camera stream.');\n this.setState_(StreamState.ERROR, {error});\n reject(error);\n };\n this.video_.play();\n });\n\n // Once the stream is loaded and dimensions are known, set the final state\n const details = {\n width: this.width,\n height: this.height,\n aspectRatio: this.aspectRatio,\n device: this.getCurrentDevice(),\n facingMode: this.currentTrackSettings_.facingMode,\n trackSettings: this.currentTrackSettings_,\n };\n this.setState_(StreamState.STREAMING, details);\n } catch (error) {\n this.setState_(StreamState.ERROR, {error: error as Error});\n throw error;\n } finally {\n this.isInitializing_ = false;\n }\n }\n\n /**\n * Sets the active camera by its device ID. Removes potentially conflicting\n * constraints such as facingMode.\n * @param deviceId - Device id.\n */\n async setDeviceId(deviceId: string) {\n const newIndex = this.availableDevices_.findIndex(\n device => device.deviceId === deviceId);\n if (newIndex === -1) {\n throw new Error(`Device with ID ${deviceId} not found.`);\n }\n if (newIndex === this.currentDeviceIndex_) {\n console.log(`Device ${deviceId} is already active.`);\n return;\n }\n delete this.videoConstraints_.facingMode;\n this.videoConstraints_.deviceId = {exact: deviceId};\n await this.initStream_();\n }\n\n /**\n * Sets the active camera by its facing mode ('user' or 'environment').\n * @param facingMode - facing mode\n */\n async setFacingMode(facingMode: VideoFacingModeEnum) {\n delete this.videoConstraints_.deviceId;\n this.videoConstraints_.facingMode = facingMode;\n this.currentDeviceIndex_ = -1;\n await this.initStream_();\n }\n\n /**\n * Gets the list of enumerated video devices.\n */\n getAvailableDevices() {\n return this.availableDevices_;\n }\n\n /**\n * Gets the currently active device info, if available.\n */\n getCurrentDevice() {\n if (this.currentDeviceIndex_ === -1 || !this.availableDevices_.length) {\n return undefined;\n }\n return this.availableDevices_[this.currentDeviceIndex_];\n }\n\n /**\n * Gets the settings of the currently active video track.\n */\n getCurrentTrackSettings() {\n return this.currentTrackSettings_;\n }\n\n /**\n * Gets the index of the currently active device.\n */\n getCurrentDeviceIndex() {\n return this.currentDeviceIndex_;\n }\n\n registerSimulatorCamera(simulatorCamera: SimulatorCamera) {\n this.simulatorCamera = simulatorCamera;\n this.init();\n }\n}\n","import type {Constructor} from '../../utils/Types';\n\nexport class Registry {\n private instances = new Map<Constructor, object>();\n\n /**\n * Registers an new instanceof a given type.\n * If an existing instance of the same type is already registered, it will be\n * overwritten.\n * @param instance - The instance to register.\n * @param type - Type to register the instance as. Will default to\n * `instance.constructor` if not defined.\n */\n register<T extends object>(instance: T, type?: Constructor<T>) {\n const registrationType = type ?? instance.constructor as Constructor<T>;\n if (instance instanceof registrationType) {\n this.instances.set(registrationType, instance);\n } else {\n throw new Error(`Instance of type '${\n instance.constructor\n .name}' is not an instance of the registration type '${\n registrationType.name}'.`);\n }\n }\n\n /**\n * Gets an existing instance of a registered type.\n * @param type - The constructor function of the type to retrieve.\n * @returns The instance of the requested type.\n */\n get<T extends object>(type: Constructor<T>): T|undefined {\n return this.instances.get(type) as T | undefined;\n }\n\n /**\n * Gets an existing instance of a registered type, or creates a new one if it\n * doesn't exist.\n * @param type - The constructor function of the type to retrieve.\n * @param factory - A function that creates a new instance of the type if it\n * doesn't already exist.\n * @returns The instance of the requested type.\n */\n getOrCreate<T extends object>(type: Constructor<T>, factory: () => T): T {\n let instance = this.get(type);\n if (instance === undefined) {\n instance = factory();\n if (!(instance instanceof type)) {\n throw new Error(`Factory for type ${\n type.name} returned an incompatible instance of type ${\n (instance.constructor as Constructor).name}.`);\n }\n // Register the new instance with the requested type.\n this.register(instance, type);\n }\n return instance;\n }\n\n /**\n * Unregisters an instance of a given type.\n * @param type - The type to unregister.\n */\n unregister(type: Constructor): void {\n this.instances.delete(type);\n }\n}\n","import * as THREE from 'three';\nimport {FullScreenQuad} from 'three/addons/postprocessing/Pass.js';\n\nimport {XRDeviceCamera} from '../../camera/XRDeviceCamera.js';\n\nfunction flipBufferVertically(\n buffer: Uint8Array, width: number, height: number) {\n const bytesPerRow = width * 4;\n const tempRow = new Uint8Array(bytesPerRow);\n for (let y = 0; y < height / 2; y++) {\n const topRowY = y;\n const bottomRowY = height - 1 - y;\n const topRowOffset = topRowY * bytesPerRow;\n const bottomRowOffset = bottomRowY * bytesPerRow;\n tempRow.set(buffer.subarray(topRowOffset, topRowOffset + bytesPerRow));\n buffer.set(\n buffer.subarray(bottomRowOffset, bottomRowOffset + bytesPerRow),\n topRowOffset);\n buffer.set(tempRow, bottomRowOffset);\n }\n}\n\nclass PendingScreenshotRequest {\n constructor(\n public resolve: (value: string) => void,\n public reject: (reason?: Error) => void, public overlayOnCamera: boolean) {}\n}\n\nexport class ScreenshotSynthesizer {\n private pendingScreenshotRequests: PendingScreenshotRequest[] = [];\n private virtualCanvas?: HTMLCanvasElement;\n private virtualBuffer = new Uint8Array();\n private virtualRealCanvas?: HTMLCanvasElement;\n private virtualRealBuffer = new Uint8Array();\n private realVirtualRenderTarget?: THREE.WebGLRenderTarget;\n private fullScreenQuad?: FullScreenQuad;\n\n async onAfterRender(\n renderer: THREE.WebGLRenderer, deviceCamera?: XRDeviceCamera) {\n if (this.pendingScreenshotRequests.length == 0) {\n return;\n }\n\n const renderTarget = renderer.getRenderTarget();\n if (renderTarget == null) {\n throw new Error('Expecting render target');\n }\n const haveVirtualOnlyRequests = this.pendingScreenshotRequests.every(\n (request) => !request.overlayOnCamera);\n if (haveVirtualOnlyRequests) {\n this.createVirtualImageDataURL(renderer).then((virtualImageDataUrl) => {\n this.resolveVirtualOnlyRequests(virtualImageDataUrl);\n });\n }\n\n const haveVirtualAndRealReqeusts = this.pendingScreenshotRequests.some(\n (request) => request.overlayOnCamera);\n if (haveVirtualAndRealReqeusts && deviceCamera) {\n this.createVirtualRealImageDataURL(renderer, deviceCamera)\n .then((virtualRealImageDataUrl) => {\n if (virtualRealImageDataUrl) {\n this.resolveVirtualRealRequests(virtualRealImageDataUrl);\n }\n });\n } else if (haveVirtualAndRealReqeusts) {\n throw new Error('No device camera provided');\n }\n }\n\n private async createVirtualImageDataURL(renderer: THREE.WebGLRenderer) {\n const renderTarget = renderer.getRenderTarget()!;\n if (this.virtualBuffer.length !=\n renderTarget.width * renderTarget.height * 4) {\n this.virtualBuffer =\n new Uint8Array(renderTarget.width * renderTarget.height * 4);\n }\n const buffer = this.virtualBuffer;\n await renderer.readRenderTargetPixelsAsync(\n renderTarget, 0, 0, renderTarget.width, renderTarget.height, buffer);\n\n flipBufferVertically(buffer, renderTarget.width, renderTarget.height);\n const canvas = this.virtualCanvas ||\n (this.virtualCanvas = document.createElement('canvas'));\n canvas.width = renderTarget.width;\n canvas.height = renderTarget.height;\n const context = canvas.getContext('2d');\n if (!context) {\n throw new Error('Failed to get 2D context');\n }\n const imageData = new ImageData(\n new Uint8ClampedArray(buffer), renderTarget.width, renderTarget.height);\n context.putImageData(imageData, 0, 0);\n return canvas.toDataURL();\n }\n\n private resolveVirtualOnlyRequests(virtualImageDataUrl: string) {\n let remainingRequests = 0;\n for (let i = 0; i < this.pendingScreenshotRequests.length; i++) {\n const request = this.pendingScreenshotRequests[i];\n if (!request.overlayOnCamera) {\n request.resolve(virtualImageDataUrl);\n } else {\n this.pendingScreenshotRequests[remainingRequests++] = request;\n }\n }\n this.pendingScreenshotRequests.length = remainingRequests;\n }\n\n private async createVirtualRealImageDataURL(\n renderer: THREE.WebGLRenderer, deviceCamera: XRDeviceCamera) {\n if (!deviceCamera.loaded) {\n console.log('Waiting for device camera to be loaded');\n return null;\n }\n if (!this.realVirtualRenderTarget) {\n this.realVirtualRenderTarget = new THREE.WebGLRenderTarget(640, 480);\n }\n const virtualRenderTarget = renderer.getRenderTarget()!;\n\n const renderTarget = this.realVirtualRenderTarget;\n renderer.setRenderTarget(renderTarget);\n const quad = this.getFullScreenQuad();\n (quad.material as THREE.MeshBasicMaterial).map = deviceCamera.texture;\n quad.render(renderer);\n (quad.material as THREE.MeshBasicMaterial).map =\n virtualRenderTarget.texture;\n quad.render(renderer);\n renderer.setRenderTarget(virtualRenderTarget);\n\n if (this.virtualRealBuffer.length !=\n renderTarget.width * renderTarget.height * 4) {\n this.virtualRealBuffer =\n new Uint8Array(renderTarget.width * renderTarget.height * 4);\n }\n const buffer = this.virtualRealBuffer;\n await renderer.readRenderTargetPixelsAsync(\n renderTarget, 0, 0, renderTarget.width, renderTarget.height, buffer);\n\n flipBufferVertically(buffer, renderTarget.width, renderTarget.height);\n const canvas = this.virtualRealCanvas ||\n (this.virtualRealCanvas = document.createElement('canvas'));\n canvas.width = renderTarget.width;\n canvas.height = renderTarget.height;\n const context = canvas.getContext('2d');\n if (!context) {\n throw new Error('Failed to get 2D context');\n }\n const imageData = new ImageData(\n new Uint8ClampedArray(buffer), renderTarget.width, renderTarget.height);\n context.putImageData(imageData, 0, 0);\n return canvas.toDataURL();\n }\n\n private resolveVirtualRealRequests(virtualRealImageDataUrl: string) {\n let remainingRequests = 0;\n for (let i = 0; i < this.pendingScreenshotRequests.length; i++) {\n const request = this.pendingScreenshotRequests[i];\n if (request.overlayOnCamera) {\n request.resolve(virtualRealImageDataUrl);\n } else {\n this.pendingScreenshotRequests[remainingRequests++] = request;\n }\n }\n this.pendingScreenshotRequests.length = remainingRequests;\n }\n\n private getFullScreenQuad() {\n if (!this.fullScreenQuad) {\n this.fullScreenQuad =\n new FullScreenQuad(new THREE.MeshBasicMaterial({transparent: true}));\n }\n return this.fullScreenQuad;\n }\n\n /**\n * Requests a screenshot from the scene as a DataURL.\n * @param overlayOnCamera - If true, overlays the image on a camera image\n * without any projection or aspect ratio correction.\n * @returns Promise which returns the screenshot.\n */\n async getScreenshot(overlayOnCamera = false) {\n return await new Promise((resolve, reject) => {\n this.pendingScreenshotRequests.push(\n new PendingScreenshotRequest(resolve, reject, overlayOnCamera));\n });\n }\n}\n","import * as THREE from 'three';\n\nimport {KeyEvent, Script, SelectEvent} from '../Script';\n\ntype MaybeScript = THREE.Object3D&{isXRScript?: boolean};\n\nexport class ScriptsManager {\n /** The set of all currently initialized scripts. */\n scripts = new Set<Script>();\n\n callSelectStartBound = this.callSelectStart.bind(this);\n callSelectEndBound = this.callSelectEnd.bind(this);\n callSelectBound = this.callSelect.bind(this);\n callSqueezeStartBound = this.callSqueezeStart.bind(this);\n callSqueezeEndBound = this.callSqueezeEnd.bind(this);\n callSqueezeBound = this.callSqueeze.bind(this);\n callKeyDownBound = this.callKeyDown.bind(this);\n callKeyUpBound = this.callKeyUp.bind(this);\n\n /** The set of scripts currently being initialized. */\n private initializingScripts = new Set<Script>();\n\n constructor(private initScriptFunction: (script: Script) => Promise<void>) {}\n\n /**\n * Initializes a script and adds it to the set of scripts which will receive\n * callbacks. This will be called automatically by Core when a script is found\n * in the scene but can also be called manually.\n * @param script - The script to initialize\n * @returns A promise which resolves when the script is initialized.\n */\n async initScript(script: Script) {\n if (this.scripts.has(script) || this.initializingScripts.has(script)) {\n return;\n }\n this.initializingScripts.add(script);\n await this.initScriptFunction(script);\n this.scripts.add(script);\n this.initializingScripts.delete(script);\n }\n\n /**\n * Uninitializes a script calling dispose and removes it from the set of\n * scripts which will receive callbacks.\n * @param script - The script to uninitialize.\n */\n uninitScript(script: Script) {\n if (!this.scripts.has(script)) {\n return;\n }\n script.dispose();\n this.scripts.delete(script);\n this.initializingScripts.delete(script);\n }\n\n /**\n * Finds all scripts in the scene and initializes them or uninitailizes them.\n * Returns a promise which resolves when all new scripts are finished\n * initalizing.\n * @param scene - The main scene which is used to find scripts.\n */\n async syncScriptsWithScene(scene: THREE.Scene) {\n const seenScripts = new Set<Script>();\n const promises: Promise<void>[] = [];\n scene.traverse((obj) => {\n if ((obj as MaybeScript).isXRScript) {\n const script = obj as Script;\n promises.push(this.initScript(script));\n seenScripts.add(script);\n }\n });\n await Promise.allSettled(promises);\n // Delete missing scripts.\n for (const script of this.scripts) {\n if (!seenScripts.has(script)) {\n this.uninitScript(script);\n }\n }\n }\n\n callSelectStart(event: SelectEvent) {\n for (const script of this.scripts) {\n script.onSelectStart(event);\n }\n }\n\n callSelectEnd(event: SelectEvent) {\n for (const script of this.scripts) {\n script.onSelectEnd(event);\n }\n }\n\n callSelect(event: SelectEvent) {\n for (const script of this.scripts) {\n script.onSelect(event);\n }\n }\n\n callSqueezeStart(event: SelectEvent) {\n for (const script of this.scripts) {\n script.onSqueezeStart(event);\n }\n }\n\n callSqueezeEnd(event: SelectEvent) {\n for (const script of this.scripts) {\n script.onSqueezeEnd(event);\n }\n }\n\n callSqueeze(event: SelectEvent) {\n for (const script of this.scripts) {\n script.onSqueeze(event);\n }\n }\n\n callKeyDown(event: KeyEvent) {\n for (const script of this.scripts) {\n script.onKeyDown(event);\n }\n }\n\n callKeyUp(event: KeyEvent) {\n for (const script of this.scripts) {\n script.onKeyUp(event);\n }\n }\n\n onXRSessionStarted(session: XRSession) {\n for (const script of this.scripts) {\n script.onXRSessionStarted(session);\n }\n }\n\n onXRSessionEnded() {\n for (const script of this.scripts) {\n script.onXRSessionEnded();\n }\n }\n\n onSimulatorStarted() {\n for (const script of this.scripts) {\n script.onSimulatorStarted();\n }\n }\n}\n","export class WaitFrame {\n private callbacks: (() => void)[] = [];\n\n /**\n * Executes all registered callbacks and clears the list.\n */\n onFrame() {\n this.callbacks.forEach((callback) => {\n try {\n callback();\n } catch (e) {\n console.error(e);\n }\n });\n this.callbacks.length = 0;\n }\n\n /**\n * Wait for the next frame.\n */\n async waitFrame() {\n return new Promise<void>((resolve) => {\n this.callbacks.push(resolve);\n });\n }\n}\n","import * as THREE from 'three';\n\nexport const IMMERSIVE_AR = 'immersive-ar';\nexport const IMMERSIVE_VR = 'immersive-vr';\n\ndeclare global {\n interface XRSystem {\n offerSession?: (\n mode: XRSessionMode,\n sessionInit?: XRSessionInit,\n ) => Promise<XRSession>;\n }\n}\n\n// Event type definitions for clarity\nexport enum WebXRSessionEventType {\n UNSUPPORTED = 'unsupported',\n READY = 'ready',\n SESSION_START = 'sessionstart',\n SESSION_END = 'sessionend',\n}\n\nexport type WebXRSessionManagerEventMap = THREE.Object3DEventMap&{\n [WebXRSessionEventType.UNSUPPORTED]: object;\n [WebXRSessionEventType.READY]: {sessionOptions: XRSessionInit};\n [WebXRSessionEventType.SESSION_START]: {session: XRSession};\n [WebXRSessionEventType.SESSION_END]: object;\n}\n\n/**\n * Manages the WebXR session lifecycle by extending THREE.EventDispatcher\n * to broadcast its state to any listener.\n */\nexport class WebXRSessionManager extends\n THREE.EventDispatcher<WebXRSessionManagerEventMap> {\n public currentSession?: XRSession;\n private sessionOptions?: XRSessionInit;\n private onSessionEndedBound = this.onSessionEndedInternal.bind(this);\n private xrModeSupported?: boolean;\n\n constructor(\n private renderer: THREE.WebGLRenderer,\n private sessionInit: XRSessionInit,\n private mode: XRSessionMode,\n ) {\n super(); // Initialize the EventDispatcher\n }\n\n /**\n * Checks for WebXR support and availability of the requested session mode.\n * This should be called to initialize the manager and trigger the first\n * events.\n */\n public async initialize() {\n if (!('xr' in navigator)) {\n console.warn('WebXR not supported');\n this.xrModeSupported = false;\n this.dispatchEvent({type: WebXRSessionEventType.UNSUPPORTED});\n return;\n }\n\n let modeSupported = false;\n try {\n modeSupported =\n (await navigator.xr!.isSessionSupported(this.mode)) || false;\n } catch (e) {\n console.error('Error getting isSessionSupported', e);\n this.xrModeSupported = false;\n this.dispatchEvent({type: WebXRSessionEventType.UNSUPPORTED});\n return;\n }\n\n if (modeSupported) {\n this.xrModeSupported = true;\n this.sessionOptions = {\n ...this.sessionInit,\n optionalFeatures: [\n 'local-floor',\n ...(this.sessionInit.optionalFeatures || []),\n ],\n };\n\n // Fire the 'ready' event with the sessionOptions in the data payload\n this.dispatchEvent({\n type: WebXRSessionEventType.READY,\n sessionOptions: this.sessionOptions,\n });\n\n // Automatically start session if 'offerSession' is available\n if (navigator.xr!.offerSession !== undefined) {\n navigator.xr!.offerSession!(this.mode, this.sessionOptions)\n .then(this.onSessionStartedInternal.bind(this))\n .catch((err) => {\n console.warn(err);\n });\n }\n } else {\n console.log(`${this.mode} not supported`);\n this.xrModeSupported = false;\n this.dispatchEvent({type: WebXRSessionEventType.UNSUPPORTED});\n }\n }\n\n /**\n * Ends the WebXR session.\n */\n public startSession() {\n if (this.xrModeSupported === undefined) {\n throw new Error('Initialize not yet complete');\n } else if (!this.xrModeSupported) {\n throw new Error('WebXR not supported');\n } else if (this.currentSession) {\n throw new Error('Session already started');\n }\n navigator.xr!.requestSession(this.mode, this.sessionOptions)\n .then(this.onSessionStartedInternal.bind(this));\n }\n\n /**\n * Ends the WebXR session.\n */\n public endSession() {\n if (!this.currentSession) {\n throw new Error('No session to end');\n }\n this.currentSession.end();\n this.currentSession = undefined;\n }\n\n /**\n * Returns whether XR is supported. Will be undefined until initialize is\n * complete.\n */\n public isXRSupported() {\n return this.xrModeSupported;\n }\n\n /** Internal callback for when a session successfully starts. */\n private async onSessionStartedInternal(session: XRSession) {\n session.addEventListener('end', this.onSessionEndedBound);\n await this.renderer.xr.setSession(session);\n this.currentSession = session;\n\n // Fire the 'sessionstart' event with the session in the data payload\n this.dispatchEvent({\n type: WebXRSessionEventType.SESSION_START,\n session: session,\n });\n }\n\n /** Internal callback for when the session ends. */\n private onSessionEndedInternal(/*event*/) {\n // Fire the 'sessionend' event\n this.dispatchEvent({type: WebXRSessionEventType.SESSION_END});\n\n this.currentSession?.removeEventListener('end', this.onSessionEndedBound);\n this.currentSession = undefined;\n }\n}\n","import {onDesktopUserAgent} from '../../utils/BrowserUtils';\n\nimport {WebXRSessionEventType, WebXRSessionManager} from './WebXRSessionManager';\n\nconst XRBUTTON_WRAPPER_ID = 'XRButtonWrapper';\nconst XRBUTTON_CLASS = 'XRButton';\n\nexport class XRButton {\n public domElement = document.createElement('div');\n public simulatorButtonElement = document.createElement('button');\n public xrButtonElement = document.createElement('button');\n\n constructor(\n private sessionManager: WebXRSessionManager,\n private startText = 'ENTER XR',\n private endText = 'END XR',\n private invalidText = 'XR NOT SUPPORTED',\n private startSimulatorText = 'START SIMULATOR',\n enableSimulator = false,\n showSimulatorButtonOnMobile = false,\n public startSimulator = () => {},\n ) {\n this.domElement.id = XRBUTTON_WRAPPER_ID;\n this.createXRButtonElement();\n\n if (enableSimulator &&\n (onDesktopUserAgent() || showSimulatorButtonOnMobile)) {\n this.createSimulatorButton();\n }\n\n this.sessionManager.addEventListener(\n WebXRSessionEventType.UNSUPPORTED,\n this.showXRNotSupported.bind(this),\n );\n this.sessionManager.addEventListener(\n WebXRSessionEventType.READY,\n () => this.onSessionReady(),\n );\n this.sessionManager.addEventListener(\n WebXRSessionEventType.SESSION_START,\n () => this.onSessionStarted(),\n );\n this.sessionManager.addEventListener(\n WebXRSessionEventType.SESSION_END,\n this.onSessionEnded.bind(this),\n );\n\n this.sessionManager.initialize();\n }\n\n private createSimulatorButton() {\n this.simulatorButtonElement.classList.add(XRBUTTON_CLASS);\n this.simulatorButtonElement.innerText = this.startSimulatorText;\n this.simulatorButtonElement.onclick = () => {\n this.domElement.remove();\n this.startSimulator();\n };\n this.domElement.appendChild(this.simulatorButtonElement);\n }\n\n private createXRButtonElement() {\n this.xrButtonElement.classList.add(XRBUTTON_CLASS);\n this.xrButtonElement.disabled = true;\n this.xrButtonElement.textContent = '...';\n this.domElement.appendChild(this.xrButtonElement);\n }\n\n private onSessionReady() {\n const button = this.xrButtonElement;\n button.style.display = '';\n button.innerHTML = this.startText;\n button.disabled = false;\n\n button.onclick = () => {\n this.sessionManager.startSession();\n };\n }\n\n private showXRNotSupported() {\n this.xrButtonElement.textContent = this.invalidText;\n this.xrButtonElement.disabled = true;\n }\n\n private async onSessionStarted() {\n this.xrButtonElement.innerHTML = this.endText;\n }\n\n private onSessionEnded() {\n this.xrButtonElement.innerHTML = this.startText;\n }\n}\n","import * as THREE from 'three';\nimport {Pass} from 'three/addons/postprocessing/Pass.js';\n\nexport class XRPass extends Pass {\n render(\n _renderer: THREE.WebGLRenderer, _writeBuffer: THREE.WebGLRenderTarget,\n _readBuffer: THREE.WebGLRenderTarget, _deltaTime: number,\n _maskActive: boolean, _viewId: number = 0) {}\n}\n\n/**\n * XREffects manages the XR rendering pipeline.\n * Use core.effects\n * It handles multiple passes and render targets for applying effects to XR\n * scenes.\n */\nexport class XREffects {\n passes: XRPass[] = [];\n renderTargets: THREE.WebGLRenderTarget[] = [];\n dimensions = new THREE.Vector2();\n\n constructor(\n private renderer: THREE.WebGLRenderer, private scene: THREE.Scene,\n private timer: THREE.Timer) {};\n\n /**\n * Adds a pass to the effect pipeline.\n */\n addPass(pass: XRPass) {\n pass.renderToScreen = false;\n this.passes.push(pass);\n }\n\n /**\n * Sets up render targets for the effect pipeline.\n */\n setupRenderTargets(dimensions: THREE.Vector2) {\n const defaultTarget = this.renderer.getRenderTarget();\n if (defaultTarget == null) {\n return;\n }\n const neededRenderTargets = this.renderer.xr.isPresenting ? 4 : 2;\n for (let i = 0; i < neededRenderTargets; i++) {\n if (i >= this.renderTargets.length ||\n this.renderTargets[i].width != dimensions.x ||\n this.renderTargets[i].height != dimensions.y) {\n this.renderTargets[i]?.depthTexture?.dispose();\n this.renderTargets[i]?.dispose();\n this.renderTargets[i] = defaultTarget.clone();\n this.renderTargets[i].depthTexture =\n new THREE.DepthTexture(dimensions.x, dimensions.y);\n }\n }\n for (let i = neededRenderTargets; i < this.renderTargets.length; i++) {\n this.renderTargets[i].depthTexture?.dispose();\n this.renderTargets[i].dispose();\n }\n }\n\n /**\n * Renders the XR effects.\n */\n render() {\n this.renderer.getDrawingBufferSize(this.dimensions);\n this.setupRenderTargets(this.dimensions);\n this.renderer.xr.cameraAutoUpdate = false;\n const defaultTarget = this.renderer.getRenderTarget();\n if (!defaultTarget) {\n return;\n }\n if (this.renderer.xr.isPresenting) {\n this.renderXr();\n } else {\n this.renderSimulator();\n }\n }\n\n private renderXr() {\n const defaultTarget = this.renderer.getRenderTarget()!;\n const renderer = this.renderer;\n const xrEnabled = renderer.xr.enabled;\n const xrIsPresenting = renderer.xr.isPresenting;\n const renderTargets = this.renderTargets;\n const viewport = new THREE.Vector4();\n renderer.getViewport(viewport);\n renderer.xr.cameraAutoUpdate = false;\n renderer.xr.enabled = false;\n const deltaTime = this.timer.getDelta();\n if (renderer.xr.getCamera().cameras.length == 2) {\n for (let camIndex = 0; camIndex < 2; ++camIndex) {\n const cam = renderer.xr.getCamera().cameras[camIndex];\n renderer.setViewport(cam.viewport);\n renderer.setRenderTarget(renderTargets[camIndex]);\n renderer.clear();\n renderer.xr.isPresenting = true;\n renderer.render(this.scene, cam);\n }\n renderer.setRenderTarget(defaultTarget);\n renderer.clear();\n renderer.xr.isPresenting = false;\n renderer.autoClearColor = false;\n for (let eye = 0; eye < 2; eye++) {\n for (let i = 0; i < this.passes.length - 1; ++i) {\n const lastRenderTargetIndex = i % 2;\n const nextRenderTargetIndex = (i + 1) % 2;\n defaultTarget.viewport.set(\n eye * this.dimensions.x / 2, 0, this.dimensions.x / 2,\n this.dimensions.y);\n this.passes[i].render(\n renderer, this.renderTargets[2 * nextRenderTargetIndex + eye],\n this.renderTargets[2 * lastRenderTargetIndex + eye], deltaTime,\n /*maskActive=*/ false, /*viewId=*/ eye);\n }\n if (this.passes.length > 0) {\n const lastRenderTargetIndex = (this.passes.length - 1) % 2;\n defaultTarget.viewport.set(\n eye * this.dimensions.x / 2, 0, this.dimensions.x / 2,\n this.dimensions.y);\n this.passes[this.passes.length - 1].render(\n renderer, defaultTarget,\n this.renderTargets[2 * lastRenderTargetIndex + eye], deltaTime,\n /*maskActive=*/ false, /*viewId=*/ eye);\n }\n }\n renderer.xr.enabled = xrEnabled;\n renderer.xr.isPresenting = xrIsPresenting;\n }\n }\n\n private renderSimulator() {\n const defaultTarget = this.renderer.getRenderTarget()!;\n const renderer = this.renderer;\n const xrEnabled = renderer.xr.enabled;\n const xrIsPresenting = renderer.xr.isPresenting;\n const viewport = new THREE.Vector4();\n renderer.getViewport(viewport);\n renderer.xr.cameraAutoUpdate = false;\n renderer.xr.enabled = false;\n const deltaTime = this.timer.getDelta();\n renderer.setRenderTarget(defaultTarget);\n renderer.clear();\n renderer.xr.isPresenting = false;\n renderer.autoClearColor = false;\n for (let i = 0; i < this.passes.length - 1; ++i) {\n const lastRenderTargetIndex = i % 2;\n const nextRenderTargetIndex = (i + 1) % 2;\n this.passes[i].render(\n renderer, this.renderTargets[nextRenderTargetIndex],\n this.renderTargets[lastRenderTargetIndex], deltaTime,\n /*maskActive=*/ false, /*viewId=*/ 0);\n }\n if (this.passes.length > 0) {\n const lastRenderTargetIndex = (this.passes.length - 1) % 2;\n this.passes[this.passes.length - 1].render(\n renderer, defaultTarget, this.renderTargets[lastRenderTargetIndex],\n deltaTime,\n /*maskActive=*/ false, /*viewId=*/ 0);\n }\n renderer.xr.enabled = xrEnabled;\n renderer.xr.isPresenting = xrIsPresenting;\n }\n}\n","export const HAND_JOINT_NAMES = [\n 'wrist',\n 'thumb-metacarpal',\n 'thumb-phalanx-proximal',\n 'thumb-phalanx-distal',\n 'thumb-tip',\n 'index-finger-metacarpal',\n 'index-finger-phalanx-proximal',\n 'index-finger-phalanx-intermediate',\n 'index-finger-phalanx-distal',\n 'index-finger-tip',\n 'middle-finger-metacarpal',\n 'middle-finger-phalanx-proximal',\n 'middle-finger-phalanx-intermediate',\n 'middle-finger-phalanx-distal',\n 'middle-finger-tip',\n 'ring-finger-metacarpal',\n 'ring-finger-phalanx-proximal',\n 'ring-finger-phalanx-intermediate',\n 'ring-finger-phalanx-distal',\n 'ring-finger-tip',\n 'pinky-finger-metacarpal',\n 'pinky-finger-phalanx-proximal',\n 'pinky-finger-phalanx-intermediate',\n 'pinky-finger-phalanx-distal',\n 'pinky-finger-tip'\n] as const;\n","import * as THREE from 'three';\n\nimport {HAND_JOINT_NAMES} from './components/HandJointNames.js';\n\ntype JointName = typeof HAND_JOINT_NAMES[number];\n\n/**\n * Utility class for managing WebXR hand tracking data based on\n * reported Handedness.\n */\n\n/**\n * Enum for handedness, using WebXR standard strings.\n */\nexport enum Handedness {\n NONE = -1, // Represents unknown or unspecified handedness\n LEFT = 0,\n RIGHT = 1,\n}\n\n/**\n * Represents and provides access to WebXR hand tracking data.\n * Uses the 'handedness' property of input hands for identification.\n */\nexport class Hands {\n dominant = Handedness.RIGHT;\n\n /**\n * @param hands - An array containing XRHandSpace objects from Three.js.\n */\n constructor(public hands: THREE.XRHandSpace[]) {}\n\n /**\n * Retrieves a specific joint object for a given hand.\n * @param jointName - The name of the joint to retrieve (e.g.,\n * 'index-finger-tip').\n * @param targetHandednessEnum - The hand enum value\n * (Handedness.LEFT or Handedness.RIGHT)\n * to retrieve the joint from. If Handedness.NONE, uses the dominant\n * hand.\n * @returns The requested joint object, or null if not\n * found or invalid input.\n */\n getJoint(jointName: JointName, targetHandednessEnum: Handedness) {\n let resolvedHandednessEnum = targetHandednessEnum;\n if (resolvedHandednessEnum === Handedness.NONE) {\n resolvedHandednessEnum = this.dominant;\n }\n\n const hand = this.hands[resolvedHandednessEnum];\n if (!hand) {\n console.log('no hand');\n return undefined;\n }\n\n if (!hand.joints || !(jointName in hand.joints)) {\n return undefined;\n }\n\n return hand.joints[jointName];\n }\n\n /**\n * Gets the index finger tip joint.\n * @param handedness - Optional handedness\n * ('left'/'right'),\n * defaults to NONE (uses dominant hand).\n * @returns The joint object or null.\n */\n getIndexTip(handedness = Handedness.NONE) {\n return this.getJoint('index-finger-tip', handedness);\n }\n\n /**\n * Gets the thumb tip joint.\n * @param handedness - Optional handedness\n * ('left'/'right'),\n * defaults to NONE (uses dominant hand).\n * @returns The joint object or null.\n */\n getThumbTip(handedness = Handedness.NONE) {\n return this.getJoint('thumb-tip', handedness);\n }\n\n /**\n * Gets the middle finger tip joint.\n * @param handedness - Optional handedness\n * ('left'/'right'),\n * defaults to NONE (uses dominant hand).\n * @returns The joint object or null.\n */\n getMiddleTip(handedness = Handedness.NONE) {\n return this.getJoint('middle-finger-tip', handedness);\n }\n\n /**\n * Gets the ring finger tip joint.\n * @param handedness - Optional handedness\n * ('left'/'right'),\n * defaults to NONE (uses dominant hand).\n * @returns The joint object or null.\n */\n getRingTip(handedness = Handedness.NONE) {\n return this.getJoint('ring-finger-tip', handedness);\n }\n\n /**\n * Gets the pinky finger tip joint.\n * @param handedness - Optional handedness\n * ('left'/'right'),\n * defaults to NONE (uses dominant hand).\n * @returns The joint object or null.\n */\n getPinkyTip(handedness = Handedness.NONE) {\n return this.getJoint('pinky-finger-tip', handedness);\n }\n\n /**\n * Gets the wrist joint.\n * @param handedness - Optional handedness enum value\n * (LEFT/RIGHT/NONE),\n * defaults to NONE (uses dominant hand).\n * @returns The joint object or null.\n */\n getWrist(handedness = Handedness.NONE) {\n return this.getJoint('wrist', handedness);\n }\n\n /**\n * Generates a string representation of the hand joint data for both hands.\n * Always lists LEFT hand data first, then RIGHT hand data, if available.\n * @returns A string containing position data for all available\n * joints.\n */\n toString() {\n let s = '';\n const orderedHandedness = [Handedness.LEFT, Handedness.RIGHT];\n\n orderedHandedness.forEach((handedness) => {\n const hand = this.hands[handedness];\n\n if (!hand || !hand.joints) {\n s += `${handedness} Hand: Data unavailable\\n`;\n return; // Continue to the next handedness\n }\n\n HAND_JOINT_NAMES.forEach((jointName) => {\n const joint = hand.joints[jointName];\n if (joint) {\n if (joint.position) {\n s += `${handedness} - ${jointName}: ${\n joint.position.x.toFixed(3)}, ${joint.position.y.toFixed(3)}, ${\n joint.position.z.toFixed(3)}\\n`;\n } else {\n s += `${handedness} - ${jointName}: Position unavailable\\n`;\n }\n } else {\n s += `${handedness} - ${jointName}: Joint unavailable\\n`;\n }\n });\n });\n return s;\n }\n\n /**\n * Converts the pose data (position and quaternion) of all joints for both\n * hands into a single flat array. Each joint is represented by 7 numbers\n * (3 for position, 4 for quaternion). Missing joints or hands are represented\n * by zeros. Ensures a consistent output order: all left hand joints first,\n * then all right hand joints.\n * @returns A flat array containing position (x, y, z) and\n * quaternion (x, y, z, w) data for all joints, ordered [left...,\n * right...]. Size is always 2 * HAND_JOINT_NAMES.length * 7.\n */\n toPositionQuaternionArray() {\n const data = [];\n const orderedHandedness = [Handedness.LEFT, Handedness.RIGHT];\n const numJoints = HAND_JOINT_NAMES.length;\n const numValuesPerJoint = 7; // 3 position + 4 quaternion\n\n orderedHandedness.forEach((handedness) => {\n const hand = this.hands[handedness];\n\n // Check if hand and joints data exist for this handedness\n const handDataAvailable = hand && hand.joints;\n\n HAND_JOINT_NAMES.forEach((jointName) => {\n const joint = handDataAvailable ? hand.joints[jointName] : null;\n\n // Check if specific joint and its properties exist\n if (joint && joint.position && joint.quaternion) {\n data.push(joint.position.x, joint.position.y, joint.position.z);\n data.push(\n joint.quaternion.x, joint.quaternion.y, joint.quaternion.z,\n joint.quaternion.w);\n } else {\n // If hand, joints, joint, or properties missing, push zeros\n for (let i = 0; i < numValuesPerJoint; i++) {\n data.push(0);\n }\n }\n });\n });\n\n // The final array should always have the same size\n const expectedSize =\n orderedHandedness.length * numJoints * numValuesPerJoint;\n if (data.length !== expectedSize) {\n // This case should theoretically not happen with the logic above,\n // but added as a safeguard during development/debugging.\n console.error(\n `XRHands.toPositionQuaternionArray: Output array size mismatch. Expected ${\n expectedSize}, got ${data.length}. Padding with zeros.`);\n // Pad with zeros if necessary, though ideally the logic prevents this\n while (data.length < expectedSize) {\n data.push(0);\n }\n }\n\n return data;\n }\n\n /**\n * Checks for the availability of hand data.\n * If an integer (0 for LEFT, 1 for RIGHT) is provided, it checks for that\n * specific hand. If no integer is provided, it checks that data for *both*\n * hands is available.\n * @param handIndex - Optional. The index of the hand to validate\n * (0 or 1).\n * @returns `true` if the specified hand(s) have data, `false`\n * otherwise.\n */\n isValid(handIndex?: number): boolean {\n if (!this.hands || !Array.isArray(this.hands) || this.hands.length !== 2) {\n return false;\n }\n\n if (handIndex === 0 || handIndex === 1) {\n return !!this.hands[handIndex];\n }\n\n return !!this.hands[Handedness.LEFT] && !!this.hands[Handedness.RIGHT];\n }\n}\n","import * as THREE from 'three';\n\n/**\n * Shader for the Reticle UI component.\n *\n * This shader renders a dynamic, anti-aliased circle that provides visual\n * feedback for user interaction. It can smoothly transition between a hollow\n * ring (idle/hover state) and a solid, shrinking circle (pressed state).\n * The anti-aliasing is achieved using screen-space derivatives (fwidth) to\n * ensure crisp edges at any resolution or distance.\n */\nexport const ReticleShader = {\n name: 'ReticleShader',\n uniforms: {\n 'uColor': {value: new THREE.Color().setHex(0xFFFFFF)},\n 'uPressed': {value: 0.0},\n },\n\n vertexShader: /* glsl */ `\n varying vec2 vTexCoord;\n\n void main() {\n vTexCoord = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n // Makes the position slightly closer to avoid z fighting.\n gl_Position.z -= 0.1;\n }\n`,\n fragmentShader: /* glsl */ `\n precision mediump float;\n\n uniform sampler2D uDepthTexture;\n uniform vec3 uColor;\n uniform float uPressed;\n\n varying vec2 vTexCoord;\n\n void main(void) {\n // Distance from center of quad.\n highp float dist = distance(vTexCoord, vec2(0.5f, 0.5f));\n if (dist > 0.45) discard;\n\n // Get the rate of change of dist on x and y.\n highp vec2 dist_grad = vec2(dFdx(dist), dFdy(dist));\n highp float grad_magnitude = length(dist_grad);\n highp float antialias_dist = max(grad_magnitude, 0.001f);\n\n // Outer radius is 0.5, but we want to bring it in a few pixels so we have room\n // for a gradient outward to anti-alias the circle.\n // These \"few pixels\" are determined by our derivative calculation above.\n highp float outerradius = 0.5f - antialias_dist;\n highp float delta_to_outer = dist - outerradius;\n highp float clamped_outer_delta = clamp(delta_to_outer, 0.0f, antialias_dist);\n highp float outer_alpha = 1.0f - (clamped_outer_delta / antialias_dist);\n\n // #FFFFFF = (1,1,1)\n // #FFFFFF with 0.5 alpha = (((1,1,1) * 0.5), 0.5)\n vec4 inner_base_color = vec4(0.5 * uColor, 0.5);\n vec4 pressed_inner_color = vec4(uColor, 1.0);\n // #505050 = (0.077,0.077,0.077)\n // #505050 with 0.7 alpha = (((0.077,0.077,0.077)*0.7), 0.7)\n const vec4 inner_gradient_color = vec4(0.054, 0.054, 0.054, 1.0);\n const vec4 outer_ring_color = vec4(0.077, 0.077, 0.077, 1.0);\n // 0.5 - stoke_width (0.75dp = 0.04 approx)\n const float gradient_end = 0.46;\n // 73% of gradient_end\n const float gradient_start = 0.33;\n // gradient_end - 130% stoke_width. Additional 30% to account for the down scaling.\n const float pressed_inner_radius = 0.41;\n\n vec4 unpressed_inner_color =\n mix(inner_base_color, inner_gradient_color,\n smoothstep(gradient_start, gradient_end, dist));\n vec4 unpressed_color =\n mix(unpressed_inner_color, outer_ring_color,\n step(gradient_end, dist));\n\n // Builds a smooth gradient to fade between colors.\n highp float smooth_distance = antialias_dist * 4.0;\n float percent_to_inner_rad = max(pressed_inner_radius - dist, 0.0) / pressed_inner_radius;\n highp float pressed_color_t = 1.0 - percent_to_inner_rad;\n pressed_color_t -= (1.0 - smooth_distance);\n pressed_color_t *= (1.0 / smooth_distance);\n pressed_color_t = clamp(pressed_color_t, 0.0, 1.0);\n vec4 pressed_color = mix(pressed_inner_color, outer_ring_color, pressed_color_t);\n\n vec4 final_color = mix(unpressed_color, pressed_color, uPressed);\n gl_FragColor = final_color * outer_alpha;\n // Converts to straight alpha.\n gl_FragColor.rgb = gl_FragColor.rgb / max(gl_FragColor.a, 0.001);\n }\n`\n};\n","import * as THREE from 'three';\n\nimport {lerp} from '../../utils/utils';\nimport {ReticleShader} from '../shaders/ReticleShader';\n\n/**\n * A 3D visual marker used to indicate a user's aim or interaction\n * point in an XR scene. It orients itself to surfaces it intersects with and\n * provides visual feedback for states like \"pressed\".\n */\nexport class Reticle extends\n THREE.Mesh<THREE.BufferGeometry, THREE.ShaderMaterial> {\n /** Text description of the PanelMesh */\n name = 'Reticle';\n\n /** Prevents the reticle itself from being a target for raycasting. */\n ignoreReticleRaycast = true;\n\n /** The world-space direction vector of the ray that hit the target. */\n direction = new THREE.Vector3();\n\n /** Ensures the reticle is drawn on top of other transparent objects. */\n renderOrder = 1000;\n\n /** The smoothing factor for rotational slerp interpolation. */\n rotationSmoothing: number;\n\n /** The z-offset to prevent visual artifacts (z-fighting). */\n offset: number;\n\n /** The most recent intersection data that positioned this reticle. */\n intersection?: THREE.Intersection;\n\n /** Object on which the reticle is hovering. */\n targetObject?: THREE.Object3D;\n\n // --- Private properties for performance optimization ---\n private readonly originalNormal = new THREE.Vector3(0, 0, 1);\n private readonly newRotation = new THREE.Quaternion();\n private readonly objectRotation = new THREE.Quaternion();\n private readonly normalVector = new THREE.Vector3();\n\n /**\n * Creates an instance of Reticle.\n * @param rotationSmoothing - A factor between 0.0 (no smoothing) and\n * 1.0 (no movement) to smoothly animate orientation changes.\n * @param offset - A small z-axis offset to prevent z-fighting.\n * @param size - The radius of the reticle's circle geometry.\n * @param depthTest - Determines if the reticle should be occluded by other\n * objects. Defaults to `false` to ensure it is always visible.\n */\n constructor(\n rotationSmoothing = 0.8, offset = 0.001, size = 0.019,\n depthTest = false) {\n const geometry = new THREE.CircleGeometry(size, 32);\n geometry.applyMatrix4(new THREE.Matrix4().makeTranslation(0, 0, offset));\n\n super(geometry, new THREE.ShaderMaterial({\n uniforms: THREE.UniformsUtils.clone(ReticleShader.uniforms),\n vertexShader: ReticleShader.vertexShader,\n fragmentShader: ReticleShader.fragmentShader,\n depthTest: depthTest,\n transparent: true\n }));\n\n this.rotationSmoothing = rotationSmoothing;\n this.offset = offset;\n }\n\n /**\n * Orients the reticle to be flush with a surface, based on the surface\n * normal. It smoothly interpolates the rotation for a polished visual effect.\n * @param normal - The world-space normal of the surface.\n */\n setRotationFromNormalVector(normal: THREE.Vector3) {\n const angle = this.originalNormal.angleTo(normal);\n\n // Calculate the rotation axis by taking the cross product.\n // Note: this.originalNormal is modified here but reset by the next line.\n this.originalNormal.cross(normal).normalize();\n this.newRotation.setFromAxisAngle(this.originalNormal, angle);\n this.originalNormal.set(0, 0, 1); // Reset for next use.\n\n // Smoothly interpolate from the current rotation to the new rotation.\n this.quaternion.slerp(this.newRotation, 1.0 - this.rotationSmoothing);\n }\n\n /**\n * Updates the reticle's complete pose (position and rotation) from a\n * raycaster intersection object.\n * @param intersection - The intersection data from a raycast.\n */\n setPoseFromIntersection(intersection: THREE.Intersection) {\n if (!intersection || !intersection.normal) return;\n\n this.intersection = intersection;\n this.position.copy(intersection.point);\n\n // The intersection normal is in the local space of the intersected object.\n // It must be transformed into world space to correctly orient the reticle.\n intersection.object.getWorldQuaternion(this.objectRotation);\n this.normalVector.copy(intersection.normal)\n .applyQuaternion(this.objectRotation);\n this.setRotationFromNormalVector(this.normalVector);\n }\n\n /**\n * Sets the color of the reticle via its shader uniform.\n * @param color - The color to apply.\n */\n setColor(color: THREE.Color|number|string) {\n this.material.uniforms.uColor.value.set(color);\n }\n\n /**\n * Gets the current color of the reticle.\n * @returns The current color from the shader uniform.\n */\n getColor(): THREE.Color {\n return this.material.uniforms.uColor.value;\n }\n\n /**\n * Sets the visual state of the reticle to \"pressed\" or \"unpressed\".\n * This provides visual feedback to the user during interaction.\n * @param pressed - True to show the pressed state, false otherwise.\n */\n setPressed(pressed: boolean) {\n this.material.uniforms.uPressed.value = pressed ? 1.0 : 0.0;\n this.scale.setScalar(pressed ? 0.7 : 1.0);\n }\n\n /**\n * Sets the pressed state as a continuous value for smooth animations.\n * @param pressedAmount - A value from 0.0 (unpressed) to 1.0 (fully\n * pressed).\n */\n setPressedAmount(pressedAmount: number) {\n this.material.uniforms.uPressed.value = pressedAmount;\n this.scale.setScalar(lerp(1.0, 0.7, pressedAmount));\n }\n\n /**\n * Overrides the default raycast method to make the reticle ignored by\n * raycasters.\n */\n raycast() {}\n}\n","import * as THREE from 'three';\n\nexport class ControllerRayVisual extends THREE.Line {\n constructor() {\n const geometry = new THREE.BufferGeometry().setFromPoints(\n [new THREE.Vector3(0, 0, 0), new THREE.Vector3(0, 0, -1)]);\n\n super(geometry);\n this.scale.z = 5;\n }\n\n // Ignore raycasts to this line.\n raycast() {}\n}\n","import {clamp} from '../../utils/utils';\n\n/**\n * A simple utility class for linearly animating a numeric value over\n * time. It clamps the value within a specified min/max range and updates it\n * based on a given speed.\n */\nexport class AnimatableNumber {\n constructor(\n public value = 0, public minValue = 0, public maxValue = 1,\n public speed = 1) {}\n\n /**\n * Updates the value based on the elapsed time.\n * @param deltaTimeSeconds - The time elapsed since the last update, in\n * seconds.\n */\n update(deltaTimeSeconds: number) {\n this.value = clamp(\n this.value + deltaTimeSeconds * this.speed, this.minValue,\n this.maxValue);\n }\n}\n","import * as THREE from 'three';\n\nimport {Script} from '../core/Script';\nimport {Reticle} from '../ui/core/Reticle';\nimport {AnimatableNumber} from '../ui/interaction/AnimatableNumber';\n\nimport {Controller} from './Controller';\n\n/**\n * A threshold for gaze movement speed (in units per second) to determine if the\n * user's gaze is stable. If the reticle moves faster than this, the selection\n * timer resets.\n */\nconst PRESS_MOVEMENT_THRESHOLD = 0.2;\n\ninterface GazeControllerEventMap extends THREE.Object3DEventMap {\n connected: {target: GazeController};\n disconnected: {target: GazeController};\n selectstart: {target: GazeController};\n selectend: {target: GazeController};\n}\n\n/**\n * Implements a gaze-based controller for XR interactions.\n * This allows users to select objects by looking at them for a set duration.\n * It functions as a virtual controller that is always aligned with the user's\n * camera (head pose).\n * WebXR Eye Tracking is not yet available. This API simulates a reticle\n * at the center of the field of view for simulating gaze-based interaction.\n */\nexport class GazeController extends Script<GazeControllerEventMap> implements\n Controller {\n static dependencies = {camera: THREE.Camera};\n\n /**\n * User data for the controller, including its connection status, unique ID,\n * and selection state.\n */\n userData = {connected: false, id: 2, selected: false};\n\n /**\n * The visual indicator for where the user is looking.\n */\n reticle = new Reticle();\n\n /**\n * The time in seconds the user must gaze at an object to trigger a selection.\n */\n activationTimeSeconds = 1.5;\n\n /**\n * An animatable number that tracks the progress of the gaze selection, from\n * 0.0 to 1.0.\n */\n activationAmount =\n new AnimatableNumber(0.0, 0.0, 1.0, 1.0 / this.activationTimeSeconds);\n\n /**\n * Stores the reticle's position from the previous frame to calculate movement\n * speed.\n */\n lastReticlePosition = new THREE.Vector3();\n\n /**\n * A clock to measure the time delta between frames for smooth animation and\n * movement calculation.\n */\n clock = new THREE.Clock();\n\n camera!: THREE.Camera;\n\n init({camera}: {camera: THREE.Camera}) {\n this.camera = camera;\n }\n\n /**\n * The main update loop, called every frame by the core engine.\n * It handles syncing the controller with the camera and manages the gaze\n * selection logic.\n */\n update() {\n super.update();\n this.position.copy(this.camera.position);\n this.quaternion.copy(this.camera.quaternion);\n this.updateMatrixWorld();\n const delta = this.clock.getDelta();\n this.activationAmount.update(delta);\n const movement =\n this.lastReticlePosition.distanceTo(this.reticle.position) / delta;\n if (movement > PRESS_MOVEMENT_THRESHOLD) {\n this.activationAmount.value = 0.0;\n if (this.userData.selected) {\n this.callSelectEnd();\n }\n this.userData.selected = false;\n }\n if (this.activationAmount.value == 1.0 && !this.userData.selected) {\n this.callSelectStart();\n }\n this.updateReticleScale();\n this.lastReticlePosition.copy(this.reticle.position);\n }\n\n /**\n * Updates the reticle's scale and shader uniforms to provide visual feedback\n * for gaze activation. The reticle shrinks and fills in as the activation\n * timer progresses.\n */\n updateReticleScale() {\n this.reticle.setPressedAmount(this.activationAmount.value);\n }\n\n /**\n * Dispatches a 'selectstart' event, signaling that a gaze selection has been\n * initiated.\n */\n callSelectStart() {\n this.dispatchEvent({type: 'selectstart', target: this});\n }\n\n /**\n * Dispatches a 'selectend' event, signaling that a gaze selection has been\n * released (e.g., by moving gaze).\n */\n callSelectEnd() {\n this.dispatchEvent({type: 'selectend', target: this});\n }\n\n /**\n * Connects the gaze controller to the input system.\n */\n connect() {\n this.dispatchEvent({type: 'connected', target: this});\n }\n\n /**\n * Disconnects the gaze controller from the input system.\n */\n disconnect() {\n this.dispatchEvent({type: 'disconnected', target: this});\n }\n}\n","import * as THREE from 'three';\n\nimport {Script} from '../core/Script.js';\n\nimport {Controller} from './Controller.js';\n\n/** Defines the event map for the MouseController's custom events. */\ninterface MouseControllerEventMap extends THREE.Object3DEventMap {\n connected: {target: MouseController};\n disconnected: {target: MouseController};\n selectstart: {target: MouseController};\n selectend: {target: MouseController};\n}\n\n/**\n * Simulates an XR controller using the mouse for desktop\n * environments. This class translates 2D mouse movements on the screen into a\n * 3D ray in the scene, allowing for point-and-click interactions in a\n * non-immersive context. It functions as a virtual controller that is always\n * aligned with the user's pointer.\n */\nexport class MouseController extends Script<MouseControllerEventMap> implements\n Controller {\n static dependencies = {\n camera: THREE.Camera,\n };\n\n /**\n * User data for the controller, including its connection status, unique ID,\n * and selection state (mouse button pressed).\n */\n userData = {id: 3, connected: false, selected: false};\n\n /** A THREE.Raycaster used to determine the 3D direction of the mouse. */\n raycaster = new THREE.Raycaster();\n\n /** A normalized vector representing the default forward direction. */\n forwardVector = new THREE.Vector3(0, 0, -1);\n\n /** A reference to the main scene camera. */\n camera!: THREE.Camera;\n\n constructor() {\n super();\n }\n\n /**\n * Initialize the MouseController\n */\n init({camera}: {camera: THREE.Camera}) {\n this.camera = camera;\n }\n\n /**\n * The main update loop, called every frame.\n * If connected, it syncs the controller's origin point with the camera's\n * position.\n */\n update() {\n super.update();\n if (!this.userData.connected) {\n return;\n }\n this.position.copy(this.camera.position);\n }\n\n /**\n * Updates the controller's transform based on the mouse's position on the\n * screen. This method sets both the position and rotation, ensuring the\n * object has a valid world matrix for raycasting.\n * @param event - The mouse event containing clientX and clientY coordinates.\n */\n updateMousePositionFromEvent(event: MouseEvent) {\n // The controller's origin point is always the camera's position.\n this.position.copy(this.camera.position);\n\n const mouse = new THREE.Vector2();\n // Converts mouse coordinates from screen space (pixels) to normalized\n // device coordinates (-1 to +1).\n mouse.x = (event.clientX / window.innerWidth) * 2 - 1;\n mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;\n\n // Updates the raycaster and sets the controller's new rotation.\n this.raycaster.setFromCamera(mouse, this.camera);\n const rayDirection = this.raycaster.ray.direction;\n this.quaternion.setFromUnitVectors(this.forwardVector, rayDirection);\n this.updateMatrixWorld();\n }\n\n /**\n * Dispatches a 'selectstart' event, simulating the start of a controller\n * press (e.g., mouse down).\n */\n callSelectStart() {\n this.dispatchEvent({type: 'selectstart', target: this});\n }\n\n /**\n * Dispatches a 'selectend' event, simulating the end of a controller press\n * (e.g., mouse up).\n */\n callSelectEnd() {\n this.dispatchEvent({type: 'selectend', target: this});\n }\n\n /**\n * \"Connects\" the virtual controller, notifying the input system that it is\n * active.\n */\n connect() {\n this.dispatchEvent({type: 'connected', target: this});\n }\n\n /**\n * \"Disconnects\" the virtual controller.\n */\n disconnect() {\n this.dispatchEvent({type: 'disconnected', target: this});\n }\n}\n","import * as THREE from 'three';\nimport {XRControllerModelFactory} from 'three/addons/webxr/XRControllerModelFactory.js';\nimport {XRHandModelFactory} from 'three/addons/webxr/XRHandModelFactory.js';\n\nimport {NUM_HANDS} from '../constants';\nimport {Options} from '../core/Options.js';\nimport {KeyEvent, Script} from '../core/Script';\nimport {Reticle} from '../ui/core/Reticle.js';\n\nimport {ControllerRayVisual} from './components/ControllerRayVisual';\nimport type {Controller, ControllerEvent, ControllerEventMap} from './Controller';\nimport {GazeController} from './GazeController';\nimport {MouseController} from './MouseController';\n\nexport class ActiveControllers extends THREE.Object3D {};\n\nexport type HasIgnoreReticleRaycast = {\n ignoreReticleRaycast: boolean;\n};\nexport type MaybeHasIgnoreReticleRaycast = Partial<HasIgnoreReticleRaycast>;\n\n// Reusable objects for performance.\nconst MATRIX4 = new THREE.Matrix4();\n\n/**\n * The XRInput class holds all the controllers and performs raycasts through the\n * scene each frame.\n */\nexport class Input {\n options!: Options;\n controllers: Controller[] = [];\n controllerGrips: THREE.Group[] = [];\n hands: THREE.XRHandSpace[] = [];\n raycaster = new THREE.Raycaster();\n initialized = false;\n pivotsEnabled = false;\n gazeController = new GazeController();\n mouseController = new MouseController();\n controllersEnabled = true;\n listeners = new Map();\n intersectionsForController = new Map<Controller, THREE.Intersection[]>();\n intersections = [];\n activeControllers = new ActiveControllers();\n leftController?: Controller;\n rightController?: Controller;\n scene!: THREE.Scene;\n\n /**\n * Initializes an instance with XR controllers, grips, hands, raycaster, and\n * default options. Only called by Core.\n */\n init({scene, options, renderer}: {\n scene: THREE.Scene,\n options: Options,\n renderer: THREE.WebGLRenderer\n }) {\n scene.add(this.activeControllers);\n\n this.options = options;\n this.scene = scene;\n\n const controllers = this.controllers;\n const controllerGrips = this.controllerGrips;\n\n for (let i = 0; i < NUM_HANDS; ++i) {\n controllers.push(renderer.xr.getController(i));\n controllers[i].userData.id = i;\n this.activeControllers.add(this.controllers[i]);\n }\n controllers.push(this.gazeController);\n controllers.push(this.mouseController);\n this.activeControllers.add(this.mouseController);\n\n for (const controller of controllers) {\n this.intersectionsForController.set(controller, []);\n }\n\n if (options.controllers.enabled) {\n if (options.controllers.visualization) {\n const controllerModelFactory = new XRControllerModelFactory();\n for (let i = 0; i < NUM_HANDS; ++i) {\n controllerGrips.push(renderer.xr.getControllerGrip(i));\n controllerGrips[i].add(\n controllerModelFactory.createControllerModel(controllerGrips[i]));\n this.activeControllers.add(controllerGrips[i]);\n }\n }\n\n // TODO: Separate logic to XR Hands.\n if (options.hands.enabled) {\n for (let i = 0; i < NUM_HANDS; ++i) {\n this.hands.push(renderer.xr.getHand(i));\n this.activeControllers.add(this.hands[i]);\n }\n\n if (options.hands.visualization) {\n if (options.hands.visualizeJoints) {\n console.log('Visualize hand joints.');\n const handModelFactory = new XRHandModelFactory();\n for (let i = 0; i < NUM_HANDS; ++i) {\n const handModel =\n handModelFactory.createHandModel(this.hands[i], 'boxes');\n (handModel as MaybeHasIgnoreReticleRaycast).ignoreReticleRaycast =\n true;\n this.hands[i].add(handModel);\n }\n }\n if (options.hands.visualizeMeshes) {\n console.log('Visualize hand meshes.');\n const handModelFactory = new XRHandModelFactory();\n for (let i = 0; i < NUM_HANDS; ++i) {\n const handModel =\n handModelFactory.createHandModel(this.hands[i], 'mesh');\n (handModel as MaybeHasIgnoreReticleRaycast).ignoreReticleRaycast =\n true;\n this.hands[i].add(handModel);\n }\n }\n }\n }\n }\n\n if (options.controllers.visualizeRays) {\n for (let i = 0; i < NUM_HANDS; ++i) {\n controllers[i].add(new ControllerRayVisual());\n }\n }\n\n this.bindSelectStart(this.defaultOnSelectStart.bind(this));\n this.bindSelectEnd(this.defaultOnSelectEnd.bind(this));\n this.bindSqueezeStart(this.defaultOnSelectStart.bind(this));\n this.bindSqueezeEnd(this.defaultOnSelectEnd.bind(this));\n this.bindListener('connected', this.defaultOnConnected.bind(this));\n this.bindListener('disconnected', this.defaultOnDisconnected.bind(this));\n }\n\n /**\n * Retrieves the controller object by its ID.\n * @param id - The ID of the controller.\n * @returns The controller with the specified ID.\n */\n get(id: number): THREE.Object3D {\n return this.controllers[id];\n }\n\n /**\n * Adds an object to both controllers by creating a new group and cloning it.\n * @param obj - The object to add to each controller.\n */\n addObject(obj: THREE.Object3D) {\n const group = new THREE.Group();\n group.add(obj);\n // Clones the group for each controller, adding it to the controller.\n for (let i = 0; i < this.controllers.length; ++i) {\n this.controllers[i].add(group.clone());\n }\n }\n\n /**\n * Creates a pivot point for each hand, primarily used as a reference\n * point.\n */\n enablePivots() {\n if (this.pivotsEnabled) return;\n this.pivotsEnabled = true;\n const pivot = new THREE.Mesh(new THREE.IcosahedronGeometry(0.01, 3));\n pivot.name = 'pivot';\n pivot.position.z = -0.05;\n this.addObject(pivot);\n }\n\n /**\n * Adds reticles to the controllers and scene, with initial visibility set to\n * false.\n */\n addReticles() {\n let id = 0;\n for (const controller of this.controllers) {\n if (controller.reticle == null) {\n controller.reticle = new Reticle();\n controller.reticle.name = 'Reticle ' + id;\n ++id;\n }\n controller.reticle.visible = false;\n this.scene.add(controller.reticle);\n }\n }\n\n /**\n * Default action to handle the start of a selection, setting the selecting\n * state to true.\n */\n defaultOnSelectStart(event: ControllerEvent) {\n const controller = event.target;\n controller.userData.selected = true;\n this._setRaycasterFromController(controller);\n this.performRaycastOnScene(controller);\n }\n\n /**\n * Default action to handle the end of a selection, setting the selecting\n * state to false.\n */\n defaultOnSelectEnd(event: ControllerEvent) {\n const controller = event.target;\n controller.userData.selected = false;\n }\n\n defaultOnSqueezeStart(event: ControllerEvent) {\n const controller = event.target;\n controller.userData.squeezing = true;\n }\n\n defaultOnSqueezeEnd(event: ControllerEvent) {\n const controller = event.target;\n controller.userData.squeezing = false;\n }\n\n defaultOnConnected(event: ControllerEvent) {\n const controller = event.target;\n controller.userData.connected = true;\n controller.gamepad = event.data?.gamepad;\n controller.inputSource = event.data;\n switch (event.data?.handedness) {\n case 'left':\n this.leftController = controller;\n break;\n case 'right':\n this.rightController = controller;\n break;\n }\n }\n\n defaultOnDisconnected(event: ControllerEvent) {\n const controller = event.target;\n controller.userData.connected = false;\n if (controller.reticle) {\n controller.reticle.visible = false;\n }\n delete controller?.gamepad;\n switch (event.data?.handedness) {\n case 'left':\n this.leftController = undefined;\n break;\n case 'right':\n this.rightController = undefined;\n break;\n }\n }\n\n /**\n * Binds a listener to both controllers.\n * @param listenerName - Event name\n * @param listener - Function to call\n */\n bindListener(\n listenerName: keyof ControllerEventMap,\n listener: (event: ControllerEvent) => void) {\n for (const controller of this.controllers) {\n controller.addEventListener(listenerName, listener);\n }\n if (!this.listeners.has(listenerName)) {\n this.listeners.set(listenerName, []);\n }\n this.listeners.get(listenerName).push(listener);\n }\n\n unbindListener(\n listenerName: keyof ControllerEventMap,\n listener: (event: ControllerEvent) => void) {\n if (this.listeners.has(listenerName)) {\n const listeners = this.listeners.get(listenerName);\n const index = listeners.indexOf(listener);\n if (index !== -1) {\n listeners.splice(index, 1);\n }\n }\n for (const controller of this.controllers) {\n controller.removeEventListener(listenerName, listener);\n }\n }\n\n dispatchEvent(event: ControllerEvent) {\n if (this.listeners.has(event.type)) {\n for (const listener of this.listeners.get(event.type)) {\n listener(event);\n }\n }\n }\n\n /**\n * Binds an event listener to handle 'selectstart' events for both\n * controllers.\n * @param event - The event listener function.\n */\n bindSelectStart(event: (event: ControllerEvent) => void) {\n this.bindListener('selectstart', event);\n }\n\n /**\n * Binds an event listener to handle 'selectend' events for both controllers.\n * @param event - The event listener function.\n */\n bindSelectEnd(event: (event: ControllerEvent) => void) {\n this.bindListener('selectend', event);\n }\n\n /**\n * Binds an event listener to handle 'select' events for both controllers.\n * @param event - The event listener function.\n */\n bindSelect(event: (event: ControllerEvent) => void) {\n this.bindListener('select', event);\n }\n\n /**\n * Binds an event listener to handle 'squeezestart' events for both\n * controllers.\n * @param event - The event listener function.\n */\n bindSqueezeStart(event: (event: ControllerEvent) => void) {\n this.bindListener('squeezestart', event);\n }\n\n /**\n * Binds an event listener to handle 'squeezeend' events for both controllers.\n * @param event - The event listener function.\n */\n bindSqueezeEnd(event: (event: ControllerEvent) => void) {\n this.bindListener('squeezeend', event);\n }\n\n bindSqueeze(event: (event: ControllerEvent) => void) {\n this.bindListener('squeeze', event);\n }\n\n bindKeyDown(event: (event: KeyEvent) => void) {\n window.addEventListener('keydown', event);\n }\n\n bindKeyUp(event: (event: KeyEvent) => void) {\n window.addEventListener('keyup', event);\n }\n\n unbindKeyDown(event: (event: KeyEvent) => void) {\n window.removeEventListener('keydown', event);\n }\n\n unbindKeyUp(event: (event: KeyEvent) => void) {\n window.removeEventListener('keyup', event);\n }\n\n /**\n * Finds intersections between a controller's ray and a specified object.\n * @param controller - The controller casting the ray.\n * @param obj - The object to intersect.\n * @returns Array of intersection points, if any.\n */\n intersectObjectByController(controller: THREE.Object3D, obj: THREE.Object3D):\n THREE.Intersection[] {\n controller.updateMatrixWorld();\n this.raycaster.setFromXRController(controller as THREE.XRTargetRaySpace);\n return this.raycaster.intersectObject(obj, false);\n }\n\n /**\n * Finds intersections based on an event's target controller and a specified\n * object.\n * @param event - The event containing the controller reference.\n * @param obj - The object to intersect.\n * @returns Array of intersection points, if any.\n */\n intersectObjectByEvent(event: ControllerEvent, obj: THREE.Object3D):\n THREE.Intersection[] {\n return this.intersectObjectByController(event.target, obj);\n }\n\n /**\n * Finds intersections with an object from either controller.\n * @param obj - The object to intersect.\n * @returns Array of intersection points, if any.\n */\n intersectObject(obj: THREE.Object3D): THREE.Intersection[] {\n // Checks for intersections from the first controller.\n const intersection =\n this.intersectObjectByController(this.controllers[0], obj);\n if (intersection.length > 0) {\n return intersection;\n }\n // Checks for intersections from the second controller if no intersection\n // found.\n return this.intersectObjectByController(this.controllers[1], obj);\n }\n\n update() {\n if (this.controllersEnabled) {\n for (const controller of this.controllers) {\n this.updateController(controller);\n }\n }\n }\n\n updateController(controller: Controller) {\n if (controller.userData.connected === false) {\n return;\n }\n controller.updateMatrixWorld();\n this._setRaycasterFromController(controller);\n this.performRaycastOnScene(controller);\n this.updateReticleFromIntersections(controller);\n }\n\n\n /**\n * Sets the raycaster's origin and direction from any Object3D that\n * represents a controller. This replaces the non-standard\n * `setFromXRController`.\n * @param controller - The controller to cast a ray from.\n */\n private _setRaycasterFromController(controller: THREE.Object3D) {\n controller.getWorldPosition(this.raycaster.ray.origin);\n MATRIX4.identity().extractRotation(controller.matrixWorld);\n this.raycaster.ray.direction.set(0, 0, -1)\n .applyMatrix4(MATRIX4)\n .normalize();\n }\n\n updateReticleFromIntersections(controller: Controller) {\n if (!controller.reticle) return;\n const reticle = controller.reticle;\n const intersection =\n this.intersectionsForController.get(controller)?.find(intersection => {\n let target: THREE.Object3D|null = intersection.object;\n while (target) {\n if ((target as MaybeHasIgnoreReticleRaycast)\n .ignoreReticleRaycast === true) {\n return false;\n }\n target = target.parent;\n }\n return true;\n });\n if (!intersection) {\n reticle.visible = false;\n return;\n }\n reticle.visible = true;\n\n // Here isXRScript is semantically equals to isInteractable.\n if ((intersection.object as Partial<Script>)?.isXRScript) {\n (intersection.object as Script).ux.update(controller, intersection);\n } else if ((intersection.object?.parent as Partial<Script>)?.isXRScript) {\n (intersection.object.parent as Script)\n .ux.update(controller, intersection);\n }\n\n reticle.intersection = intersection;\n reticle.direction.copy(this.raycaster.ray.direction).normalize();\n reticle.setPoseFromIntersection(intersection);\n reticle.setPressed(controller.userData.selected);\n }\n\n enableGazeController() {\n this.activeControllers.add(this.gazeController);\n this.gazeController.connect();\n }\n\n disableGazeController() {\n this.gazeController.disconnect();\n this.activeControllers.remove(this.gazeController);\n }\n\n disableControllers() {\n this.controllersEnabled = false;\n for (const controller of this.controllers) {\n controller.userData.selected = false\n if (controller.reticle) {\n controller.reticle.visible = false;\n controller.reticle.targetObject = undefined;\n }\n }\n }\n\n enableControllers() {\n this.controllersEnabled = true;\n }\n\n // Performs the raycast assuming the raycaster is already set up.\n performRaycastOnScene(controller: Controller) {\n if (!this.intersectionsForController.has(controller)) {\n this.intersectionsForController.set(controller, []);\n }\n const intersections = this.intersectionsForController.get(controller)!;\n intersections.length = 0;\n this.raycaster.intersectObject(this.scene, true, intersections);\n }\n};\n","import * as THREE from 'three';\nimport {XREstimatedLight} from 'three/addons/webxr/XREstimatedLight.js';\n\nimport {Depth} from '../depth/Depth.js';\n\nimport {LightingOptions} from './LightingOptions.js';\n\nconst DEBUGGING = false;\n\n/**\n * Lighting provides XR lighting capabilities within the XR Blocks framework.\n * It uses webXR to propvide estimated lighting that matches the environment\n * and supports casting shadows from the estimated light.\n */\nexport class Lighting {\n static instance?: Lighting;\n /** WebXR estimated lighting. */\n private xrLight?: XREstimatedLight;\n /** Main Directional light. */\n dirLight = new THREE.DirectionalLight();\n /** Ambient spherical harmonics light. */\n ambientProbe = new THREE.LightProbe();\n /** Ambient RGB light. */\n ambientLight = new THREE.Vector3();\n /** Opacity of cast shadow. */\n private shadowOpacity = 0.0;\n /** Light group to attach to scene. */\n private lightGroup = new THREE.Group();\n /** Lighting options. Set during initialiation.*/\n private options!: LightingOptions;\n /** Depth manager. Used to get depth mesh on which to cast shadow. */\n private depth?: Depth;\n /** Flag to indicate if simulator is running. Controlled by Core. */\n simulatorRunning = false;\n\n /**\n * Lighting is a lightweight manager based on three.js to simply prototyping\n * with Lighting features within the XR Blocks framework.\n */\n constructor() {\n if (Lighting.instance) {\n return Lighting.instance;\n }\n Lighting.instance = this;\n }\n\n /**\n * Initializes the lighting module with the given options. Sets up lights and\n * shadows and adds necessary components to the scene.\n * @param lightingOptions - Lighting options.\n * @param renderer - Main renderer.\n * @param scene - Main scene.\n * @param depth - Depth manager.\n */\n init(\n lightingOptions: LightingOptions, renderer: THREE.WebGLRenderer,\n scene: THREE.Scene, depth?: Depth) {\n this.options = lightingOptions;\n this.depth = depth;\n\n if (this.options.enabled) {\n this.xrLight = new XREstimatedLight(renderer);\n\n if (this.options.castDirectionalLightShadow) {\n renderer.shadowMap.enabled = true;\n renderer.shadowMap.type = THREE.PCFShadowMap;\n }\n\n if (this.options.castDirectionalLightShadow) {\n const dirLight = this.dirLight;\n dirLight.castShadow = true;\n dirLight.shadow.mapSize.width = 2048;\n dirLight.shadow.mapSize.height = 2048;\n dirLight.shadow.camera.near = 0.3;\n dirLight.shadow.camera.far = 50.0;\n const cameraFrustrumRadius = 4.0;\n dirLight.shadow.camera.left = -cameraFrustrumRadius;\n dirLight.shadow.camera.right = cameraFrustrumRadius;\n dirLight.shadow.camera.top = cameraFrustrumRadius;\n dirLight.shadow.camera.bottom = -cameraFrustrumRadius;\n dirLight.shadow.blurSamples = 25;\n dirLight.shadow.radius = 5.0;\n dirLight.shadow.bias = 0.0;\n\n this.lightGroup.add(dirLight.target);\n\n if (this.options.debugging || DEBUGGING) {\n scene.add(new THREE.CameraHelper(dirLight.shadow.camera));\n }\n }\n\n if (this.options.useAmbientSH) {\n this.lightGroup.add(this.ambientProbe);\n }\n if (this.options.useDirectionalLight) {\n this.lightGroup.add(this.dirLight);\n }\n scene.add(this.lightGroup);\n\n this.xrLight.addEventListener('estimationend', () => {\n scene.remove(this.xrLight!);\n });\n }\n }\n\n /**\n * Updates the lighting and shadow setup used to render. Called every frame\n * in the render loop.\n */\n update() {\n // Update lights from WebXR estimated light.\n if (this.options.enabled) {\n this.dirLight.position.copy(this.xrLight!.directionalLight.position)\n .multiplyScalar(20.0);\n this.dirLight.target.position.setScalar(0.0);\n this.dirLight.color = this.xrLight!.directionalLight.color;\n this.dirLight.intensity = this.xrLight!.directionalLight.intensity;\n this.ambientProbe.sh.copy(this.xrLight!.lightProbe.sh);\n this.ambientProbe.intensity = this.xrLight!.lightProbe.intensity;\n this.ambientLight.copy(this.xrLight!.lightProbe.sh.coefficients[0]);\n\n // Replace lights with harcoded default if using simulator.\n if (this.simulatorRunning) {\n this.dirLight.position.set(-10.0, 10.0, -2.0);\n this.dirLight.target.position.set(0.0, 0.0, -0.5);\n this.dirLight.color.setHex(0xffffff);\n this.dirLight.intensity = 3.8;\n this.ambientProbe.sh.fromArray([\n 0.22636516392230988, 0.2994415760040283, 0.2827182114124298,\n 0.03430574759840965, 0.029604531824588776, -0.002050594426691532,\n 0.016114741563796997, 0.004344218410551548, 0.07621686905622482,\n 0.024204734712839127, -0.02397896535694599, -0.07645703107118607,\n 0.15790101885795593, 0.16706973314285278, 0.18418270349502563,\n -0.13088643550872803, -0.1461198776960373, -0.1411236822605133,\n 0.04788218438625336, 0.08909443765878677, 0.10185115039348602,\n 0.020251473411917686, -0.002100071171298623, -0.06455840915441513,\n -0.12393051385879517, -0.05158703774213791, -0.00532124936580658\n ]);\n this.ambientProbe.intensity = 1.0;\n this.ambientLight.copy(this.ambientProbe.sh.coefficients[0]);\n }\n\n if (this.options.castDirectionalLightShadow &&\n this.options.useDynamicSoftShadow) {\n const ambientLightIntensity = this.ambientLight;\n const ambientMonoIntensity = 0.21 * ambientLightIntensity.x +\n 0.72 * ambientLightIntensity.y + 0.07 * ambientLightIntensity.z;\n const mainLightIntensity =\n new THREE\n .Vector3(\n this.dirLight.color.r, this.dirLight.color.g,\n this.dirLight.color.b)\n .multiplyScalar(this.dirLight.intensity);\n const mainMonoIntensity = 0.21 * mainLightIntensity.x +\n 0.72 * mainLightIntensity.y + 0.07 * mainLightIntensity.z;\n const ambientToMain = ambientMonoIntensity / mainMonoIntensity;\n this.dirLight.shadow.radius =\n Math.min(Math.max(1.0, ambientToMain * 30), 10.0);\n this.shadowOpacity =\n Math.max(Math.min((10.0 - ambientToMain * 30) * 0.7, 0.7), 0.3);\n\n // Override depth material opacity with shadowOpacity\n if (this.depth?.options?.enabled &&\n this.depth.options.depthMesh.enabled &&\n this.depth.depthMesh?.material instanceof THREE.ShadowMaterial) {\n this.depth.depthMesh.material.opacity = this.shadowOpacity;\n }\n }\n }\n\n if (this.options.debugging || DEBUGGING) {\n this.debugLog();\n }\n }\n\n /**\n * Logs current estimate light parameters for debugging.\n */\n debugLog() {\n console.log('Lighting.dirLight', this.dirLight);\n console.log('Lighting.ambientProbe', this.ambientProbe);\n console.log('Lighting.ambientLight', this.ambientLight);\n }\n};\n","import type RAPIER from 'rapier3d';\n\nimport {PhysicsOptions, RAPIERCompat} from './PhysicsOptions';\n\n/**\n * Integrates the RAPIER physics engine into the XRCore lifecycle.\n * It sets up the physics in a blended world that combines virtual and physical\n * objects, steps the simulation forward in sync with the application's\n * framerate, and manages the lifecycle of physics-related objects.\n */\nexport class Physics {\n initialized = false;\n options?: PhysicsOptions;\n RAPIER!: RAPIERCompat;\n fps: number = 0;\n blendedWorld!: RAPIER.World;\n eventQueue!: RAPIER.EventQueue;\n\n get timestep() {\n return 1 / this.fps;\n }\n\n /**\n * Asynchronously initializes the RAPIER physics engine and creates the\n * blendedWorld. This is called in Core before the physics simulation starts.\n */\n async init({physicsOptions}: {physicsOptions: PhysicsOptions}) {\n this.options = physicsOptions;\n this.RAPIER = this.options.RAPIER!;\n this.fps = this.options.fps;\n if (this.RAPIER.init) {\n await this.RAPIER.init();\n }\n this.blendedWorld = new this.RAPIER!.World(this.options.gravity);\n this.blendedWorld.timestep = this.timestep;\n if (this.options.useEventQueue) {\n this.eventQueue = new this.RAPIER!.EventQueue(true);\n }\n this.initialized = true;\n }\n\n /**\n * Advances the physics simulation by one step.\n */\n physicsStep() {\n if (this.options?.worldStep && this.blendedWorld) {\n this.blendedWorld.step(this.eventQueue);\n }\n }\n\n /**\n * Frees the memory allocated by the RAPIER physics blendedWorld and event\n * queue. This is crucial for preventing memory leaks when the XR session\n * ends.\n */\n dispose() {\n if (this.eventQueue) {\n this.eventQueue.free();\n }\n if (this.blendedWorld) {\n this.blendedWorld.free();\n }\n }\n};\n","import {deepMerge} from '../utils/OptionsUtils';\nimport {DeepPartial, DeepReadonly} from '../utils/Types';\n\nexport class HandsOptions {\n /** Whether hand tracking is enabled. */\n enabled = false;\n /** Whether to show any hand visualization. */\n visualization = false;\n /** Whether to show the tracked hand joints. */\n visualizeJoints = false;\n /** Whether to show the virtual hand meshes. */\n visualizeMeshes = false;\n\n debugging = false;\n\n constructor(options?: DeepReadonly<DeepPartial<HandsOptions>>) {\n deepMerge(this, options);\n }\n\n /**\n * Enables hands tracking.\n * @returns The instance for chaining.\n */\n enableHands() {\n this.enabled = true;\n return this;\n }\n\n enableHandsVisualization() {\n this.enabled = true;\n this.visualization = true;\n return this;\n }\n}\n","import {deepMerge} from '../utils/OptionsUtils.js';\nimport {DeepPartial, DeepReadonly} from '../utils/Types';\n\n/**\n * Default options for controlling Lighting module features.\n */\nexport class LightingOptions {\n /** Enables debugging renders and logs. */\n debugging = false;\n /** Enables XR lighting. */\n enabled = false;\n /** Add ambient spherical harmonics to lighting. */\n useAmbientSH = false;\n /** Add main diredtional light to lighting. */\n useDirectionalLight = false;\n /** Cast shadows using diretional light. */\n castDirectionalLightShadow = false;\n /**\n * Adjust hardness of shadows according to relative brightness of main light.\n */\n useDynamicSoftShadow = false; // experimental\n\n constructor(options?: DeepReadonly<DeepPartial<LightingOptions>>) {\n deepMerge(this, options);\n }\n}\n","import type RAPIER from 'rapier3d';\n\nexport type RAPIERCompat = typeof RAPIER&{\n init?: () => Promise<void>;\n}\n\nexport class PhysicsOptions {\n /**\n * The target frames per second for the physics simulation loop.\n */\n fps = 45;\n\n /**\n * The global gravity vector applied to the physics world.\n */\n gravity = {x: 0.0, y: -9.81, z: 0.0};\n\n /**\n * If true, the `Physics` manager will automatically call `world.step()`\n * on its fixed interval. Set to false if you want to control the\n * simulation step manually.\n */\n worldStep = true;\n\n /**\n * If true, an event queue will be created and passed to `world.step()`,\n * enabling the handling of collision and contact events.\n */\n useEventQueue = false\n\n /**\n * Instance of RAPIER.\n */\n RAPIER?: RAPIERCompat;\n}\n","import type {TemplateResult} from 'lit';\n\nimport {XR_BLOCKS_ASSETS_PATH} from '../constants';\nimport {Handedness} from '../input/Hands';\nimport {deepMerge} from '../utils/OptionsUtils';\nimport {DeepPartial, DeepReadonly} from '../utils/Types';\n\nexport enum SimulatorMode {\n USER = 'User',\n POSE = 'Navigation',\n CONTROLLER = 'Hands',\n}\n\nexport const NEXT_SIMULATOR_MODE = {\n [SimulatorMode.USER]: SimulatorMode.POSE,\n [SimulatorMode.POSE]: SimulatorMode.CONTROLLER,\n [SimulatorMode.CONTROLLER]: SimulatorMode.USER,\n};\n\nexport interface SimulatorCustomInstruction {\n header: string|TemplateResult;\n videoSrc?: string;\n description: string|TemplateResult;\n}\n\nexport class SimulatorOptions {\n initialCameraPosition = {x: 0, y: 1.5, z: 0};\n scenePath = XR_BLOCKS_ASSETS_PATH +\n 'simulator/scenes/XREmulatorsceneV5_livingRoom.glb';\n initialScenePosition = {x: -1.6, y: 0.3, z: 0};\n defaultMode = SimulatorMode.USER;\n defaultHand = Handedness.LEFT;\n modeIndicator = {\n enabled: true,\n element: 'xrblocks-simulator-mode-indicator',\n };\n instructions = {\n enabled: true,\n element: 'xrblocks-simulator-instructions',\n customInstructions: [] as SimulatorCustomInstruction[],\n };\n handPosePanel = {\n enabled: true,\n element: 'xrblocks-simulator-hand-pose-panel',\n };\n geminilive = false;\n stereo = {\n enabled: false,\n };\n // Whether to render the main scene to a render texture or directly to the\n // canvas.\n // This is a temporary option until we figure out why splats look faded.\n renderToRenderTexture = true;\n\n constructor(options?: DeepReadonly<DeepPartial<SimulatorOptions>>) {\n deepMerge(this, options);\n }\n};\n","export class SpeechSynthesizerOptions {\n enabled = false;\n /** If true, a new call to speak() will interrupt any ongoing speech. */\n allowInterruptions = false;\n}\n\nexport class SpeechRecognizerOptions {\n enabled = true;\n /** Recognition language (e.g., 'en-US'). */\n lang = 'en-US';\n /** If true, recognition continues after a pause. */\n continuous = false;\n /** Keywords to detect as commands. */\n commands: string[] = [];\n /** If true, provides interim results. */\n interimResults = false;\n /** Minimum confidence (0-1) for a command. */\n commandConfidenceThreshold = 0.7;\n /** If true, play activation sounds in simulator. */\n playSimulatorActivationSounds = true;\n}\n\nexport class SoundOptions {\n speechSynthesizer = new SpeechSynthesizerOptions();\n speechRecognizer = new SpeechRecognizerOptions();\n}\n","import {deepMerge} from '../../utils/OptionsUtils';\nimport {DeepPartial} from '../../utils/Types';\n\n/**\n * Configuration options for the ObjectDetector.\n */\nexport class ObjectsOptions {\n debugging = false;\n enabled = false;\n showDebugVisualizations = false;\n\n /**\n * Margin to add when cropping the object image, as a percentage of image\n * size.\n */\n objectImageMargin = 0.05;\n\n /**\n * Configuration for the detection backends.\n */\n backendConfig = {\n /** The active backend to use for detection. */\n activeBackend: 'gemini' as 'gemini' | 'mediapipe',\n gemini: {\n systemInstruction:\n `Please provide me with the bounding box coordinates for the primary objects in the given image, prioritizing objects that are nearby. For each bounding box, include ymin, xmin, ymax, and xmax. These coordinates should be absolute values ranging from 0 to 1000, corresponding to the image as if it were resized to 1000x1000 pixels. The origin (xmin:0; ymin:0) is the top-left corner of the image, and (xmax:1000; ymax:1000) is the bottom-right corner. List a maximum of 5 objects. Ignore hands and other human body parts, as well as any UI elements attached to them (e.g., a blue circle attached to a finger).`,\n responseSchema: {\n type: 'ARRAY',\n items: {\n type: 'OBJECT',\n required: ['objectName', 'ymin', 'xmin', 'ymax', 'xmax'],\n properties: {\n objectName: {type: 'STRING'},\n ymin: {type: 'NUMBER'},\n xmin: {type: 'NUMBER'},\n ymax: {type: 'NUMBER'},\n xmax: {type: 'NUMBER'},\n },\n },\n },\n },\n /** Placeholder for a future MediaPipe backend configuration. */\n mediapipe: {},\n };\n\n\n constructor(options?: DeepPartial<ObjectsOptions>) {\n if (options) {\n deepMerge(this, options);\n }\n }\n\n /**\n * Enables the object detector.\n */\n enable() {\n this.enabled = true;\n return this;\n }\n}\n","import {deepMerge} from '../../utils/OptionsUtils';\nimport {DeepPartial} from '../../utils/Types'\n\nexport class PlanesOptions {\n debugging = false;\n enabled = false;\n showDebugVisualizations = false;\n\n constructor(options?: DeepPartial<PlanesOptions>) {\n if (options) {\n deepMerge(this, options);\n }\n }\n\n enable() {\n this.enabled = true;\n return this;\n }\n}\n","import {deepMerge} from '../utils/OptionsUtils';\nimport {DeepPartial} from '../utils/Types'\n\nimport {ObjectsOptions} from './objects/ObjectsOptions';\nimport {PlanesOptions} from './planes/PlanesOptions';\n\nexport class WorldOptions {\n debugging = false;\n enabled = false;\n planes = new PlanesOptions();\n objects = new ObjectsOptions();\n\n constructor(options?: DeepPartial<WorldOptions>) {\n if (options) {\n deepMerge(this, options);\n }\n }\n\n /**\n * Enables plane detection.\n */\n enablePlaneDetection() {\n this.enabled = true;\n this.planes.enable();\n return this;\n }\n\n /**\n * Enables object detection.\n */\n enableObjectDetection() {\n this.enabled = true;\n this.objects.enable();\n return this;\n }\n}\n","import {AIOptions} from '../ai/AIOptions';\nimport {DeviceCameraOptions, xrDeviceCameraEnvironmentOptions, xrDeviceCameraUserOptions} from '../camera/CameraOptions.js';\nimport {DepthOptions, xrDepthMeshOptions} from '../depth/DepthOptions.js';\nimport {HandsOptions} from '../input/HandsOptions.js';\nimport {LightingOptions} from '../lighting/LightingOptions.js';\nimport {PhysicsOptions} from '../physics/PhysicsOptions';\nimport {SimulatorOptions} from '../simulator/SimulatorOptions';\nimport {SoundOptions} from '../sound/SoundOptions';\nimport {deepMerge} from '../utils/OptionsUtils';\nimport {DeepPartial, DeepReadonly} from '../utils/Types';\nimport {WorldOptions} from '../world/WorldOptions';\n\n/**\n * Default options for XR controllers, which encompass hands by default in\n * Android XR, mouse input on desktop, tracked controllers, and gamepads.\n */\nexport class InputOptions {\n /** Whether controller input is enabled. */\n enabled = true;\n /** Whether mouse input should act as a controller on desktop. */\n enabledMouse = true;\n /** Whether to enable debugging features for controllers. */\n debug = false;\n /** Whether to show controller models. */\n visualization = false;\n /** Whether to show the ray lines extending from the controllers. */\n visualizeRays = false;\n};\n\n/**\n * Default options for the reticle (pointing cursor).\n */\nexport class ReticleOptions {\n enabled = true;\n}\n\n/**\n * Options for the XR transition effect.\n */\nexport class XRTransitionOptions {\n /** Whether the transition effect is enabled. */\n enabled = false;\n /** The duration of the transition in seconds. */\n transitionTime = 0.5;\n /** The default background color for VR transitions. */\n defaultBackgroundColor = 0xffffff;\n}\n\n/**\n * A central configuration class for the entire XR Blocks system. It aggregates\n * all settings and provides chainable methods for enabling common features.\n */\nexport class Options {\n /**\n * Whether to use antialiasing.\n */\n antialias = true;\n /**\n * Whether to use a logarithmic depth buffer. Useful for depth-aware\n * occlusions.\n */\n logarithmicDepthBuffer = false;\n /**\n * Global flag for enabling various debugging features.\n */\n debugging = false;\n /**\n * Whether to request a stencil buffer.\n */\n stencil = false;\n\n controllers = new InputOptions();\n depth = new DepthOptions();\n lighting = new LightingOptions();\n deviceCamera = new DeviceCameraOptions();\n hands = new HandsOptions();\n reticles = new ReticleOptions();\n sound = new SoundOptions();\n ai = new AIOptions();\n simulator = new SimulatorOptions();\n world = new WorldOptions();\n physics = new PhysicsOptions();\n transition = new XRTransitionOptions();\n camera = {\n near: 0.01,\n far: 500,\n }\n\n /**\n * Whether to use post-processing effects.\n */\n usePostprocessing = false;\n\n /**\n * Configuration for the XR session button.\n */\n xrButton = {\n enabled: true,\n startText: 'Enter XR',\n endText: 'Exit XR',\n invalidText: 'XR Not Supported',\n startSimulatorText: 'Enter Simulator',\n enableSimulator: true,\n showSimulatorButtonOnMobile: false,\n autostartSimulatorOnDesktop: true,\n // Whether to always autostart the simulator.\n autostartSimulator: false\n };\n\n /**\n * Constructs the Options object by merging default values with provided\n * custom options.\n * @param options - A custom options object to override the defaults.\n */\n constructor(options?: DeepReadonly<DeepPartial<Options>>) {\n deepMerge(this, options)\n }\n\n /**\n * Enables a standard set of options for a UI-focused experience.\n * @returns The instance for chaining.\n */\n enableUI() {\n this.antialias = true;\n this.reticles.enabled = true;\n return this;\n }\n\n /**\n * Enables reticles for visualizing targets of hand rays in WebXR.\n * @returns The instance for chaining.\n */\n enableReticles() {\n this.reticles.enabled = true;\n return this;\n }\n\n /**\n * Enables depth sensing in WebXR with default options.\n * @returns The instance for chaining.\n */\n enableDepth() {\n this.depth = new DepthOptions(xrDepthMeshOptions);\n return this;\n }\n\n /**\n * Enables plane detection.\n * @returns The instance for chaining.\n */\n enablePlaneDetection() {\n this.world.enablePlaneDetection();\n return this;\n }\n\n /**\n * Enables object detection.\n * @returns The instance for chaining.\n */\n enableObjectDetection() {\n this.world.enableObjectDetection();\n return this;\n }\n\n\n /**\n * Enables device camera (passthrough) with a specific facing mode.\n * @param facingMode - The desired camera facing mode, either 'environment' or\n * 'user'.\n * @returns The instance for chaining.\n */\n enableCamera(facingMode: 'environment'|'user' = 'environment') {\n this.deviceCamera = new DeviceCameraOptions(\n facingMode === 'environment' ? xrDeviceCameraEnvironmentOptions :\n xrDeviceCameraUserOptions);\n return this;\n }\n\n /**\n * Enables hand tracking.\n * @returns The instance for chaining.\n */\n enableHands() {\n this.hands.enabled = true;\n return this;\n }\n\n /**\n * Enables the visualization of rays for hand tracking.\n * @returns The instance for chaining.\n */\n enableHandRays() {\n this.controllers.visualizeRays = true;\n return this;\n }\n\n /**\n * Enables the Gemini Live feature.\n * @returns The instance for chaining.\n */\n enableGeminiLive() {\n this.simulator.geminilive = true;\n return this;\n }\n\n /**\n * Enables a standard set of AI features, including Gemini Live.\n * @returns The instance for chaining.\n */\n enableAI() {\n this.ai.enabled = true;\n this.ai.gemini.enabled = true;\n this.ai.gemini.live.enabled = true;\n return this;\n }\n\n /**\n * Enables the XR transition component for toggling VR.\n * @returns The instance for chaining.\n */\n enableXRTransitions() {\n this.transition.enabled = true;\n return this;\n }\n}\n","export class SimulatorMediaDeviceInfo {\n constructor(\n public deviceId = 'simulator', public groupId = 'simulator',\n public kind: MediaDeviceKind = 'videoinput',\n public label = 'Simulator Camera') {}\n}\n","export enum ConstrainDomStringMatch {\n EXACT = 0,\n IDEAL = 1,\n ACCEPTABLE = 2,\n UNACCEPTABLE = 3\n}\n\n/**\n * Evaluates how a string value satisfies a ConstrainDOMString constraint.\n *\n * @param constraint - The ConstrainDOMString to check against.\n * @param value - The string value to test.\n * @returns A `ConstrainDomStringMatch` enum indicating the match level.\n */\nexport function evaluateConstrainDOMString(\n constraint: ConstrainDOMString, value: string): ConstrainDomStringMatch {\n // Helper to check for a match against a string or string array.\n const matches = (c: string|string[], v: string): boolean => {\n return typeof c === 'string' ? v === c : c.includes(v);\n };\n\n // If no constraint is given, the value is simply acceptable.\n if (constraint == null) {\n return ConstrainDomStringMatch.ACCEPTABLE;\n }\n\n // A standalone string or array is treated as an implicit 'exact' requirement.\n if (typeof constraint === 'string' || Array.isArray(constraint)) {\n return matches(constraint, value) ? ConstrainDomStringMatch.EXACT :\n ConstrainDomStringMatch.UNACCEPTABLE;\n }\n\n // Handle the object-based constraint.\n if (typeof constraint === 'object') {\n // The 'exact' property is a hard requirement that overrides all others.\n if (constraint.exact !== undefined) {\n return matches(constraint.exact, value) ?\n ConstrainDomStringMatch.EXACT :\n ConstrainDomStringMatch.UNACCEPTABLE;\n }\n\n // If there's no 'exact' constraint, check 'ideal'.\n if (constraint.ideal !== undefined) {\n if (matches(constraint.ideal, value)) {\n return ConstrainDomStringMatch.IDEAL;\n }\n }\n\n // If the value doesn't match 'ideal' (or if 'ideal' wasn't specified),\n // it's still acceptable because 'ideal' is only a preference.\n return ConstrainDomStringMatch.ACCEPTABLE;\n }\n\n // Fallback for any unknown constraint types.\n return ConstrainDomStringMatch.UNACCEPTABLE;\n}\n","import * as THREE from 'three';\n\nimport {SimulatorMediaDeviceInfo} from './SimulatorMediaDeviceInfo';\nimport {ConstrainDomStringMatch, evaluateConstrainDOMString} from './utils/CameraUtils';\n\nexport class SimulatorCamera {\n private cameraCreated = false;\n private cameraInfo?: SimulatorMediaDeviceInfo;\n private mediaStream?: MediaStream;\n private canvas?: HTMLCanvasElement;\n private context?: CanvasRenderingContext2D|null;\n private fps = 30;\n matchRenderingCamera = true;\n width = 512;\n height = 512;\n camera = new THREE.PerspectiveCamera();\n\n constructor(private renderer: THREE.WebGLRenderer) {}\n\n init() {\n this.createSimulatorCamera();\n }\n\n createSimulatorCamera() {\n if (this.cameraCreated) {\n return;\n }\n this.canvas = document.createElement('canvas');\n this.canvas.width = this.width;\n this.canvas.height = this.height;\n this.context = this.canvas.getContext('2d');\n this.mediaStream = this.canvas.captureStream(this.fps);\n const videoTrack = this.mediaStream.getVideoTracks()[0];\n const id = this.mediaStream.getVideoTracks()[0].getSettings().deviceId;\n this.cameraInfo = new SimulatorMediaDeviceInfo(/*deviceId=*/ id);\n videoTrack.stop();\n this.cameraCreated = true;\n }\n\n async enumerateDevices() {\n if (this.cameraInfo) {\n return [this.cameraInfo];\n }\n return [];\n }\n\n onBeforeSimulatorSceneRender(\n camera: THREE.Camera, renderScene: (_: THREE.Camera) => void) {\n if (!this.cameraCreated) {\n return;\n }\n if (!this.matchRenderingCamera) {\n this.camera.position.copy(camera.position);\n this.camera.quaternion.copy(camera.quaternion);\n renderScene(this.camera);\n const sWidth = this.renderer.domElement.width;\n const sHeight = this.renderer.domElement.height;\n const aspectRatio = this.width / this.height;\n const croppedSourceWidth = Math.min(sWidth, sHeight * aspectRatio);\n const croppedSourceHeight = Math.min(sHeight, sWidth / aspectRatio);\n const sx = (sWidth - croppedSourceWidth) / 2;\n const sy = (sHeight - croppedSourceHeight) / 2;\n this.context!.drawImage(\n this.renderer.domElement, sx, sy, croppedSourceWidth,\n croppedSourceHeight, 0, 0, this.width, this.height);\n }\n }\n\n onSimulatorSceneRendered() {\n if (!this.cameraCreated) {\n return;\n }\n if (this.matchRenderingCamera) {\n const sWidth = this.renderer.domElement.width;\n const sHeight = this.renderer.domElement.height;\n const aspectRatio = this.width / this.height;\n const croppedSourceWidth = Math.min(sWidth, sHeight * aspectRatio);\n const croppedSourceHeight = Math.min(sHeight, sWidth / aspectRatio);\n const sx = (sWidth - croppedSourceWidth) / 2;\n const sy = (sHeight - croppedSourceHeight) / 2;\n this.context!.drawImage(\n this.renderer.domElement, sx, sy, croppedSourceWidth,\n croppedSourceHeight, 0, 0, this.width, this.height);\n }\n }\n\n restartVideoTrack() {\n if (!this.cameraCreated) {\n return;\n }\n this.mediaStream = this.canvas!.captureStream(this.fps);\n const id = this.mediaStream.getVideoTracks()[0].getSettings().deviceId;\n this.cameraInfo!.deviceId = id || '';\n }\n\n getMedia(constraints: MediaTrackConstraints = {}) {\n if (!this.cameraCreated) {\n return;\n }\n if (!constraints?.deviceId ||\n evaluateConstrainDOMString(\n constraints?.deviceId, this.cameraInfo!.deviceId) !=\n ConstrainDomStringMatch.UNACCEPTABLE) {\n const videoTrack = this.mediaStream!.getVideoTracks()[0];\n if (videoTrack.readyState == 'ended') {\n this.restartVideoTrack();\n }\n return this.mediaStream;\n }\n return null;\n }\n}\n","export const AVERAGE_IPD_METERS = 0.063;\nexport enum SimulatorRenderMode {\n DEFAULT = 'default',\n STEREO_LEFT = 'left',\n STEREO_RIGHT = 'right',\n}","/**\n * A frozen object containing standardized string values for `event.code`.\n * Used for desktop simulation.\n */\nexport enum Keycodes {\n // --- Movement Keys ---\n W_CODE = 'KeyW',\n A_CODE = 'KeyA',\n S_CODE = 'KeyS',\n D_CODE = 'KeyD',\n UP = 'ArrowUp',\n DOWN = 'ArrowDown',\n LEFT = 'ArrowLeft',\n RIGHT = 'ArrowRight',\n\n // --- Vertical Movement / Elevation ---\n Q_CODE = 'KeyQ', // Often used for 'down' or 'strafe left'\n E_CODE = 'KeyE', // Often used for 'up' or 'strafe right'\n PAGE_UP = 'PageUp',\n PAGE_DOWN = 'PageDown',\n\n // --- Action & Interaction Keys ---\n SPACE_CODE = 'Space',\n ENTER_CODE = 'Enter',\n T_CODE = 'KeyT', // General purpose 'toggle' or 'tool' key\n\n // --- Modifier Keys ---\n LEFT_SHIFT_CODE = 'ShiftLeft',\n RIGHT_SHIFT_CODE = 'ShiftRight',\n LEFT_CTRL_CODE = 'ControlLeft',\n RIGHT_CTRL_CODE = 'ControlRight',\n LEFT_ALT_CODE = 'AltLeft',\n RIGHT_ALT_CODE = 'AltRight',\n CAPS_LOCK_CODE = 'CapsLock',\n\n // --- UI & System Keys ---\n ESCAPE_CODE = 'Escape',\n TAB_CODE = 'Tab',\n\n // --- Alphabet Keys ---\n B_CODE = 'KeyB',\n C_CODE = 'KeyC',\n F_CODE = 'KeyF',\n G_CODE = 'KeyG',\n H_CODE = 'KeyH',\n I_CODE = 'KeyI',\n J_CODE = 'KeyJ',\n K_CODE = 'KeyK',\n L_CODE = 'KeyL',\n M_CODE = 'KeyM',\n N_CODE = 'KeyN',\n O_CODE = 'KeyO',\n P_CODE = 'KeyP',\n R_CODE = 'KeyR',\n U_CODE = 'KeyU',\n V_CODE = 'KeyV',\n X_CODE = 'KeyX',\n Y_CODE = 'KeyY',\n Z_CODE = 'KeyZ',\n\n // --- Number Keys ---\n DIGIT_0 = 'Digit0',\n DIGIT_1 = 'Digit1',\n DIGIT_2 = 'Digit2',\n DIGIT_3 = 'Digit3',\n DIGIT_4 = 'Digit4',\n DIGIT_5 = 'Digit5',\n DIGIT_6 = 'Digit6',\n DIGIT_7 = 'Digit7',\n DIGIT_8 = 'Digit8',\n DIGIT_9 = 'Digit9',\n\n BACKQUOTE = 'Backquote',\n}\n","import * as THREE from 'three';\n\nexport class SimulatorControllerState {\n localControllerPositions =\n [new THREE.Vector3(-0.3, -0.1, -0.3), new THREE.Vector3(0.3, -0.1, -0.3)];\n localControllerOrientations =\n [new THREE.Quaternion(), new THREE.Quaternion()];\n\n currentControllerIndex = 0;\n}","import * as THREE from 'three';\n\nimport {Input} from '../../input/Input.js';\nimport {Keycodes} from '../../utils/Keycodes';\nimport {SimulatorRenderMode} from '../SimulatorConstants';\nimport {SimulatorControllerState} from '../SimulatorControllerState';\nimport {SimulatorHands} from '../SimulatorHands.js';\n\nconst {A_CODE, D_CODE, E_CODE, Q_CODE, S_CODE, W_CODE} = Keycodes;\nconst vector3 = new THREE.Vector3();\nconst euler = new THREE.Euler();\n\nexport class SimulatorControlMode {\n camera!: THREE.Camera;\n input!: Input;\n timer!: THREE.Timer;\n\n /**\n * Create a SimulatorControlMode\n */\n constructor(\n protected simulatorControllerState: SimulatorControllerState,\n protected downKeys: Set<Keycodes>, protected hands: SimulatorHands,\n protected setStereoRenderMode: (_: SimulatorRenderMode) => void,\n protected toggleUserInterface: () => void) {}\n\n /**\n * Initialize the simulator control mode.\n */\n init({camera, input, timer}:\n {camera: THREE.Camera, input: Input, timer: THREE.Timer}) {\n this.camera = camera;\n this.input = input;\n this.timer = timer;\n }\n\n onPointerDown(_: MouseEvent) {}\n onPointerUp(_: MouseEvent) {}\n onPointerMove(_: MouseEvent) {}\n onKeyDown(event: KeyboardEvent) {\n if (event.code == Keycodes.DIGIT_1) {\n this.setStereoRenderMode(SimulatorRenderMode.STEREO_LEFT);\n } else if (event.code == Keycodes.DIGIT_2) {\n this.setStereoRenderMode(SimulatorRenderMode.STEREO_RIGHT);\n } else if (event.code == Keycodes.BACKQUOTE) {\n this.toggleUserInterface();\n }\n }\n onModeActivated() {}\n onModeDeactivated() {}\n\n update() {\n this.updateCameraPosition();\n this.updateControllerPositions();\n }\n\n updateCameraPosition() {\n const deltaTime = this.timer.getDelta();\n const cameraRotation = this.camera.quaternion;\n const cameraPosition = this.camera.position;\n const downKeys = this.downKeys;\n vector3\n .set(\n Number(downKeys.has(D_CODE)) - Number(downKeys.has(A_CODE)),\n Number(downKeys.has(Q_CODE)) - Number(downKeys.has(E_CODE)),\n Number(downKeys.has(S_CODE)) - Number(downKeys.has(W_CODE)),\n )\n .multiplyScalar(deltaTime)\n .applyQuaternion(cameraRotation)\n cameraPosition.add(vector3);\n }\n\n updateControllerPositions() {\n this.camera.updateMatrixWorld();\n for (let i = 0; i < 2; i++) {\n const controller = this.input.controllers[i];\n controller.position\n .copy(this.simulatorControllerState.localControllerPositions[i])\n .applyMatrix4(this.camera.matrixWorld);\n controller.quaternion\n .copy(this.simulatorControllerState.localControllerOrientations[i])\n .premultiply(this.camera.quaternion);\n controller.updateMatrix();\n const mesh =\n i == 0 ? this.hands.leftController : this.hands.rightController;\n mesh.position.copy(controller.position);\n mesh.quaternion.copy(controller.quaternion);\n }\n }\n\n rotateOnPointerMove(\n event: MouseEvent, objectQuaternion: THREE.Quaternion,\n multiplier = 0.002) {\n euler.setFromQuaternion(objectQuaternion, 'YXZ');\n euler.y += event.movementX * multiplier;\n euler.x += event.movementY * multiplier;\n\n // Clamp camera pitch to +/-90 deg (+/-1.57 rad) with a 0.01 rad (0.573 deg)\n // buffer to prevent gimbal lock.\n const PI_2 = Math.PI / 2;\n euler.x = Math.max(-PI_2 + 0.01, Math.min(PI_2 - 0.01, euler.x));\n\n objectQuaternion.setFromEuler(euler);\n }\n\n enableSimulatorHands() {\n this.hands.showHands();\n this.input.dispatchEvent({\n type: 'connected',\n target: this.input.controllers[0],\n data: {handedness: 'left'}\n });\n this.input.dispatchEvent({\n type: 'connected',\n target: this.input.controllers[1],\n data: {handedness: 'right'}\n });\n }\n\n disableSimulatorHands() {\n this.hands.hideHands();\n this.input.dispatchEvent({\n type: 'disconnected',\n target: this.input.controllers[0],\n data: {handedness: 'left'}\n });\n this.input.dispatchEvent({\n type: 'disconnected',\n target: this.input.controllers[1],\n data: {handedness: 'right'}\n });\n }\n}\n","import * as THREE from 'three';\n\nimport {Keycodes} from '../../utils/Keycodes';\n\nimport {SimulatorControlMode} from './SimulatorControlMode';\n\nconst vector3 = new THREE.Vector3();\nconst {A_CODE, D_CODE, E_CODE, Q_CODE, S_CODE, SPACE_CODE, T_CODE, W_CODE} =\n Keycodes;\n\nexport class SimulatorControllerMode extends SimulatorControlMode {\n onPointerMove(event: MouseEvent) {\n if (event.buttons) {\n const controllerOrientation =\n this.simulatorControllerState\n .localControllerOrientations[this.simulatorControllerState\n .currentControllerIndex];\n this.rotateOnPointerMove(event, controllerOrientation, -0.002);\n }\n }\n\n override update() {\n this.updateControllerPositions();\n }\n\n onModeActivated() {\n this.enableSimulatorHands();\n }\n\n updateControllerPositions() {\n const deltaTime = this.timer.getDelta();\n const downKeys = this.downKeys;\n vector3\n .set(\n Number(downKeys.has(D_CODE)) - Number(downKeys.has(A_CODE)),\n Number(downKeys.has(Q_CODE)) - Number(downKeys.has(E_CODE)),\n Number(downKeys.has(S_CODE)) - Number(downKeys.has(W_CODE)),\n )\n .multiplyScalar(deltaTime);\n this.simulatorControllerState\n .localControllerPositions[this.simulatorControllerState\n .currentControllerIndex]\n .add(vector3);\n super.updateControllerPositions();\n }\n\n toggleControllerIndex() {\n this.hands.toggleHandedness();\n }\n\n onKeyDown(event: KeyboardEvent) {\n super.onKeyDown(event);\n if (event.code == T_CODE) {\n this.toggleControllerIndex();\n } else if (event.code == SPACE_CODE) {\n const controllerSelecting =\n this.input\n .controllers[this.simulatorControllerState.currentControllerIndex]\n .userData?.selected;\n const newSelectingState = !controllerSelecting;\n if (this.simulatorControllerState.currentControllerIndex == 0) {\n this.hands.setLeftHandPinching(newSelectingState);\n } else {\n this.hands.setRightHandPinching(newSelectingState);\n }\n }\n }\n}\n","\nimport {SimulatorControlMode} from './SimulatorControlMode.js';\n\nexport class SimulatorPoseMode extends SimulatorControlMode {\n onModeActivated() {\n this.enableSimulatorHands();\n }\n\n onPointerMove(event: MouseEvent) {\n if (event.buttons) {\n this.rotateOnPointerMove(event, this.camera.quaternion);\n }\n }\n}\n","import {SimulatorControlMode} from './SimulatorControlMode.js';\n\nexport class SimulatorUserMode extends SimulatorControlMode {\n onModeActivated() {\n this.disableSimulatorHands();\n this.input.mouseController.connect();\n }\n\n onModeDeactivated() {\n this.input.mouseController.disconnect();\n }\n\n onPointerDown(event: MouseEvent) {\n if (event.buttons & 1) {\n this.input.mouseController.callSelectStart();\n }\n }\n\n onPointerUp() {\n if (this.input.mouseController.userData.selected) {\n this.input.mouseController.callSelectEnd();\n }\n }\n\n onPointerMove(event: MouseEvent) {\n this.input.mouseController.updateMousePositionFromEvent(event);\n if (event.buttons & 2) {\n this.rotateOnPointerMove(event, this.camera.quaternion);\n }\n }\n}\n","import {SimulatorMode} from '../SimulatorOptions';\n\nexport class SetSimulatorModeEvent extends Event {\n static type = 'setSimulatorMode';\n constructor(public simulatorMode: SimulatorMode) {\n super(SetSimulatorModeEvent.type, {bubbles: true, composed: true});\n }\n}\n","import * as THREE from 'three';\n\nimport {Handedness} from '../input/Hands';\nimport {Input} from '../input/Input';\nimport {Keycodes} from '../utils/Keycodes';\n\nimport {SimulatorControllerMode} from './controlModes/SimulatorControllerMode'\nimport {SimulatorControlMode} from './controlModes/SimulatorControlMode';\nimport {SimulatorPoseMode} from './controlModes/SimulatorPoseMode';\nimport {SimulatorUserMode} from './controlModes/SimulatorUserMode';\nimport {SetSimulatorModeEvent} from './events/SimulatorModeEvents';\nimport {SimulatorRenderMode} from './SimulatorConstants';\nimport {SimulatorControllerState} from './SimulatorControllerState';\nimport {SimulatorHands} from './SimulatorHands';\nimport {SimulatorInterface} from './SimulatorInterface';\nimport {NEXT_SIMULATOR_MODE, SimulatorMode, SimulatorOptions} from './SimulatorOptions';\n\nfunction preventDefault(event: Event) {\n event.preventDefault();\n}\n\nexport type SimulatorModeIndicatorElement = HTMLElement&{\n simulatorMode: SimulatorMode;\n}\n\nexport class SimulatorControls {\n pointerDown = false;\n downKeys = new Set<Keycodes>();\n\n // Custom HTML element indicating the simulator control mode.\n modeIndicatorElement?: SimulatorModeIndicatorElement;\n\n simulatorMode = SimulatorMode.USER;\n\n simulatorModeControls: SimulatorControlMode;\n simulatorModes: {[key: string]: SimulatorControlMode};\n renderer!: THREE.WebGLRenderer;\n\n private _onPointerDown = this.onPointerDown.bind(this);\n private _onPointerUp = this.onPointerUp.bind(this);\n private _onKeyDown = this.onKeyDown.bind(this);\n private _onKeyUp = this.onKeyUp.bind(this);\n private _onPointerMove = this.onPointerMove.bind(this);\n\n /**\n * Create the simulator controls.\n * @param hands - The simulator hands manager.\n * @param setStereoRenderMode - A function to set the stereo mode.\n * @param userInterface - The simulator user interface manager.\n */\n constructor(\n public simulatorControllerState: SimulatorControllerState,\n public hands: SimulatorHands,\n setStereoRenderMode: (_: SimulatorRenderMode) => void,\n private userInterface: SimulatorInterface) {\n const toggleUserInterface = () => {\n this.userInterface.toggleInterfaceVisible();\n };\n this.simulatorModes = {\n [SimulatorMode.USER]: new SimulatorUserMode(\n this.simulatorControllerState, this.downKeys, hands,\n setStereoRenderMode, toggleUserInterface),\n [SimulatorMode.POSE]: new SimulatorPoseMode(\n this.simulatorControllerState, this.downKeys, hands,\n setStereoRenderMode, toggleUserInterface),\n [SimulatorMode.CONTROLLER]: new SimulatorControllerMode(\n this.simulatorControllerState, this.downKeys, hands,\n setStereoRenderMode, toggleUserInterface),\n };\n\n this.simulatorModeControls = this.simulatorModes[this.simulatorMode];\n }\n\n /**\n * Initialize the simulator controls.\n */\n init({camera, input, timer, renderer, simulatorOptions}: {\n camera: THREE.Camera,\n input: Input,\n timer: THREE.Timer,\n renderer: THREE.WebGLRenderer,\n simulatorOptions: SimulatorOptions\n }) {\n for (const mode in this.simulatorModes) {\n this.simulatorModes[mode].init({camera, input, timer});\n }\n this.renderer = renderer;\n this.setSimulatorMode(simulatorOptions.defaultMode);\n this.simulatorControllerState.currentControllerIndex =\n simulatorOptions.defaultHand === Handedness.LEFT ? 0 : 1;\n this.connect();\n }\n\n connect() {\n const domElement = this.renderer.domElement;\n document.addEventListener('keyup', this._onKeyUp);\n document.addEventListener('keydown', this._onKeyDown);\n domElement.addEventListener('pointermove', this._onPointerMove);\n domElement.addEventListener('pointerdown', this._onPointerDown);\n domElement.addEventListener('pointerup', this._onPointerUp);\n domElement.addEventListener('contextmenu', preventDefault);\n }\n\n update() {\n this.simulatorModeControls.update();\n }\n\n\n onPointerMove(event: MouseEvent) {\n this.simulatorModeControls.onPointerMove(event);\n }\n\n onPointerDown(event: MouseEvent) {\n this.simulatorModeControls.onPointerDown(event);\n this.pointerDown = true;\n }\n\n onPointerUp(event: MouseEvent) {\n this.simulatorModeControls.onPointerUp(event);\n this.pointerDown = false;\n }\n\n onKeyDown(event: KeyboardEvent) {\n this.downKeys.add(event.code as Keycodes);\n if (event.code == Keycodes.LEFT_SHIFT_CODE) {\n this.setSimulatorMode(NEXT_SIMULATOR_MODE[this.simulatorMode]);\n }\n this.simulatorModeControls.onKeyDown(event);\n }\n\n onKeyUp(event: KeyboardEvent) {\n this.downKeys.delete(event.code as Keycodes);\n }\n\n setSimulatorMode(mode: SimulatorMode) {\n this.simulatorMode = mode;\n this.simulatorModeControls.onModeDeactivated();\n this.simulatorModeControls = this.simulatorModes[this.simulatorMode];\n this.simulatorModeControls.onModeActivated();\n if (this.modeIndicatorElement) {\n this.modeIndicatorElement.simulatorMode = mode;\n }\n }\n\n setModeIndicatorElement(element: SimulatorModeIndicatorElement) {\n element.simulatorMode = this.simulatorMode;\n element.addEventListener('setSimulatorMode', (event) => {\n if (event instanceof SetSimulatorModeEvent) {\n this.setSimulatorMode(event.simulatorMode);\n }\n });\n this.modeIndicatorElement = element;\n }\n}\n","import * as THREE from 'three';\n\nexport class SimulatorDepthMaterial extends THREE.MeshBasicMaterial {\n override onBeforeCompile(\n shader:\n {vertexShader: string, fragmentShader: string, uniforms: object}) {\n shader.vertexShader =\n shader.vertexShader\n .replace(\n '#include <clipping_planes_pars_vertex>',\n [\n '#include <clipping_planes_pars_vertex>',\n 'varying vec4 vViewCoordinates;'\n ].join('\\n'))\n .replace('#include <project_vertex>', [\n '#include <project_vertex>', 'vViewCoordinates = mvPosition;'\n ].join('\\n'));\n shader.fragmentShader =\n shader.fragmentShader\n .replace(\n '#include <clipping_planes_pars_fragment>',\n [\n '#include <clipping_planes_pars_fragment>',\n 'varying vec4 vViewCoordinates;'\n ].join('\\n'))\n .replace('#include <dithering_fragment>', [\n '#include <dithering_fragment>',\n 'gl_FragColor = vec4(-vViewCoordinates.z, 0.0, 0.0, 1.0);'\n ].join('\\n'));\n }\n}","import * as THREE from 'three';\n\nimport {Depth} from '../depth/Depth';\n\nimport {SimulatorDepthMaterial} from './SimulatorDepthMaterial';\nimport {SimulatorScene} from './SimulatorScene';\n\nexport class SimulatorDepth {\n renderer!: THREE.WebGLRenderer;\n camera!: THREE.Camera;\n depth!: Depth;\n depthWidth = 160;\n depthHeight = 160;\n depthBufferSlice = new Float32Array();\n depthMaterial!: SimulatorDepthMaterial;\n depthRenderTarget!: THREE.WebGLRenderTarget;\n depthBuffer!: Float32Array;\n\n constructor(private simulatorScene: SimulatorScene) {}\n\n /**\n * Initialize Simulator Depth.\n */\n init(renderer: THREE.WebGLRenderer, camera: THREE.Camera, depth: Depth) {\n this.renderer = renderer;\n this.camera = camera;\n this.depth = depth;\n\n this.createRenderTarget();\n this.depthMaterial = new SimulatorDepthMaterial();\n }\n\n createRenderTarget() {\n this.depthRenderTarget =\n new THREE.WebGLRenderTarget(this.depthWidth, this.depthHeight, {\n format: THREE.RedFormat,\n type: THREE.FloatType,\n });\n this.depthBuffer = new Float32Array(this.depthWidth * this.depthHeight);\n }\n\n update() {\n this.renderDepthScene();\n this.updateDepth();\n }\n\n renderDepthScene() {\n const originalRenderTarget = this.renderer.getRenderTarget();\n this.renderer.setRenderTarget(this.depthRenderTarget);\n this.simulatorScene.overrideMaterial = this.depthMaterial;\n this.renderer.render(this.simulatorScene, this.camera);\n this.simulatorScene.overrideMaterial = null;\n this.renderer.setRenderTarget(originalRenderTarget);\n }\n\n updateDepth() {\n // We preventively unbind the PIXEL_PACK_BUFFER before reading from the\n // render target in case external libraries (Spark.js) left it bound.\n const context = this.renderer.getContext() as WebGL2RenderingContext;\n context.bindBuffer(context.PIXEL_PACK_BUFFER, null);\n\n this.renderer.readRenderTargetPixels(\n this.depthRenderTarget, 0, 0, this.depthWidth, this.depthHeight,\n this.depthBuffer);\n\n // Flip the depth buffer.\n if (this.depthBufferSlice.length != this.depthWidth) {\n this.depthBufferSlice = new Float32Array(this.depthWidth);\n }\n for (let i = 0; i < this.depthHeight / 2; ++i) {\n const j = this.depthHeight - 1 - i;\n const i_offset = i * this.depthWidth;\n const j_offset = j * this.depthWidth;\n\n // Copy row i to a temp slice\n this.depthBufferSlice.set(\n this.depthBuffer.subarray(i_offset, i_offset + this.depthWidth));\n // Copy row j to row i\n this.depthBuffer.copyWithin(\n i_offset, j_offset, j_offset + this.depthWidth);\n // Copy the temp slice (original row i) to row j\n this.depthBuffer.set(this.depthBufferSlice, j_offset);\n }\n\n const depthData = {\n width: this.depthWidth,\n height: this.depthHeight,\n data: this.depthBuffer.buffer,\n rawValueToMeters: 1.0,\n };\n\n this.depth.updateDepthData(depthData as XRCPUDepthInformation, 0);\n }\n}\n","import {SimulatorHandPose} from '../handPoses/HandPoses';\n\n// Request to change the hand pose.\nexport class SimulatorHandPoseChangeRequestEvent extends Event {\n static type = 'SimulatorHandPoseChangeRequestEvent';\n constructor(public pose: SimulatorHandPose) {\n super(\n SimulatorHandPoseChangeRequestEvent.type,\n {bubbles: true, composed: true});\n }\n}\n","import type {DeepReadonly} from '../../utils/Types';\n\nimport {LEFT_HAND_FIST, RIGHT_HAND_FIST} from './FistHandPoses';\nimport type {SimulatorHandPoseJoints} from './HandPoseJoints';\nimport {LEFT_HAND_PINCHING, RIGHT_HAND_PINCHING} from './PinchingHandPoses';\nimport {LEFT_HAND_POINTING, RIGHT_HAND_POINTING} from './PointingHandPoses';\nimport {LEFT_HAND_RELAXED, RIGHT_HAND_RELAXED} from './RelaxedHandPoses';\nimport {LEFT_HAND_ROCK, RIGHT_HAND_ROCK} from './RockHandPoses';\nimport {LEFT_HAND_THUMBS_DOWN, RIGHT_HAND_THUMBS_DOWN} from './ThumbsDownPoses';\nimport {LEFT_HAND_THUMBS_UP, RIGHT_HAND_THUMBS_UP} from './ThumbsUpPoses';\nimport {LEFT_HAND_VICTORY, RIGHT_HAND_VICTORY} from './VictoryHandPoses';\n\n// Enum of hand poses.\nexport enum SimulatorHandPose {\n RELAXED = 'relaxed',\n PINCHING = 'pinching',\n FIST = 'fist',\n THUMBS_UP = 'thumbs_up',\n POINTING = 'pointing',\n ROCK = 'rock',\n THUMBS_DOWN = 'thumbs_down',\n VICTORY = 'victory'\n}\n\nexport const SIMULATOR_HAND_POSE_TO_JOINTS_LEFT:\n DeepReadonly<Record<SimulatorHandPose, SimulatorHandPoseJoints>> =\n Object.freeze({\n [SimulatorHandPose.RELAXED]: LEFT_HAND_RELAXED,\n [SimulatorHandPose.PINCHING]: LEFT_HAND_PINCHING,\n [SimulatorHandPose.FIST]: LEFT_HAND_FIST,\n [SimulatorHandPose.THUMBS_UP]: LEFT_HAND_THUMBS_UP,\n [SimulatorHandPose.POINTING]: LEFT_HAND_POINTING,\n [SimulatorHandPose.ROCK]: LEFT_HAND_ROCK,\n [SimulatorHandPose.THUMBS_DOWN]: LEFT_HAND_THUMBS_DOWN,\n [SimulatorHandPose.VICTORY]: LEFT_HAND_VICTORY\n } as const);\n\nexport const SIMULATOR_HAND_POSE_TO_JOINTS_RIGHT:\n DeepReadonly<Record<SimulatorHandPose, SimulatorHandPoseJoints>> =\n Object.freeze({\n [SimulatorHandPose.RELAXED]: RIGHT_HAND_RELAXED,\n [SimulatorHandPose.PINCHING]: RIGHT_HAND_PINCHING,\n [SimulatorHandPose.FIST]: RIGHT_HAND_FIST,\n [SimulatorHandPose.THUMBS_UP]: RIGHT_HAND_THUMBS_UP,\n [SimulatorHandPose.POINTING]: RIGHT_HAND_POINTING,\n [SimulatorHandPose.ROCK]: RIGHT_HAND_ROCK,\n [SimulatorHandPose.THUMBS_DOWN]: RIGHT_HAND_THUMBS_DOWN,\n [SimulatorHandPose.VICTORY]: RIGHT_HAND_VICTORY\n });\n\nexport const SIMULATOR_HAND_POSE_NAMES:\n Readonly<Record<SimulatorHandPose, string>> = Object.freeze({\n [SimulatorHandPose.RELAXED]: 'Relaxed',\n [SimulatorHandPose.PINCHING]: 'Pinching',\n [SimulatorHandPose.FIST]: 'Fist',\n [SimulatorHandPose.THUMBS_UP]: 'Thumbs Up',\n [SimulatorHandPose.POINTING]: 'Pointing',\n [SimulatorHandPose.ROCK]: 'Rock',\n [SimulatorHandPose.THUMBS_DOWN]: 'Thumbs Down',\n [SimulatorHandPose.VICTORY]: 'Victory'\n });\n","export const LEFT_HAND_RELAXED = [\n {'t': [-0.05, -0.08, -0.1], 'r': [0.5373, 0, 0, 0.8434]},\n {'t': [-0.0281, -0.0594, -0.1165], 'r': [0.3943, -0.2036, -0.3103, 0.8407]},\n {'t': [0.0026, -0.0299, -0.1518], 'r': [0.3476, -0.1049, -0.5285, 0.7674]},\n {'t': [0.0169, -0.0181, -0.1728], 'r': [0.3521, 0.0515, -0.635, 0.6857]},\n {'t': [0.0268, -0.0018, -0.1966], 'r': [0.3521, 0.0515, -0.635, 0.6857]},\n {'t': [-0.0369, -0.0541, -0.1121], 'r': [0.5882, -0.1036, 0.0205, 0.8018]},\n {'t': [-0.024, 0.0143, -0.1465], 'r': [0.3269, -0.0887, -0.0003, 0.9409]},\n {'t': [-0.0172, 0.0394, -0.1765], 'r': [-0.0114, -0.0813, -0.0286, 0.9962]},\n {'t': [-0.0138, 0.0388, -0.1986], 'r': [-0.1994, -0.0379, -0.0372, 0.9785]},\n {'t': [-0.0125, 0.0287, -0.2199], 'r': [-0.1994, -0.0379, -0.0372, 0.9785]},\n {'t': [-0.0499, -0.0528, -0.1125], 'r': [0.5569, -0.0203, 0.0319, 0.8297]},\n {'t': [-0.0496, 0.0131, -0.1445], 'r': [0.3908, -0.0273, 0.1089, 0.9136]},\n {'t': [-0.0513, 0.0438, -0.1738], 'r': [0.0747, -0.0923, 0.0634, 0.9909]},\n {'t': [-0.0462, 0.0488, -0.2036], 'r': [-0.1936, -0.1156, 0.0299, 0.9738]},\n {'t': [-0.0404, 0.0387, -0.2253], 'r': [-0.1936, -0.1156, 0.0299, 0.9738]},\n {'t': [-0.0612, -0.0561, -0.1138], 'r': [0.5095, 0.0572, 0.0274, 0.8581]},\n {'t': [-0.0698, 0.0022, -0.1468], 'r': [0.4396, -0.0068, 0.1748, 0.881]},\n {'t': [-0.0751, 0.0329, -0.1719], 'r': [0.071, -0.0911, 0.1344, 0.9842]},\n {'t': [-0.0703, 0.0383, -0.2029], 'r': [-0.1764, -0.1244, 0.0831, 0.9729]},\n {'t': [-0.0641, 0.0302, -0.2227], 'r': [-0.1764, -0.1244, 0.0831, 0.9729]},\n {'t': [-0.0708, -0.0616, -0.1145], 'r': [0.4571, 0.1437, 0.0457, 0.8765]},\n {'t': [-0.0889, -0.0132, -0.148], 'r': [0.3971, 0.0569, 0.2436, 0.883]},\n {'t': [-0.098, 0.0096, -0.1727], 'r': [0.1604, -0.0085, 0.243, 0.9566]},\n {'t': [-0.0997, 0.0171, -0.194], 'r': [-0.0034, -0.0735, 0.1859, 0.9798]},\n {'t': [-0.0979, 0.0165, -0.2131], 'r': [-0.0034, -0.0735, 0.1859, 0.9798]}\n] as const;\n\nexport const RIGHT_HAND_RELAXED = [\n {'t': [0.05, -0.08, -0.1], 'r': [0.5373, 0, 0, 0.8434]},\n {'t': [0.0279, -0.0592, -0.1167], 'r': [0.3237, 0.1161, 0.293, 0.8921]},\n {'t': [0.0026, -0.0313, -0.158], 'r': [0.2171, 0.0194, 0.5207, 0.8254]},\n {'t': [-0.0042, -0.0219, -0.1837], 'r': [0.2597, -0.0685, 0.6498, 0.711]},\n {'t': [-0.01, -0.0084, -0.2107], 'r': [0.2597, -0.0685, 0.6498, 0.711]},\n {'t': [0.037, -0.0539, -0.1123], 'r': [0.5808, 0.1164, -0.0414, 0.8046]},\n {'t': [0.0238, 0.0151, -0.147], 'r': [0.3081, 0.0484, -0.0273, 0.9497]},\n {'t': [0.0206, 0.0393, -0.1786], 'r': [-0.0461, 0.0526, -0.0104, 0.9975]},\n {'t': [0.0185, 0.0373, -0.201], 'r': [-0.1674, 0.0162, -0.0064, 0.9857]},\n {'t': [0.0177, 0.0287, -0.223], 'r': [-0.1674, 0.0162, -0.0064, 0.9857]},\n {'t': [0.05, -0.0527, -0.1126], 'r': [0.5619, 0.0306, -0.0478, 0.8252]},\n {'t': [0.0497, 0.0138, -0.1449], 'r': [0.353, 0.0474, -0.1014, 0.9289]},\n {'t': [0.0491, 0.0425, -0.1767], 'r': [0.0777, 0.1076, -0.0559, 0.9896]},\n {'t': [0.0431, 0.0478, -0.2066], 'r': [-0.0679, 0.1248, -0.0343, 0.9893]},\n {'t': [0.0369, 0.0436, -0.2302], 'r': [-0.0679, 0.1248, -0.0343, 0.9893]},\n {'t': [0.0614, -0.0561, -0.1136], 'r': [0.5303, -0.05, -0.0384, 0.8455]},\n {'t': [0.0699, 0.0028, -0.1472], 'r': [0.4168, 0.0427, -0.1662, 0.8926]},\n {'t': [0.0722, 0.0331, -0.1739], 'r': [0.1339, 0.1107, -0.1236, 0.977]},\n {'t': [0.0665, 0.0425, -0.2041], 'r': [-0.0175, 0.1318, -0.0809, 0.9878]},\n {'t': [0.0606, 0.0413, -0.2257], 'r': [-0.0175, 0.1318, -0.0809, 0.9878]},\n {'t': [0.0711, -0.0618, -0.1145], 'r': [0.4891, -0.1378, -0.0535, 0.8596]},\n {'t': [0.0892, -0.0127, -0.1484], 'r': [0.3439, 0.0196, -0.23, 0.9102]},\n {'t': [0.0924, 0.0087, -0.1761], 'r': [0.1965, 0.0585, -0.2173, 0.9543]},\n {'t': [0.0921, 0.0184, -0.1968], 'r': [0.0936, 0.1069, -0.1575, 0.9773]},\n {'t': [0.0896, 0.0217, -0.2157], 'r': [0.0936, 0.1069, -0.1575, 0.9773]}\n] as const;\n","export const LEFT_HAND_PINCHING = [\n {'t': [-0.05, -0.08, -0.1], 'r': [0.5373, 0, 0, 0.8434], 's': [1, 1, 1]},\n {\n 't': [-0.0281, -0.0594, -0.1165],\n 'r': [0.3072, -0.0483, -0.257, 0.915],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0083, -0.0299, -0.1581],\n 'r': [0.1832, 0.0632, -0.4718, 0.8602],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0069, -0.0195, -0.1841],\n 'r': [0.2232, 0.1362, -0.6112, 0.747],\n 's': [1, 1, 0.9999]\n },\n {\n 't': [-0.0063, -0.0051, -0.2109],\n 'r': [0.2232, 0.1362, -0.6112, 0.747],\n 's': [1, 1, 0.9999]\n },\n {\n 't': [-0.0369, -0.0541, -0.112],\n 'r': [0.5858, -0.1038, 0.0205, 0.8035],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.024, 0.0142, -0.1465],\n 'r': [0.1342, -0.1392, -0.0707, 0.9786],\n 's': [1.0001, 1, 0.9999]\n },\n {\n 't': [-0.0122, 0.0248, -0.1828],\n 'r': [-0.2614, -0.0983, -0.1184, 0.9529],\n 's': [1.0001, 0.9999, 0.9999]\n },\n {\n 't': [-0.0095, 0.0131, -0.2017],\n 'r': [-0.3454, -0.0506, -0.1338, 0.9275],\n 's': [1, 0.9999, 1]\n },\n {\n 't': [-0.0098, -0.0028, -0.219],\n 'r': [-0.3454, -0.0506, -0.1338, 0.9275],\n 's': [1, 0.9999, 1]\n },\n {\n 't': [-0.0498, -0.0529, -0.1126],\n 'r': [0.5552, -0.0196, 0.0307, 0.8309],\n 's': [1.0001, 1, 1]\n },\n {\n 't': [-0.0496, 0.0131, -0.1444],\n 'r': [0.3957, -0.0669, 0.0916, 0.9113],\n 's': [1, 0.9999, 1]\n },\n {\n 't': [-0.0477, 0.0443, -0.173],\n 'r': [0.0284, -0.1256, 0.0276, 0.9913],\n 's': [1, 1, 0.9999]\n },\n {\n 't': [-0.0403, 0.0463, -0.2027],\n 'r': [-0.1956, -0.1387, -0.007, 0.9708],\n 's': [1.0001, 1, 1]\n },\n {\n 't': [-0.0339, 0.036, -0.224],\n 'r': [-0.1956, -0.1387, -0.007, 0.9708],\n 's': [1.0001, 1, 1]\n },\n {\n 't': [-0.0612, -0.0561, -0.1137],\n 'r': [0.5088, 0.0591, 0.0245, 0.8585],\n 's': [1, 1.0001, 1]\n },\n {\n 't': [-0.0697, 0.0021, -0.1467],\n 'r': [0.464, -0.0595, 0.1601, 0.8692],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0713, 0.0348, -0.1698],\n 'r': [0.0595, -0.1373, 0.0948, 0.9842],\n 's': [1.0001, 1.0001, 1]\n },\n {\n 't': [-0.0633, 0.0395, -0.2003],\n 'r': [-0.1735, -0.159, 0.0354, 0.9713],\n 's': [1, 1, 0.9999]\n },\n {\n 't': [-0.0561, 0.0313, -0.2197],\n 'r': [-0.1735, -0.159, 0.0354, 0.9713],\n 's': [1, 1, 0.9999]\n },\n {\n 't': [-0.0707, -0.0617, -0.1146],\n 'r': [0.4573, 0.1467, 0.0408, 0.8762],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0889, -0.0132, -0.148],\n 'r': [0.4065, 0.0051, 0.2314, 0.8838],\n 's': [1, 0.9999, 1.0001]\n },\n {\n 't': [-0.0946, 0.0109, -0.1723],\n 'r': [0.1595, -0.0578, 0.2175, 0.9612],\n 's': [1, 0.9999, 1]\n },\n {\n 't': [-0.094, 0.019, -0.1934],\n 'r': [-0.0122, -0.1189, 0.1509, 0.9813],\n 's': [1.0001, 1, 1]\n },\n {\n 't': [-0.0904, 0.0182, -0.2123],\n 'r': [-0.0122, -0.1189, 0.1509, 0.9813],\n 's': [1.0001, 1, 1]\n }\n] as const;\n\nexport const RIGHT_HAND_PINCHING = [\n {'t': [0.05, -0.08, -0.1], 'r': [0.5373, 0, 0, 0.8434], 's': [1, 1, 1]},\n {\n 't': [0.0279, -0.0593, -0.1166],\n 'r': [0.307, 0.046, 0.2483, 0.9176],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0082, -0.0291, -0.1587],\n 'r': [0.1833, -0.0669, 0.4657, 0.8632],\n 's': [0.9999, 1, 1]\n },\n {\n 't': [0.0071, -0.0186, -0.185],\n 'r': [0.2256, -0.1369, 0.6093, 0.7477],\n 's': [1, 1, 0.9999]\n },\n {\n 't': [0.0064, -0.0039, -0.212],\n 'r': [0.2256, -0.1369, 0.6093, 0.7477],\n 's': [1, 1, 0.9999]\n },\n {\n 't': [0.037, -0.0539, -0.1122],\n 'r': [0.5831, 0.1146, -0.0388, 0.8034],\n 's': [1, 0.9999, 1]\n },\n {\n 't': [0.0237, 0.0153, -0.147],\n 'r': [0.1209, 0.0891, 0.0196, 0.9885],\n 's': [1, 0.9999, 1]\n },\n {\n 't': [0.0163, 0.0257, -0.1849],\n 'r': [-0.2747, 0.0723, 0.0511, 0.9574],\n 's': [1, 0.9999, 0.9999]\n },\n {\n 't': [0.014, 0.0138, -0.204],\n 'r': [-0.3165, 0.0337, 0.0633, 0.9459],\n 's': [1, 0.9999, 1]\n },\n {\n 't': [0.0136, -0.0012, -0.2226],\n 'r': [-0.3165, 0.0337, 0.0633, 0.9459],\n 's': [1, 0.9999, 1]\n },\n {\n 't': [0.0501, -0.0527, -0.1126],\n 'r': [0.5625, 0.0291, -0.0455, 0.825],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0497, 0.0141, -0.1449],\n 'r': [0.3465, 0.0658, -0.0921, 0.9312],\n 's': [1.0001, 0.9999, 0.9999]\n },\n {\n 't': [0.0473, 0.0424, -0.177],\n 'r': [0.0559, 0.1235, -0.0403, 0.9899],\n 's': [1.0001, 1, 0.9999]\n },\n {\n 't': [0.0402, 0.0463, -0.2069],\n 'r': [-0.0703, 0.1381, -0.0195, 0.9877],\n 's': [1.0001, 1, 0.9999]\n },\n {\n 't': [0.0335, 0.0419, -0.2304],\n 'r': [-0.0703, 0.1381, -0.0195, 0.9877],\n 's': [1.0001, 1, 0.9999]\n },\n {\n 't': [0.0615, -0.0561, -0.1136],\n 'r': [0.5287, -0.0513, -0.0363, 0.8465],\n 's': [1.0001, 1, 0.9999]\n },\n {\n 't': [0.07, 0.003, -0.1472],\n 'r': [0.4197, 0.0598, -0.1607, 0.8913],\n 's': [1, 1, 0.9999]\n },\n {\n 't': [0.0709, 0.0336, -0.1737],\n 'r': [0.1329, 0.1258, -0.1128, 0.9766],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0643, 0.0431, -0.2038],\n 'r': [-0.0172, 0.145, -0.068, 0.9869],\n 's': [1.0001, 0.9999, 1]\n },\n {\n 't': [0.0577, 0.0418, -0.2253],\n 'r': [-0.0172, 0.145, -0.068, 0.9869],\n 's': [1.0001, 0.9999, 1]\n },\n {\n 't': [0.0711, -0.0617, -0.1145],\n 'r': [0.4861, -0.139, -0.0517, 0.8612],\n 's': [1.0001, 0.9999, 1]\n },\n {\n 't': [0.0893, -0.0125, -0.1485],\n 'r': [0.317, 0.0459, -0.2224, 0.9208],\n 's': [1.0001, 0.9999, 1]\n },\n {\n 't': [0.0902, 0.0078, -0.1772],\n 'r': [0.1921, 0.0784, -0.2077, 0.9559],\n 's': [1, 1, 0.9999]\n },\n {\n 't': [0.0889, 0.0174, -0.1979],\n 'r': [0.0936, 0.1253, -0.1462, 0.9768],\n 's': [1.0001, 1, 1]\n },\n {\n 't': [0.0857, 0.0208, -0.2167],\n 'r': [0.0936, 0.1253, -0.1462, 0.9768],\n 's': [1.0001, 1, 1]\n }\n] as const;\n","export const LEFT_HAND_FIST = [\n {'t': [-0.0933, -0.0266, -0.1338], 'r': [0.1346, -0.1437, 0.0038, 0.9804]},\n {'t': [-0.0648, -0.0265, -0.1529], 'r': [0.0354, -0.3351, -0.1786, 0.9244]},\n {'t': [-0.0318, -0.0293, -0.1932], 'r': [0.0407, -0.2202, -0.5685, 0.7916]},\n {'t': [-0.0212, -0.0345, -0.2179], 'r': [0.0132, -0.12, -0.576, 0.8084]},\n {'t': [-0.0161, -0.039, -0.2469], 'r': [0.0132, -0.12, -0.576, 0.8084]},\n {'t': [-0.0731, -0.0197, -0.1569], 'r': [0.0999, -0.2377, 0.0822, 0.9627]},\n {'t': [-0.0399, -0.0023, -0.2221], 'r': [-0.4356, -0.1075, -0.0127, 0.8936]},\n {'t': [-0.0325, -0.0319, -0.246], 'r': [0.9331, 0.066, 0.0832, -0.3436]},\n {'t': [-0.035, -0.0462, -0.2296], 'r': [0.9874, 0.021, 0.128, -0.0903]},\n {'t': [-0.0408, -0.0496, -0.2076], 'r': [0.9874, 0.021, 0.128, -0.0903]},\n {'t': [-0.0853, -0.0187, -0.1614], 'r': [0.115, -0.1594, 0.0889, 0.9765]},\n {'t': [-0.0646, -0.0007, -0.2271], 'r': [-0.4919, -0.1197, 0.0382, 0.8616]},\n {'t': [-0.0544, -0.0353, -0.2477], 'r': [0.9309, 0.1571, 0.0605, -0.324]},\n {'t': [-0.0548, -0.0542, -0.2244], 'r': [0.9835, 0.1315, 0.1097, 0.0583]},\n {'t': [-0.0607, -0.051, -0.2013], 'r': [0.9835, 0.1315, 0.1097, 0.0583]},\n {'t': [-0.0972, -0.0213, -0.1628], 'r': [0.0881, -0.0966, 0.0847, 0.9878]},\n {'t': [-0.0856, -0.0088, -0.2263], 'r': [-0.4818, -0.1075, 0.1033, 0.8635]},\n {'t': [-0.0742, -0.0406, -0.246], 'r': [0.9378, 0.1774, 0.0089, -0.2983]},\n {'t': [-0.0715, -0.0585, -0.2205], 'r': [0.9769, 0.1847, 0.0804, 0.0714]},\n {'t': [-0.0757, -0.0552, -0.1994], 'r': [0.9769, 0.1847, 0.0804, 0.0714]},\n {'t': [-0.1078, -0.0253, -0.162], 'r': [0.0535, -0.0126, 0.0933, 0.9941]},\n {'t': [-0.1069, -0.0188, -0.2215], 'r': [-0.4433, -0.1294, 0.1523, 0.8738]},\n {'t': [-0.0939, -0.0444, -0.2398], 'r': [0.9002, 0.2018, -0.0275, -0.385]},\n {'t': [-0.0891, -0.0599, -0.2248], 'r': [0.9644, 0.2553, 0.0425, -0.0538]},\n {'t': [-0.0914, -0.0623, -0.2063], 'r': [0.9644, 0.2553, 0.0425, -0.0538]}\n] as const;\n\nexport const RIGHT_HAND_FIST = [\n {'t': [0.0504, -0.0155, -0.1083], 'r': [0.1392, 0.117, -0.058, 0.9816]},\n {'t': [0.022, -0.0122, -0.1291], 'r': [-0.0068, 0.3422, 0.1705, 0.924]},\n {'t': [-0.011, -0.019, -0.1691], 'r': [-0.0952, 0.2257, 0.5977, 0.7634]},\n {'t': [-0.0171, -0.0305, -0.1932], 'r': [-0.249, 0.0162, 0.627, 0.738]},\n {'t': [-0.0073, -0.0427, -0.2185], 'r': [-0.249, 0.0162, 0.627, 0.738]},\n {'t': [0.0314, -0.0068, -0.133], 'r': [0.1126, 0.213, -0.1468, 0.9594]},\n {'t': [0.0035, 0.014, -0.1987], 'r': [-0.5177, 0.1865, 0.0124, 0.8349]},\n {'t': [-0.0086, -0.0192, -0.2148], 'r': [0.9671, -0.1129, -0.1466, -0.1747]},\n {'t': [-0.0031, -0.0274, -0.1952], 'r': [0.9714, -0.0492, -0.2057, 0.1081]},\n {'t': [0.0063, -0.0222, -0.1749], 'r': [0.9714, -0.0492, -0.2057, 0.1081]},\n {'t': [0.0441, -0.0073, -0.137], 'r': [0.1251, 0.1341, -0.1467, 0.972]},\n {'t': [0.0283, 0.0126, -0.2028], 'r': [-0.5227, 0.1469, -0.0852, 0.8354]},\n {'t': [0.0144, -0.0224, -0.2202], 'r': [0.9399, -0.2078, -0.0451, -0.2671]},\n {'t': [0.0137, -0.0382, -0.1948], 'r': [0.9665, -0.181, -0.1188, 0.1381]},\n {'t': [0.0207, -0.0318, -0.1726], 'r': [0.9665, -0.181, -0.1188, 0.1381]},\n {'t': [0.0559, -0.0112, -0.1379], 'r': [0.0948, 0.0732, -0.1351, 0.9836]},\n {'t': [0.0482, 0.0022, -0.2011], 'r': [-0.5015, 0.1223, -0.1588, 0.8416]},\n {'t': [0.0337, -0.0294, -0.2191], 'r': [0.9432, -0.2267, 0.0156, -0.2423]},\n {'t': [0.0294, -0.0438, -0.1916], 'r': [0.9569, -0.2379, -0.08, 0.1464]},\n {'t': [0.0346, -0.0376, -0.1714], 'r': [0.9569, -0.2379, -0.08, 0.1464]},\n {'t': [0.0662, -0.0164, -0.1368], 'r': [0.0546, -0.0084, -0.1349, 0.9893]},\n {'t': [0.068, -0.0102, -0.1955], 'r': [-0.4587, 0.1335, -0.2099, 0.853]},\n {'t': [0.0529, -0.0353, -0.2127], 'r': [0.9107, -0.2444, 0.0606, -0.3274]},\n {'t': [0.0466, -0.0483, -0.1959], 'r': [0.9518, -0.3056, -0.0236, 0.0063]},\n {'t': [0.0488, -0.0485, -0.1773], 'r': [0.9518, -0.3056, -0.0236, 0.0063]}\n] as const;\n","export const LEFT_HAND_THUMBS_UP = [\n {'t': [-0.011, -0.0299, -0.0701], 'r': [0.1224, -0.1562, 0.6052, 0.771]},\n {'t': [0.0025, -0.0017, -0.0854], 'r': [0.3796, -0.3776, 0.3843, 0.7521]},\n {'t': [0.0162, 0.041, -0.1065], 'r': [0.6152, -0.1749, 0.0935, 0.763]},\n {'t': [0.0204, 0.0676, -0.1116], 'r': [0.5992, -0.1247, 0.1335, 0.7795]},\n {'t': [0.0225, 0.096, -0.1202], 'r': [0.5992, -0.1247, 0.1335, 0.7795]},\n {'t': [-0.0042, -0.008, -0.0928], 'r': [0.1427, -0.2467, 0.6763, 0.6793]},\n {'t': [0.0063, 0.0312, -0.155], 'r': [-0.4551, -0.5645, 0.3425, 0.5974]},\n {'t': [0.0447, 0.0257, -0.1538], 'r': [0.7509, 0.6277, 0.1981, -0.053]},\n {'t': [0.0396, 0.0184, -0.1338], 'r': [0.7246, 0.5124, 0.4244, 0.1797]},\n {'t': [0.0207, 0.0148, -0.1212], 'r': [0.7246, 0.5124, 0.4244, 0.1797]},\n {'t': [-0.0078, -0.0192, -0.0982], 'r': [0.109, -0.1737, 0.6698, 0.7137]},\n {'t': [-0.0006, 0.0083, -0.163], 'r': [-0.4929, -0.5301, 0.4215, 0.5462]},\n {'t': [0.0407, 0.0046, -0.1614], 'r': [0.705, 0.703, 0.0897, -0.0263]},\n {'t': [0.0382, -0.0005, -0.132], 'r': [0.6279, 0.5816, 0.4074, 0.3186]},\n {'t': [0.0165, -0.0021, -0.1217], 'r': [0.6279, 0.5816, 0.4074, 0.3186]},\n {'t': [-0.0092, -0.031, -0.0993], 'r': [0.0472, -0.1416, 0.6514, 0.7439]},\n {'t': [0.0006, -0.0142, -0.1626], 'r': [-0.5202, -0.4929, 0.4819, 0.5042]},\n {'t': [0.0398, -0.0159, -0.1611], 'r': [0.6996, 0.7076, 0.0706, 0.0696]},\n {'t': [0.0338, -0.0161, -0.1304], 'r': [0.5876, 0.6289, 0.3607, 0.3593]},\n {'t': [0.0143, -0.0168, -0.1208], 'r': [0.5876, 0.6289, 0.3607, 0.3593]},\n {'t': [-0.0081, -0.0426, -0.0982], 'r': [-0.0269, -0.0934, 0.6476, 0.7558]},\n {'t': [0.0026, -0.0377, -0.1578], 'r': [0.5435, 0.4612, -0.5243, -0.4658]},\n {'t': [0.0366, -0.0376, -0.1559], 'r': [0.6991, 0.7017, 0.0384, 0.1318]},\n {'t': [0.032, -0.0347, -0.1344], 'r': [0.575, 0.6796, 0.2522, 0.3795]},\n {'t': [0.0166, -0.0342, -0.1237], 'r': [0.575, 0.6796, 0.2522, 0.3795]}\n] as const;\n\nexport const RIGHT_HAND_THUMBS_UP = [\n {'t': [0.0317, -0.0212, -0.089], 'r': [0.2199, 0.1003, -0.594, 0.7673]},\n {'t': [0.0223, 0.009, -0.1042], 'r': [0.4294, 0.285, -0.3619, 0.7768]},\n {'t': [0.0158, 0.0521, -0.1273], 'r': [0.6012, 0.067, -0.0513, 0.7947]},\n {'t': [0.0145, 0.0784, -0.1348], 'r': [0.597, 0.0134, -0.0918, 0.7968]},\n {'t': [0.0163, 0.1065, -0.1446], 'r': [0.597, 0.0134, -0.0918, 0.7968]},\n {'t': [0.0303, 0.0032, -0.1103], 'r': [0.2434, 0.2002, -0.656, 0.6858]},\n {'t': [0.0337, 0.0475, -0.1698], 'r': [-0.3298, 0.4729, -0.4297, 0.6949]},\n {'t': [-0.0026, 0.0462, -0.1835], 'r': [0.7134, -0.6368, -0.0002, -0.2925]},\n {'t': [-0.0107, 0.0369, -0.1654], 'r': [0.7745, -0.5891, -0.2133, -0.0877]},\n {'t': [-0.0047, 0.0282, -0.145], 'r': [0.7745, -0.5891, -0.2133, -0.0877]},\n {'t': [0.0347, -0.0077, -0.1158], 'r': [0.2088, 0.1254, -0.6589, 0.7117]},\n {'t': [0.0416, 0.0251, -0.1782], 'r': [-0.3597, 0.4829, -0.4746, 0.6421]},\n {'t': [0.0018, 0.0251, -0.19], 'r': [-0.673, 0.7069, -0.0014, 0.2177]},\n {'t': [-0.0077, 0.0162, -0.163], 'r': [0.6957, -0.6456, -0.2988, 0.0994]},\n {'t': [0.0063, 0.0104, -0.1443], 'r': [0.6957, -0.6456, -0.2988, 0.0994]},\n {'t': [0.0361, -0.0196, -0.1178], 'r': [0.1467, 0.0923, -0.6537, 0.7367]},\n {'t': [0.0398, 0.0027, -0.1801], 'r': [-0.3611, 0.446, -0.5466, 0.6099]},\n {'t': [0.0028, 0.0047, -0.193], 'r': [-0.6782, 0.7246, -0.0014, 0.1226]},\n {'t': [-0.003, -0.0006, -0.1628], 'r': [-0.652, 0.6801, 0.2937, -0.1613]},\n {'t': [0.0108, -0.0046, -0.1465], 'r': [-0.652, 0.6801, 0.2937, -0.1613]},\n {'t': [0.0343, -0.0315, -0.1182], 'r': [0.0757, 0.0463, -0.6692, 0.7378]},\n {'t': [0.0363, -0.021, -0.1779], 'r': [-0.3141, 0.3981, -0.6168, 0.602]},\n {'t': [0.0062, -0.0166, -0.1931], 'r': [-0.6691, 0.7354, -0.0331, 0.1021]},\n {'t': [0.0012, -0.0185, -0.1716], 'r': [-0.6175, 0.7316, 0.235, -0.168]},\n {'t': [0.0116, -0.0223, -0.1564], 'r': [-0.6175, 0.7316, 0.235, -0.168]}\n] as const;\n","export const LEFT_HAND_POINTING = [\n {'t': [-0.0283, -0.0376, -0.0293], 'r': [0.1372, -0.208, 0.241, 0.938]},\n {'t': [0.0016, -0.0246, -0.0431], 'r': [0.0106, -0.3992, -0.0014, 0.9168]},\n {'t': [0.0392, -0.0237, -0.0781], 'r': [-0.1, -0.2869, -0.466, 0.831]},\n {'t': [0.0496, -0.0357, -0.1004], 'r': [-0.1511, -0.183, -0.4918, 0.8377]},\n {'t': [0.0533, -0.0497, -0.1265], 'r': [-0.1511, -0.183, -0.4918, 0.8377]},\n {'t': [-0.0078, -0.0226, -0.0496], 'r': [0.1168, -0.3031, 0.3253, 0.8881]},\n {'t': [0.0265, 0.0074, -0.1082], 'r': [0.0563, -0.1303, 0.2725, 0.9516]},\n {'t': [0.0346, 0.0153, -0.1453], 'r': [-0.0635, -0.1606, 0.2541, 0.9516]},\n {'t': [0.0419, 0.0144, -0.1659], 'r': [-0.1073, -0.1342, 0.2464, 0.9538]},\n {'t': [0.0494, 0.0105, -0.1873], 'r': [-0.1073, -0.1342, 0.2464, 0.9538]},\n {'t': [-0.0184, -0.0273, -0.0562], 'r': [0.1156, -0.2249, 0.3238, 0.9117]},\n {'t': [0.0052, -0.0021, -0.1177], 'r': [-0.4452, -0.2871, 0.2041, 0.8233]},\n {'t': [0.0324, -0.0274, -0.1363], 'r': [0.8476, 0.3909, 0.031, -0.3574]},\n {'t': [0.0392, -0.0465, -0.1142], 'r': [0.9167, 0.3645, 0.16, -0.0352]},\n {'t': [0.032, -0.0501, -0.0915], 'r': [0.9167, 0.3645, 0.16, -0.0352]},\n {'t': [-0.028, -0.0348, -0.0593], 'r': [0.0757, -0.1724, 0.308, 0.9326]},\n {'t': [-0.01, -0.0186, -0.1201], 'r': [-0.5151, -0.3075, 0.2332, 0.7654]},\n {'t': [0.018, -0.0439, -0.1306], 'r': [0.8841, 0.4115, 0.0419, -0.2175]},\n {'t': [0.0214, -0.0572, -0.1026], 'r': [0.8915, 0.3885, 0.1955, 0.1266]},\n {'t': [0.0111, -0.0549, -0.0835], 'r': [0.8915, 0.3885, 0.1955, 0.1266]},\n {'t': [-0.0357, -0.0434, -0.0601], 'r': [0.0242, -0.0998, 0.3079, 0.9459]},\n {'t': [-0.0254, -0.037, -0.1183], 'r': [-0.4608, -0.35, 0.2807, 0.7658]},\n {'t': [0.0022, -0.0544, -0.1281], 'r': [0.8346, 0.4535, 0.0038, -0.3127]},\n {'t': [0.0089, -0.0663, -0.1107], 'r': [0.8657, 0.4769, 0.1519, -0.0059]},\n {'t': [0.003, -0.0699, -0.0932], 'r': [0.8657, 0.4769, 0.1519, -0.0059]}\n] as const;\n\nexport const RIGHT_HAND_POINTING = [\n {'t': [-0.0042, -0.0248, -0.0222], 'r': [0.1163, -0.0095, -0.3006, 0.9466]},\n {'t': [-0.024, -0.0114, -0.048], 'r': [-0.052, 0.2376, -0.0719, 0.9673]},\n {'t': [-0.0482, -0.0149, -0.0937], 'r': [-0.2324, 0.2162, 0.3797, 0.869]},\n {'t': [-0.0535, -0.0306, -0.1155], 'r': [-0.2846, 0.1212, 0.4068, 0.8595]},\n {'t': [-0.0521, -0.0492, -0.1388], 'r': [-0.2846, 0.1212, 0.4068, 0.8595]},\n {'t': [-0.0129, -0.0119, -0.0508], 'r': [0.1258, 0.0866, -0.3895, 0.9083]},\n {'t': [-0.0173, 0.01, -0.1215], 'r': [0.1174, -0.0564, -0.3421, 0.9306]},\n {'t': [-0.0097, 0.018, -0.1587], 'r': [-0.0512, 0.0028, -0.347, 0.9365]},\n {'t': [-0.0105, 0.0158, -0.1805], 'r': [-0.1583, 0.003, -0.3458, 0.9249]},\n {'t': [-0.0137, 0.0085, -0.2021], 'r': [-0.1583, 0.003, -0.3458, 0.9249]},\n {'t': [-0.0017, -0.019, -0.052], 'r': [0.1155, 0.0062, -0.386, 0.9152]},\n {'t': [0.0038, -0.0037, -0.1206], 'r': [-0.2494, 0.0619, -0.3947, 0.8822]},\n {'t': [-0.0086, -0.0197, -0.1569], 'r': [-0.7146, 0.3231, -0.2612, 0.5628]},\n {'t': [-0.0306, -0.0389, -0.1502], 'r': [0.8643, -0.4054, 0.1306, -0.2676]},\n {'t': [-0.0406, -0.0469, -0.1297], 'r': [0.8643, -0.4054, 0.1306, -0.2676]},\n {'t': [0.0068, -0.0279, -0.0499], 'r': [0.0671, -0.0438, -0.3807, 0.9212]},\n {'t': [0.0155, -0.022, -0.1146], 'r': [-0.3096, 0.1005, -0.4385, 0.8377]},\n {'t': [-0.0022, -0.0389, -0.1452], 'r': [0.7388, -0.369, 0.2794, -0.4899]},\n {'t': [-0.0264, -0.0553, -0.1341], 'r': [0.852, -0.4611, 0.1257, -0.214]},\n {'t': [-0.0346, -0.0602, -0.1146], 'r': [0.852, -0.4611, 0.1257, -0.214]},\n {'t': [0.0126, -0.0374, -0.0464], 'r': [0.0105, -0.1129, -0.3882, 0.9146]},\n {'t': [0.0254, -0.0415, -0.1045], 'r': [-0.3088, 0.1125, -0.4825, 0.8119]},\n {'t': [0.0078, -0.0548, -0.1304], 'r': [-0.6368, 0.3211, -0.3767, 0.5912]},\n {'t': [-0.0112, -0.0661, -0.1307], 'r': [0.7535, -0.4639, 0.2523, -0.3916]},\n {'t': [-0.0244, -0.0737, -0.1196], 'r': [0.7535, -0.4639, 0.2523, -0.3916]}\n] as const;\n","export const LEFT_HAND_ROCK = [\n {\n 't': [-0.0123, -0.0183, -0.0267],\n 'r': [0.5149, -0.0845, -0.1158, 0.8452],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0153, -0.0052, -0.0437],\n 'r': [0.2665, -0.0899, -0.3721, 0.8846],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0335, 0.0154, -0.0867],\n 'r': [0.0177, 0.1842, -0.6731, 0.716],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0267, 0.0228, -0.1122],\n 'r': [0.0728, 0.2226, -0.6735, 0.7011],\n 's': [1, 1, 1]\n },\n {\n 't': [0.019, 0.0341, -0.1386],\n 'r': [0.0728, 0.2226, -0.6735, 0.7011],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0067, 0.0029, -0.0406],\n 'r': [0.475, -0.2118, -0.0726, 0.851],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0388, 0.061, -0.0749],\n 'r': [0.5779, -0.1002, -0.0602, 0.8077],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0481, 0.097, -0.086],\n 'r': [0.5059, -0.0922, -0.0672, 0.855],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0529, 0.1158, -0.0964],\n 'r': [0.4458, -0.0565, -0.053, 0.8918],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0562, 0.1334, -0.1107],\n 'r': [0.4458, -0.0565, -0.053, 0.8918],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0052, 0.0075, -0.0412],\n 'r': [0.5055, -0.126, -0.0623, 0.8513],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0144, 0.0671, -0.0735],\n 'r': [0.1227, -0.0631, -0.0269, 0.9901],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0199, 0.0775, -0.1133],\n 'r': [-0.4479, -0.0687, -0.0876, 0.8871],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0211, 0.0534, -0.1312],\n 'r': [-0.6828, -0.0523, -0.1046, 0.7212],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0192, 0.0294, -0.1316],\n 'r': [-0.6828, -0.0523, -0.1046, 0.7212],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0167, 0.0074, -0.0424],\n 'r': [0.491, -0.0372, -0.0778, 0.8669],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0075, 0.0623, -0.0758],\n 'r': [0.1717, -0.0904, 0.0273, 0.9806],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0007, 0.0753, -0.1121],\n 'r': [-0.3257, -0.1136, -0.0418, 0.9377],\n 's': [1, 1, 1]\n },\n {\n 't': [0.005, 0.0561, -0.1361],\n 'r': [-0.5492, -0.1111, -0.0905, 0.8233],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0066, 0.0356, -0.1433],\n 'r': [-0.5492, -0.1111, -0.0905, 0.8233],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0273, 0.0051, -0.0431],\n 'r': [0.4566, 0.0629, -0.0766, 0.8841],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0297, 0.0531, -0.0769],\n 'r': [0.3942, -0.0035, 0.1163, 0.9116],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0317, 0.0768, -0.1013],\n 'r': [0.4582, 0.0006, 0.1099, 0.882],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0341, 0.0951, -0.1136],\n 'r': [0.4085, -0.0179, 0.0535, 0.911],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0354, 0.1086, -0.1266],\n 'r': [0.4085, -0.0179, 0.0535, 0.911],\n 's': [1, 1, 1]\n }\n] as const;\n\nexport const RIGHT_HAND_ROCK = [\n {\n 't': [0.0015, -0.0417, -0.0513],\n 'r': [0.5617, 0.0123, 0.1355, 0.8161],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0235, -0.025, -0.07],\n 'r': [0.2818, 0.0046, 0.4006, 0.8718],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0354, -0.0001, -0.1128],\n 'r': [-0.0257, -0.2764, 0.6652, 0.6931],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0238, 0.0089, -0.1359],\n 'r': [-0.0006, -0.3419, 0.6556, 0.6733],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0088, 0.0215, -0.1584],\n 'r': [-0.0006, -0.3419, 0.6556, 0.6733],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.015, -0.0179, -0.0645],\n 'r': [0.5302, 0.1299, 0.1154, 0.8299],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0403, 0.0456, -0.0947],\n 'r': [0.5874, 0.0115, 0.0813, 0.8051],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0451, 0.0825, -0.1058],\n 'r': [0.5048, 0.001, 0.0806, 0.8595],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0468, 0.1015, -0.1165],\n 'r': [0.4494, -0.0352, 0.0601, 0.8906],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0465, 0.1195, -0.1308],\n 'r': [0.4494, -0.0352, 0.0601, 0.8906],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0029, -0.0139, -0.063],\n 'r': [0.5567, 0.046, 0.0996, 0.8234],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.016, 0.0502, -0.0895],\n 'r': [0.1657, -0.0189, 0.0053, 0.986],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0146, 0.0642, -0.1285],\n 'r': [-0.4455, 0.0104, 0.0258, 0.8948],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0143, 0.0404, -0.1468],\n 'r': [-0.7027, 0.0133, 0.0292, 0.7107],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0137, 0.0163, -0.146],\n 'r': [-0.7027, 0.0133, 0.0292, 0.7107],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0087, -0.0144, -0.0627],\n 'r': [0.5389, -0.0411, 0.1061, 0.8346],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0058, 0.0446, -0.0897],\n 'r': [0.2331, 0.0139, -0.0389, 0.9716],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0052, 0.0621, -0.1248],\n 'r': [-0.3041, 0.0513, -0.0024, 0.9512],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0022, 0.0442, -0.1503],\n 'r': [-0.5472, 0.0609, 0.0335, 0.8341],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0009, 0.0239, -0.1579],\n 'r': [-0.5472, 0.0609, 0.0335, 0.8341],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0194, -0.0172, -0.0627],\n 'r': [0.5054, -0.1365, 0.0899, 0.8473],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0276, 0.0346, -0.0893],\n 'r': [0.4597, -0.0527, -0.1093, 0.8797],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0334, 0.0611, -0.1099],\n 'r': [0.5162, -0.056, -0.0989, 0.8489],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0378, 0.0805, -0.1194],\n 'r': [0.4448, -0.0407, -0.0462, 0.8935],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0411, 0.0949, -0.1311],\n 'r': [0.4448, -0.0407, -0.0462, 0.8935],\n 's': [1, 1, 1]\n }\n] as const;\n","export const LEFT_HAND_THUMBS_DOWN = [\n {\n 't': [-0.0169, 0.0317, -0.0845],\n 'r': [0.2721, -0.3488, -0.6314, 0.6369],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0019, 0.008, -0.1021],\n 'r': [-0.0533, 0.5043, 0.7891, -0.3467],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0208, -0.0318, -0.1276],\n 'r': [-0.2229, 0.6138, 0.7555, 0.0539],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0282, -0.0578, -0.1318],\n 'r': [-0.2724, 0.6476, 0.7112, 0.0242],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0389, -0.0856, -0.1338],\n 'r': [-0.2724, 0.6476, 0.7112, 0.0242],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0046, 0.0177, -0.0997],\n 'r': [0.1919, -0.3993, -0.6438, 0.6238],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0618, -0.0034, -0.1463],\n 'r': [-0.1884, 0.0883, -0.6795, 0.7035],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0481, -0.0093, -0.1821],\n 'r': [0.6204, -0.5352, 0.4297, -0.3794],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0275, -0.0094, -0.1746],\n 'r': [0.6806, -0.6532, 0.2814, -0.176],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0141, -0.0064, -0.1561],\n 'r': [0.6806, -0.6532, 0.2814, -0.176],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0062, 0.0299, -0.1019],\n 'r': [0.2399, -0.3631, -0.598, 0.6731],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0621, 0.0218, -0.1466],\n 'r': [-0.241, 0.1225, -0.6156, 0.7403],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0427, 0.0133, -0.1823],\n 'r': [0.7097, -0.4862, 0.373, -0.3475],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0165, 0.0095, -0.1681],\n 'r': [0.7968, -0.5892, 0.1321, -0.0209],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0119, 0.0128, -0.1447],\n 'r': [0.7968, -0.5892, 0.1321, -0.0209],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0033, 0.0406, -0.1037],\n 'r': [0.2574, -0.3085, -0.5681, 0.7183],\n 's': [1, 1, 1]\n },\n {\n 't': [0.052, 0.0419, -0.1485],\n 'r': [-0.2306, 0.1278, -0.5499, 0.7925],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0339, 0.0328, -0.182],\n 'r': [0.7575, -0.4754, 0.2861, -0.344],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0099, 0.025, -0.1634],\n 'r': [0.843, -0.5293, 0.0926, -0.0248],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0068, 0.0266, -0.142],\n 'r': [0.843, -0.5293, 0.0926, -0.0248],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0018, 0.0508, -0.104],\n 'r': [0.2798, -0.2351, -0.5355, 0.7614],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0378, 0.0613, -0.1483],\n 'r': [-0.1652, 0.0952, -0.5046, 0.842],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0259, 0.054, -0.1792],\n 'r': [0.7429, -0.4404, 0.2677, -0.4273],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0084, 0.0449, -0.169],\n 'r': [0.8704, -0.4542, 0.1121, -0.1532],\n 's': [1, 1, 1]\n },\n {\n 't': [0.002, 0.0431, -0.1514],\n 'r': [0.8704, -0.4542, 0.1121, -0.1532],\n 's': [1, 1, 1]\n }\n] as const;\n\nexport const RIGHT_HAND_THUMBS_DOWN = [\n {\n 't': [0.0237, 0.033, -0.083],\n 'r': [0.325, 0.2979, 0.5612, 0.7004],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0039, 0.0142, -0.1018],\n 'r': [0.0744, 0.4501, 0.7672, 0.4508],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0239, -0.0191, -0.133],\n 'r': [0.2089, 0.5732, 0.7915, 0.0363],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0341, -0.0435, -0.1401],\n 'r': [0.2664, 0.6251, 0.7316, 0.0555],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0476, -0.0698, -0.144],\n 'r': [0.2664, 0.6251, 0.7316, 0.0555],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0003, 0.0251, -0.0989],\n 'r': [0.2488, 0.3591, 0.5717, 0.6944],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0603, 0.0201, -0.1463],\n 'r': [-0.2217, -0.1036, 0.5936, 0.7667],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.045, 0.0116, -0.1809],\n 'r': [0.681, 0.4806, -0.3657, -0.4143],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0253, 0.0071, -0.1724],\n 'r': [0.7487, 0.5817, -0.2444, -0.2032],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0121, 0.0068, -0.1535],\n 'r': [0.7487, 0.5817, -0.2444, -0.2032],\n 's': [1, 1, 1]\n },\n {\n 't': [0.001, 0.0374, -0.1005],\n 'r': [0.2971, 0.3158, 0.527, 0.7309],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0548, 0.0447, -0.1454],\n 'r': [-0.2475, -0.1117, 0.5236, 0.8076],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0369, 0.0331, -0.181],\n 'r': [0.759, 0.413, -0.3155, -0.3922],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0126, 0.0231, -0.1665],\n 'r': [0.8595, 0.4988, -0.1065, -0.0339],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0084, 0.0248, -0.1428],\n 'r': [0.8595, 0.4988, -0.1065, -0.0339],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0064, 0.0472, -0.1018],\n 'r': [0.3122, 0.2567, 0.4998, 0.766],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0402, 0.0619, -0.1463],\n 'r': [-0.22, -0.1072, 0.4537, 0.8569],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.025, 0.0506, -0.1806],\n 'r': [0.8003, 0.3914, -0.2353, -0.3886],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0035, 0.0369, -0.1624],\n 'r': [0.8979, 0.4322, -0.0728, -0.0395],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0008, 0.0373, -0.1409],\n 'r': [0.8979, 0.4322, -0.0728, -0.0395],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0136, 0.0558, -0.1017],\n 'r': [0.3278, 0.1772, 0.4672, 0.8018],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0219, 0.0775, -0.1452],\n 'r': [-0.1811, -0.0932, 0.4016, 0.8929],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0108, 0.0677, -0.1758],\n 'r': [0.7842, 0.3582, -0.2073, -0.4623],\n 's': [1, 1, 1]\n },\n {\n 't': [0.004, 0.0547, -0.1656],\n 'r': [0.9158, 0.3542, -0.0821, -0.1706],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0096, 0.0511, -0.1481],\n 'r': [0.9158, 0.3542, -0.0821, -0.1706],\n 's': [1, 1, 1]\n }\n] as const;\n","export const LEFT_HAND_VICTORY = [\n {\n 't': [-0.0485, -0.0629, -0.0748],\n 'r': [0.5235, 0.0269, -0.0122, 0.8515],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0274, -0.0424, -0.0935],\n 'r': [0.2683, -0.0091, -0.2476, 0.9309],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0197, -0.0171, -0.1372],\n 'r': [-0.0874, 0.2587, -0.5403, 0.7959],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0337, -0.0134, -0.1604],\n 'r': [-0.1021, 0.3471, -0.5231, 0.7717],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0538, -0.0084, -0.1819],\n 'r': [-0.1021, 0.3471, -0.5231, 0.7717],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0376, -0.037, -0.0897],\n 'r': [0.5048, -0.107, 0.0348, 0.8559],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0266, 0.0281, -0.1246],\n 'r': [0.567, -0.0696, 0.0098, 0.8207],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0224, 0.0646, -0.1371],\n 'r': [0.5031, -0.0677, 0.0059, 0.8615],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0201, 0.0836, -0.1477],\n 'r': [0.4589, -0.0365, 0.0223, 0.8874],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.019, 0.1018, -0.1617],\n 'r': [0.4589, -0.0365, 0.0223, 0.8874],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0503, -0.0361, -0.0891],\n 'r': [0.5225, -0.0136, 0.0382, 0.8517],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0515, 0.0267, -0.1211],\n 'r': [0.5428, 0.1035, 0.1149, 0.8255],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0638, 0.0631, -0.1369],\n 'r': [0.5306, 0.067, 0.0906, 0.8401],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0702, 0.0896, -0.1495],\n 'r': [0.5467, 0.0608, 0.081, 0.8312],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0747, 0.1108, -0.1601],\n 'r': [0.5467, 0.0608, 0.081, 0.8312],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0613, -0.0396, -0.0891],\n 'r': [0.4925, 0.0763, 0.0204, 0.8667],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0712, 0.0158, -0.1219],\n 'r': [0.2546, -0.0246, 0.1592, 0.9535],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0722, 0.0349, -0.1561],\n 'r': [-0.2354, -0.1181, 0.1042, 0.959],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0638, 0.0217, -0.1832],\n 'r': [-0.4573, -0.1496, 0.0503, 0.8752],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0571, 0.0041, -0.1941],\n 'r': [-0.4573, -0.1496, 0.0503, 0.8752],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0706, -0.045, -0.0892],\n 'r': [0.4433, 0.1733, 0.0233, 0.8791],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0898, 0.0006, -0.1216],\n 'r': [0.0458, -0.1976, 0.107, 0.9733],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0762, 0.0038, -0.1526],\n 'r': [-0.348, -0.2273, 0.0117, 0.9095],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0668, -0.0095, -0.1675],\n 'r': [-0.5475, -0.2656, -0.0806, 0.7894],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0618, -0.0269, -0.1725],\n 'r': [-0.5475, -0.2656, -0.0806, 0.7894],\n 's': [1, 1, 1]\n }\n] as const;\n\nexport const RIGHT_HAND_VICTORY = [\n {\n 't': [-0.0017, -0.0652, -0.0663],\n 'r': [0.5651, 0.0392, -0.0573, 0.8221],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0247, -0.042, -0.0786],\n 'r': [0.3207, 0.0849, 0.243, 0.9115],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0407, -0.0141, -0.1186],\n 'r': [-0.0285, -0.1953, 0.5625, 0.8029],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.031, -0.0094, -0.1439],\n 'r': [-0.0751, -0.3079, 0.5331, 0.7845],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0133, -0.0043, -0.1673],\n 'r': [-0.0751, -0.3079, 0.5331, 0.7845],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0136, -0.0376, -0.076],\n 'r': [0.5464, 0.1682, -0.0848, 0.8161],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0272, 0.0313, -0.1019],\n 'r': [0.6129, 0.1411, -0.0752, 0.7738],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.032, 0.0692, -0.1089],\n 'r': [0.5643, 0.143, -0.0679, 0.8103],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0353, 0.0897, -0.1161],\n 'r': [0.5256, 0.1162, -0.0834, 0.8386],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.038, 0.11, -0.1265],\n 'r': [0.5256, 0.1162, -0.0834, 0.8386],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0009, -0.0372, -0.0776],\n 'r': [0.5593, 0.0765, -0.0968, 0.8197],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0021, 0.0287, -0.1033],\n 'r': [0.6072, -0.0412, -0.1868, 0.7712],\n 's': [1, 1, 1]\n },\n {\n 't': [0.01, 0.0671, -0.1136],\n 'r': [0.5687, 0.0002, -0.1587, 0.8071],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0156, 0.0946, -0.124],\n 'r': [0.5609, 0.0092, -0.1498, 0.8142],\n 's': [1, 1, 1]\n },\n {\n 't': [0.019, 0.1163, -0.1339],\n 'r': [0.5609, 0.0092, -0.1498, 0.8142],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0096, -0.0411, -0.08],\n 'r': [0.5291, -0.0092, -0.0837, 0.8443],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0165, 0.0173, -0.1087],\n 'r': [0.2191, 0.1389, -0.1874, 0.9474],\n 's': [1, 1, 1]\n },\n {\n 't': [0.009, 0.0353, -0.1427],\n 'r': [-0.3548, 0.2386, -0.0503, 0.9026],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0055, 0.0162, -0.1628],\n 'r': [-0.5898, 0.2546, 0.0402, 0.7653],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0126, -0.0042, -0.1657],\n 'r': [-0.5898, 0.2546, 0.0402, 0.7653],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0184, -0.0469, -0.0826],\n 'r': [0.4806, -0.0996, -0.0936, 0.8662],\n 's': [1, 1, 1]\n },\n {\n 't': [0.034, 0.0014, -0.1134],\n 'r': [0.079, 0.2891, -0.1225, 0.9461],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0152, 0.0077, -0.141],\n 'r': [-0.2784, 0.3171, 0.0012, 0.9066],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0023, -0.0029, -0.1556],\n 'r': [-0.458, 0.3482, 0.1094, 0.8106],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0053, -0.0187, -0.1623],\n 'r': [-0.458, 0.3482, 0.1094, 0.8106],\n 's': [1, 1, 1]\n }\n] as const;\n","\nexport class SimulatorXRHand {}","import * as THREE from 'three';\nimport {GLTFLoader} from 'three/addons/loaders/GLTFLoader.js';\n\nimport {HAND_JOINT_NAMES} from '../input/components/HandJointNames';\nimport {Input} from '../input/Input';\nimport type {DeepReadonly} from '../utils/Types';\n\nimport {SimulatorHandPoseChangeRequestEvent} from './events/SimulatorHandEvents';\nimport {SimulatorHandPoseJoints} from './handPoses/HandPoseJoints';\nimport {SIMULATOR_HAND_POSE_TO_JOINTS_LEFT, SIMULATOR_HAND_POSE_TO_JOINTS_RIGHT, SimulatorHandPose} from './handPoses/HandPoses';\nimport {SimulatorControllerState} from './SimulatorControllerState';\nimport {SimulatorXRHand} from './SimulatorXRHand';\n\nconst DEFAULT_HAND_PROFILE_PATH =\n 'https://cdn.jsdelivr.net/npm/@webxr-input-profiles/assets@1.0/dist/profiles/generic-hand/';\n\nconst vector3 = new THREE.Vector3();\nconst quaternion = new THREE.Quaternion();\n\nexport type SimulatorHandPoseHTMLElement = HTMLElement&{\n visible: boolean;\n handPose?: SimulatorHandPose;\n}\n\nexport class SimulatorHands {\n leftController = new THREE.Object3D();\n rightController = new THREE.Object3D();\n leftHand?: THREE.Group;\n rightHand?: THREE.Group;\n leftHandBones: THREE.Object3D[] = [];\n rightHandBones: THREE.Object3D[] = [];\n leftHandPose? = SimulatorHandPose.RELAXED;\n rightHandPose? = SimulatorHandPose.RELAXED;\n leftHandTargetJoints: DeepReadonly<SimulatorHandPoseJoints> =\n SIMULATOR_HAND_POSE_TO_JOINTS_LEFT[SimulatorHandPose.RELAXED];\n rightHandTargetJoints: DeepReadonly<SimulatorHandPoseJoints> =\n SIMULATOR_HAND_POSE_TO_JOINTS_RIGHT[SimulatorHandPose.RELAXED];\n lerpSpeed = 0.1;\n handPosePanelElement?: SimulatorHandPoseHTMLElement;\n onHandPoseChangeRequestBound = this.onHandPoseChangeRequest.bind(this);\n input!: Input;\n loader!: GLTFLoader;\n\n private leftXRHand = new SimulatorXRHand();\n private rightXRHand = new SimulatorXRHand();\n\n constructor(\n private simulatorControllerState: SimulatorControllerState,\n private simulatorScene: THREE.Scene) {}\n\n /**\n * Initialize Simulator Hands.\n */\n init({input}: {input: Input}) {\n this.input = input;\n this.loadMeshes();\n this.simulatorScene.add(this.leftController);\n this.simulatorScene.add(this.rightController);\n }\n\n loadMeshes() {\n this.loader = new GLTFLoader();\n this.loader.setPath(DEFAULT_HAND_PROFILE_PATH);\n this.loader.load('left.glb', gltf => {\n this.leftHand = gltf.scene;\n this.leftController.add(this.leftHand);\n HAND_JOINT_NAMES.forEach(jointName => {\n const bone = gltf.scene.getObjectByName(jointName);\n if (bone) {\n this.leftHandBones.push(bone);\n } else {\n console.warn(`Couldn't find ${jointName} in left hand mesh`);\n }\n });\n this.setLeftHandJoints(this.leftHandTargetJoints);\n this.input.hands[0]?.dispatchEvent?.({\n type: 'connected',\n data: {hand: this.leftXRHand, handedness: 'left'} as XRInputSource\n });\n });\n this.loader.load('right.glb', gltf => {\n this.rightHand = gltf.scene;\n this.rightController.add(this.rightHand);\n HAND_JOINT_NAMES.forEach(jointName => {\n const bone = gltf.scene.getObjectByName(jointName);\n if (bone) {\n this.rightHandBones.push(bone);\n } else {\n console.warn(`Couldn't find ${jointName} in right hand mesh`);\n }\n });\n this.setRightHandJoints(this.rightHandTargetJoints);\n this.input.hands[1]?.dispatchEvent?.({\n type: 'connected',\n data: {hand: this.rightXRHand, handedness: 'right'} as XRInputSource\n });\n });\n }\n\n setLeftHandLerpPose(pose: SimulatorHandPose) {\n if (this.leftHandPose === pose) return;\n\n if (pose === SimulatorHandPose.PINCHING) {\n this.input.dispatchEvent({\n type: 'selectstart',\n target: this.input.controllers[0],\n data: {\n handedness: 'left',\n }\n });\n } else if (this.leftHandPose === SimulatorHandPose.PINCHING) {\n this.input.dispatchEvent({\n type: 'selectend',\n target: this.input.controllers[0],\n data: {\n handedness: 'left',\n }\n });\n }\n\n this.leftHandPose = pose;\n this.leftHandTargetJoints = SIMULATOR_HAND_POSE_TO_JOINTS_LEFT[pose];\n this.updateHandPosePanel();\n }\n\n setRightHandLerpPose(pose: SimulatorHandPose) {\n if (this.rightHandPose === pose) return;\n\n if (pose === SimulatorHandPose.PINCHING) {\n this.input.dispatchEvent({\n type: 'selectstart',\n target: this.input.controllers[1],\n data: {\n handedness: 'right',\n }\n });\n } else if (this.rightHandPose === SimulatorHandPose.PINCHING) {\n this.input.dispatchEvent({\n type: 'selectend',\n target: this.input.controllers[1],\n data: {\n handedness: 'right',\n }\n });\n }\n\n this.rightHandPose = pose;\n this.rightHandTargetJoints = SIMULATOR_HAND_POSE_TO_JOINTS_RIGHT[pose];\n this.updateHandPosePanel();\n }\n\n setLeftHandJoints(joints: DeepReadonly<SimulatorHandPoseJoints>) {\n // Unset the pose if the joints are manually defined.\n if (this.leftHandPose === SimulatorHandPose.PINCHING) {\n this.input.dispatchEvent({\n type: 'selectend',\n target: this.input.controllers[1],\n data: {\n handedness: 'left',\n }\n });\n }\n if (joints != this.leftHandTargetJoints) {\n this.leftHandPose = undefined;\n this.leftHandTargetJoints = joints;\n }\n for (let i = 0; i < this.leftHandBones.length; i++) {\n const bone = this.leftHandBones[i];\n const jointData = joints[i];\n if (bone && jointData) {\n bone.position.fromArray(jointData.t)\n bone.quaternion.fromArray(jointData.r);\n bone.scale.fromArray([1, 1, 1]);\n }\n }\n }\n\n setRightHandJoints(joints: DeepReadonly<SimulatorHandPoseJoints>) {\n // Unset the pose if the joints are manually defined.\n if (this.rightHandPose === SimulatorHandPose.PINCHING) {\n this.input.dispatchEvent({\n type: 'selectend',\n target: this.input.controllers[1],\n data: {\n handedness: 'right',\n }\n });\n }\n if (joints != this.rightHandTargetJoints) {\n this.rightHandPose = undefined;\n this.rightHandTargetJoints = joints;\n }\n for (let i = 0; i < this.rightHandBones.length; i++) {\n const bone = this.rightHandBones[i];\n const jointData = joints[i];\n if (bone && jointData) {\n bone.position.fromArray(jointData.t)\n bone.quaternion.fromArray(jointData.r);\n bone.scale.fromArray([1, 1, 1]);\n }\n }\n }\n\n update() {\n this.lerpLeftHandPose();\n this.lerpRightHandPose();\n this.syncHandJoints();\n }\n\n lerpLeftHandPose() {\n for (let i = 0; i < this.leftHandBones.length; i++) {\n const bone = this.leftHandBones[i];\n const targetJoint = this.leftHandTargetJoints[i];\n if (bone && targetJoint) {\n vector3.fromArray(targetJoint.t)\n quaternion.fromArray(targetJoint.r);\n\n bone.position.lerp(vector3, this.lerpSpeed);\n bone.quaternion.slerp(quaternion, this.lerpSpeed);\n }\n }\n }\n\n lerpRightHandPose() {\n for (let i = 0; i < this.rightHandBones.length; i++) {\n const bone = this.rightHandBones[i];\n const targetJoint = this.rightHandTargetJoints[i];\n if (bone && targetJoint) {\n vector3.fromArray(targetJoint.t)\n quaternion.fromArray(targetJoint.r);\n\n bone.position.lerp(vector3, this.lerpSpeed);\n bone.quaternion.slerp(quaternion, this.lerpSpeed);\n }\n }\n }\n\n syncHandJoints() {\n const hands = this.input.hands;\n const leftHand = hands[0];\n if (leftHand) {\n this.leftController.updateWorldMatrix(true, false);\n leftHand.position.setFromMatrixPosition(this.leftController.matrixWorld);\n leftHand.setRotationFromMatrix(this.leftController.matrixWorld);\n leftHand.updateMatrix();\n for (let i = 0; i < this.leftHandBones.length; i++) {\n const joint = HAND_JOINT_NAMES[i];\n if (!(joint in leftHand.joints)) {\n leftHand.joints[joint] = new THREE.Group() as THREE.XRJointSpace;\n leftHand.add(leftHand.joints[joint]);\n }\n leftHand.joints[joint]!.position.copy(this.leftHandBones[i].position);\n leftHand.joints[joint]!.quaternion.copy(\n this.leftHandBones[i].quaternion);\n leftHand.updateWorldMatrix(false, true);\n }\n }\n const rightHand = hands[1];\n if (rightHand) {\n this.rightController.updateWorldMatrix(true, false);\n rightHand.position.setFromMatrixPosition(\n this.rightController.matrixWorld);\n rightHand.setRotationFromMatrix(this.rightController.matrixWorld);\n rightHand.updateMatrix();\n for (let i = 0; i < this.rightHandBones.length; i++) {\n const joint = HAND_JOINT_NAMES[i];\n if (!(joint in rightHand.joints)) {\n rightHand.joints[joint] = new THREE.Group() as THREE.XRJointSpace;\n rightHand.add(rightHand.joints[joint]);\n }\n rightHand.joints[joint]!.position.copy(this.rightHandBones[i].position);\n rightHand.joints[joint]!.quaternion.copy(\n this.rightHandBones[i].quaternion);\n rightHand.updateWorldMatrix(false, true);\n }\n }\n }\n\n setLeftHandPinching(pinching = true) {\n this.setLeftHandLerpPose(\n pinching ? SimulatorHandPose.PINCHING : SimulatorHandPose.RELAXED);\n }\n\n setRightHandPinching(pinching = true) {\n this.setRightHandLerpPose(\n pinching ? SimulatorHandPose.PINCHING : SimulatorHandPose.RELAXED);\n }\n\n showHands() {\n this.leftController.visible = true;\n this.rightController.visible = true;\n for (let i = 0; i < this.input.hands.length; i++) {\n this.input.hands[i].visible = true;\n }\n this.updateHandPosePanel();\n }\n\n hideHands() {\n this.leftController.visible = false;\n this.rightController.visible = false;\n for (let i = 0; i < this.input.hands.length; i++) {\n this.input.hands[i].visible = false;\n }\n this.updateHandPosePanel();\n }\n\n updateHandPosePanel() {\n if (!this.handPosePanelElement) return;\n if (this.simulatorControllerState.currentControllerIndex === 0) {\n this.handPosePanelElement.visible = this.leftController.visible;\n this.handPosePanelElement.handPose = this.leftHandPose;\n } else {\n this.handPosePanelElement.visible = this.rightController.visible;\n this.handPosePanelElement.handPose = this.rightHandPose;\n }\n }\n\n setHandPosePanelElement(element: HTMLElement) {\n if (this.handPosePanelElement) {\n this.handPosePanelElement.removeEventListener(\n SimulatorHandPoseChangeRequestEvent.type,\n this.onHandPoseChangeRequestBound);\n }\n element.addEventListener(\n SimulatorHandPoseChangeRequestEvent.type,\n this.onHandPoseChangeRequestBound);\n this.handPosePanelElement = element as SimulatorHandPoseHTMLElement;\n this.updateHandPosePanel();\n }\n\n onHandPoseChangeRequest(event: Event) {\n if (event.type != SimulatorHandPoseChangeRequestEvent.type) return;\n const handPoseChangeEvent = event as SimulatorHandPoseChangeRequestEvent;\n if (this.simulatorControllerState.currentControllerIndex === 0) {\n this.setLeftHandLerpPose(handPoseChangeEvent.pose);\n } else {\n this.setRightHandLerpPose(handPoseChangeEvent.pose);\n }\n }\n\n toggleHandedness() {\n this.simulatorControllerState.currentControllerIndex =\n (this.simulatorControllerState.currentControllerIndex + 1) % 2;\n this.updateHandPosePanel();\n }\n}\n","import {SimulatorControls, SimulatorModeIndicatorElement} from './SimulatorControls.js';\nimport {SimulatorHands} from './SimulatorHands.js';\nimport {SimulatorCustomInstruction, SimulatorOptions} from './SimulatorOptions.js';\n\ntype SimulatorInstructionsHTMLElement = HTMLElement&{\n customInstructions: SimulatorCustomInstruction[];\n}\n\nexport class SimulatorInterface {\n private elements: HTMLElement[] = [];\n private interfaceVisible = true;\n\n /**\n * Initialize the simulator interface.\n */\n init(\n simulatorOptions: SimulatorOptions, simulatorControls: SimulatorControls,\n simulatorHands: SimulatorHands) {\n this.createModeIndicator(simulatorOptions, simulatorControls);\n this.showGeminiLivePanel(simulatorOptions);\n this.createHandPosePanel(simulatorOptions, simulatorHands);\n this.showInstructions(simulatorOptions);\n }\n\n createModeIndicator(\n simulatorOptions: SimulatorOptions,\n simulatorControls: SimulatorControls) {\n if (simulatorOptions.modeIndicator.enabled) {\n const modeIndicatorElement =\n document.createElement(simulatorOptions.modeIndicator.element) as\n SimulatorModeIndicatorElement;\n document.body.appendChild(modeIndicatorElement);\n simulatorControls.setModeIndicatorElement(modeIndicatorElement);\n this.elements.push(modeIndicatorElement);\n }\n }\n\n showInstructions(simulatorOptions: SimulatorOptions) {\n if (simulatorOptions.instructions.enabled) {\n const element =\n document.createElement(simulatorOptions.instructions.element) as\n SimulatorInstructionsHTMLElement;\n element.customInstructions =\n simulatorOptions.instructions.customInstructions;\n document.body.appendChild(element);\n this.elements.push(element);\n }\n }\n\n showGeminiLivePanel(simulatorOptions: SimulatorOptions) {\n if (simulatorOptions.geminilive) {\n const element = document.createElement('xrblocks-simulator-geminilive');\n document.body.appendChild(element);\n this.elements.push(element);\n }\n }\n\n createHandPosePanel(\n simulatorOptions: SimulatorOptions, simulatorHands: SimulatorHands) {\n if (simulatorOptions.handPosePanel.enabled) {\n const handsPanelElement =\n document.createElement(simulatorOptions.handPosePanel.element);\n document.body.appendChild(handsPanelElement);\n simulatorHands.setHandPosePanelElement(handsPanelElement);\n this.elements.push(handsPanelElement);\n }\n }\n\n hideUiElements() {\n for (const element of this.elements) {\n element.style.display = 'none';\n }\n this.interfaceVisible = false;\n }\n\n showUiElements() {\n for (const element of this.elements) {\n element.style.display = '';\n }\n this.interfaceVisible = true;\n }\n\n getInterfaceVisible() {\n return !this.interfaceVisible;\n }\n\n toggleInterfaceVisible() {\n if (this.interfaceVisible) {\n this.hideUiElements();\n } else {\n this.showUiElements();\n }\n }\n}","import * as THREE from 'three';\nimport {GLTFLoader} from 'three/addons/loaders/GLTFLoader.js';\nimport type {GLTF} from 'three/addons/loaders/GLTFLoader.js';\n\nimport {SimulatorOptions} from './SimulatorOptions';\n\nexport class SimulatorScene extends THREE.Scene {\n gltf?: GLTF;\n\n constructor() {\n super();\n }\n\n async init(simulatorOptions: SimulatorOptions) {\n this.addLights();\n if (simulatorOptions.scenePath) {\n await this.loadGLTF(\n simulatorOptions.scenePath,\n new THREE.Vector3(\n simulatorOptions.initialScenePosition.x,\n simulatorOptions.initialScenePosition.y,\n simulatorOptions.initialScenePosition.z));\n }\n }\n\n addLights() {\n this.add(new THREE.HemisphereLight(0xbbbbbb, 0x888888, 3));\n }\n\n async loadGLTF(path: string, initialPosition: THREE.Vector3) {\n const loader = new GLTFLoader();\n return new Promise((resolve, reject) => {\n loader.load(\n path,\n (gltf) => {\n gltf.scene.position.copy(initialPosition);\n this.add(gltf.scene);\n this.gltf = gltf;\n resolve(gltf);\n },\n () => {},\n (error) => {\n reject(error);\n });\n });\n }\n}\n","import {Registry} from '../core/components/Registry';\nimport type {Constructor} from '../utils/Types';\n\n// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\nexport type InjectableConstructor = Function&{\n // Static property for dependencies.\n dependencies?: Record<string, Constructor>;\n}\n\nexport interface Injectable {\n init(...args: unknown[]): Promise<void>|void; // The init method.\n constructor: InjectableConstructor; // A reference to its own constructor.\n}\n\n/**\n * Call init on a script or subsystem with dependency injection.\n */\nexport async function callInitWithDependencyInjection(\n script: Injectable, registry: Registry, fallback: unknown) {\n const dependencies = script.constructor.dependencies;\n if (dependencies == null) {\n await script.init(fallback);\n return;\n }\n await script.init(\n Object.fromEntries(Object.entries(dependencies).map(([key, value]) => {\n const dependency = registry.get(value);\n if (!dependency) {\n throw new Error(`Dependency not found for key: ${value.name}`);\n }\n return [key, dependency];\n })));\n}\n","import {Registry} from '../core/components/Registry.js';\nimport {WaitFrame} from '../core/components/WaitFrame.js';\nimport {Script} from '../core/Script.js';\nimport {callInitWithDependencyInjection} from '../utils/DependencyInjection';\n\nimport {SimulatorUserAction} from './userActions/SimulatorUserAction.js';\n\nexport class SimulatorUser extends Script {\n static dependencies = {waitFrame: WaitFrame, registry: Registry};\n journeyId = 0;\n waitFrame!: WaitFrame;\n registry!: Registry;\n\n constructor() {\n super();\n }\n\n init({waitFrame, registry}: {waitFrame: WaitFrame, registry: Registry}) {\n this.waitFrame = waitFrame;\n this.registry = registry;\n }\n\n stopJourney() {\n ++this.journeyId;\n }\n\n isOnJourneyId(id: number) {\n return id == this.journeyId;\n }\n\n async loadJourney(actions: SimulatorUserAction[]) {\n console.log('Load journey');\n const currentJourneyId = ++this.journeyId;\n for (let i = 0; this.isOnJourneyId(currentJourneyId) && i < actions.length;\n ++i) {\n callInitWithDependencyInjection(actions[i], this.registry, undefined);\n await actions[i].play({\n simulatorUser: this,\n journeyId: currentJourneyId,\n waitFrame: this.waitFrame\n });\n }\n console.log('Journey finished');\n }\n}","import * as THREE from 'three';\nimport {FullScreenQuad} from 'three/addons/postprocessing/Pass.js';\n\nimport {XRDeviceCamera} from '../camera/XRDeviceCamera.js';\nimport {Registry} from '../core/components/Registry';\nimport {XREffects} from '../core/components/XREffects';\nimport {Options} from '../core/Options';\nimport {Script} from '../core/Script';\nimport {Depth} from '../depth/Depth';\nimport {DepthMesh} from '../depth/DepthMesh';\nimport {Input} from '../input/Input';\n\nimport {SimulatorCamera} from './SimulatorCamera';\nimport {AVERAGE_IPD_METERS, SimulatorRenderMode} from './SimulatorConstants';\nimport {SimulatorControllerState} from './SimulatorControllerState';\nimport {SimulatorControls} from './SimulatorControls';\nimport {SimulatorDepth} from './SimulatorDepth';\nimport {SimulatorHands} from './SimulatorHands';\nimport {SimulatorInterface} from './SimulatorInterface';\nimport {SimulatorOptions} from './SimulatorOptions';\nimport {SimulatorScene} from './SimulatorScene';\nimport {SimulatorUser} from './SimulatorUser';\n\nexport class Simulator extends Script {\n static dependencies = {\n simulatorOptions: SimulatorOptions,\n input: Input,\n timer: THREE.Timer,\n camera: THREE.Camera,\n renderer: THREE.WebGLRenderer,\n scene: THREE.Scene,\n registry: Registry,\n options: Options,\n depth: Depth,\n };\n\n simulatorScene = new SimulatorScene();\n depth = new SimulatorDepth(this.simulatorScene);\n // Controller poses relative to the camera.\n simulatorControllerState = new SimulatorControllerState();\n hands =\n new SimulatorHands(this.simulatorControllerState, this.simulatorScene);\n simulatorUser = new SimulatorUser();\n userInterface = new SimulatorInterface();\n controls = new SimulatorControls(\n this.simulatorControllerState, this.hands,\n this.setStereoRenderMode.bind(this), this.userInterface);\n renderDepthPass = false;\n renderMode = SimulatorRenderMode.DEFAULT;\n stereoCameras: THREE.Camera[] = [];\n effects?: XREffects;\n\n // Render target for the virtual scene.\n virtualSceneRenderTarget?: THREE.WebGLRenderTarget;\n virtualSceneFullScreenQuad?: FullScreenQuad;\n\n camera?: SimulatorCamera;\n options!: SimulatorOptions;\n renderer!: THREE.WebGLRenderer;\n mainCamera!: THREE.Camera;\n mainScene!: THREE.Scene;\n\n private initialized = false;\n private renderSimulatorSceneToCanvasBound =\n this.renderSimulatorSceneToCanvas.bind(this);\n\n constructor(\n private renderMainScene: (cameraOverride?: THREE.Camera) => void) {\n super();\n this.add(this.simulatorUser);\n }\n\n async init({\n simulatorOptions,\n input,\n timer,\n camera,\n renderer,\n scene,\n registry,\n options,\n depth,\n }: {\n simulatorOptions: SimulatorOptions,\n input: Input,\n timer: THREE.Timer,\n camera: THREE.Camera,\n renderer: THREE.WebGLRenderer,\n scene: THREE.Scene,\n registry: Registry,\n options: Options,\n depth: Depth,\n }) {\n if (this.initialized) return;\n // Get optional dependencies from the registry.\n const deviceCamera = registry.get(XRDeviceCamera);\n const depthMesh = registry.get(DepthMesh);\n this.options = simulatorOptions;\n camera.position.copy(this.options.initialCameraPosition);\n this.userInterface.init(simulatorOptions, this.controls, this.hands);\n renderer.autoClearColor = false;\n await this.simulatorScene.init(simulatorOptions);\n this.hands.init({input});\n this.controls.init({camera, input, timer, renderer, simulatorOptions});\n if (deviceCamera && !this.camera) {\n this.camera = new SimulatorCamera(renderer);\n this.camera.init();\n deviceCamera.registerSimulatorCamera(this.camera);\n }\n\n if (options.depth.enabled) {\n this.renderDepthPass = true;\n this.depth.init(renderer, camera, depth);\n if (options.depth.depthMesh.enabled && depthMesh) {\n camera.add(depthMesh);\n }\n }\n scene.add(camera);\n\n if (this.options.stereo.enabled) {\n this.setupStereoCameras(camera);\n }\n\n this.virtualSceneRenderTarget = new THREE.WebGLRenderTarget(\n renderer.domElement.width, renderer.domElement.height,\n {stencilBuffer: options.stencil});\n this.virtualSceneFullScreenQuad =\n new FullScreenQuad(new THREE.MeshBasicMaterial(\n {map: this.virtualSceneRenderTarget.texture, transparent: true}));\n\n this.renderer = renderer;\n this.mainCamera = camera;\n this.mainScene = scene;\n this.initialized = true;\n }\n\n\n simulatorUpdate() {\n this.controls.update();\n this.hands.update();\n\n if (this.renderDepthPass) {\n this.depth.update();\n }\n }\n\n setStereoRenderMode(mode: SimulatorRenderMode) {\n if (!this.options.stereo.enabled) return;\n this.renderMode = mode;\n }\n\n setupStereoCameras(camera: THREE.Camera) {\n const leftCamera = camera.clone();\n const rightCamera = camera.clone();\n leftCamera.layers.disableAll();\n leftCamera.layers.enable(0);\n leftCamera.layers.enable(1);\n rightCamera.layers.disableAll();\n rightCamera.layers.enable(0);\n rightCamera.layers.enable(2);\n leftCamera.position.set(-AVERAGE_IPD_METERS / 2, 0, 0);\n rightCamera.position.set(AVERAGE_IPD_METERS / 2, 0, 0);\n leftCamera.updateWorldMatrix(true, false);\n rightCamera.updateWorldMatrix(true, false);\n this.stereoCameras.length = 0;\n this.stereoCameras.push(leftCamera, rightCamera);\n camera.add(leftCamera, rightCamera);\n this.setStereoRenderMode(SimulatorRenderMode.STEREO_LEFT);\n }\n\n onBeforeSimulatorSceneRender() {\n if (this.camera) {\n this.camera.onBeforeSimulatorSceneRender(\n this.mainCamera, this.renderSimulatorSceneToCanvasBound);\n }\n }\n\n onSimulatorSceneRendered() {\n if (this.camera) {\n this.camera.onSimulatorSceneRendered();\n }\n }\n\n getRenderCamera() {\n return {\n [SimulatorRenderMode.DEFAULT]: this.mainCamera,\n [SimulatorRenderMode.STEREO_LEFT]: this.stereoCameras[0],\n [SimulatorRenderMode.STEREO_RIGHT]: this.stereoCameras[1]\n }[this.renderMode];\n }\n\n // Called by core when the simulator is running.\n renderScene() {\n if (!this.renderer) return;\n if (!this.options.renderToRenderTexture) return;\n // Allocate a new render target if the resolution changes.\n if (this.virtualSceneRenderTarget!.width !=\n this.renderer.domElement.width ||\n this.virtualSceneRenderTarget!.height !=\n this.renderer.domElement.height) {\n const stencilEnabled = !!this.virtualSceneRenderTarget?.stencilBuffer;\n this.virtualSceneRenderTarget!.dispose();\n this.virtualSceneRenderTarget = new THREE.WebGLRenderTarget(\n this.renderer.domElement.width, this.renderer.domElement.height,\n {stencilBuffer: stencilEnabled});\n (this.virtualSceneFullScreenQuad!.material as THREE.MeshBasicMaterial)\n .map = this.virtualSceneRenderTarget.texture;\n }\n this.renderer.setRenderTarget(this.virtualSceneRenderTarget!);\n this.renderer.clear();\n this.renderMainScene(this.getRenderCamera());\n }\n\n // Renders the simulator scene onto the main canvas.\n // Then composites the virtual render with the simulator render.\n // Called by core after renderScene.\n renderSimulatorScene() {\n this.onBeforeSimulatorSceneRender();\n this.renderSimulatorSceneToCanvas(this.getRenderCamera());\n this.onSimulatorSceneRendered();\n if (this.options.renderToRenderTexture) {\n this.virtualSceneFullScreenQuad!.render(this.renderer);\n } else {\n // Temporary workaround since splats look faded when rendered to a render\n // texture.\n this.renderMainScene(this.getRenderCamera());\n }\n }\n\n private renderSimulatorSceneToCanvas(camera: THREE.Camera) {\n this.renderer.setRenderTarget(null);\n this.renderer.render(this.simulatorScene, camera);\n this.renderer.clearDepth();\n }\n}\n","import {AI} from '../ai/AI';\nimport {Registry} from '../core/components/Registry';\nimport {Script} from '../core/Script.js';\n\nexport interface AudioListenerOptions {\n sampleRate?: number;\n channelCount?: number;\n echoCancellation?: boolean;\n noiseSuppression?: boolean;\n autoGainControl?: boolean;\n}\n\nfunction arrayBufferToBase64(buffer: ArrayBuffer) {\n const bytes = new Uint8Array(buffer);\n let binary = '';\n for (let i = 0; i < bytes.length; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n return btoa(binary);\n}\n\nexport class AudioListener extends Script {\n static dependencies = {registry: Registry};\n private options: AudioListenerOptions;\n private audioStream?: MediaStream;\n private audioContext?: AudioContext;\n private sourceNode?: MediaStreamAudioSourceNode;\n private processorNode?: AudioWorkletNode;\n private isCapturing = false;\n private latestAudioBuffer: ArrayBuffer|null = null;\n private registry!: Registry;\n aiService?: AI;\n private onAudioData?: ((audioBuffer: ArrayBuffer) => void);\n private onError?: ((error: Error) => void);\n\n constructor(options: AudioListenerOptions = {}) {\n super();\n this.options = {\n sampleRate: 16000,\n channelCount: 1,\n echoCancellation: true,\n noiseSuppression: true,\n autoGainControl: true,\n ...options\n };\n }\n\n /**\n * Init the AudioListener.\n */\n init({registry}: {registry: Registry;}) {\n this.registry = registry;\n }\n\n async startCapture(callbacks: {\n onAudioData?: (audioBuffer: ArrayBuffer) => void;\n onError?: (error: Error) => void;\n } = {}) {\n if (this.isCapturing) return;\n this.onAudioData = callbacks.onAudioData;\n this.onError = callbacks.onError;\n try {\n await this.setupAudioCapture();\n this.isCapturing = true;\n } catch (error) {\n console.error('Failed to start audio capture:', error);\n this.onError?.(error as Error);\n this.cleanup();\n }\n }\n\n stopCapture() {\n if (!this.isCapturing) return;\n this.cleanup();\n this.isCapturing = false;\n }\n\n async setupAudioCapture() {\n this.audioStream =\n await navigator.mediaDevices.getUserMedia({audio: true, video: false});\n\n const actualSampleRate =\n this.audioStream.getAudioTracks()[0].getSettings().sampleRate;\n this.audioContext = new AudioContext({sampleRate: actualSampleRate});\n await this.setupAudioWorklet();\n\n this.sourceNode =\n this.audioContext.createMediaStreamSource(this.audioStream);\n this.processorNode =\n new AudioWorkletNode(this.audioContext, 'audio-capture-processor');\n\n this.processorNode.port.onmessage = (event) => {\n if (event.data.type === 'audioData') {\n this.latestAudioBuffer = event.data.data;\n this.onAudioData?.(event.data.data);\n this.streamToAI(event.data.data);\n }\n };\n\n // Check if the AudioContext is running, resume if necessary\n if (this.audioContext.state === 'suspended') {\n await this.audioContext.resume();\n }\n\n this.sourceNode.connect(this.processorNode);\n }\n\n private async setupAudioWorklet() {\n const processorCode = `\n class AudioCaptureProcessor extends AudioWorkletProcessor {\n process(inputs, outputs, parameters) {\n const input = inputs[0];\n if (input && input[0]) {\n const inputData = input[0];\n const pcmData = new Int16Array(inputData.length);\n for (let i = 0; i < inputData.length; i++) {\n pcmData[i] = Math.max(-32768, Math.min(32767, inputData[i] * 32768));\n }\n this.port.postMessage({type: 'audioData', data: pcmData.buffer});\n }\n return true;\n }\n }\n registerProcessor('audio-capture-processor', AudioCaptureProcessor);\n `;\n\n const blob = new Blob([processorCode], {type: 'application/javascript'});\n const processorURL = URL.createObjectURL(blob);\n await this.audioContext!.audioWorklet.addModule(processorURL);\n URL.revokeObjectURL(processorURL);\n }\n\n streamToAI(audioBuffer: ArrayBuffer) {\n if (!this.aiService?.sendRealtimeInput) return;\n const base64Audio = arrayBufferToBase64(audioBuffer);\n const actualSampleRate =\n this.audioContext?.sampleRate || this.options.sampleRate;\n this.aiService.sendRealtimeInput({\n audio: {data: base64Audio, mimeType: `audio/pcm;rate=${actualSampleRate}`}\n });\n }\n\n setAIStreaming(enabled: boolean) {\n this.aiService = enabled ? this.registry.get(AI) : undefined;\n }\n\n cleanup() {\n this.processorNode?.disconnect();\n this.sourceNode?.disconnect();\n if (this.audioContext && this.audioContext.state !== 'closed') {\n this.audioContext.close();\n }\n this.audioStream?.getTracks().forEach(track => track.stop());\n this.processorNode = undefined;\n this.sourceNode = undefined;\n this.audioContext = undefined;\n this.audioStream = undefined;\n this.onAudioData = undefined;\n this.onError = undefined;\n this.latestAudioBuffer = null;\n this.aiService = undefined;\n }\n\n static isSupported() {\n return !!(navigator.mediaDevices && navigator.mediaDevices.getUserMedia);\n }\n\n getIsCapturing() {\n return this.isCapturing;\n }\n\n getLatestAudioBuffer() {\n return this.latestAudioBuffer;\n }\n\n clearLatestAudioBuffer() {\n this.latestAudioBuffer = null;\n }\n\n dispose() {\n this.stopCapture();\n super.dispose();\n }\n}\n","import {Script} from '../core/Script.js';\n\nexport interface AudioPlayerOptions {\n sampleRate?: number;\n channelCount?: number;\n}\n\nexport class AudioPlayer extends Script {\n private options: AudioPlayerOptions = {};\n private audioContext?: AudioContext;\n private audioQueue: AudioBuffer[] = [];\n private isPlaying = false;\n private nextStartTime = 0;\n\n constructor(options: AudioPlayerOptions = {}) {\n super();\n this.options = {sampleRate: 24000, channelCount: 1, ...options};\n }\n\n async initializeAudioContext() {\n if (!this.audioContext) {\n this.audioContext =\n new AudioContext({sampleRate: this.options.sampleRate});\n this.nextStartTime = this.audioContext.currentTime;\n }\n }\n\n async playAudioChunk(base64AudioData: string) {\n if (!base64AudioData) return;\n\n await this.initializeAudioContext();\n const arrayBuffer = this.base64ToArrayBuffer(base64AudioData);\n const audioBuffer = this.audioContext!.createBuffer(\n this.options.channelCount!, arrayBuffer.byteLength / 2,\n this.options.sampleRate!);\n\n const channelData = audioBuffer.getChannelData(0);\n const int16View = new Int16Array(arrayBuffer);\n\n for (let i = 0; i < int16View.length; i++) {\n channelData[i] = int16View[i] / 32768.0;\n }\n\n this.audioQueue.push(audioBuffer);\n if (!this.isPlaying) this.playNextAudioBuffer();\n }\n\n playNextAudioBuffer() {\n if (this.audioQueue.length === 0) {\n this.isPlaying = false;\n return;\n }\n\n this.isPlaying = true;\n const audioBuffer = this.audioQueue.shift()!;\n const currentTime = this.audioContext!.currentTime;\n const startTime = Math.max(this.nextStartTime, currentTime);\n\n const source = this.audioContext!.createBufferSource();\n source.buffer = audioBuffer;\n source.connect(this.audioContext!.destination);\n source.onended = () => this.playNextAudioBuffer();\n source.start(startTime);\n this.nextStartTime = startTime + audioBuffer.duration;\n }\n\n clearQueue() {\n this.audioQueue = [];\n this.isPlaying = false;\n }\n\n getIsPlaying() {\n return this.isPlaying;\n }\n\n getQueueLength() {\n return this.audioQueue.length;\n }\n\n base64ToArrayBuffer(base64: string) {\n const binaryString = atob(base64);\n const bytes = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n return bytes.buffer;\n }\n\n stop() {\n this.clearQueue();\n if (this.audioContext) {\n this.audioContext.close();\n this.audioContext = undefined;\n }\n }\n\n static isSupported() {\n return !!('AudioContext' in window || 'webkitAudioContext' in window);\n }\n\n dispose() {\n this.stop();\n super.dispose();\n }\n}\n","import * as THREE from 'three';\n\nimport {XR_BLOCKS_ASSETS_PATH} from '../constants';\nimport {Script} from '../core/Script';\n\nimport {CategoryVolumes} from './CategoryVolumes';\n\nconst MUSIC_LIBRARY_PATH = XR_BLOCKS_ASSETS_PATH + 'musicLibrary/';\n\nconst musicLibrary = {\n 'ambient': MUSIC_LIBRARY_PATH + 'AmbientLoop.opus',\n 'background': MUSIC_LIBRARY_PATH + 'BackgroundMusic4.mp3',\n 'buttonHover': MUSIC_LIBRARY_PATH + 'ButtonHover.opus',\n 'buttonPress': MUSIC_LIBRARY_PATH + 'ButtonPress.opus',\n 'menuDismiss': MUSIC_LIBRARY_PATH + 'MenuDismiss.opus'\n} as const;\n\nclass BackgroundMusic extends Script {\n private audioLoader = new THREE.AudioLoader();\n\n private currentAudio: THREE.Audio|null = null;\n private isPlaying = false;\n private musicLibrary = musicLibrary;\n\n private specificVolume = 0.5;\n private musicCategory = 'music';\n\n constructor(\n private listener: THREE.AudioListener,\n private categoryVolumes: CategoryVolumes) {\n super();\n }\n\n // Set the volume for this instance of BackgroundMusic\n setVolume(level: number) {\n this.specificVolume = THREE.MathUtils.clamp(level, 0.0, 1.0);\n if (this.currentAudio && this.isPlaying && this.categoryVolumes) {\n const effectiveVolume = this.categoryVolumes.getEffectiveVolume(\n this.musicCategory, this.specificVolume);\n this.currentAudio.setVolume(effectiveVolume);\n console.log(`BackgroundMusic volume updated to: ${\n effectiveVolume} (specific: ${this.specificVolume})`);\n }\n }\n\n playMusic(musicKey: keyof typeof musicLibrary, category = 'music') {\n if (!this.categoryVolumes || !this.listener || !this.audioLoader) {\n console.error('BackgroundMusic not properly initialized.');\n return;\n }\n const soundPath = this.musicLibrary[musicKey];\n\n if (!soundPath) {\n console.error(`BackgroundMusic: Music key \"${musicKey}\" not found.`);\n return;\n }\n\n this.stopMusic();\n console.log(`BackgroundMusic: Loading sound: ${soundPath}`);\n this.musicCategory = category;\n\n const listener = this.listener;\n\n this.audioLoader.load(\n soundPath,\n (buffer) => {\n console.log(`BackgroundMusic: Successfully loaded ${soundPath}`);\n const audio = new THREE.Audio(listener);\n audio.setBuffer(buffer);\n audio.setLoop(\n this.musicCategory === 'music' ||\n this.musicCategory === 'ambient');\n\n const effectiveVolume = this.categoryVolumes.getEffectiveVolume(\n this.musicCategory, this.specificVolume);\n audio.setVolume(effectiveVolume);\n console.log(`BackgroundMusic: Setting volume for \"${musicKey}\" to ${\n effectiveVolume}`);\n\n audio.play();\n this.currentAudio = audio;\n this.isPlaying = true;\n console.log(`BackgroundMusic: Playing \"${musicKey}\" in category \"${\n this.musicCategory}\"`);\n },\n (xhr) => {\n console.log(`BackgroundMusic: Loading ${soundPath} - ${\n (xhr.loaded / xhr.total * 100).toFixed(0)}% loaded`);\n },\n (error) => {\n console.error(\n `BackgroundMusic: Error loading sound ${soundPath}:`, error);\n this.currentAudio = null;\n this.isPlaying = false;\n });\n }\n\n stopMusic() {\n if (this.currentAudio && this.isPlaying) {\n console.log('BackgroundMusic: Stopping current audio.');\n this.currentAudio.stop();\n }\n this.currentAudio = null;\n this.isPlaying = false;\n }\n\n destroy() {\n console.log('BackgroundMusic Destroying...');\n this.stopMusic();\n }\n}\n\nexport {BackgroundMusic};\n","import * as THREE from 'three';\n\nexport enum VolumeCategory {\n music = 'music',\n sfx = 'sfx',\n speech = 'speech',\n ui = 'ui'\n}\n\nexport class CategoryVolumes {\n isMuted = false;\n masterVolume = 1.0;\n\n volumes: Record<VolumeCategory, number> =\n Object.fromEntries(\n Object.values(VolumeCategory).map(cat => [cat, 1.0])) as\n Record<VolumeCategory, number>;\n\n getCategoryVolume(category: string): number {\n return this.volumes[category as VolumeCategory] ?? 1.0;\n }\n\n getEffectiveVolume(category: string, specificVolume = 1.0): number {\n if (this.isMuted) return 0.0;\n const categoryVol = this.getCategoryVolume(category);\n const clampedSpecificVolume =\n THREE.MathUtils.clamp(specificVolume, 0.0, 1.0);\n return this.masterVolume * categoryVol * clampedSpecificVolume;\n }\n}\n","import {Script} from '../core/Script.js';\n\ninterface SoundPresetTone {\n frequency: number;\n duration: number;\n waveformType: OscillatorType;\n delay?: number;\n}\n\n/**\n * Defines common UI sound presets with their default parameters.\n * Each preset specifies frequency, duration, and waveform type.\n */\nexport const SOUND_PRESETS = {\n BEEP: {frequency: 1000, duration: 0.07, waveformType: 'sine'},\n CLICK: [\n {frequency: 1500, duration: 0.02, waveformType: 'triangle', delay: 0},\n ],\n ACTIVATE: [\n {frequency: 800, duration: 0.05, waveformType: 'sine', delay: 0},\n {frequency: 1200, duration: 0.07, waveformType: 'sine', delay: 50}\n ],\n DEACTIVATE: [\n {frequency: 1200, duration: 0.05, waveformType: 'sine', delay: 0},\n {frequency: 800, duration: 0.07, waveformType: 'sine', delay: 50}\n ]\n} as const;\n\nexport class SoundSynthesizer extends Script {\n audioContext?: AudioContext;\n isInitialized = false;\n debug = false;\n\n /**\n * Initializes the AudioContext.\n */\n private _initAudioContext() {\n if (!this.isInitialized) {\n this.audioContext = new AudioContext();\n this.isInitialized = true;\n if (this.debug) {\n console.log('SoundSynthesizer: AudioContext initialized.');\n }\n }\n }\n\n /**\n * Plays a single tone with specified parameters.\n * @param frequency - The frequency of the tone in Hz.\n * @param duration - The duration of the tone in seconds.\n * @param volume - The volume of the tone (0.0 to 1.0).\n * @param waveformType - The type of waveform ('sine', 'square', 'sawtooth',\n * 'triangle').\n */\n playTone(\n frequency: number, duration: number, volume: number,\n waveformType: OscillatorType) {\n this._initAudioContext(); // Initialize context on first interaction\n\n if (!this.audioContext) {\n console.error(\n 'SoundSynthesizer: AudioContext not available. Cannot play tone.');\n return;\n }\n\n const oscillator = this.audioContext.createOscillator();\n oscillator.type = waveformType;\n oscillator.frequency.setValueAtTime(\n frequency, this.audioContext.currentTime);\n const gainNode = this.audioContext.createGain();\n gainNode.gain.setValueAtTime(volume, this.audioContext.currentTime);\n oscillator.connect(gainNode);\n gainNode.connect(this.audioContext.destination);\n oscillator.start();\n\n // Stop the sound after the specified duration with a slight fade out to\n // prevent clicks\n const stopTime = this.audioContext.currentTime + duration;\n const fadeOutTime = Math.max(\n 0.01, duration * 0.1); // Fade out over 10% of duration, min 0.01s\n\n gainNode.gain.exponentialRampToValueAtTime(0.00001, stopTime - fadeOutTime);\n oscillator.stop(stopTime);\n }\n\n /**\n * Plays a predefined sound preset.\n * @param presetName - The name of the preset (e.g., 'BEEP', 'CLICK',\n * 'ACTIVATE', 'DEACTIVATE').\n * @param volume - The volume for the preset (overrides default\n * if present, otherwise uses this).\n */\n playPresetTone(presetName: keyof typeof SOUND_PRESETS, volume = 0.5) {\n const preset = SOUND_PRESETS[presetName];\n\n if (!preset) {\n console.warn(`SoundSynthesizer: Preset '${presetName}' not found.`);\n return;\n }\n\n // Handle single tone presets\n if (!Array.isArray(preset)) {\n const tone = preset as SoundPresetTone;\n this.playTone(tone.frequency, tone.duration, volume, tone.waveformType);\n } else {\n // Handle multi-tone sequences\n preset.forEach(toneConfig => {\n setTimeout(() => {\n this.playTone(\n toneConfig.frequency, toneConfig.duration, volume,\n toneConfig.waveformType);\n }, toneConfig.delay || 0);\n });\n }\n }\n}\n","import * as THREE from 'three';\n\nimport {Script} from '../core/Script.js';\n\nimport {CategoryVolumes} from './CategoryVolumes.js';\n\nconst spatialSoundLibrary = {\n 'ambient': 'musicLibrary/AmbientLoop.opus',\n 'buttonHover': 'musicLibrary/ButtonHover.opus',\n 'paintOneShot1': 'musicLibrary/PaintOneShot1.opus',\n} as const;\n\nlet soundIdCounter = 0;\n\nexport interface PlaySoundOptions {\n loop?: boolean;\n volume?: number;\n refDistance?: number;\n rolloffFactor?: number;\n onEnded?: () => void;\n}\n\ninterface ActiveSound {\n audio: THREE.PositionalAudio;\n target: THREE.Object3D;\n options: PlaySoundOptions;\n}\n\nexport class SpatialAudio extends Script {\n private audioLoader = new THREE.AudioLoader();\n private soundLibrary = spatialSoundLibrary;\n // Stores { audio: PositionalAudio, target: Object3D } by id\n private activeSounds = new Map<number, ActiveSound>();\n\n private specificVolume = 1.0;\n private category = 'sfx' as const;\n private defaultRefDistance = 1;\n private defaultRolloffFactor = 1;\n\n constructor(\n private listener: THREE.AudioListener,\n private categoryVolumes: CategoryVolumes) {\n super();\n }\n\n /**\n * Plays a sound attached to a specific 3D object.\n * @param soundKey - Key from the soundLibrary.\n * @param targetObject - The object the sound should emanate\n * from.\n * @param options - Optional settings \\{ loop: boolean, volume:\n * number, refDistance: number, rolloffFactor: number, onEnded: function\n * \\}.\n * @returns A unique ID for the playing sound instance, or null\n * if failed.\n */\n playSoundAtObject(\n soundKey: keyof typeof spatialSoundLibrary, targetObject: THREE.Object3D,\n options: PlaySoundOptions = {}) {\n if (!this.listener || !this.audioLoader || !targetObject) {\n console.error(\n 'SpatialAudio not properly initialized or targetObject missing.');\n return null;\n }\n\n const soundPath = this.soundLibrary[soundKey];\n if (!soundPath) {\n console.error(`SpatialAudio: Sound key \"${soundKey}\" not found.`);\n return null;\n }\n\n const soundId = ++soundIdCounter;\n const specificVolume =\n options.volume !== undefined ? options.volume : this.specificVolume;\n const loop = options.loop || false;\n const refDistance = options.refDistance !== undefined ?\n options.refDistance :\n this.defaultRefDistance;\n const rolloffFactor = options.rolloffFactor !== undefined ?\n options.rolloffFactor :\n this.defaultRolloffFactor;\n\n console.log(`SpatialAudio: Loading sound \"${soundKey}\" (${soundPath})`);\n\n this.audioLoader.load(\n soundPath,\n (buffer) => {\n console.log(`SpatialAudio: Successfully loaded \"${soundKey}\"`);\n if (!this.listener) {\n console.error('SpatialAudio: Listener lost during load.');\n return;\n }\n const audio = new THREE.PositionalAudio(this.listener);\n audio.setBuffer(buffer);\n audio.setLoop(loop);\n audio.setRefDistance(refDistance);\n audio.setRolloffFactor(rolloffFactor);\n\n const effectiveVolume = this.categoryVolumes.getEffectiveVolume(\n this.category, specificVolume);\n audio.setVolume(effectiveVolume);\n\n targetObject.add(audio);\n this.activeSounds.set(\n soundId, {audio: audio, target: targetObject, options: options});\n\n // Set up cleanup for non-looping sounds\n if (!loop) {\n audio.onEnded = () => {\n console.log(\n `SpatialAudio: Sound \"${soundKey}\" (ID: ${soundId}) ended.`);\n this._cleanupSound(soundId);\n if (options.onEnded && typeof options.onEnded === 'function') {\n options.onEnded();\n }\n // Important: Clear the onEnded handler after it runs once\n // to prevent issues if the object is reused.\n audio.onEnded = () => {};\n };\n }\n\n audio.play();\n console.log(\n `SpatialAudio: Playing \"${soundKey}\" (ID: ${soundId}) at object ${\n targetObject.name ||\n targetObject.uuid}, Volume: ${effectiveVolume}`);\n },\n (xhr) => {\n console.log(`SpatialAudio: Loading \"${soundKey}\" - ${\n (xhr.loaded / xhr.total * 100).toFixed(0)}% loaded`);\n },\n (error) => {\n console.error(\n `SpatialAudio: Error loading sound \"${soundKey}\":`, error);\n this.activeSounds.delete(soundId); // Clean up if loading failed\n });\n\n return soundId;\n }\n\n /**\n * Stops a specific sound instance by its ID.\n * @param soundId - The ID returned by playSoundAtObject.\n */\n stopSound(soundId: number) {\n const soundData = this.activeSounds.get(soundId);\n if (soundData) {\n console.log(`SpatialAudio: Stopping sound ID: ${soundId}`);\n if (soundData.audio.isPlaying) {\n soundData.audio.stop();\n }\n this._cleanupSound(soundId);\n } else {\n console.warn(`SpatialAudio: Sound ID ${soundId} not found for stopping.`);\n }\n }\n\n /**\n * Internal method to remove sound from object and map.\n * @param soundId - id\n */\n private _cleanupSound(soundId: number) {\n const soundData = this.activeSounds.get(soundId);\n if (soundData) {\n if (soundData.audio.isPlaying) {\n try {\n soundData.audio.stop();\n } catch {\n // continue regardless of error\n }\n }\n if (soundData.target && soundData.audio.parent === soundData.target) {\n soundData.target.remove(soundData.audio);\n }\n this.activeSounds.delete(soundId);\n console.log(`SpatialAudio: Cleaned up sound ID: ${soundId}`);\n }\n }\n\n /**\n * Sets the base specific volume for subsequently played spatial sounds.\n * Does NOT affect currently playing sounds (use updateAllVolumes for that).\n * @param level - Volume level (0.0 to 1.0).\n */\n setVolume(level: number) {\n this.specificVolume = THREE.MathUtils.clamp(level, 0.0, 1.0);\n console.log(\n `SpatialAudio default specific volume set to: ${this.specificVolume}`);\n }\n\n /**\n * Updates the volume of all currently playing spatial sounds managed by this\n * instance.\n */\n updateAllVolumes() {\n if (!this.categoryVolumes) return;\n console.log(`SpatialAudio: Updating volumes for ${\n this.activeSounds.size} active sounds.`);\n this.activeSounds.forEach((soundData) => {\n const specificVolume = soundData.options.volume !== undefined ?\n soundData.options.volume :\n this.specificVolume;\n const effectiveVolume = this.categoryVolumes.getEffectiveVolume(\n this.category, specificVolume);\n soundData.audio.setVolume(effectiveVolume);\n });\n }\n\n destroy() {\n console.log('SpatialAudio Destroying...');\n const idsToStop = Array.from(this.activeSounds.keys());\n idsToStop.forEach(id => this.stopSound(id));\n\n this.activeSounds.clear();\n console.log('SpatialAudio Destroyed.');\n }\n}\n","import * as THREE from 'three';\n\nimport {Script} from '../core/Script.js';\n\nimport {SoundOptions, SpeechRecognizerOptions} from './SoundOptions.js';\nimport {SoundSynthesizer} from './SoundSynthesizer.js';\n\ntype WindowWithSpeechRecognition = Window&typeof globalThis&{\n SpeechRecognition?: SpeechRecognition;\n webkitSpeechRecognition?: SpeechRecognition;\n};\n\ninterface SpeechRecognizerEventMap extends THREE.Object3DEventMap {\n start: object;\n error: {error: string};\n end: object;\n result: {\n originalEvent: SpeechRecognitionEvent; transcript: string;\n confidence: number;\n command?: string; isFinal: boolean;\n };\n}\n\nexport class SpeechRecognizer extends Script<SpeechRecognizerEventMap> {\n static dependencies = {soundOptions: SoundOptions};\n\n options!: SpeechRecognizerOptions;\n recognition?: SpeechRecognition;\n isListening = false;\n lastTranscript = '';\n lastCommand?: string;\n lastConfidence = 0;\n error?: string;\n playActivationSounds = false;\n\n private handleStartBound = this._handleStart.bind(this);\n private handleResultBound = this._handleResult.bind(this);\n private handleEndBound = this._handleEnd.bind(this);\n private handleErrorBound = this._handleError.bind(this);\n\n constructor(private soundSynthesizer: SoundSynthesizer) {\n super();\n }\n\n override init({soundOptions}: {soundOptions: SoundOptions}) {\n this.options = soundOptions.speechRecognizer;\n const SpeechRecognitionAPI =\n (window as WindowWithSpeechRecognition).SpeechRecognition ||\n (window as WindowWithSpeechRecognition).webkitSpeechRecognition;\n if (!SpeechRecognitionAPI) {\n console.warn(\n 'SpeechRecognizer: Speech Recognition API not supported in this browser.');\n this.error = 'API not supported';\n return;\n }\n\n this.recognition = new SpeechRecognitionAPI();\n this.recognition.lang = this.options.lang;\n this.recognition.continuous = this.options.continuous;\n this.recognition.interimResults = this.options.interimResults;\n\n // Setup native event listeners\n this.recognition.onstart = this.handleStartBound;\n this.recognition.onresult = this.handleResultBound;\n this.recognition.onend = this.handleEndBound;\n this.recognition.onerror = this.handleErrorBound;\n }\n\n onSimulatorStarted() {\n this.playActivationSounds = this.options.playSimulatorActivationSounds;\n }\n\n start() {\n if (!this.recognition) {\n console.error('SpeechRecognizer: Not initialized.');\n return;\n }\n if (this.isListening) {\n console.warn('SpeechRecognizer: Already listening.');\n return;\n }\n try {\n this.lastTranscript = '';\n this.lastCommand = undefined;\n this.lastConfidence = 0;\n this.error = undefined;\n this.recognition.start();\n this.isListening = true;\n console.debug('SpeechRecognizer: Listening started.');\n } catch (e: unknown) {\n console.error('SpeechRecognizer: Error starting recognition:', e);\n this.error = (e as Partial<Error>).message || 'Start failed';\n this.isListening = false;\n this.dispatchEvent({type: 'error', error: this.error!});\n }\n }\n\n stop() {\n if (!this.recognition || !this.isListening) {\n return;\n }\n try {\n this.recognition.stop();\n console.debug('SpeechRecognizer: Stop requested.');\n } catch (e) {\n console.error('SpeechRecognizer: Error stopping recognition:', e);\n this.error = (e as Partial<Error>).message || 'Stop failed';\n this.isListening = false;\n }\n }\n\n getLastTranscript() {\n return this.lastTranscript;\n }\n\n getLastCommand() {\n return this.lastCommand;\n }\n\n getLastConfidence() {\n return this.lastConfidence;\n }\n\n // Private handler for the 'start' event\n private _handleStart() {\n console.debug('SpeechRecognizer: Listening started.');\n this.dispatchEvent({type: 'start'});\n if (this.playActivationSounds) {\n this.soundSynthesizer.playPresetTone('ACTIVATE');\n }\n }\n\n // Private handler for the 'result' event\n private _handleResult(event: SpeechRecognitionEvent) {\n let interimTranscript = '';\n let finalTranscript = '';\n let currentConfidence = 0;\n\n for (let i = event.resultIndex; i < event.results.length; ++i) {\n const result = event.results[i];\n const transcript = result[0].transcript;\n if (result.isFinal) {\n finalTranscript += transcript;\n currentConfidence = result[0].confidence;\n } else {\n interimTranscript += transcript;\n }\n }\n\n this.lastTranscript = finalTranscript.trim() || interimTranscript.trim();\n this.lastConfidence = currentConfidence;\n this.lastCommand = undefined;\n\n if (finalTranscript && this.options.commands.length > 0) {\n const upperTranscript = finalTranscript.trim().toUpperCase();\n for (const command of this.options.commands) {\n if (upperTranscript.includes(command.toUpperCase()) &&\n this.lastConfidence >= this.options.commandConfidenceThreshold) {\n this.lastCommand = command;\n console.debug(\n `SpeechRecognizer Detected Command: ${this.lastCommand}`);\n break;\n }\n }\n }\n\n // Dispatch a 'result' event with all the relevant data\n this.dispatchEvent({\n type: 'result',\n originalEvent: event,\n transcript: this.lastTranscript,\n confidence: this.lastConfidence,\n command: this.lastCommand,\n isFinal: !!finalTranscript\n });\n }\n\n // Private handler for the 'end' event (e.g., when silence is detected)\n _handleEnd() {\n this.isListening = false;\n this.dispatchEvent({type: 'end'});\n\n if (this.options.continuous && this.error !== 'aborted' &&\n this.error !== 'no-speech') {\n console.debug('SpeechRecognizer: Restarting continuous listening...');\n setTimeout(() => this.start(), 100);\n } else if (this.playActivationSounds) {\n this.soundSynthesizer.playPresetTone('DEACTIVATE');\n }\n }\n\n // Private handler for the 'error' event\n _handleError(event: SpeechRecognitionErrorEvent) {\n console.error('SpeechRecognizer: Error:', event.error);\n this.error = event.error;\n this.isListening = false;\n this.dispatchEvent({type: 'error', error: event.error});\n }\n\n destroy() {\n this.stop();\n if (this.recognition) {\n this.recognition.onstart = null;\n this.recognition.onresult = null;\n this.recognition.onend = null;\n this.recognition.onerror = null;\n this.recognition = undefined;\n }\n }\n}\n","import * as THREE from 'three';\n\nimport {Script} from '../core/Script.js';\n\nimport {CategoryVolumes} from './CategoryVolumes.js';\nimport {SoundOptions, SpeechSynthesizerOptions} from './SoundOptions.js';\n\nexport class SpeechSynthesizer extends Script {\n static dependencies = {soundOptions: SoundOptions};\n\n private synth = window.speechSynthesis;\n private voices: SpeechSynthesisVoice[] = [];\n private selectedVoice?: SpeechSynthesisVoice;\n private isSpeaking = false;\n private debug = false;\n private specificVolume = 1.0;\n private speechCategory = 'speech';\n private options!: SpeechSynthesizerOptions;\n\n constructor(\n private categoryVolumes: CategoryVolumes,\n private onStartCallback = () => {}, private onEndCallback = () => {},\n private onErrorCallback = (_: Error) => {}) {\n super();\n\n if (!this.synth) {\n console.error('SpeechSynthesizer: Speech Synthesis API not supported.');\n } else {\n this.loadVoices();\n if (this.synth.onvoiceschanged !== undefined) {\n this.synth.onvoiceschanged = this.loadVoices.bind(this);\n }\n }\n if (!this.categoryVolumes && this.synth) {\n console.warn(\n 'SpeechSynthesizer: CategoryVolumes not found. Volume control will use specificVolume only.');\n }\n }\n\n init({soundOptions}: {soundOptions: SoundOptions}) {\n this.options = soundOptions.speechSynthesizer;\n if (this.debug) {\n console.log('SpeechSynthesizer initialized.');\n }\n }\n\n loadVoices() {\n if (!this.synth) return;\n this.voices = this.synth.getVoices();\n if (this.debug) {\n console.log('SpeechSynthesizer: Voices loaded:', this.voices.length);\n }\n this.selectedVoice = this.voices.find(\n voice => voice.name.includes('Google') &&\n voice.lang.startsWith('en')) ||\n this.voices.find(voice => voice.lang.startsWith('en'));\n if (this.selectedVoice) {\n if (this.debug) {\n console.log(\n 'SpeechSynthesizer: Selected voice:', this.selectedVoice.name);\n }\n } else {\n console.warn('SpeechSynthesizer: No suitable default voice found.');\n }\n }\n\n setVolume(level: number) {\n this.specificVolume = THREE.MathUtils.clamp(level, 0.0, 1.0);\n console.log(\n `SpeechSynthesizer specific volume set to: ${this.specificVolume}`);\n }\n\n speak(text: string, lang = 'en-US', pitch = 1.0, rate = 1.0) {\n return new Promise<void>((resolve, reject) => {\n if (!this.synth) {\n console.warn('SpeechSynthesizer: Cannot speak. API not supported.');\n return reject(new Error('Speech Synthesis API not supported.'));\n }\n\n if (this.isSpeaking) {\n if (this.options.allowInterruptions) {\n console.warn(\n 'SpeechSynthesizer: Already speaking. Interrupting current speech.');\n this.cancel();\n } else {\n const errorMsg =\n 'Already speaking and interruptions are not allowed.';\n console.warn(`SpeechSynthesizer: ${errorMsg}`);\n return reject(new Error(errorMsg));\n }\n }\n\n const utterance = new SpeechSynthesisUtterance(text);\n\n utterance.onstart = () => {\n this.isSpeaking = true;\n console.log('SpeechSynthesizer: Speaking started.');\n if (this.onStartCallback) this.onStartCallback();\n };\n\n utterance.onend = () => {\n this.isSpeaking = false;\n console.log('SpeechSynthesizer: Speaking ended.');\n if (this.onEndCallback) this.onEndCallback();\n resolve();\n };\n\n utterance.onerror = (event) => {\n if (this.options.allowInterruptions &&\n (event.error === 'interrupted' || event.error === 'canceled')) {\n console.warn(`SpeechSynthesizer: Speech utterance interrupted: ${\n event.error}`);\n return;\n }\n\n // For all other errors, reject the promise.\n console.error('SpeechSynthesizer: Error occurred:', event.error);\n this.isSpeaking = false;\n this.onErrorCallback(\n new Error(`Speech synthesis error code ${event.error}`));\n reject(event.error);\n };\n\n // Find a suitable voice if not already selected or if lang changed\n let voice = this.selectedVoice;\n if (!voice || !voice.lang.startsWith(lang.substring(0, 2))) {\n voice = this.voices.find(\n v => v.lang === lang && v.name.includes('Google')) ||\n this.voices.find(\n v => v.lang.startsWith(lang.substring(0, 2)) &&\n v.name.includes('Google')) ||\n this.voices.find(v => v.lang === lang) ||\n this.voices.find(v => v.lang.startsWith(lang.substring(0, 2)));\n }\n\n if (voice) {\n utterance.voice = voice;\n console.log(\n `SpeechSynthesizer: Using voice: ${voice.name} for lang ${lang}`);\n } else {\n utterance.lang = lang;\n console.warn(`SpeechSynthesizer: No specific voice found for lang ${\n lang}. Using browser default.`);\n }\n\n utterance.pitch = THREE.MathUtils.clamp(pitch, 0, 2);\n utterance.rate = THREE.MathUtils.clamp(rate, 0.1, 10);\n\n let effectiveVolume = this.specificVolume;\n if (this.categoryVolumes) {\n effectiveVolume = this.categoryVolumes.getEffectiveVolume(\n this.speechCategory, this.specificVolume);\n } else {\n effectiveVolume = THREE.MathUtils.clamp(this.specificVolume, 0.0, 1.0);\n }\n utterance.volume = effectiveVolume;\n console.log(\n `SpeechSynthesizer: Setting utterance volume to ${effectiveVolume}`);\n\n this.synth.speak(utterance);\n });\n }\n\n tts(text: string, lang?: string, pitch?: number, rate?: number) {\n this.speak(text, lang, pitch, rate);\n }\n\n cancel() {\n if (this.synth && this.synth.speaking) {\n this.synth.cancel();\n this.isSpeaking = false;\n console.log('SpeechSynthesizer: Speech cancelled.');\n }\n }\n\n destroy() {\n this.cancel();\n if (this.synth && this.synth.onvoiceschanged !== undefined) {\n this.synth.onvoiceschanged = null;\n }\n this.voices = [];\n console.log('SpeechSynthesizer destroyed.');\n }\n}\n","import * as THREE from 'three';\n\nimport {Script} from '../core/Script';\n\nimport {AudioListener} from './AudioListener';\nimport {AudioPlayer} from './AudioPlayer';\nimport {BackgroundMusic} from './BackgroundMusic';\nimport {CategoryVolumes, VolumeCategory} from './CategoryVolumes';\nimport {SoundOptions} from './SoundOptions';\nimport {SoundSynthesizer} from './SoundSynthesizer';\nimport {SpatialAudio} from './SpatialAudio';\nimport {SpeechRecognizer} from './SpeechRecognizer';\nimport {SpeechSynthesizer} from './SpeechSynthesizer';\n\nexport class CoreSound extends Script {\n static dependencies = {camera: THREE.Camera, soundOptions: SoundOptions}\n\n categoryVolumes = new CategoryVolumes();\n soundSynthesizer = new SoundSynthesizer();\n listener = new THREE.AudioListener();\n backgroundMusic!: BackgroundMusic;\n spatialAudio!: SpatialAudio\n speechRecognizer?: SpeechRecognizer\n speechSynthesizer?: SpeechSynthesizer\n audioListener!: AudioListener;\n audioPlayer!: AudioPlayer;\n options!: SoundOptions;\n\n init({camera, soundOptions}:\n {camera: THREE.Camera; soundOptions: SoundOptions;}) {\n this.options = soundOptions;\n\n this.backgroundMusic =\n new BackgroundMusic(this.listener, this.categoryVolumes);\n this.spatialAudio = new SpatialAudio(this.listener, this.categoryVolumes);\n this.audioListener = new AudioListener();\n this.audioPlayer = new AudioPlayer();\n\n camera.add(this.listener);\n this.add(this.backgroundMusic);\n this.add(this.spatialAudio);\n this.add(this.audioListener);\n this.add(this.audioPlayer);\n this.add(this.soundSynthesizer);\n\n if (this.options.speechRecognizer.enabled) {\n this.speechRecognizer = new SpeechRecognizer(this.soundSynthesizer);\n this.add(this.speechRecognizer);\n }\n\n if (this.options.speechSynthesizer.enabled) {\n this.speechSynthesizer = new SpeechSynthesizer(this.categoryVolumes);\n this.add(this.speechSynthesizer);\n }\n }\n\n getAudioListener() {\n return this.listener;\n }\n\n setMasterVolume(level: number) {\n this.categoryVolumes.masterVolume = THREE.MathUtils.clamp(level, 0.0, 1.0);\n }\n\n getMasterVolume() {\n return this.categoryVolumes.isMuted ? 0.0 :\n this.categoryVolumes.masterVolume;\n }\n\n setCategoryVolume(category: VolumeCategory, level: number) {\n if (category in this.categoryVolumes.volumes) {\n this.categoryVolumes.volumes[category] =\n THREE.MathUtils.clamp(level, 0.0, 1.0);\n }\n }\n\n getCategoryVolume(category: VolumeCategory) {\n return category in this.categoryVolumes.volumes ?\n this.categoryVolumes.volumes[category] :\n 1.0;\n }\n\n async enableAudio(options: {streamToAI?: boolean;} = {}) {\n const {streamToAI = true} = options;\n if (streamToAI && this.speechRecognizer?.isListening) {\n console.log('Disabling SpeechRecognizer while streaming audio.');\n this.speechRecognizer.stop();\n }\n this.audioListener.setAIStreaming(streamToAI);\n await this.audioListener.startCapture({});\n }\n\n disableAudio() {\n this.audioListener?.stopCapture();\n }\n\n setAIStreaming(enabled: boolean) {\n this.audioListener?.setAIStreaming(enabled);\n }\n\n isAIStreamingEnabled() {\n return this.audioListener?.aiService !== null;\n }\n\n async playAIAudio(base64AudioData: string) {\n await this.audioPlayer.playAudioChunk(base64AudioData);\n }\n\n stopAIAudio() {\n this.audioPlayer?.clearQueue();\n }\n\n isAIAudioPlaying() {\n return this.audioPlayer?.getIsPlaying();\n }\n\n isAudioEnabled() {\n return this.audioListener?.getIsCapturing();\n }\n\n getLatestAudioBuffer() {\n return this.audioListener?.getLatestAudioBuffer();\n }\n\n clearLatestAudioBuffer() {\n this.audioListener?.clearLatestAudioBuffer();\n }\n\n getEffectiveVolume(category: VolumeCategory, specificVolume = 1.0) {\n return this.categoryVolumes.getEffectiveVolume(category, specificVolume);\n }\n\n muteAll() {\n this.categoryVolumes.isMuted = true;\n }\n\n unmuteAll() {\n this.categoryVolumes.isMuted = false;\n }\n\n destroy() {\n this.backgroundMusic?.destroy();\n this.spatialAudio?.destroy();\n this.speechRecognizer?.destroy();\n this.speechSynthesizer?.destroy();\n this.audioListener?.dispose();\n this.audioPlayer?.dispose();\n this.listener?.parent?.remove(this.listener);\n }\n}\n","/**\n * Conversion factor from Density-Independent Pixels (DP) to\n * distance-independent millimeters (DMM).\n */\nexport const DP_TO_DMM = 0.868;\n","import * as THREE from 'three';\n\nimport {VIEW_DEPTH_GAP} from '../../constants';\nimport {Script} from '../../core/Script';\nimport {DP_TO_DMM} from '../constants';\n\nimport type {ViewOptions} from './ViewOptions';\n\n// Temporary variables.\nconst worldScale = new THREE.Vector3();\n\n/**\n * A fundamental UI component for creating interactive user\n * interfaces. It serves as a base class for other UI elements like Panels,\n * Rows, and Columns, providing core layout logic, visibility control, and\n * interaction hooks.\n *\n * Each `View` is a `THREE.Object3D` and inherits lifecycle methods from\n * `Script`.\n */\nexport class View<TEventMap extends THREE.Object3DEventMap =\n THREE.Object3DEventMap> extends\n Script<TEventMap> {\n /** Text description of the view */\n name = 'View';\n /** Flag indicating View behaves as a 2D quad in layout calculations. */\n isQuad = true;\n /** Flag indicating if this is the root view of a layout. */\n isRoot = false;\n /** Type identifier for easy checking with `instanceof`. */\n isView = true;\n /** Determines if this view can be targeted by user input. */\n selectable = true;\n\n // --- Layout Properties ---\n\n /** Proportional size used in layouts like `Row` or `Col`. */\n weight = 0.5;\n /** The width of the view, as a 0-1 ratio of its parent's available space. */\n width = 1;\n /** The height of the view, as a 0-1 ratio of its parent's available space. */\n height = 1;\n /**\n * The local x-coordinate within the parent's layout, from -0.5 to 0.5.\n * For root view (Panel), this will be addition to the global positioning.\n */\n x = 0;\n /**\n * The local y-coordinate within the parent's layout, from -0.5 to 0.5.\n * For root view (Panel), this will be addition to the global positioning.\n */\n y = 0;\n /**\n * The local z-coordinate within the parent's layout.\n * For root view (Panel), this will be addition to the global positioning.\n */\n z = 0;\n /** Horizontal padding, as a 0-1 ratio of the parent's width. */\n paddingX = 0;\n /** Vertical padding, as a 0-1 ratio of the parent's height. */\n paddingY = 0;\n /** Depth padding, for z-axis adjustment to prevent z-fighting. */\n paddingZ = 0;\n\n // --- Visual Properties ---\n\n /** The overall opacity of the view and its children. */\n opacity = 1.0;\n /** The underlying THREE.Mesh if the view has a visible geometry. */\n mesh?: THREE.Mesh;\n /** The calculated aspect ratio (width / height) of this view. */\n aspectRatio = 1.0;\n\n /**\n * Gets the effective horizontal range for child elements, normalized to 1.0\n * for the smaller dimension.\n * @returns The horizontal layout range.\n */\n get rangeX(): number {\n return Math.max(this.aspectRatio, 1.0);\n }\n\n /**\n * Gets the effective vertical range for child elements, normalized to 1.0 for\n * the smaller dimension.\n * @returns The vertical layout range.\n */\n get rangeY(): number {\n return Math.max(1.0 / this.aspectRatio, 1.0);\n }\n\n /**\n * Creates an instance of View.\n * @param options - Configuration options to apply to the view.\n * @param geometry - The geometry for the view's mesh.\n * @param material - The material for the view's mesh.\n */\n constructor(\n options: ViewOptions = {}, geometry?: THREE.BufferGeometry,\n material?: THREE.Material) {\n super();\n if (geometry && material) {\n this.mesh = new THREE.Mesh(geometry, material);\n this.add(this.mesh);\n }\n Object.assign(this, options);\n }\n\n /**\n * Converts a value from Density-Independent Pixels (DP) to meters.\n * @param dp - The value in density-independent pixels.\n * @returns The equivalent value in meters.\n */\n static dpToMeters(dp: number): number {\n return dp * DP_TO_DMM * 0.001;\n }\n\n /**\n * Converts a value from Density-Independent Pixels (DP) to local units.\n * @param dp - The value in density-independent pixels.\n * @returns The equivalent value in local units.\n */\n dpToLocalUnits(dp: number): number {\n this.getWorldScale(worldScale);\n return View.dpToMeters(dp) / worldScale.x;\n }\n\n /** Makes the view and all its descendants visible. */\n show() {\n this.visible = true;\n this.traverse((child) => {\n child.visible = true;\n });\n }\n\n /** Makes the view and all its descendants invisible. */\n hide() {\n this.visible = false;\n this.traverse((child) => {\n child.visible = false;\n });\n }\n\n /**\n * Calculates and applies the position and scale for this single view based on\n * its layout properties and its parent's dimensions.\n */\n updateLayout() {\n if (this.isRoot || this.parent == null) {\n // Root views are centered and scaled directly by their width and height.\n this.aspectRatio = this.width / this.height;\n this.scale.setScalar(Math.min(this.width, this.height));\n } else if (this.parent instanceof View) {\n // Child views are positioned relative to their parent with padding.\n // A small depth gap is added to prevent z-fighting between UI layers.\n this.position.set(\n (this.x + this.paddingX) * this.parent.rangeX,\n (this.y - this.paddingY) * this.parent.rangeY,\n this.paddingZ + VIEW_DEPTH_GAP);\n this.aspectRatio = (this.width / this.height) * this.parent.aspectRatio;\n this.scale.setScalar(Math.min(\n this.parent.rangeX * this.width, this.parent.rangeY * this.height));\n\n // Increment renderOrder to ensure children render on top of parents,\n // which is crucial for transparency.\n this.renderOrder = this.parent.renderOrder + 1;\n }\n }\n\n /** Triggers a layout update for this view and all its descendants. */\n updateLayouts() {\n this.updateLayoutsBFS();\n }\n\n /**\n * Performs a Breadth-First Search (BFS) traversal to update the layout tree,\n * ensuring parent layouts are calculated before their children.\n */\n updateLayoutsBFS() {\n const queue: THREE.Object3D[] = [this];\n while (queue.length > 0) {\n const currentView = queue.shift();\n if (currentView instanceof View) {\n currentView.updateLayout();\n currentView.children.forEach((childView) => {\n queue.push(childView);\n });\n }\n }\n }\n\n /**\n * Resets the layout state of this view. Intended for override by subclasses.\n */\n resetLayout() {}\n\n /** Resets the layout state for this view and all its descendants. */\n resetLayouts() {\n const queue: THREE.Object3D[] = [this];\n while (queue.length > 0) {\n const currentView = queue.shift();\n if (currentView instanceof View) {\n currentView.resetLayout();\n currentView.children.forEach((childView) => {\n queue.push(childView);\n });\n }\n }\n }\n\n /**\n * Overrides `THREE.Object3D.add` to automatically trigger a layout update\n * when a new `View` is added as a child.\n */\n add(...children: THREE.Object3D[]) {\n super.add(...children);\n for (const child of children) {\n if (child instanceof View) {\n child.updateLayoutsBFS();\n }\n }\n return this;\n }\n\n /**\n * Hook called on a complete select action (e.g., a click) when this view is\n * the target. Intended for override by subclasses.\n * @param _id - The ID of the controller that triggered the action.\n */\n onTriggered(_id: number) {}\n}\n","export const FONT_FAMILIES = {\n Roboto: 'https://fonts.gstatic.com/s/roboto/v18/KFOmCnqEu92Fr1Mu4mxM.woff',\n 'Noto Sans':\n 'https://fonts.gstatic.com/s/notosans/v7/o-0IIpQlx3QUlC5A4PNr5TRG.woff',\n Comfortaa:\n 'https://fonts.gstatic.com/s/comfortaa/v12/1Ptsg8LJRfWJmhDAuUs4TYFs.woff',\n Cookie: 'https://fonts.gstatic.com/s/cookie/v8/syky-y18lb0tSbf9kgqU.woff',\n Philosopher:\n 'https://fonts.gstatic.com/s/philosopher/v9/vEFV2_5QCwIS4_Dhez5jcWBuT0s.woff',\n Quicksand:\n 'https://fonts.gstatic.com/s/quicksand/v7/6xKtdSZaM9iE8KbpRA_hK1QL.woff',\n Trirong: 'https://fonts.gstatic.com/s/trirong/v3/7r3GqXNgp8wxdOdOn4so3g.woff',\n Trocchi: 'https://fonts.gstatic.com/s/trocchi/v6/qWcqB6WkuIDxDZLcPrxeuw.woff',\n 'Advent Pro':\n 'https://fonts.gstatic.com/s/adventpro/v7/V8mAoQfxVT4Dvddr_yOwhTqtLg.woff',\n 'Henny Penny':\n 'https://fonts.gstatic.com/s/hennypenny/v5/wXKvE3UZookzsxz_kjGSfPQtvXQ.woff',\n Orbitron:\n 'https://fonts.gstatic.com/s/orbitron/v9/yMJRMIlzdpvBhQQL_Qq7dys.woff',\n Sacramento:\n 'https://fonts.gstatic.com/s/sacramento/v5/buEzpo6gcdjy0EiZMBUG4C0f-w.woff',\n 'Snowburst One':\n 'https://fonts.gstatic.com/s/snowburstone/v5/MQpS-WezKdujBsXY3B7I-UT7SZieOA.woff',\n Syncopate:\n 'https://fonts.gstatic.com/s/syncopate/v9/pe0sMIuPIYBCpEV5eFdCBfe5.woff',\n Wallpoet:\n 'https://fonts.gstatic.com/s/wallpoet/v9/f0X10em2_8RnXVVdUObp58I.woff',\n 'Sirin Stencil':\n 'https://fonts.gstatic.com/s/sirinstencil/v6/mem4YaWwznmLx-lzGfN7MdRyRc9MAQ.woff',\n 'Roboto Slab':\n 'https://cdn.jsdelivr.net/gh/google/fonts@3b179b729ac3306ab2a249d848d94ff08b90a0af/apache/robotoslab/static/RobotoSlab-Black.ttf'\n};\n\nexport const MATERIAL_ICONS_FONT_FILE =\n 'https://cdn.jsdelivr.net/gh/marella/material-icons@v1.13.14/iconfont/material-icons.woff';","import * as THREE from 'three';\nimport type TroikaThreeText from 'troika-three-text';\n\nimport {getColorHex} from '../../utils/utils';\nimport {View} from '../core/View';\nimport {ViewOptions} from '../core/ViewOptions';\n\nimport {FONT_FAMILIES} from './utils/FontFamilies';\n\n\n// --- Dynamic Import of Troika Three Text and its dependencies ---\n\n/** Enum for the status of the Troika dynamic import. */\nenum TroikaImportStatus {\n PENDING = 0,\n SUCCESS = 1,\n FAILED = 2,\n}\n\n// --- Troika Dependency Management ---\nlet Text: typeof TroikaThreeText.Text;\nlet troikaImportStatus = TroikaImportStatus.PENDING;\nlet troikaImportError: Error|undefined;\n\nasync function importTroika() {\n if (Text) return true;\n try {\n const troikaModule = await import('troika-three-text');\n Text = troikaModule.Text;\n troikaImportStatus = TroikaImportStatus.SUCCESS;\n return true;\n } catch (error: unknown) {\n if (error instanceof Error) {\n troikaImportError = error;\n }\n troikaImportStatus = TroikaImportStatus.FAILED;\n return false;\n }\n};\n\ninterface TextViewEventMap extends THREE.Object3DEventMap {\n synccomplete: object;\n}\n\nexport type TextViewOptions = ViewOptions&{\n useSDFText?: boolean;\n font?: string;\n fontSize?: number;\n /**\n * Font size in dp. This will be scale up so it's a consistent size in world\n * coordinates.\n */\n fontSizeDp?: number;\n fontColor?: string|number;\n maxWidth?: number;\n mode?: 'fitWidth'|'center';\n anchorX?: number|'left'|'center'|'right'|`${number}%`;\n anchorY?: number|'top'|'top-baseline'|'top-cap'|'top-ex'|'middle'|\n 'bottom-baseline'|'bottom'|`${number}%`;\n textAlign?: 'left'|'center'|'right';\n imageOverlay?: string;\n imageOffsetX?: number;\n imageOffsetY?: number;\n text?: string;\n};\n\n/**\n * A view for displaying text in 3D. It features a dual-rendering\n * system:\n * 1. **SDF Text (Default):** Uses `troika-three-text` to render crisp,\n * high-quality text using Signed Distance Fields. This is ideal for most\n * use cases. The library is loaded dynamically on demand.\n * 2. **HTML Canvas Fallback:** If `troika-three-text` fails to load or is\n * disabled via `useSDFText: false`, it renders text to an HTML canvas and\n * applies it as a texture to a plane.\n */\nexport class TextView extends View<TextViewEventMap> {\n /** Determines which rendering backend to use. Defaults to SDF text. */\n useSDFText = true;\n /** TextView resides in a panel by default. */\n isRoot = false;\n /** Default description of this view in Three.js DevTools. */\n name = 'TextView';\n\n /** The underlying renderable object (either a Troika Text or a Plane. */\n textObj?: TroikaThreeText.Text|THREE.Mesh;\n /** The font file to use. Defaults to Roboto. */\n font = FONT_FAMILIES.Roboto;\n /** The size of the font in world units. */\n fontSize?: number;\n fontSizeDp?: number;\n /** The color of the font. */\n fontColor: string|number = 0xFFFFFF;\n /**\n * The maximum width the text can occupy before wrapping.\n * To fit a long TextView within a container, this value should be its\n * container's height / width to avoid it getting rendered outside.\n */\n maxWidth = 1.0;\n /** Layout mode. 'fitWidth' scales text to fit the view's width. */\n mode = 'fitWidth';\n /** Horizontal anchor point ('left', 'center', 'right'). */\n anchorX: number|'left'|'center'|'right'|`${number}%` = 'center';\n /** Vertical anchor point ('top', 'middle', 'bottom'). */\n anchorY: number|'top'|'top-baseline'|'top-cap'|'top-ex'|'middle'|\n 'bottom-baseline'|'bottom'|`${number}%` = 'middle';\n /** Horizontal alignment ('left', 'center', 'right'). */\n textAlign = 'center';\n /** An optional image URL to use as an overlay texture on the text. */\n imageOverlay?: string;\n /** The horizontal offset for the `imageOverlay` texture. */\n imageOffsetX = 0;\n /** The vertical offset for the `imageOverlay` texture. */\n imageOffsetY = 0;\n\n /** Relative local offset in X. */\n x = 0;\n /** Relative local offset in Y. */\n y = 0;\n /** Relative local width. */\n width = 1;\n /** Relative local height. */\n height = 1;\n\n /** Fallback HTML canvas to render legacy text. */\n canvas?: HTMLCanvasElement;\n /** Fallback HTML canvas context to render legacy text. */\n ctx?: CanvasRenderingContext2D;\n /** The calculated height of a single line of text. */\n lineHeight = 0;\n /** The total number of lines after text wrapping. */\n lineCount = 0;\n\n private _initializeTextCalled = false;\n private _text = 'TextView';\n set text(text) {\n this._text = text;\n if (this.useSDFText && Text && this.textObj instanceof Text) {\n this.textObj.text = text;\n this.textObj.sync();\n } else {\n this.updateHTMLText();\n }\n }\n\n get text() {\n return this._text;\n }\n\n /**\n * TextView can render text using either Troika SDF text or HTML canvas.\n * @param options - Configuration options for the TextView.\n * @param geometry - Optional geometry for the view's background mesh.\n * @param material - Optional material for the view's background mesh.\n */\n constructor(\n options: TextViewOptions = {}, geometry?: THREE.BufferGeometry,\n material?: THREE.Material) {\n super(options, geometry, material);\n\n this.useSDFText = options.useSDFText ?? this.useSDFText;\n this.font = options.font ?? this.font;\n this.fontSize = options.fontSize ?? this.fontSize;\n this.fontSizeDp = options.fontSizeDp ?? this.fontSizeDp;\n this.fontColor = options.fontColor ?? this.fontColor;\n this.maxWidth = options.maxWidth ?? this.maxWidth;\n\n this.mode = options.mode ?? this.mode;\n this.anchorX = options.anchorX ?? this.anchorX;\n this.anchorY = options.anchorY ?? this.anchorY;\n this.textAlign = options.textAlign ?? this.textAlign;\n this.imageOverlay = options.imageOverlay ?? this.imageOverlay;\n this.imageOffsetX = options.imageOffsetX ?? this.imageOffsetX;\n this.imageOffsetY = options.imageOffsetY ?? this.imageOffsetY;\n this.text = options.text ?? this._text;\n }\n\n /**\n * Initializes the TextView. It waits for the Troika module to be imported\n * and then creates the text object, sets up aspect ratio, and loads overlays.\n */\n override async init(_?: object) {\n this.useSDFText = this.useSDFText && await importTroika();\n this._initializeText();\n }\n\n /**\n * Sets the text content of the view.\n * @param text - The text to be displayed.\n */\n setText(text: string) {\n this.text = text;\n }\n\n /**\n * Updates the layout of the text object, such as its render order.\n */\n override updateLayout() {\n super.updateLayout();\n if (this.textObj) {\n this.textObj.renderOrder = this.renderOrder;\n if (this.fontSizeDp === undefined) {\n switch (this.mode) {\n case 'fitWidth':\n this.textObj.scale.setScalar(this.rangeX);\n break;\n }\n }\n }\n if (this.fontSizeDp && this.textObj) {\n this.createTextSDF();\n }\n }\n\n /**\n * Creates the text object using Troika Three Text for SDF rendering.\n * This method should only be called from _initializeText() when `useSDFText`\n * is true and the `troika-three-text` module has been successfully imported.\n */\n protected createTextSDF() {\n const obj =\n Text && this.textObj instanceof Text ? this.textObj : new Text();\n obj.text = this.text;\n obj.color = getColorHex(this.fontColor);\n obj.font = this.font;\n obj.anchorX = this.anchorX;\n obj.anchorY = this.anchorY;\n if (this.fontSizeDp !== undefined) {\n obj.fontSize = this.dpToLocalUnits(this.fontSizeDp);\n } else if (this.fontSize !== undefined) {\n obj.fontSize = this.fontSize;\n } else {\n obj.fontSize = 0.06;\n }\n obj.maxWidth = this.maxWidth;\n obj.textAlign = this.textAlign;\n // Transparent objects should not write to depth.\n if (obj.material) {\n obj.material.depthWrite = !obj.material.transparent;\n }\n obj.sync();\n\n this.textObj = obj;\n this.textObj.layers.mask = this.layers.mask;\n this.add(this.textObj);\n }\n\n /**\n * Creates a text object using an HTML canvas as a texture on a THREE.Plane.\n * This serves as a fallback when Troika is not available or `useSDFText` is\n * false. This method should only be called from _initializeText().\n */\n private createTextHTML() {\n this.canvas = document.createElement('canvas');\n this.ctx = this.canvas.getContext('2d')!;\n const planeGeometry = new THREE.PlaneGeometry(this.width, this.height);\n const texture = new THREE.CanvasTexture(this.canvas);\n const planeMaterial = new THREE.MeshBasicMaterial({\n map: texture,\n transparent: true,\n });\n\n this.textObj = new THREE.Mesh(planeGeometry, planeMaterial);\n this.updateHTMLText();\n this.add(this.textObj);\n }\n\n /**\n * Updates the content of the HTML canvas when not using SDF text.\n * It clears the canvas and redraws the text with the current properties.\n */\n private updateHTMLText() {\n if (!this.ctx) return;\n const {canvas, ctx} = this;\n // A higher resolution gives sharper text.\n const resolution = 256;\n canvas!.width = this.width * resolution;\n canvas!.height = this.height * resolution;\n\n ctx.clearRect(0, 0, canvas!.width, canvas!.height);\n const fontSize = this.fontSizeDp !== undefined ?\n this.dpToLocalUnits(this.fontSizeDp) :\n this.fontSize ?? 0.06;\n ctx.font = `${fontSize * resolution}px ${this.font}`;\n ctx.fillStyle =\n `#${getColorHex(this.fontColor).toString(16).padStart(6, '0')}`;\n ctx.textAlign = 'center';\n ctx.textBaseline = 'middle';\n // TODO: add line-break for canvas-based text.\n ctx.fillText(this.text, canvas!.width / 2, canvas!.height / 2);\n\n if (this.textObj?.material.map) {\n this.textObj.material.map.needsUpdate = true;\n }\n }\n\n /**\n * Callback executed when Troika's text sync is complete.\n * It captures layout data like total height and line count.\n */\n onSyncComplete() {\n if (!this.useSDFText || !(this.textObj instanceof Text) ||\n !this.textObj.textRenderInfo) {\n return;\n }\n const caretPositions = this.textObj.textRenderInfo.caretPositions;\n const numberOfChars = caretPositions.length / 4;\n let lineCount = 0;\n const firstBottom = numberOfChars > 0 ? caretPositions[0] : 0;\n let lastBottom = 999999;\n for (let i = 0; i < numberOfChars; i++) {\n const bottom = caretPositions[i * 4 + 2];\n const top = caretPositions[i * 4 + 3];\n const lineHeight = top - bottom;\n if (bottom < lastBottom - lineHeight / 2) {\n lineCount++;\n lastBottom = bottom;\n }\n }\n this.lineHeight =\n numberOfChars > 0 ? (firstBottom - lastBottom) / lineCount : 0;\n this.lineCount = lineCount;\n this.dispatchEvent({type: 'synccomplete'});\n }\n\n /**\n * Private method to perform the actual initialization after the async\n * import has resolved.\n */\n protected _initializeText() {\n if (this._initializeTextCalled) return;\n this._initializeTextCalled = true;\n // Decide whether to use SDF text or fallback to HTML canvas.\n if (this.useSDFText && troikaImportStatus === TroikaImportStatus.SUCCESS) {\n this.createTextSDF();\n } else {\n // If the import failed, log a warning.\n if (troikaImportStatus === TroikaImportStatus.FAILED) {\n console.warn(\n 'Failed to import `troika-three-text`. For 3D text rendering, please ensure `troika-three-text`, `troika-three-utils`, `troika-worker-utils`, `bidi-js`, and `webgl-sdf-generator` are included in your importmap or installed via npm. Refer to templates/1_ui for an example. Falling back to HTML-based text rendering.',\n 'Error details:', troikaImportError?.message);\n // Clear the error so we don't log it repeatedly.\n troikaImportError = undefined;\n }\n this.createTextHTML();\n }\n\n // Applies settings that require the textObj to exist.\n if (this.useSDFText && Text && this.textObj instanceof Text) {\n this.textObj.addEventListener(\n // @ts-expect-error Missing type in Troika\n 'synccomplete', this.onSyncComplete.bind(this));\n\n if (this.imageOverlay) {\n (new THREE.TextureLoader()).load(this.imageOverlay, (texture) => {\n texture.colorSpace = THREE.SRGBColorSpace;\n texture.offset.x = this.imageOffsetX;\n const textObj = this.textObj as unknown as TroikaThreeText.Text;\n textObj.material.map = texture;\n textObj.material.needsUpdate = true;\n textObj.sync();\n });\n }\n }\n this.updateLayout();\n }\n\n protected syncTextObj() {\n if (Text && this.textObj instanceof Text) {\n this.textObj.sync();\n }\n }\n\n protected setTextColor(color: number) {\n if (Text && this.textObj instanceof Text) {\n this.textObj.color = color;\n }\n }\n\n /**\n * Disposes of resources used by the TextView, such as event listeners.\n */\n override dispose() {\n if (this.useSDFText && this.textObj && Text &&\n this.textObj instanceof Text) {\n this.textObj.removeEventListener(\n // @ts-expect-error Missing type in Troika\n 'synccomplete', this.onSyncComplete.bind(this));\n }\n super.dispose();\n }\n}\n","import * as THREE from 'three';\n\nimport {VIEW_DEPTH_GAP} from '../../constants';\nimport {TextView, TextViewOptions} from '../components/TextView';\n\nimport {MATERIAL_ICONS_FONT_FILE} from './utils/FontFamilies';\n\n/**\n * An interactive circular button that displays a single character\n * icon from the Material Icons font library. It provides visual feedback for\n * hover and selection states by changing its background opacity.\n */\nexport type IconButtonOptions = TextViewOptions&{\n backgroundColor?: THREE.ColorRepresentation;\n defaultOpacity?: number;\n hoverColor?: number;\n hoverOpacity?: number;\n selectedOpacity?: number;\n opacity?: number;\n};\n\nexport class IconButton extends TextView {\n /** The overall opacity when the button is not being interacted with. */\n opacity = 1.0;\n /** The background opacity when the button is not being interacted with. */\n defaultOpacity = 0.0;\n /** The background color when a reticle hovers over the button. */\n hoverColor = 0xaaaaaa;\n /** The background opacity when a reticle hovers over the button. */\n hoverOpacity = 0.2;\n /** The background opacity when the button is actively being pressed. */\n selectedOpacity = 0.4;\n\n /** The icon font file to use. Defaults to Material Icons. */\n font = MATERIAL_ICONS_FONT_FILE;\n /** The underlying mesh for the button's background. */\n mesh!: THREE.Mesh<THREE.PlaneGeometry, THREE.MeshBasicMaterial>;\n\n /**\n * Overrides the parent `rangeX` to ensure the circular shape is not affected\n * by panel aspect ratio.\n */\n get rangeX() {\n return 1;\n }\n\n /**\n * Overrides the parent `rangeY` to ensure the circular shape is not affected\n * by panel aspect ratio.\n */\n get rangeY() {\n return 1;\n }\n\n /**\n * An interactive button that displays a single character icon from a font\n * file. Inherits from TextView to handle text rendering.\n * @param options - The options for the IconButton.\n */\n constructor(options: IconButtonOptions = {}) {\n const {backgroundColor = 0xaaaaaa} = options;\n\n const radius = 0.5;\n const segments = 32;\n const geometry = new THREE.CircleGeometry(radius, segments);\n const material = new THREE.MeshBasicMaterial({\n color: backgroundColor,\n transparent: true,\n depthWrite: false,\n opacity: 0, // Start with zero opacity, will be controlled by interaction\n // logic\n side: THREE.FrontSide\n });\n\n // Pass geometry and material to the TextView -> View chain.\n super(options, geometry, material);\n\n // Applies all provided options to this instance.\n Object.assign(this, options);\n }\n\n /**\n * Handles behavior when the cursor hovers over the button.\n * @override\n */\n onHoverOver() {\n if (!this.ux) return;\n this.update(); // Consolidate logic in update()\n }\n\n /**\n * Handles behavior when the cursor moves off the button.\n * @override\n */\n onHoverOut() {\n if (!this.ux) return;\n this.update(); // Consolidate logic in update()\n }\n\n /**\n * Updates the button's visual state based on hover and selection status.\n */\n update() {\n if (!this.ux) return;\n if (this.ux.isHovered() || this.ux.isSelected()) {\n this.mesh!.material.opacity = this.ux.isSelected() ?\n this.selectedOpacity * this.opacity :\n this.hoverOpacity * this.opacity;\n } else {\n this.mesh!.material.opacity = this.defaultOpacity * this.opacity;\n }\n }\n\n /**\n * Overrides the parent's private initialization method. This is called by the\n * parent's `init()` method after the Troika module is confirmed to be loaded.\n */\n protected override _initializeText() {\n // First, run the parent's initialization to ensure this.textObj is created.\n super._initializeText();\n\n // Now that this.textObj is guaranteed to exist, run IconButton-specific\n // logic.\n if (this.textObj) {\n this.textObj.position.set(0, 0, VIEW_DEPTH_GAP);\n\n // Disable raycasting on the text part of the object so it doesn't\n // interfere with the main button geometry's interaction.\n this.textObj.raycast = () => {};\n\n // Run initial state update\n this.update();\n\n switch (this.mode) {\n case 'center':\n this.textObj.scale.setScalar(this.rangeX);\n break;\n }\n this.textObj.scale.set(1, 1, 1);\n }\n\n this.syncTextObj();\n\n // The parent _initializeText already calls updateLayout, so this is not\n // strictly necessary, but kept for clarity.\n this.updateLayout();\n }\n}\n","import {TextView, TextViewOptions} from '../components/TextView.js';\n\nimport {MATERIAL_ICONS_FONT_FILE} from './utils/FontFamilies';\n\n/**\n * A specialized `TextView` component designed for conveniently\n * displaying icons from the Google Material Icons font library.\n *\n * This class simplifies the process of creating an icon by pre-configuring the\n * `font` property. To use it, you provide the codepoint or ligature for the\n * desired icon in the `text` option.\n *\n * @example\n * ```typescript\n * // Creates a 'home' icon.\n * const homeIcon = new IconView({ text: 'home', fontSize: 0.1 });\n * ```\n */\nexport type IconViewOptions = TextViewOptions;\n\nexport class IconView extends TextView {\n constructor(options: IconViewOptions = {}) {\n super({font: MATERIAL_ICONS_FONT_FILE, ...options});\n }\n};\n","import * as THREE from 'three';\n\nimport {View} from '../core/View';\nimport {ViewOptions} from '../core/ViewOptions';\n\n/**\n * A UI component for displaying a 2D image on a panel in XR.\n * It automatically handles loading the image and scaling it to fit within its\n * layout bounds while preserving the original aspect ratio.\n */\nexport type ImageViewOptions = ViewOptions&{\n src?: string;\n};\n\nexport class ImageView extends View {\n /** The URL of the image file to be displayed. */\n src?: string;\n /** The material applied to the image plane. */\n material: THREE.MeshBasicMaterial;\n /** The mesh that renders the image. */\n mesh: THREE.Mesh<THREE.PlaneGeometry, THREE.MeshBasicMaterial>;\n\n private texture?: THREE.Texture;\n private initCalled = false;\n private textureLoader = new THREE.TextureLoader();\n\n /**\n * @param options - Configuration options. Can include properties like\n * `src`, `width`, `height`, and other properties from the base `View` class.\n */\n constructor(options: ImageViewOptions = {}) {\n super(options);\n\n const material = new THREE.MeshBasicMaterial({\n map: null, // Texture will be loaded and assigned in reload()\n transparent: true,\n depthWrite: false,\n side: THREE.DoubleSide,\n });\n\n const geometry = new THREE.PlaneGeometry(1, 1);\n this.mesh = new THREE.Mesh(geometry, material);\n this.material = material;\n this.add(this.mesh);\n }\n\n /**\n * Initializes the component. Called once by the XR Blocks lifecycle.\n */\n init() {\n if (this.initCalled) return;\n this.initCalled = true;\n this.reload();\n }\n\n /**\n * Reloads the image from the `src` URL. If a texture already exists, it is\n * properly disposed of before loading the new one.\n */\n reload() {\n if (!this.src) {\n // If no source, ensure no texture is displayed.\n if (this.material.map) {\n this.material.map = null;\n this.material.needsUpdate = true;\n }\n this.texture?.dispose();\n this.texture = undefined;\n return;\n }\n\n this.texture?.dispose();\n this.texture = this.textureLoader.load(this.src, (loadedTexture) => {\n loadedTexture.colorSpace = THREE.SRGBColorSpace;\n this.material.map = loadedTexture;\n this.material.needsUpdate = true;\n // Updates layout after the image has loaded to get correct dimensions.\n this.updateLayout();\n });\n }\n\n /**\n * Updates the layout of the view and then adjusts the mesh scale to maintain\n * the image's aspect ratio.\n * @override\n */\n updateLayout() {\n super.updateLayout();\n if (this.mesh) {\n this.mesh.renderOrder = this.renderOrder;\n }\n this.scaleImageToCorrectAspectRatio();\n }\n\n /**\n * Calculates the correct scale for the image plane to fit within the view's\n * bounds without distortion.\n */\n scaleImageToCorrectAspectRatio() {\n if (this.texture?.image) {\n const {image} = this.texture;\n const textureWidth = image.width;\n const textureHeight = image.height;\n\n // Determines the scaling factor to fit the image within the view's range.\n const widthScaleFactor = this.rangeX / textureWidth;\n const heightScaleFactor = this.rangeY / textureHeight;\n const minScaleFactor = Math.min(widthScaleFactor, heightScaleFactor);\n\n // Applies the calculated scale to the mesh.\n this.mesh.scale.set(\n textureWidth * minScaleFactor, textureHeight * minScaleFactor, 1);\n }\n }\n\n /**\n * Sets a new image source and reloads it.\n * @param src - The URL of the new image to load.\n */\n load(src: string) {\n this.src = src;\n this.reload();\n }\n}\n","import {UI_OVERLAY_LAYER} from '../../constants';\n\nimport {TextView, TextViewOptions} from './TextView';\n\n/**\n * Identical to text view except sets this.layer to UI_OVERLAY_LAYER.\n */\nexport type LabelViewOptions = TextViewOptions;\n\nexport class LabelView extends TextView {\n constructor(options: LabelViewOptions = {}) {\n super(options);\n this.layers.set(UI_OVERLAY_LAYER);\n }\n\n protected override createTextSDF() {\n super.createTextSDF();\n this.textObj!.material.depthText = false;\n this.textObj!.material.depthWrite = false;\n }\n}\n","import * as THREE from 'three';\n\n/**\n * Shader for the non-interactive Panel background.\n *\n * This shader renders a simple, anti-aliased rounded rectangle (squircle). It\n * can display either a solid background color or a texture map. It is more\n * performant than the SpatialPanelShader as it omits all interactive highlight\n * calculations.\n */\nexport const SquircleShader = {\n uniforms: {\n 'uMainTex': {value: null},\n 'uUseImage': {value: 0.0},\n 'uBackgroundColor': {\n value: new THREE.Vector4(0.4, 0.8, 1.0, 1.0),\n },\n 'uBoxSize': {value: new THREE.Vector2(0.5, 0.5)},\n 'uRadius': {value: 0.05},\n 'uOpacity': {value: 1.0}\n },\n\n vertexShader: /* glsl */ `\n #define USE_UV\n #include <common>\n #include <batching_pars_vertex>\n #include <uv_pars_vertex>\n #include <envmap_pars_vertex>\n #include <color_pars_vertex>\n #include <fog_pars_vertex>\n #include <morphtarget_pars_vertex>\n #include <skinning_pars_vertex>\n #include <logdepthbuf_pars_vertex>\n #include <clipping_planes_pars_vertex>\n\n void main() {\n #include <uv_vertex>\n #include <color_vertex>\n #include <morphinstance_vertex>\n #include <morphcolor_vertex>\n #include <batching_vertex>\n\n #if defined ( USE_ENVMAP ) || defined ( USE_SKINNING )\n\n #include <beginnormal_vertex>\n #include <morphnormal_vertex>\n #include <skinbase_vertex>\n #include <skinnormal_vertex>\n #include <defaultnormal_vertex>\n\n #endif\n\n #include <begin_vertex>\n #include <morphtarget_vertex>\n #include <skinning_vertex>\n #include <project_vertex>\n #include <logdepthbuf_vertex>\n #include <clipping_planes_vertex>\n\n #include <worldpos_vertex>\n #include <envmap_vertex>\n #include <fog_vertex>\n }\n `,\n\n fragmentShader: /* glsl */ `\n precision mediump float;\n\n uniform sampler2D uMainTex;\n uniform vec4 uBackgroundColor;\n uniform vec2 uBoxSize;\n uniform float uRadius;\n uniform float uUseImage;\n uniform float uOpacity;\n\n #define USE_UV\n #include <common>\n #include <dithering_pars_fragment>\n #include <color_pars_fragment>\n #include <uv_pars_fragment>\n #include <map_pars_fragment>\n #include <alphamap_pars_fragment>\n #include <alphatest_pars_fragment>\n #include <alphahash_pars_fragment>\n #include <aomap_pars_fragment>\n #include <lightmap_pars_fragment>\n #include <envmap_common_pars_fragment>\n #include <envmap_pars_fragment>\n #include <fog_pars_fragment>\n #include <specularmap_pars_fragment>\n #include <logdepthbuf_pars_fragment>\n #include <clipping_planes_pars_fragment>\n\n // Distance function for rounded box.\n float distRoundBox(vec2 p, vec2 b, float r) {\n return length(max(abs(p) - b + r, 0.0)) - r;\n }\n\n void main(void) {\n #include <clipping_planes_fragment>\n\n #include <logdepthbuf_fragment>\n #include <map_fragment>\n #include <color_fragment>\n #include <alphamap_fragment>\n #include <alphatest_fragment>\n #include <alphahash_fragment>\n #include <specularmap_fragment>\n vec2 size = uBoxSize * 1000.0;\n\n // Calculates the adjusted radius based on box size.\n float radius = min(size.x, size.y) * (0.05 + uRadius);\n vec2 half_size = 0.5 * size;\n\n // Compute the distance from the rounded box edge.\n float dist = distRoundBox(vUv * size - half_size, half_size, radius);\n\n // Use lerp for smooth color transition based on distance.\n vec4 colorInside = uBackgroundColor;\n\n if (uUseImage > 0.5) {\n colorInside = texture2D(uMainTex, vUv);\n colorInside.a = 1.0;\n }\n\n // Transparent black for outside.\n vec4 colorOutside = vec4(0.0, 0.0, 0.0, 0.0);\n\n vec4 finalColor = mix(colorInside, colorOutside, smoothstep(0.0, 1.0, dist));\n\n // Return premultiplied alpha.\n gl_FragColor = uOpacity * finalColor.a * vec4(finalColor.rgb, 1.0);\n }\n `\n};\n","import * as THREE from 'three';\n\nimport {VIEW_DEPTH_GAP} from '../../constants';\nimport {getVec4ByColorString} from '../../utils/utils';\nimport {TextView, TextViewOptions} from '../components/TextView';\nimport {SquircleShader} from '../shaders/SquircleShader';\n\n/**\n * An interactive button with a rounded rectangle background and a\n * text label. It provides visual feedback for hover and selection states.\n */\nexport type TextButtonOptions = TextViewOptions&{\n backgroundColor?: string,\n opacity?: number,\n maxWidth?: number,\n radius?: number,\n boxSize?: number,\n};\n\nexport class TextButton extends TextView {\n /** Default description of this view in Three.js DevTools. */\n name = 'TextButton';\n /** The font size of the text label. */\n fontSize = 0.05;\n /** The color of the text in its default state. */\n fontColor: string|number = 0xFFFFFF;\n /** The opacity multiplier of the button. */\n opacity = 1.0;\n /** The intrinsic opacity of the button. */\n defaultOpacity = 1.0;\n\n /** The color of the text when the button is hovered. */\n hoverColor: string|number = 0xaaaaaa;\n /** The opacity multiplier of the text when the button is hovered. */\n hoverOpacity = 0.2;\n\n /** The color of the text when the button is pressed. */\n selectedFontColor: string|number = 0x999999;\n /** The opacity multiplier of the text when the button is pressed. */\n selectedOpacity = 0.4;\n\n /** Relative local width. */\n width = 0.9;\n /** Relative local height. */\n height = 0.9;\n\n /** Layout mode. */\n mode = 'center';\n\n /** The horizontal offset for the `imageOverlay` texture. */\n imageOffsetX = 0;\n /** The vertical offset for the `imageOverlay` texture. */\n imageOffsetY = 0;\n\n private uniforms;\n\n /**\n * @param options - Configuration options for the TextButton.\n */\n constructor(options: TextButtonOptions = {}) {\n const geometry = new THREE.PlaneGeometry(1, 1);\n const colorVec4 =\n getVec4ByColorString(options.backgroundColor ?? '#00000000');\n\n const {\n opacity = 0.0,\n radius = SquircleShader.uniforms.uRadius.value,\n boxSize = SquircleShader.uniforms.uBoxSize.value\n } = options;\n\n const uniforms = {\n ...SquircleShader.uniforms,\n uBackgroundColor: {value: colorVec4},\n uOpacity: {value: opacity},\n uAspect: {value: 1.0},\n uRadius: {value: radius},\n uBoxSize: {value: boxSize}\n };\n\n const material = new THREE.ShaderMaterial({\n ...SquircleShader,\n transparent: true,\n uniforms: uniforms,\n depthWrite: false\n });\n\n super(options, geometry, material);\n\n this.uniforms = uniforms;\n this.opacity = opacity;\n\n // Applies our own overrides to the default values.\n this.fontSize = options.fontSize ?? this.fontSize;\n this.fontColor = options.fontColor ?? this.fontColor;\n }\n\n /**\n * Initializes the text object after async dependencies are loaded.\n * @override\n */\n async init() {\n await super.init();\n this.textObj!.position.set(0, 0, VIEW_DEPTH_GAP);\n\n // Disable raycasting on the text part so it doesn't interfere\n // with the main button geometry's interaction.\n this.textObj!.raycast = () => {};\n };\n\n // TODO: Implement onHoverOver() and onHoverOut().\n update() {\n if (!this.textObj) {\n return;\n }\n if (this.textObj) {\n this.textObj.renderOrder = this.renderOrder + 1;\n }\n const ux = this.ux;\n if (ux.isHovered()) {\n if (ux.isSelected()) {\n this.setTextColor(0x666666);\n } else {\n this.setTextColor(0xaaaaaa);\n }\n } else {\n this.setTextColor(0xffffff);\n this.uniforms.uOpacity.value = this.defaultOpacity * this.opacity;\n }\n }\n};\n","import * as THREE from 'three';\n\nimport {VideoStream, VideoStreamDetails} from '../../video/VideoStream';\nimport {View} from '../core/View';\nimport {ViewOptions} from '../core/ViewOptions';\n\n/**\n * A UI component for displaying video content on a 3D plane. It\n * supports various sources, including URLs, HTMLVideoElement,\n * THREE.VideoTexture, and the XR Blocks `VideoStream` class. It automatically\n * handles aspect ratio correction to prevent distortion.\n */\nexport type VideoViewOptions = ViewOptions&{\n src?: string;\n muted?: boolean;\n loop?: boolean;\n autoplay?: boolean;\n playsInline?: boolean;\n crossOrigin?: string;\n mode?: 'center'|'stretch';\n};\n\nexport class VideoView extends View {\n /** Default description of this view in Three.js DevTools. */\n name: string = 'VideoView';\n /** The display mode for the video ('center' preserves aspect ratio). */\n mode: 'center'|'stretch' = 'center';\n /** The underlying HTMLVideoElement being used for playback. */\n video?: HTMLVideoElement;\n /** The URL source of the video, if loaded from a URL. */\n src?: string\n /** VideoView resides in a panel by default. */\n isRoot = false;\n\n /** If true, the video will be muted. Default is true. */\n muted = true;\n /** If true, the video will loop. Default is true. */\n loop = true;\n /** If true, the video will attempt to play automatically. Default is true. */\n autoplay = true;\n /** If true, the video will play inline on mobile devices. Default is true. */\n playsInline = true;\n /** The cross-origin setting for the video element. Default is 'anonymous'. */\n crossOrigin = 'anonymous';\n\n /** The material applied to the video plane. */\n material: THREE.MeshBasicMaterial;\n /** The mesh that renders the video texture. */\n mesh: THREE.Mesh<THREE.PlaneGeometry, THREE.MeshBasicMaterial>;\n\n private stream_?: VideoStream;\n private streamReadyCallback_?: (event: {\n details?:\n VideoStreamDetails&{\n aspectRatio?: number\n }\n }) => void;\n\n private texture?: THREE.Texture;\n private videoAspectRatio: number = 0.0;\n\n /**\n * @param options - Configuration options for the VideoView.\n */\n constructor(options: VideoViewOptions = {}) {\n super(options);\n const videoGeometry = new THREE.PlaneGeometry(1, 1);\n const videoMaterial = new THREE.MeshBasicMaterial({\n transparent: true,\n depthWrite: false,\n side: THREE.DoubleSide,\n // `map` will be set based on options.texture or during load\n });\n this.mesh = new THREE.Mesh<THREE.PlaneGeometry, THREE.MeshBasicMaterial>(\n videoGeometry, videoMaterial);\n this.material = videoMaterial;\n this.add(this.mesh);\n\n if (this.texture instanceof THREE.Texture) {\n this.material.map = this.texture;\n } else {\n this.texture = new THREE.Texture();\n this.material.map = this.texture;\n }\n }\n\n /**\n * Initializes the component, loading from `src` if provided in options.\n */\n init() {\n super.init(); // Calls View's init method.\n\n if (this.material.map instanceof THREE.VideoTexture &&\n this.material.map.image) {\n this.loadFromVideoTexture(this.material.map);\n } else if (this.src) {\n this.load(this.src);\n }\n }\n\n /**\n * Loads a video from various source types. This is the main method for\n * setting the video content.\n * @param source - The video source (URL, HTMLVideoElement, VideoTexture, or\n * VideoStream).\n */\n load(source: string|HTMLVideoElement|THREE.VideoTexture|VideoStream) {\n if (source instanceof HTMLVideoElement) {\n this.loadFromVideoElement(source);\n } else if (source instanceof THREE.VideoTexture) {\n this.loadFromVideoTexture(source);\n } else if (typeof source === 'string') {\n this.loadFromURL(source);\n } else if (source instanceof VideoStream) {\n this.loadFromStream(source);\n } else {\n console.error('VideoView: Invalid video source provided.', source);\n }\n }\n\n /**\n * Loads video content from an VideoStream, handling the 'ready' event\n * to correctly display the stream and set the aspect ratio.\n * @param stream - The VideoStream instance.\n */\n loadFromStream(stream: VideoStream) {\n this.disposeStreamListener_();\n this.stream_ = stream;\n\n this.streamReadyCallback_ = (event: {details?: {aspectRatio?: number}}) => {\n if (!this.stream_?.texture) {\n console.warn('Stream is ready, but its texture is not available.');\n return;\n }\n this.loadFromVideoTexture(this.stream_.texture);\n // The event from VideoStream provides the definitive aspect ratio\n if (event.details?.aspectRatio !== undefined) {\n this.videoAspectRatio = event.details?.aspectRatio;\n }\n this.updateLayout();\n };\n\n if (this.stream_.loaded) {\n // If the stream is already loaded, manually trigger the handler\n this.streamReadyCallback_(\n {details: {aspectRatio: this.stream_.aspectRatio!}});\n } else {\n // Otherwise, wait for the 'ready' event\n this.stream_.addEventListener('statechange', this.streamReadyCallback_);\n }\n }\n\n /**\n * Creates a video element and loads content from a URL.\n * @param url - The URL of the video file.\n */\n loadFromURL(url: string) {\n this.src = url;\n const videoElement = document.createElement('video');\n videoElement.muted = this.muted;\n videoElement.loop = this.loop;\n videoElement.playsInline = this.playsInline;\n videoElement.autoplay = this.autoplay;\n videoElement.crossOrigin = this.crossOrigin;\n videoElement.src = url;\n this.loadFromVideoElement(videoElement);\n }\n\n /**\n * Configures the view to use an existing `HTMLVideoElement`.\n * @param videoElement - The video element to use as the source.\n */\n loadFromVideoElement(videoElement: HTMLVideoElement) {\n this.video = videoElement;\n\n if (this.video.autoplay && this.video.paused) {\n this.video.play().catch(error => {\n console.warn('VideoView: Autoplay prevented for video element.', error);\n });\n }\n\n const videoTextureInstance = new THREE.VideoTexture(this.video);\n videoTextureInstance.colorSpace = THREE.SRGBColorSpace;\n\n this.texture = videoTextureInstance; // Update internal texture reference\n this.material.map = this.texture;\n this.material.needsUpdate = true;\n\n const onLoadedMetadata = () => {\n if (this.video!.videoWidth && this.video!.videoHeight) {\n this.videoAspectRatio =\n this.video!.videoWidth / this.video!.videoHeight;\n } else {\n console.warn('VideoView: Video metadata loaded but dimensions are 0.');\n this.videoAspectRatio = 0; // Invalid aspect ratio\n }\n this.updateLayout(); // Update layout now that aspect ratio is known\n };\n\n if (this.video.readyState >= this.video.HAVE_METADATA) {\n onLoadedMetadata();\n } else {\n this.video.addEventListener(\n 'loadedmetadata', onLoadedMetadata, {once: true});\n }\n }\n\n /**\n * Configures the view to use an existing `THREE.VideoTexture`.\n * @param videoTextureInstance - The texture to display.\n */\n loadFromVideoTexture(videoTextureInstance: THREE.VideoTexture) {\n this.texture = videoTextureInstance;\n this.material.map = this.texture;\n this.material.needsUpdate = true;\n this.video = this.texture.image; // Underlying HTMLVideoElement\n\n if (this.video && this.video.videoWidth && this.video.videoHeight) {\n this.videoAspectRatio = this.video.videoWidth / this.video.videoHeight;\n this.updateLayout();\n } else if (this.video) {\n this.video.addEventListener('loadedmetadata', () => {\n if (this.video!.videoWidth && this.video!.videoHeight) {\n this.videoAspectRatio =\n this.video!.videoWidth / this.video!.videoHeight;\n } else {\n this.videoAspectRatio = 0;\n }\n this.updateLayout();\n }, {once: true});\n } else {\n console.warn(\n 'VideoView: VideoTexture does not have a valid underlying video element.');\n this.videoAspectRatio = 0;\n this.updateLayout();\n }\n }\n\n /** Starts video playback. */\n play() {\n if (this.video && this.video.paused) {\n this.video.play().catch(\n e => console.warn('VideoView: Error playing video:', e));\n }\n }\n\n /** Pauses video playback. */\n pause() {\n if (this.video && !this.video.paused) {\n this.video.pause();\n }\n }\n\n private disposeStreamListener_() {\n if (this.stream_ && this.streamReadyCallback_) {\n this.stream_.removeEventListener(\n 'statechange', this.streamReadyCallback_);\n this.stream_ = undefined;\n this.streamReadyCallback_ = undefined;\n }\n }\n\n /**\n * Cleans up resources, particularly the underlying video element and texture,\n * to prevent memory leaks.\n */\n dispose() {\n this.disposeStreamListener_();\n\n if (this.video) {\n this.video.pause();\n this.video.removeAttribute('src');\n this.video.load();\n this.video = undefined;\n }\n if (this.texture) {\n this.texture.dispose();\n this.texture = undefined;\n }\n super.dispose();\n }\n\n /**\n * Updates the layout and scales the video plane to match its aspect ratio.\n * @override\n */\n updateLayout() {\n super.updateLayout();\n if (this.mode === 'stretch' || this.videoAspectRatio <= 0 ||\n !this.material.map) {\n return;\n }\n this.mesh.scale.set(\n Math.min(this.rangeX, this.videoAspectRatio * this.rangeY),\n Math.min(this.rangeY, this.rangeX / this.videoAspectRatio), 1);\n }\n}\n","import * as THREE from 'three';\n\n/**\n * Checks if a given object is a descendant of another object in the scene\n * graph. This function is useful for determining if an interaction (like a\n * raycast hit) has occurred on a component that is part of a larger, complex\n * entity.\n *\n * It uses an iterative approach to traverse up the hierarchy from the child.\n *\n * @param child - The potential descendant object.\n * @param parent - The potential ancestor object.\n * @returns True if `child` is the same as `parent` or is a descendant of\n * `parent`.\n */\nexport function objectIsDescendantOf(\n child?: Readonly<THREE.Object3D>|null,\n parent?: Readonly<THREE.Object3D>|null) {\n // Starts the search from the child object.\n let currentNode: Readonly<THREE.Object3D>|undefined|null = child;\n\n // Traverses up the scene graph hierarchy until we reach the top (null parent)\n // or find the target parent.\n while (currentNode) {\n // If the current node is the parent we're looking for, we've found a match.\n if (currentNode === parent) {\n return true;\n }\n // Moves up to the next level in the hierarchy.\n currentNode = currentNode.parent;\n }\n\n // If we reach the top of the hierarchy without finding the parent,\n // it is not an ancestor.\n return false;\n}\n\n/**\n * Traverses the scene graph from a given node, calling a callback function for\n * each node. The traversal stops if the callback returns true.\n *\n * This function is similar to THREE.Object3D.traverse, but allows for early\n * exit from the traversal based on the callback's return value.\n *\n * @param node - The starting node for the traversal.\n * @param callback - The function to call for each node. It receives the current\n * node as an argument. If the callback returns `true`, the traversal will\n * stop.\n * @returns Whether the callback returned true for any node.\n */\nexport function traverseUtil(\n node: THREE.Object3D, callback: (node: THREE.Object3D) => boolean) {\n if (callback(node)) {\n return true;\n }\n for (const child of node.children) {\n if (traverseUtil(child, callback)) {\n return true;\n }\n }\n return false;\n}\n","import * as THREE from 'three';\n\nimport {Controller} from '../input/Controller';\nimport {Hands} from '../input/Hands';\nimport {Input} from '../input/Input';\nimport {View} from '../ui/core/View';\nimport {objectIsDescendantOf} from '../utils/SceneGraphUtils';\n\nimport {ObjectGrabEvent, ObjectTouchEvent, Script, SelectEvent} from './Script';\n\ntype MaybeXRScript = THREE.Object3D&{isXRScript?: boolean};\ntype MaybeView = THREE.Object3D&{isView?: boolean};\ntype MaybeHasIgnoreReticleRaycast = {\n ignoreReticleRaycast?: boolean;\n};\n\n/**\n * User is an embodied instance to manage hands, controllers, speech, and\n * avatars. It extends Script to update human-world interaction.\n *\n * In the long run, User is to manages avatars, hands, and everything of Human\n * I/O. In third-person view simulation, it should come with an low-poly avatar.\n * To support multi-user social XR planned for future iterations.\n */\nexport class User extends Script {\n static dependencies = {\n input: Input,\n scene: THREE.Scene,\n };\n\n /**\n * Whether to represent a local user, or another user in a multi-user session.\n */\n local = true;\n\n /**\n * The number of hands associated with the XR user.\n */\n numHands = 2;\n\n /**\n * The height of the user in meters.\n */\n height = 1.6;\n\n /**\n * The default distance of a UI panel from the user in meters.\n */\n panelDistance = 1.75;\n\n /**\n * The handedness (primary hand) of the user (0 for left, 1 for right, 2 for\n * both).\n */\n handedness = 1;\n\n /**\n * The radius of the safe space around the user in meters.\n */\n safeSpaceRadius = 0.2;\n\n /**\n * The distance of a newly spawned object from the user in meters.\n */\n objectDistance = 1.5;\n\n /**\n * The angle of a newly spawned object from the user in radians.\n */\n objectAngle = -18.0 / 180.0 * Math.PI;\n\n /**\n * An array of pivot objects. Pivot are sphere at the **starting** tip of\n * user's hand / controller / mouse rays for debugging / drawing applications.\n */\n pivots: THREE.Object3D[] = [];\n\n /**\n * Public data for user interactions, typically holding references to XRHand.\n */\n hands?: Hands;\n\n /**\n * Maps a controller to the object it is currently hovering over.\n */\n hoveredObjectsForController = new Map<Controller, THREE.Object3D|null>();\n\n /**\n * Maps a controller to the object it has currently selected.\n */\n selectedObjectsForController = new Map<Controller, THREE.Object3D>();\n\n /**\n * Maps a hand index (0 or 1) to a set of meshes it is currently touching.\n */\n touchedObjects = new Map<number, Set<THREE.Mesh>>();\n\n /**\n * Maps a hand index to another map that associates a grabbed mesh with its\n * initial grab event data.\n */\n grabbedObjects = new Map<number, Map<THREE.Mesh, ObjectGrabEvent>>();\n\n input!: Input;\n scene!: THREE.Scene;\n controllers!: Controller[];\n\n /**\n * Constructs a new User.\n */\n constructor() {\n super();\n }\n\n /**\n * Initializes the User.\n */\n init({input, scene}: {input: Input, scene: THREE.Scene}) {\n this.input = input;\n this.controllers = input.controllers;\n this.scene = scene;\n }\n\n /**\n * Sets the user's height on the first frame.\n * @param camera -\n */\n setHeight(camera: THREE.Camera) {\n this.height = camera.position.y;\n }\n\n /**\n * Adds pivots at the starting tip of user's hand / controller / mouse rays.\n */\n enablePivots() {\n this.input.enablePivots();\n }\n\n /**\n * Gets the pivot object for a given controller id.\n * @param id - The controller id.\n * @returns The pivot object.\n */\n getPivot(id: number) {\n return this.controllers[id].getObjectByName('pivot');\n }\n\n /**\n * Gets the world position of the pivot for a given controller id.\n * @param id - The controller id.\n * @returns The world position of the pivot.\n */\n getPivotPosition(id: number) {\n return this.getPivot(id)?.getWorldPosition(new THREE.Vector3());\n }\n\n /**\n * Gets reticle's direction in THREE.Vector3.\n * Requires reticle enabled to be called.\n * @param controllerId -\n */\n getReticleDirection(controllerId: number) {\n return this.controllers[controllerId].reticle?.direction;\n }\n\n /**\n * Gets the object targeted by the reticle.\n * Requires `options.reticle.enabled`.\n * @param id - The controller id.\n * @returns The targeted object, or null.\n */\n getReticleTarget(id: number) {\n return this.controllers[id].reticle?.targetObject;\n }\n\n /**\n * Gets the intersection details from the reticle's raycast.\n * Requires `options.reticle.enabled`.\n * @param id - The controller id.\n * @returns The intersection object, or null if no intersection.\n */\n getReticleIntersection(id: number) {\n return this.controllers[id].reticle?.intersection;\n }\n\n /**\n * Checks if any controller is pointing at the given object or its children.\n * @param obj - The object to check against.\n * @returns True if a controller is pointing at the object.\n */\n isPointingAt(obj: THREE.Object3D) {\n for (const selected of this.hoveredObjectsForController.values()) {\n if (objectIsDescendantOf(selected, obj)) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Checks if any controller is selecting the given object or its children.\n * @param obj - The object to check against.\n * @returns True if a controller is selecting the object.\n */\n isSelectingAt(obj: THREE.Object3D) {\n for (const selected of this.selectedObjectsForController.values()) {\n if (objectIsDescendantOf(selected, obj)) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Gets the intersection point on a specific object.\n * Not recommended for general use, since a View / ModelView's\n * ux.positions contains the intersected points.\n * @param obj - The object to check for intersection.\n * @param id - The controller ID, or -1 for any controller.\n * @returns The intersection details, or null if no intersection.\n */\n getIntersectionAt(obj: THREE.Object3D, id = -1) {\n if (id == -1) {\n for (let i = 0; i < 2; ++i) {\n if (this.getReticleTarget(i) === obj) {\n return this.getReticleIntersection(i);\n }\n }\n } else {\n if (this.getReticleTarget(id) === obj) {\n return this.getReticleIntersection(id);\n }\n }\n return null;\n }\n\n /**\n * Gets the world position of a controller.\n * @param id - The controller id.\n * @param target - The target vector to\n * store the result.\n * @returns The world position of the controller.\n */\n getControllerPosition(id: number, target = new THREE.Vector3()) {\n this.controllers[id].getWorldPosition(target);\n return target;\n }\n\n /**\n * Calculates the distance between a controller and an object.\n * @param id - The controller id.\n * @param object - The object to measure the distance to.\n * @returns The distance between the controller and the object.\n */\n getControllerObjectDistance(id: number, object: THREE.Object3D) {\n const controllerPos = this.getControllerPosition(id);\n const objPos = new THREE.Vector3();\n object.getWorldPosition(objPos);\n return controllerPos.distanceTo(objPos);\n }\n\n /**\n * Checks if either controller is selecting.\n * @param id - The controller id. If -1, check both controllers.\n * @returns True if selecting, false otherwise.\n */\n isSelecting(id = -1) {\n if (id == -1) {\n return this.input.controllers.some((controller) => {\n return controller.userData.selected;\n });\n }\n return this.input.controllers[id].userData.selected;\n }\n\n /**\n * Checks if either controller is squeezing.\n * @param id - The controller id. If -1, check both controllers.\n * @returns True if squeezing, false otherwise.\n */\n isSqueezing(id = -1) {\n if (id == -1) {\n return this.input.controllers.some((controller) => {\n return controller.userData.squeezing;\n });\n }\n return this.input.controllers[id].userData.squeezing;\n }\n\n /**\n * Handles the select start event for a controller.\n * @param event - The event object.\n */\n onSelectStart(event: SelectEvent) {\n const controller = event.target;\n const intersections =\n this.input.intersectionsForController.get(controller)!.filter(\n intersection => {\n let target: THREE.Object3D|null = intersection.object;\n while (target) {\n if ((target as MaybeHasIgnoreReticleRaycast)\n .ignoreReticleRaycast === true) {\n return false;\n }\n target = target.parent;\n }\n return true;\n });\n if (intersections && intersections.length > 0) {\n this.selectedObjectsForController.set(\n controller, intersections[0].object);\n this.callObjectSelectStart(event, intersections[0].object);\n }\n }\n\n /**\n * Handles the select end event for a controller.\n * @param event - The event object.\n */\n onSelectEnd(event: SelectEvent) {\n const controller = event.target;\n const intersections = this.input.intersectionsForController.get(controller);\n if (intersections && intersections.length > 0) {\n const selectedObject = this.selectedObjectsForController.get(controller);\n this.callObjectSelectEnd(event, selectedObject || null);\n this.selectedObjectsForController.delete(controller);\n let ancestor: THREE.Object3D|null = selectedObject || null;\n while (ancestor) {\n if ((ancestor as MaybeView).isView && ancestor.visible) {\n (ancestor as View).onTriggered(controller.userData.id);\n break;\n }\n ancestor = ancestor.parent;\n }\n }\n }\n\n /**\n * Handles the squeeze start event for a controller.\n * @param _event - The event object.\n */\n onSqueezeStart(_event: SelectEvent) {}\n\n /**\n * Handles the squeeze end event for a controller.\n * @param _event - The event object.\n */\n onSqueezeEnd(_event: SelectEvent) {}\n\n /**\n * The main update loop called each frame. Updates hover state for all\n * controllers.\n */\n update() {\n if (this.input.controllersEnabled) {\n for (const controller of this.input.controllers) {\n this.updateForController(controller);\n }\n }\n // Direct touch detection.\n this.updateTouchState();\n // Direct grab detection.\n this.updateGrabState();\n }\n\n /**\n * Checks for and handles grab events (touching + pinching).\n */\n updateGrabState() {\n if (!this.hands) {\n return;\n }\n\n for (let i = 0; i < this.numHands; i++) {\n const isPinching = this.isSelecting(i);\n const touchedMeshes = this.touchedObjects.get(i) || new Set<THREE.Mesh>();\n\n const currentlyGrabbedMeshes =\n isPinching ? touchedMeshes : new Set<THREE.Mesh>();\n const previouslyGrabbedMeshesMap =\n this.grabbedObjects.get(i) || new Map();\n\n const newlyGrabbedMeshes = [...currentlyGrabbedMeshes].filter(\n mesh => !previouslyGrabbedMeshesMap.has(mesh));\n\n const releasedMeshes = [...previouslyGrabbedMeshesMap.keys()].filter(\n mesh => !currentlyGrabbedMeshes.has(mesh));\n\n for (const mesh of newlyGrabbedMeshes) {\n const hand = this.hands.getWrist(i);\n if (!hand) continue;\n\n const grabEvent = {handIndex: i, hand: hand};\n\n if (!this.grabbedObjects.has(i)) {\n this.grabbedObjects.set(i, new Map());\n }\n this.grabbedObjects.get(i)!.set(mesh, grabEvent);\n this.callObjectGrabStart(grabEvent, mesh);\n }\n\n for (const mesh of releasedMeshes) {\n const grabEvent = previouslyGrabbedMeshesMap.get(mesh);\n this.callObjectGrabEnd(grabEvent, mesh);\n previouslyGrabbedMeshesMap.delete(mesh);\n }\n\n for (const mesh of currentlyGrabbedMeshes) {\n if (previouslyGrabbedMeshesMap.has(mesh)) {\n const grabEvent = previouslyGrabbedMeshesMap.get(mesh);\n this.callObjectGrabbing(grabEvent, mesh);\n }\n }\n }\n }\n\n /**\n * Checks for and handles touch events for the hands' index fingers.\n */\n updateTouchState() {\n if (!this.hands) {\n return;\n }\n for (let i = 0; i < this.numHands; i++) {\n const indexTip = this.hands.getIndexTip(i);\n if (!indexTip) {\n continue;\n }\n\n const indexTipPosition = new THREE.Vector3();\n indexTip.getWorldPosition(indexTipPosition);\n\n const currentlyTouchedMeshes: THREE.Mesh[] = [];\n this.scene.traverse((object) => {\n if ((object as Partial<THREE.Mesh>).isMesh && object.visible) {\n const boundingBox = new THREE.Box3().setFromObject(object);\n if (boundingBox.containsPoint(indexTipPosition)) {\n currentlyTouchedMeshes.push(object as THREE.Mesh);\n }\n }\n });\n\n const previouslyTouchedMeshes = this.touchedObjects.get(i) || new Set();\n const currentMeshesSet = new Set(currentlyTouchedMeshes);\n\n const newlyTouchedMeshes = currentlyTouchedMeshes.filter(\n mesh => !previouslyTouchedMeshes.has(mesh));\n const removedMeshes = [...previouslyTouchedMeshes].filter(\n mesh => !currentMeshesSet.has(mesh));\n\n const touchingEvent = {handIndex: i, touchPosition: indexTipPosition};\n\n if (newlyTouchedMeshes.length > 0) {\n for (const mesh of newlyTouchedMeshes) {\n this.callObjectTouchStart(touchingEvent, mesh);\n }\n }\n\n if (removedMeshes.length > 0) {\n for (const mesh of removedMeshes) {\n this.callObjectTouchEnd(touchingEvent, mesh);\n }\n }\n\n for (const mesh of currentMeshesSet) {\n this.callObjectTouching(touchingEvent, mesh);\n }\n\n if (currentMeshesSet.size > 0) {\n this.touchedObjects.set(i, currentMeshesSet);\n } else {\n this.touchedObjects.delete(i);\n }\n }\n }\n\n /**\n * Updates the hover state for a single controller.\n * @param controller - The controller to update.\n */\n updateForController(controller: Controller) {\n const intersections =\n this.input.intersectionsForController.get(controller)!;\n const currentHoverTarget =\n intersections.length > 0 ? intersections[0].object : null;\n const previousHoverTarget =\n this.hoveredObjectsForController.get(controller);\n if (previousHoverTarget !== currentHoverTarget) {\n this.callHoverExit(controller, previousHoverTarget || null);\n this.hoveredObjectsForController.set(controller, currentHoverTarget);\n this.callHoverEnter(controller, currentHoverTarget);\n } else if (previousHoverTarget) {\n this.callOnHovering(controller, previousHoverTarget);\n }\n }\n\n /**\n * Recursively calls onHoverExit on a target and its ancestors.\n * @param controller - The controller exiting hover.\n * @param target - The object being exited.\n */\n callHoverExit(controller: Controller, target: THREE.Object3D|null) {\n if (target == null) return;\n if ((target as MaybeXRScript).isXRScript) {\n (target as Script).onHoverExit(controller);\n }\n this.callHoverExit(controller, target.parent);\n }\n\n /**\n * Recursively calls onHoverEnter on a target and its ancestors.\n * @param controller - The controller entering hover.\n * @param target - The object being entered.\n */\n callHoverEnter(controller: Controller, target: THREE.Object3D|null) {\n if (target == null) return;\n if ((target as MaybeXRScript).isXRScript) {\n (target as Script).onHoverEnter(controller);\n }\n this.callHoverEnter(controller, target.parent);\n }\n\n /**\n * Recursively calls onHovering on a target and its ancestors.\n * @param controller - The controller hovering.\n * @param target - The object being entered.\n */\n callOnHovering(controller: Controller, target: THREE.Object3D|null) {\n if (target == null) return;\n if ((target as MaybeXRScript).isXRScript) {\n (target as Script).onHovering(controller);\n }\n this.callOnHovering(controller, target.parent);\n }\n\n /**\n * Recursively calls onObjectSelectStart on a target and its ancestors until\n * the event is handled.\n * @param event - The original select start event.\n * @param target - The object being selected.\n */\n callObjectSelectStart(event: SelectEvent, target: THREE.Object3D|null) {\n if (target == null) return;\n if ((target as MaybeXRScript).isXRScript &&\n (target as Script).onObjectSelectStart(event)) {\n // The event was handled already so do not propagate up.\n return;\n }\n this.callObjectSelectStart(event, target.parent);\n }\n\n /**\n * Recursively calls onObjectSelectEnd on a target and its ancestors until\n * the event is handled.\n * @param event - The original select end event.\n * @param target - The object being un-selected.\n */\n callObjectSelectEnd(event: SelectEvent, target: THREE.Object3D|null) {\n if (target == null) return;\n if ((target as MaybeXRScript).isXRScript &&\n (target as Script).onObjectSelectEnd(event)) {\n // The event was handled already so do not propagate up.\n return;\n }\n this.callObjectSelectEnd(event, target.parent);\n }\n\n /**\n * Recursively calls onObjectTouchStart on a target and its ancestors.\n * @param event - The original touch start event.\n * @param target - The object being touched.\n */\n callObjectTouchStart(event: ObjectTouchEvent, target: THREE.Object3D|null) {\n if (target == null) return;\n if ((target as MaybeXRScript).isXRScript) {\n (target as Script).onObjectTouchStart(event);\n }\n this.callObjectTouchStart(event, target.parent);\n }\n\n /**\n * Recursively calls onObjectTouching on a target and its ancestors.\n * @param event - The original touch event.\n * @param target - The object being touched.\n */\n callObjectTouching(event: ObjectTouchEvent, target: THREE.Object3D|null) {\n if (target == null) return;\n if ((target as MaybeXRScript).isXRScript) {\n (target as Script).onObjectTouching(event);\n }\n this.callObjectTouching(event, target.parent);\n }\n\n /**\n * Recursively calls onObjectTouchEnd on a target and its ancestors.\n * @param event - The original touch end event.\n * @param target - The object being un-touched.\n */\n callObjectTouchEnd(event: ObjectTouchEvent, target: THREE.Object3D|null) {\n if (target == null) return;\n if ((target as MaybeXRScript).isXRScript) {\n (target as Script).onObjectTouchEnd(event);\n }\n this.callObjectTouchEnd(event, target.parent);\n }\n\n /**\n * Recursively calls onObjectGrabStart on a target and its ancestors.\n * @param event - The original grab start event.\n * @param target - The object being grabbed.\n */\n callObjectGrabStart(event: ObjectGrabEvent, target: THREE.Object3D|null) {\n if (target == null) return;\n if ((target as MaybeXRScript).isXRScript) {\n (target as Script).onObjectGrabStart(event);\n }\n this.callObjectGrabStart(event, target.parent);\n }\n\n /**\n * Recursively calls onObjectGrabbing on a target and its ancestors.\n * @param event - The original grabbing event.\n * @param target - The object being grabbed.\n */\n callObjectGrabbing(event: ObjectGrabEvent, target: THREE.Object3D|null) {\n if (target == null) return;\n if ((target as MaybeXRScript).isXRScript) {\n (target as Script).onObjectGrabbing(event);\n }\n this.callObjectGrabbing(event, target.parent);\n }\n\n /**\n * Recursively calls onObjectGrabEnd on a target and its ancestors.\n * @param event - The original grab end event.\n * @param target - The object being released.\n */\n callObjectGrabEnd(event: ObjectGrabEvent, target: THREE.Object3D|null) {\n if (target == null) return;\n if ((target as MaybeXRScript).isXRScript) {\n (target as Script).onObjectGrabEnd(event);\n }\n this.callObjectGrabEnd(event, target.parent);\n }\n\n /**\n * Checks if a controller is selecting a specific object. Returns the\n * intersection details if true.\n * @param obj - The object to check for selection.\n * @param controller - The controller performing the select.\n * @returns The intersection object if a match is found, else null.\n */\n select(obj: THREE.Object3D, controller: THREE.Object3D) {\n const intersections = this.input.intersectionsForController.get(controller);\n return intersections && intersections.length > 0 &&\n objectIsDescendantOf(intersections[0].object, obj) ?\n intersections[0] :\n null;\n }\n};\n","import * as THREE from 'three';\n\nexport const DOWN = Object.freeze(new THREE.Vector3(0, -1, 0));\nexport const UP = Object.freeze(new THREE.Vector3(0, 1, 0));\nexport const FORWARD = Object.freeze(new THREE.Vector3(0, 0, -1));\nexport const BACK = Object.freeze(new THREE.Vector3(0, 0, 1));\nexport const LEFT = Object.freeze(new THREE.Vector3(-1, 0, 0));\nexport const RIGHT = Object.freeze(new THREE.Vector3(1, 0, 0));\nexport const ZERO_VECTOR3 = Object.freeze(new THREE.Vector3(0, 0, 0));\n","import * as THREE from 'three';\n\nimport {Script, SelectEvent} from '../core/Script';\nimport {Input} from '../input/Input';\nimport {MouseController} from '../input/MouseController';\nimport {UP} from '../utils/HelperConstants';\n\n// Temporary variables.\nconst _quaternion = new THREE.Quaternion();\nconst _euler = new THREE.Euler();\nconst _vector3 = new THREE.Vector3();\n\nexport interface Draggable extends THREE.Object3D {\n draggable: boolean;\n // Whether to continuously face the camera as the user drags.\n // If unspecified, defaults to false.\n dragFacingCamera?: boolean;\n}\n\nexport enum DragMode {\n TRANSLATING = 'TRANSLATING',\n ROTATING = 'ROTATING',\n SCALING = 'SCALING',\n DO_NOT_DRAG = 'DO_NOT_DRAG',\n}\n\nexport interface HasDraggingMode {\n draggingMode: DragMode;\n}\n\nexport class DragManager extends Script {\n static readonly dependencies = {input: Input, camera: THREE.Camera};\n static readonly IDLE = 'IDLE';\n static readonly TRANSLATING = DragMode.TRANSLATING;\n static readonly ROTATING = DragMode.ROTATING;\n static readonly SCALING = DragMode.SCALING;\n static readonly DO_NOT_DRAG = DragMode.DO_NOT_DRAG;\n private mode = DragManager.IDLE;\n private controller1?: THREE.Object3D;\n private controller2?: THREE.Object3D;\n private originalObjectPosition = new THREE.Vector3();\n private originalObjectRotation = new THREE.Quaternion();\n private originalObjectScale = new THREE.Vector3();\n private originalController1Position = new THREE.Vector3();\n private originalController1RotationInverse = new THREE.Quaternion();\n private originalController1MatrixInverse = new THREE.Matrix4();\n private originalScalingControllerDistance = 0.0;\n private originalScalingObjectScale = new THREE.Vector3();\n private intersection?: THREE.Intersection;\n private draggableObject?: Draggable;\n private input!: Input;\n private camera!: THREE.Camera;\n\n init({input, camera}: {input: Input, camera: THREE.Camera}) {\n this.input = input;\n this.camera = camera;\n }\n\n onSelectStart(event: SelectEvent) {\n const controller = event.target;\n const intersections = this.input.intersectionsForController.get(controller);\n if (intersections && intersections.length > 0) {\n this.beginDragging(intersections[0], controller);\n }\n }\n\n onSelectEnd() {\n this.mode = DragManager.IDLE;\n this.intersection = undefined;\n this.draggableObject = undefined;\n }\n\n update() {\n for (const controller of this.input.controllers) {\n this.updateDragging(controller);\n }\n }\n\n beginDragging(intersection: THREE.Intersection, controller: THREE.Object3D) {\n const [draggableObject, draggingMode] =\n this.findDraggableObjectAndDraggingMode(intersection.object);\n if (draggableObject == null || draggingMode == null ||\n draggingMode == DragManager.DO_NOT_DRAG) {\n return false;\n }\n if (this.mode != DragManager.IDLE) {\n // Already dragging, switch to scaling.\n return this.beginScaling(controller);\n }\n this.draggableObject = draggableObject;\n this.mode = draggingMode == DragManager.ROTATING ? DragManager.ROTATING :\n DragManager.TRANSLATING;\n this.originalController1Position.copy(controller.position);\n this.originalController1MatrixInverse\n .compose(controller.position, controller.quaternion, controller.scale)\n .invert();\n this.originalController1RotationInverse.copy(controller.quaternion)\n .invert();\n this.intersection = intersection;\n this.controller1 = controller;\n this.originalObjectRotation.copy(draggableObject.quaternion);\n this.originalObjectPosition.copy(draggableObject.position);\n this.originalObjectScale.copy(draggableObject.scale);\n return true;\n }\n\n // Scaling is a two-handed gesture, based on the distance between the two\n // hands.\n beginScaling(controller: THREE.Object3D) {\n this.controller2 = controller;\n this.originalScalingControllerDistance =\n _vector3\n .subVectors(this.controller1!.position, this.controller2.position)\n .length();\n this.originalScalingObjectScale.copy(this.intersection!.object.scale);\n this.mode = DragManager.SCALING;\n return true;\n }\n\n updateDragging(controller: THREE.Object3D) {\n if (this.mode == DragManager.TRANSLATING) {\n return this.updateTranslating();\n } else if (this.mode == DragManager.ROTATING) {\n return this.updateRotating(controller);\n } else if (this.mode == DragManager.SCALING) {\n return this.updateScaling();\n }\n // Continue handle controller.\n return false;\n }\n\n updateTranslating() {\n const model = this.draggableObject!;\n model.position.copy(this.originalObjectPosition);\n model.quaternion.copy(this.originalObjectRotation);\n model.scale.copy(this.originalObjectScale)\n model.updateMatrix();\n this.controller1!.updateMatrix();\n model.matrix.premultiply(this.originalController1MatrixInverse)\n .premultiply(this.controller1!.matrix);\n model.position.setFromMatrixPosition(model.matrix);\n if (model.dragFacingCamera) {\n this.turnPanelToFaceTheCamera();\n }\n return true;\n }\n\n updateRotating(controller: THREE.Object3D) {\n if (controller != this.controller1) {\n return;\n }\n if (controller instanceof MouseController) {\n return this.updateRotatingFromMouseController(controller);\n }\n const model = this.draggableObject!;\n const deltaPosition = new THREE.Vector3().subVectors(\n controller.position, this.originalController1Position);\n deltaPosition.applyQuaternion(this.originalController1RotationInverse);\n const offsetRotation =\n _quaternion.setFromAxisAngle(UP, 10.0 * deltaPosition.x);\n model.quaternion.multiplyQuaternions(\n offsetRotation, this.originalObjectRotation);\n return true;\n }\n\n updateRotatingFromMouseController(controller: THREE.Object3D) {\n const model = this.draggableObject!;\n const deltaRotation = _quaternion.multiplyQuaternions(\n controller.quaternion, this.originalController1RotationInverse);\n const rotationYawAngle = _euler.setFromQuaternion(deltaRotation, 'YXZ');\n const offsetRotation =\n _quaternion.setFromAxisAngle(UP, -10.0 * rotationYawAngle.y);\n model.quaternion.multiplyQuaternions(\n offsetRotation, this.originalObjectRotation);\n return true;\n }\n\n updateScaling() {\n const newControllerDistance =\n _vector3\n .subVectors(this.controller1!.position, this.controller2!.position)\n .length();\n const distanceRatio =\n newControllerDistance / this.originalScalingControllerDistance;\n const model = this.draggableObject!;\n model.scale.copy(this.originalScalingObjectScale)\n .multiplyScalar(distanceRatio);\n return true;\n }\n\n turnPanelToFaceTheCamera() {\n const model = this.draggableObject!;\n _vector3.subVectors(model.position, this.camera.position);\n model.quaternion.setFromAxisAngle(\n UP, (3 * Math.PI / 2) - Math.atan2(_vector3.z, _vector3.x));\n }\n\n /**\n * Seach up the scene graph to find the first draggable object and the first\n * drag mode at or below the draggable object.\n * @param target - Child object to search.\n * @returns Array containing the first draggable object and the first drag\n * mode.\n */\n private findDraggableObjectAndDraggingMode(\n target: THREE.Object3D|null|\n undefined): [Draggable|undefined, DragMode|undefined] {\n let currentTarget = target;\n let draggableObject: Draggable|undefined;\n let draggingMode: DragMode|undefined;\n while (currentTarget && !draggableObject) {\n draggableObject = (currentTarget as Partial<Draggable>).draggable ?\n (currentTarget as Draggable) :\n undefined;\n draggingMode = draggingMode ??\n (currentTarget as Partial<HasDraggingMode>).draggingMode;\n currentTarget = currentTarget.parent;\n }\n return [draggableObject, draggingMode];\n }\n}\n","import * as THREE from 'three';\n\nimport {IconButton, IconButtonOptions} from './IconButton';\n\n/**\n *A specialized `IconButton` that provides a simple, single-click\n * way for users to end the current WebXR session.\n *\n * It inherits the visual and interactive properties of `IconButton` and adds\n * the specific logic for session termination.\n */\nexport class ExitButton extends IconButton {\n /**\n * Declares the dependencies required by this script, which will be injected\n * by the core engine during initialization.\n */\n static dependencies = {\n renderer: THREE.WebGLRenderer,\n };\n\n /** The size of the 'close' icon font. */\n fontSize = 0.8;\n /** The base opacity when the button is not being interacted with. */\n defaultOpacity = 0.2;\n /** The opacity when a controller's reticle hovers over the button. */\n hoverOpacity = 0.8;\n /** The background color of the button's circular shape. */\n backgroundColor = 0xffffff;\n\n /** A private reference to the injected THREE.WebGLRenderer instance. */\n private renderer!: THREE.WebGLRenderer;\n\n /**\n * @param options - Configuration options to override the button's default\n * appearance.\n */\n constructor(options: IconButtonOptions = {}) {\n // Passes a default icon ('close') and any user-provided options to the\n // parent IconButton constructor.\n super({text: 'close', ...options});\n }\n\n /**\n * Initializes the component and stores the injected renderer dependency.\n * @param dependencies - The injected dependencies.\n */\n async init({renderer}: {renderer: THREE.WebGLRenderer;}) {\n await super.init();\n this.renderer = renderer;\n }\n\n /**\n * This method is triggered when the button is successfully selected (e.g.,\n * clicked). It finds the active WebXR session and requests to end it.\n * @override\n */\n onTriggered() {\n console.log('ExitButton triggered: Shutting down XR session.');\n const session = this.renderer.xr.getSession();\n if (session) {\n // Asynchronously end the session. No need to await.\n session.end();\n }\n }\n}\n","import {ExitButton} from '../components/ExitButton';\nimport {IconButton, IconButtonOptions} from '../components/IconButton';\nimport {IconView} from '../components/IconView';\nimport {ImageView, ImageViewOptions} from '../components/ImageView';\nimport {LabelView} from '../components/LabelView';\nimport {TextButton, TextButtonOptions} from '../components/TextButton';\nimport {TextView, TextViewOptions} from '../components/TextView';\nimport {VideoView, VideoViewOptions} from '../components/VideoView';\nimport type {Panel} from '../core/Panel';\nimport type {PanelOptions} from '../core/PanelOptions';\nimport {View} from '../core/View';\nimport {ViewOptions} from '../core/ViewOptions';\n\nimport type {Col, ColOptions} from './Col';\nimport type {Orbiter, OrbiterOptions} from './Orbiter';\nimport type {Row, RowOptions} from './Row';\n\n/**\n * A layout container that arranges child views in a grid-like\n * structure. It provides helper methods like `addRow()` and `addCol()` to\n * declaratively build complex layouts. Children are positioned based on the\n * order they are added and their respective `weight` properties.\n */\nexport type GridOptions = ViewOptions&{\n weight?: number;\n};\n\nexport class Grid extends View {\n static RowClass: typeof Row;\n static ColClass: typeof Col;\n static PanelClass: typeof Panel;\n static OrbiterClass: typeof Orbiter;\n\n /**\n * The weight of the current rows in the grid.\n */\n rowWeight = 0;\n\n /**\n * The weight of the current columns in the grid.\n */\n colWeight = 0;\n\n /**\n * The summed weight to the left of the grid.\n */\n leftWeight = 0;\n\n /**\n * The summed weight to the top of the grid.\n */\n topWeight = 0;\n\n cols = 0;\n rows = 0;\n\n /**\n * Initializes the Grid class with the provided Row, Col, and Panel\n * classes.\n * @param RowClass - The class for rows.\n * @param ColClass - The class for columns.\n * @param PanelClass - The class for panels.\n * @param OrbiterClass - The class for panels.\n */\n static init(\n RowClass: typeof Row, ColClass: typeof Col, PanelClass: typeof Panel,\n OrbiterClass: typeof Orbiter) {\n Grid.RowClass = RowClass;\n Grid.ColClass = ColClass;\n Grid.PanelClass = PanelClass;\n Grid.OrbiterClass = OrbiterClass;\n }\n\n /**\n * Adds an image to the grid.\n * @param options - The options for the image.\n * @returns The added image view.\n */\n addImage(options: ImageViewOptions) {\n const image = new ImageView(options);\n this.add(image);\n return image;\n }\n\n addVideo(options: VideoViewOptions) {\n const video = new VideoView(options);\n this.add(video);\n return video;\n }\n\n addIconButton(options: IconButtonOptions = {}) {\n const iconButton = new IconButton(options);\n this.add(iconButton);\n return iconButton;\n }\n\n addTextButton(options: TextButtonOptions = {}) {\n const iconButton = new TextButton(options);\n this.add(iconButton);\n return iconButton;\n }\n\n addIcon(options: IconButtonOptions = {}) {\n const iconView = new IconView(options);\n this.add(iconView);\n return iconView;\n }\n\n addText(options: TextViewOptions = {}) {\n const textView = new TextView(options);\n this.add(textView);\n return textView;\n }\n\n addLabel(options: object) {\n const labelView = new LabelView(options);\n this.add(labelView);\n return labelView;\n }\n\n addOrbiter(options: OrbiterOptions = {}) {\n const ui = new Grid.OrbiterClass(options);\n this.add(ui);\n return ui;\n }\n\n addExitButton(options: IconButtonOptions = {}) {\n const ui = new ExitButton(options);\n this.add(ui);\n return ui;\n }\n\n /**\n * Adds a panel to the grid.\n * @param options - The options for the panel.\n * @returns The added panel.\n */\n addPanel(options: PanelOptions = {}) {\n options.isRoot = false;\n const panel = new Grid.PanelClass(options);\n this.add(panel);\n return panel;\n }\n\n /**\n * Adds a row to the grid.\n * @param options - The options for the row.\n * @returns The added row.\n */\n addRow(options: RowOptions = {}) {\n const row = new Grid.RowClass(options);\n row.topWeight = this.rowWeight;\n row.height = row.weight;\n\n this.rowWeight += row.weight;\n this.add(row);\n this.rows++;\n return row;\n }\n\n /**\n * Adds a column to the grid.\n * @param options - The options for the column.\n * @returns The added column.\n */\n addCol(options: ColOptions = {}) {\n const col = new Grid.ColClass(options);\n col.leftWeight = this.colWeight;\n col.width = col.weight;\n\n this.colWeight += col.weight;\n this.add(col);\n this.cols++;\n return col;\n }\n\n /**\n * Updates the layout of the grid.\n */\n updateLayout() {\n this.x = -0.5 + (this.leftWeight + this.width / 2);\n this.y = 0.5 - (this.topWeight + this.height / 2);\n super.updateLayout();\n }\n\n /**\n * Initializes the layout of the grid with compose().\n */\n resetLayout() {\n this.rows = 0;\n this.cols = 0;\n this.colWeight = 0;\n this.rowWeight = 0;\n\n for (const child of this.children) {\n if (child instanceof Grid.RowClass) {\n child.topWeight = this.rowWeight;\n child.height = child.weight;\n this.rowWeight += child.weight;\n this.rows++;\n } else if (child instanceof Grid.ColClass) {\n child.leftWeight = this.colWeight;\n child.width = child.weight;\n this.colWeight += child.weight;\n this.cols++;\n }\n }\n }\n}\n","import * as THREE from 'three';\n\n/**\n * Shader for the interactive SpatialPanel UI component.\n *\n * This shader renders a rounded rectangle (squircle) that can display a\n * background color or texture. Its key feature is the ability to render\n * dynamic, radial \"glow\" highlights at the location of up to two controller\n * reticles. The highlight is constrained to the panel's border, providing clear\n * visual feedback for dragging and interaction.\n */\nexport const SpatialPanelShader = {\n uniforms: {\n 'uMainTex': {value: null},\n 'uUseImage': {value: 0.0},\n 'uBackgroundColor': {\n value: new THREE.Vector4(0.4, 0.8, 1.0, 1.0),\n },\n 'uBoxSize': {value: new THREE.Vector2(0.5, 0.5)},\n 'uRadius': {value: 0.05},\n 'uReticleUVs': {value: new THREE.Vector4(0.5, 0.5, 0.5, 0.5)},\n 'uSelected': {value: new THREE.Vector2(0.0, 0.0)},\n 'uBorderWidth': {value: 0.1},\n 'uHighlightRadius': {value: 0.2},\n 'uOutlineWidth': {value: 0.01},\n 'uOpacity': {value: 1.0}\n },\n\n vertexShader: /* glsl */ `\n varying vec2 vTexCoord;\n\n void main() {\n vTexCoord = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n }\n `,\n\n fragmentShader: /* glsl */ `\n precision mediump float;\n\n uniform sampler2D uMainTex;\n uniform vec4 uBackgroundColor;\n uniform vec2 uBoxSize;\n uniform float uRadius;\n uniform float uUseImage;\n\n uniform vec4 uReticleUVs;\n uniform vec2 uSelected;\n uniform float uBorderWidth;\n uniform float uHighlightRadius;\n uniform float uOutlineWidth;\n uniform float uOpacity;\n\n varying vec2 vTexCoord;\n\n // Distance function for rounded box.\n float distRoundBox(vec2 p, vec2 b, highp float r) {\n return length(max(abs(p) - b + r, 0.0)) - r;\n }\n\n vec4 highlight(in vec4 baseColor, in vec4 colorOutside,\n in float distOuterUV, in float aa, in vec2 mouse, in float selected) {\n\n vec4 highlightColor = vec4(0.0);\n float normDist = 1.0; // Initialize outside the highlight range\n bool mousePressed = selected > 0.0;\n bool mouseHovering = selected <= 0.0 && length(uReticleUVs.xy) > 0.0;\n bool mouseNearBorder = (mouseHovering || mousePressed);\n vec4 finalColor = baseColor;\n\n if (mouseNearBorder) {\n // Scale mouse and fragment coordinates by the inverse of uBoxSize\n\n vec2 fragAspect = vTexCoord;\n fragAspect.x *= uBoxSize.x / uBoxSize.y;\n vec2 mouseAspect = mouse;\n mouseAspect.x *= uBoxSize.x / uBoxSize.y;\n\n // Calculate vector from mouse to fragment in aspect-corrected space\n vec2 diffAspect = fragAspect - mouseAspect;\n\n // Calculate the distance in the aspect-corrected space\n float distToMouseAspect = length(diffAspect);\n\n // Normalized distance from mouse within the highlight radius\n normDist = distToMouseAspect / uHighlightRadius;\n\n // Define highlight color\n float innerWhite = mousePressed ? 0.9 : 0.8;\n\n // Radial gradient calculation\n float radialFactor = smoothstep(1.0, 0.0, normDist); // 1 at center, 0 at edge\n highlightColor = vec4(vec3(innerWhite), 1.0) * vec4(vec3(1.0), radialFactor);\n\n // Calculate distance to the inner edge of the border in UV space\n float distInnerUV = distRoundBox(\n (vTexCoord - 0.5) * uBoxSize,\n (uBoxSize - uBorderWidth) * 0.5, 0.5 * uRadius);\n\n float highlightEdgeSharpness = 200.0;\n float innerHighlightAmount = clamp(highlightEdgeSharpness * -distOuterUV, 0.0, 1.0);\n float outerHighlightAmount = clamp(highlightEdgeSharpness * distInnerUV, 0.0, 1.0);\n float highlightAmount = min(innerHighlightAmount, outerHighlightAmount);\n vec4 highlightColor = mix(finalColor, finalColor + highlightColor, highlightColor.a);\n finalColor = mix(finalColor, highlightColor, highlightAmount);\n }\n return finalColor;\n }\n\n void main(void) {\n vec2 size = uBoxSize * 1000.0;\n float radius = min(size.x, size.y) * (0.05 + uRadius);\n vec2 half_size = 0.5 * size;\n\n // Distance to the outer edge of the round box in UV space (0-1)\n float distOuterUV = distRoundBox(vTexCoord * uBoxSize - uBoxSize * 0.5, uBoxSize * 0.5, uRadius);\n\n // Antialiasing delta\n float aa = fwidth(distOuterUV) * 0.8;\n\n // Base color: opaque inside, transparent outside\n vec4 colorInside = uBackgroundColor;\n if (uUseImage > 0.5) {\n colorInside = texture2D(uMainTex, vTexCoord);\n colorInside.a = 1.0;\n }\n vec4 colorOutside = vec4(0.0, 0.0, 0.0, 0.0);\n vec4 baseColor = mix(colorInside, colorOutside, smoothstep(0.0, aa, distOuterUV));\n\n vec4 finalColor1 = highlight(baseColor, colorOutside, distOuterUV, aa, uReticleUVs.xy, uSelected.x);\n vec4 finalColor2 = highlight(baseColor, colorOutside, distOuterUV, aa, uReticleUVs.zw, uSelected.y);\n\n gl_FragColor = uOpacity * max(finalColor1, finalColor2);\n }\n `\n};\n","import * as THREE from 'three';\n\nimport type {Shader} from '../../utils/Types';\nimport {getVec4ByColorString} from '../../utils/utils';\n\n\n/**\n * A specialized `THREE.Mesh` designed for rendering UI panel\n * backgrounds. It utilizes a custom shader to draw rounded rectangles\n * (squircles) and provides methods to dynamically update its appearance,\n * such as aspect ratio and size. This class is a core building block for\n * `Panel` components.\n */\nexport class PanelMesh extends\n THREE.Mesh<THREE.PlaneGeometry, THREE.ShaderMaterial> {\n /** Text description of the PanelMesh */\n name = 'PanelMesh';\n\n /**\n * Provides convenient access to the material's shader uniforms.\n * @returns The uniforms object of the shader material.\n */\n get uniforms() {\n return this.material.uniforms;\n }\n\n /**\n * Creates an instance of PanelMesh.\n * @param shader - Shader for the panel mesh.\n * @param backgroundColor - The background color as a CSS string.\n * @param panelScale - The initial scale of the plane\n */\n constructor(shader: Shader, backgroundColor?: string, panelScale = 1.0) {\n // Each mesh needs its own unique set of uniforms.\n const uniforms = THREE.UniformsUtils.clone(shader.uniforms);\n\n const material = new THREE.ShaderMaterial({\n uniforms: uniforms,\n vertexShader: shader.vertexShader,\n fragmentShader: shader.fragmentShader,\n transparent: true,\n depthWrite: false,\n side: THREE.DoubleSide,\n });\n\n const geometry = new THREE.PlaneGeometry(panelScale, panelScale);\n\n super(geometry, material);\n\n if (backgroundColor) {\n uniforms.uBackgroundColor.value = getVec4ByColorString(backgroundColor);\n }\n }\n\n /**\n * Sets the panel's absolute dimensions (width and height) in the shader.\n * This is used by the shader to correctly calculate properties like rounded\n * corner radii.\n * @param width - The width of the panel.\n * @param height - The height of the panel.\n */\n setWidthHeight(width: number, height: number) {\n this.uniforms.uBoxSize.value.set(width, height);\n }\n\n /**\n * Adjusts the mesh's scale to match a given aspect ratio, preventing the\n * panel from appearing stretched.\n * @param aspectRatio - The desired width-to-height ratio.\n */\n setAspectRatio(aspectRatio: number) {\n this.scale.set(\n Math.max(aspectRatio, 1.0), Math.max(1.0 / aspectRatio, 1.0), 1.0);\n }\n}\n","import * as THREE from 'three';\n\nimport {User} from '../../core/User';\nimport {Draggable, DragMode, HasDraggingMode} from '../../ux/DragManager';\nimport {DP_TO_DMM} from '../constants';\nimport {Grid} from '../layouts/Grid';\nimport {SpatialPanelShader} from '../shaders/SpatialPanelShader';\nimport {SquircleShader} from '../shaders/SquircleShader';\n\nimport {PanelMesh} from './PanelMesh';\nimport {PanelOptions} from './PanelOptions';\nimport {View} from './View.js';\n\n// Default panel width in density-independent pixels (DP).\nconst DEFAULT_WIDTH_DP = 1024;\n\n// Default panel height in density-independent pixels (DP).\nconst DEFAULT_HEIGHT_DP = 720;\n\n// Default panel width in meters, calculated from DP for root panels.\nconst DEFAULT_WIDTH_M = DEFAULT_WIDTH_DP * DP_TO_DMM * 0.001;\n\n// Default panel height in meters, calculated from DP for root panels.\nconst DEFAULT_HEIGHT_M = DEFAULT_HEIGHT_DP * DP_TO_DMM * 0.001;\n\nexport type PanelFadeState = 'idle'|'fading-in'|'fading-out';\n\n/**\n * A fundamental UI container that displays content on a 2D quad in\n * 3D space. It supports background colors, rounded corners (squircles), and can\n * be made interactive and draggable. It serves as a base for building complex\n * user interfaces.\n *\n * The panel intelligently selects a shader:\n * - `SpatialPanelShader`: For interactive, draggable panels with hover/select\n * highlights.\n * - `SquircleShader`: For static, non-interactive panels with a clean, rounded\n * look.\n */\nexport class Panel extends View implements Draggable, Partial<HasDraggingMode> {\n static dependencies = {user: User, timer: THREE.Timer};\n\n keepFacingCamera = true;\n\n /** Text description of the view */\n name = 'Panel';\n\n /** Type identifier for easy checking with `instanceof`. */\n isPanel = true;\n\n /** The underlying mesh that renders the panel's background. */\n mesh: PanelMesh;\n\n /** Determines if the panel can be dragged by the user. */\n draggable = false;\n\n /** Dragging mode, defaults to true if draggable else undefined. */\n draggingMode?: DragMode;\n\n /** Determines if the panel can be touched by the user's hands. */\n touchable = false;\n\n /**\n * If true, a root panel will automatically spawn in front of the user.\n */\n useDefaultPosition = true;\n\n /**\n * Panel by default uses borderless shader.\n * This flag indicates whether to use borderless shader for Spatial Panels.\n */\n useBorderlessShader = false;\n\n /**\n * Whether to show highlights for the spatial panel.\n */\n showHighlights = false;\n\n /** The background color of the panel, expressed as a CSS color string. */\n backgroundColor = '#c2c2c255';\n\n // --- Private Fading Animation Properties ---\n /**\n * The current state of the fading animation.\n */\n private _fadeState: PanelFadeState = 'idle';\n\n /**\n * Default duration for fade animations in seconds.\n */\n private _fadeDuration = 0.2;\n\n /**\n * Timer for the current fade animation, driven by the core clock.\n */\n private _fadeTimer = 0;\n\n /**\n * The current opacity value, used during animations.\n */\n private _currentOpacity = 1.0;\n\n /**\n * The start opacity value for the current animation.\n */\n private _startOpacity = 1.0;\n\n /**\n * The target opacity value for the current animation.\n */\n private _targetOpacity = 1.0;\n\n /**\n * An optional callback function to execute when a fade animation completes.\n */\n onFadeComplete?: () => void;\n\n private timer!: THREE.Timer;\n\n constructor(options: PanelOptions = {}) {\n super(options);\n\n const isDraggable = options.draggable ?? this.draggable;\n\n const useBorderlessShader = options.useBorderlessShader ?? (!isDraggable);\n // Draggable panels have a larger geometry for interaction padding.\n const panelScale = useBorderlessShader ? 1.0 : 1.3;\n // Use SpatialPanelShader for SpatialPanel, while developers can choose\n // useBorderlessShader=false to disable the interactive border.\n const shader = useBorderlessShader ? SquircleShader : SpatialPanelShader;\n options.useBorderlessShader = useBorderlessShader;\n this.showHighlights = !useBorderlessShader;\n\n // Applies user-provided options or default options.\n this.backgroundColor = options.backgroundColor ?? this.backgroundColor;\n this.draggable = isDraggable;\n this.draggingMode = options.draggingMode ?? this.draggable ?\n DragMode.TRANSLATING :\n DragMode.DO_NOT_DRAG;\n this.touchable = options.touchable ?? this.touchable;\n this.isRoot = options.isRoot ?? true;\n this.width = options.width ?? (this.isRoot ? DEFAULT_WIDTH_M : 1);\n this.height = options.height ?? (this.isRoot ? DEFAULT_HEIGHT_M : 1);\n this.showHighlights = options.showHighlights ?? this.showHighlights;\n this.useDefaultPosition =\n options.useDefaultPosition ?? this.useDefaultPosition;\n this.useBorderlessShader =\n options.useBorderlessShader ?? this.useBorderlessShader;\n\n this.mesh = new PanelMesh(shader, this.backgroundColor, panelScale);\n this.add(this.mesh);\n\n this.updateLayout();\n }\n\n /**\n * Initializes the panel, setting its default position if applicable.\n */\n init({user, timer}: {user: User; timer: THREE.Timer;}) {\n super.init();\n this.selectable = true;\n this.timer = timer;\n\n // A manual position set in .position.set() will override the\n // default position to create the SpatialPanel.\n if (this.position.x !== 0 || this.position.y !== 0 ||\n this.position.z !== 0) {\n this.useDefaultPosition = false;\n }\n\n if (this.isRoot && this.useDefaultPosition) {\n this.position.set(\n this.x, user.height + this.y, -user.panelDistance + this.z);\n } else {\n this.position.set(\n this.position.x + this.x, this.position.y + this.y,\n this.position.z + this.z);\n }\n }\n\n /**\n * Starts fading the panel and its children in.\n * @param duration - Optional fade duration in seconds.\n * @param onComplete - Optional callback when fade completes.\n */\n fadeIn(duration?: number, onComplete?: () => void) {\n if (this._fadeState === 'fading-in') return;\n this._startFade(1.0, duration, onComplete);\n this._fadeState = 'fading-in';\n }\n\n /**\n * Starts fading the panel and its children out.\n * @param duration - Optional fade duration in seconds.\n * @param onComplete - Optional callback when fade completes.\n */\n fadeOut(duration?: number, onComplete?: () => void) {\n if (this._fadeState === 'fading-out') return;\n this._startFade(0.0, duration, onComplete);\n this._fadeState = 'fading-out';\n }\n\n /**\n * Initiates a fade animation.\n */\n private _startFade(\n targetOpacity: number, duration?: number, onComplete?: () => void) {\n this._fadeDuration = duration ?? 0.2;\n this.onFadeComplete = onComplete;\n this._fadeTimer = 0;\n this._startOpacity = this._currentOpacity;\n this._targetOpacity = targetOpacity;\n\n if (this._fadeDuration <= 0) {\n this._completeFade();\n } else {\n this._prepareMaterialsForFade();\n }\n }\n\n /**\n * Ensures all child materials are configured for transparency.\n */\n private _prepareMaterialsForFade() {\n this.traverse((child) => {\n if (child instanceof THREE.Mesh && child.material) {\n const materials: THREE.Material[] =\n Array.isArray(child.material) ? child.material : [child.material];\n materials.forEach(material => {\n material.transparent = true;\n });\n }\n });\n }\n\n /**\n * Applies the given opacity to all materials in the hierarchy.\n */\n private _applyOpacity(opacityValue: number) {\n this.traverse((child) => {\n if (child instanceof View) child.opacity = opacityValue;\n if (child instanceof THREE.Mesh && child.material) {\n const materials: THREE.Material[] =\n Array.isArray(child.material) ? child.material : [child.material];\n materials.forEach(material => {\n if (material instanceof THREE.ShaderMaterial) {\n material.uniforms.uOpacity.value = opacityValue;\n } else {\n material.opacity = opacityValue;\n }\n });\n }\n });\n }\n\n /**\n * Finalizes the fade animation, sets final visibility, and triggers callback.\n */\n private _completeFade() {\n this._currentOpacity = this._targetOpacity;\n this._applyOpacity(this._currentOpacity);\n this._fadeState = 'idle';\n if (this._currentOpacity === 0)\n this.hide();\n else\n this.show();\n this.onFadeComplete?.();\n }\n\n /**\n * Updates the fade animation progress each frame.\n */\n update() {\n if (this._fadeState !== 'idle') {\n this._fadeTimer += this.timer.getDelta();\n const progress = Math.min(this._fadeTimer / this._fadeDuration, 1.0);\n this._currentOpacity = THREE.MathUtils.lerp(\n this._startOpacity, this._targetOpacity, progress);\n this._applyOpacity(this._currentOpacity);\n if (progress >= 1.0) {\n this._completeFade();\n }\n }\n }\n\n /**\n * Adds a Grid layout as a direct child of this panel.\n * @returns The newly created Grid instance.\n */\n addGrid() {\n const grid = new Grid();\n this.add(grid);\n return grid;\n }\n\n /**\n * Updates the panel's visual dimensions based on its layout properties.\n */\n updateLayout() {\n super.updateLayout();\n this.mesh.setAspectRatio(this.aspectRatio);\n const parentAspectRatio =\n this.isRoot || !this.parent ? 1.0 : (this.parent as View).aspectRatio;\n this.mesh.setWidthHeight(\n this.width * Math.max(parentAspectRatio, 1.0),\n this.height * Math.max(1.0 / parentAspectRatio, 1.0));\n }\n\n /**\n * Gets the panel's width in meters.\n * @returns The width in meters.\n */\n getWidth() {\n return this.width;\n }\n\n /**\n * Gets the panel's height in meters.\n * @returns The height in meters.\n */\n getHeight() {\n return this.height;\n }\n}\n","import {Grid, GridOptions} from './Grid.js';\n\n/**\n * A layout component used within a `Grid` to arrange child elements\n * horizontally. The width of each column is determined by its `weight` property\n * relative to the total weight of all columns in the same row.\n */\nexport type ColOptions = GridOptions&{\n weight?: number;\n};\n\nexport class Col extends Grid {\n constructor(options: ColOptions = {}) {\n if (options.weight === undefined) {\n options.weight = 0.5;\n }\n super(options);\n }\n}\n","import {Grid, GridOptions} from './Grid.js';\n\n/**\n * A layout container designed to hold secondary UI elements, such\n * as an exit button or settings icon. It typically \"orbits\" or remains\n * attached to a corner of its parent panel, outside the main content area.\n */\nexport type OrbiterOptions = GridOptions;\n\nexport class Orbiter extends Grid {\n init() {\n super.init();\n\n this.position.set(-0.45 * this.rangeX, 0.7 * this.rangeY, this.position.z);\n this.scale.set(0.2, 0.2, 1.0);\n }\n}\n","import {Grid, GridOptions} from './Grid.js';\n\n/**\n * A layout component used within a `Grid` to arrange child elements\n * vertically. The height of each row is determined by its `weight` property\n * relative to the total weight of all rows in the grid.\n */\nexport type RowOptions = GridOptions&{\n weight?: number;\n};\n\nexport class Row extends Grid {\n constructor(options: RowOptions = {}) {\n if (options.weight === undefined) {\n options.weight = 0.5;\n }\n super(options);\n }\n}\n","import {Panel} from '../core/Panel';\nimport {PanelOptions} from '../core/PanelOptions';\n\n/**\n * A fundamental UI container that lets you display app content in a\n * 3D space. It can be thought of as a \"window\" or \"surface\" in XR. It provides\n * visual feedback for user interactions like hovering and selecting, driven by\n * a custom shader, and can be made draggable.\n */\nexport type SpatialPanelOptions = PanelOptions&{\n showEdge?: boolean;\n dragFacingCamera?: boolean;\n};\n\nexport class SpatialPanel extends Panel {\n /**\n * Keeps the panel facing the camera as it is dragged.\n */\n dragFacingCamera = true;\n\n /**\n * Creates an instance of SpatialPanel.\n */\n constructor(options: SpatialPanelOptions = {}) {\n options.draggable = options.draggable ?? true;\n options.dragFacingCamera = options.dragFacingCamera ?? true;\n super(options);\n // Reset the following fields with our own defaults.\n this.draggable = options.draggable ?? this.draggable;\n this.dragFacingCamera = options.dragFacingCamera ?? this.dragFacingCamera;\n this.mesh.material.visible = options.showEdge !== false;\n }\n\n update() {\n super.update();\n this._updateInteractionFeedback();\n }\n\n /**\n * Updates shader uniforms to provide visual feedback for controller\n * interactions, such as hover and selection highlights. This method is\n * optimized to only update uniforms when the state changes.\n */\n private _updateInteractionFeedback() {\n if (this.useBorderlessShader || !this.showHighlights) {\n return;\n }\n const [id1, id2] = this.ux.getPrimaryTwoControllerIds();\n\n // --- Update Selection Uniform ---\n const isSelected1 = (id1 !== null) ? this.ux.selected[id1] : false;\n const isSelected2 = (id2 !== null) ? this.ux.selected[id2] : false;\n\n this.mesh.material.uniforms.uSelected.value.set(\n isSelected1 ? 1.0 : 0.0, isSelected2 ? 1.0 : 0.0);\n\n // --- Update Reticle UVs Uniform ---\n const u1 = (id1 !== null) ? this.ux.uvs[id1].x : -1;\n const v1 = (id1 !== null) ? this.ux.uvs[id1].y : -1;\n const u2 = (id2 !== null) ? this.ux.uvs[id2].x : -1;\n const v2 = (id2 !== null) ? this.ux.uvs[id2].y : -1;\n\n this.mesh.material.uniforms.uReticleUVs.value.set(u1, v1, u2, v2);\n }\n}\n","/**\n * UI is a declarative 3D UI composition engine for WebXR,\n * inspired by modern frameworks like Jetpack Compose. It builds a three.js\n * scene graph from a JSON configuration, allowing for a clean separation of UI\n * structure and application logic.\n */\n\nimport {Script} from '../core/Script';\nimport type {Constructor} from '../utils/Types';\n\nimport {IconButton, IconButtonOptions} from './components/IconButton';\nimport {IconView, IconViewOptions} from './components/IconView';\nimport {ImageView, ImageViewOptions} from './components/ImageView';\nimport {LabelView, LabelViewOptions} from './components/LabelView';\nimport {TextButton, TextButtonOptions} from './components/TextButton';\nimport {TextView, TextViewOptions} from './components/TextView';\nimport {VideoView, VideoViewOptions} from './components/VideoView';\nimport {Panel} from './core/Panel';\nimport type {PanelOptions} from './core/PanelOptions';\nimport {View} from './core/View';\nimport {Col, ColOptions} from './layouts/Col';\nimport {Grid, GridOptions} from './layouts/Grid';\nimport {Orbiter, OrbiterOptions} from './layouts/Orbiter';\nimport {Row, RowOptions} from './layouts/Row';\nimport {SpatialPanel, SpatialPanelOptions} from './layouts/SpatialPanel';\n\n// Initializes the Grid class with its dependencies for declarative building.\nGrid.init(Row, Col, Panel, Orbiter);\n\nexport type UIJsonNodeOptions =\n |PanelOptions|TextViewOptions|IconViewOptions|ImageViewOptions|\n LabelViewOptions|TextButtonOptions|VideoViewOptions|ColOptions|GridOptions|\n RowOptions|OrbiterOptions|SpatialPanelOptions|IconButtonOptions;\n\nexport type UIJsonNode = {\n type: string,\n options?: UIJsonNodeOptions,\n position?: {x: number, y: number, z: number},\n rotation?: {x: number, y: number, z: number},\n children?: Array<UIJsonNode>\n};\n\n/**\n * Manages the construction and lifecycle of a declarative UI defined by a JSON\n * object. It translates the JSON structure into a hierarchy of UI objects.\n * See samples/ui for a complete example of composing UI with JSON.\n */\nexport class UI extends Script {\n views: View[] = [];\n\n /**\n * A static registry mapping string identifiers to UI component classes.\n * This allows for an extensible and declarative UI system.\n */\n static ComponentRegistry = new Map<string, Constructor<View>>();\n\n /**\n * Registers a component class with a string key, making it available to the\n * `compose` function.\n * @param typeName - The key to use in the JSON configuration.\n * @param componentClass - The class constructor of the UI component.\n */\n static registerComponent(\n typeName: string, componentClass: Constructor<View>) {\n if (UI.ComponentRegistry.has(typeName)) {\n console.warn(`UI: Component type \"${typeName}\" is being overwritten.`);\n }\n UI.ComponentRegistry.set(typeName, componentClass);\n }\n\n /**\n * Composes a UI hierarchy from a JSON object and attaches it to this UI\n * instance. This is the primary method for building a declarative UI.\n *\n * @param json - The JSON object defining the UI structure.\n * @returns The root view of the composed UI, or null if composition fails.\n */\n compose(json: UIJsonNode): View|null {\n const rootComponent = this._composeNode(json);\n if (rootComponent) {\n this.add(rootComponent);\n rootComponent.traverse((node) => {\n if (node instanceof View) {\n this.views.push(node);\n }\n });\n }\n return rootComponent;\n }\n\n /**\n * Recursively processes a single node from the UI JSON configuration.\n * @param nodeJson - The JSON node for a single UI element.\n * @returns The composed UI object for this node, or null on error.\n */\n private _composeNode(nodeJson: UIJsonNode): View|null {\n const {\n type,\n options = {},\n position = {x: 0, y: 0, z: 0},\n rotation = {x: 0, y: 0, z: 0},\n children = []\n } = nodeJson;\n const ComponentClass = UI.ComponentRegistry.get(type);\n\n if (!ComponentClass) {\n console.error(`UI Error: Unknown component type \"${\n type}\". Make sure it's registered.`);\n return null;\n }\n\n const componentInstance = new ComponentClass(options);\n componentInstance.position.set(position.x, position.y, position.z);\n componentInstance.rotation.set(rotation.x, rotation.y, rotation.z);\n\n children.forEach((childJson: UIJsonNode) => {\n const childComponent = this._composeNode(childJson);\n if (childComponent) {\n componentInstance.add(childComponent);\n }\n });\n\n // For layouts, ensure they update their children's positions.\n if (componentInstance instanceof Grid) {\n componentInstance.resetLayouts();\n }\n\n return componentInstance;\n }\n}\n\n// Pre-register the standard set of UI components.\nUI.registerComponent('Panel', Panel);\nUI.registerComponent('Grid', Grid);\nUI.registerComponent('Row', Row);\nUI.registerComponent('Col', Col);\nUI.registerComponent('Orbiter', Orbiter);\nUI.registerComponent('Text', TextView);\nUI.registerComponent('TextView', TextView);\nUI.registerComponent('Label', LabelView);\nUI.registerComponent('LabelView', LabelView);\nUI.registerComponent('VideoView', VideoView);\nUI.registerComponent('TextButton', TextButton);\nUI.registerComponent('IconButton', IconButton);\nUI.registerComponent('IconView', IconView);\nUI.registerComponent('Image', ImageView);\nUI.registerComponent('ImageView', ImageView);\nUI.registerComponent('SpatialPanel', SpatialPanel);\n","class LoadingSpinner extends HTMLElement {\n private static style = `\n /* Styles for the wrapper that covers the screen */\n .wrapper {\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background-color: rgba(0, 0, 0, 0.1);\n display: flex;\n justify-content: center;\n align-items: center;\n z-index: 9999;\n transition: visibility 0s, opacity 0.2s linear;\n }\n\n /* The spinning circle */\n .spinner {\n border: 8px solid rgba(255, 255, 255, 0.3);\n border-left-color: #ffffff;\n border-radius: 50%;\n width: 60px;\n height: 60px;\n animation: spin 1s linear infinite;\n }\n\n /* The animation is safely scoped inside the shadow DOM */\n @keyframes spin {\n to {\n transform: rotate(360deg);\n }\n }`;\n private static innerHTML = `\n <style>\n ${LoadingSpinner.style}\n </style>\n <div class=\"wrapper\">\n <div class=\"spinner\"></div>\n </div>\n `;\n\n connectedCallback() {\n const shadowRoot = this.attachShadow({mode: 'open'});\n shadowRoot.innerHTML = LoadingSpinner.innerHTML;\n }\n}\ncustomElements.define('xb-blocks-loading-spinner', LoadingSpinner);\n\n// Creates a new Loading spinner and attaches it to document.body.\nexport function createLoadingSpinner() {\n return document.body.appendChild(\n document.createElement('xb-blocks-loading-spinner'));\n}\n","import * as THREE from 'three';\n\nimport {createLoadingSpinner} from './CreateLoadingSpinner';\n\n/**\n * Manages the global THREE.DefaultLoadingManager instance for\n * XRBlocks and handles communication of loading progress to the parent iframe.\n * This module controls the visibility of a loading spinner\n * in the DOM based on loading events.\n *\n * Import the single instance\n * `loadingSpinnerManager` to use it throughout the application.\n */\nexport class LoadingSpinnerManager {\n /**\n * DOM element of the loading spinner, created\n * when showSpinner() is called and removed on `onLoad` or `onError`.\n */\n private spinnerElement?: HTMLElement;\n\n /**\n * Tracks if the manager is currently loading assets.\n */\n isLoading = false;\n\n constructor() {\n this.setupCallbacks();\n }\n\n showSpinner() {\n if (!this.spinnerElement) {\n this.spinnerElement = createLoadingSpinner();\n }\n }\n\n hideSpinner() {\n if (this.spinnerElement) {\n this.spinnerElement.remove();\n this.spinnerElement = undefined;\n }\n }\n\n private setupCallbacks() {\n /**\n * Callback function for when the first loading item starts.\n * It sends an initial 'XR_LOADING_PROGRESS' message to the parent window.\n * Note: The spinner is now shown via a manual call to showSpinner()\n * @param _url - The URL of the item being loaded.\n * @param itemsLoaded - The number of items loaded so far.\n * @param itemsTotal - The total number of items to load.\n */\n THREE.DefaultLoadingManager.onStart = (_url, itemsLoaded, itemsTotal) => {\n this.isLoading = true;\n window.parent.postMessage(\n {\n type: 'XR_LOADING_PROGRESS',\n payload: {\n progress: itemsLoaded / itemsTotal,\n message: 'Loading assets...'\n }\n },\n '*');\n };\n\n /**\n * Callback function for when a loading item progresses.\n * It sends a 'XR_LOADING_PROGRESS' message to the parent window with\n * updated progress.\n * @param _url - The URL of the item currently in progress.\n * @param itemsLoaded - The number of items loaded so far.\n * @param itemsTotal - The total number of items to load.\n */\n THREE.DefaultLoadingManager.onProgress = (_url, itemsLoaded, itemsTotal) => {\n window.parent.postMessage(\n {\n type: 'XR_LOADING_PROGRESS',\n payload: {\n progress: itemsLoaded / itemsTotal,\n message:\n `Loading ${Math.round((itemsLoaded / itemsTotal) * 100)}%`\n }\n },\n '*');\n };\n\n /**\n * Callback function for when all loading items are complete.\n * It removes the loading spinner from the DOM and sends an\n * 'XR_LOADING_COMPLETE' message to the parent window.\n */\n THREE.DefaultLoadingManager.onLoad = () => {\n this.isLoading = false;\n this.hideSpinner();\n window.parent.postMessage({type: 'XR_LOADING_COMPLETE'}, '*');\n };\n\n /**\n * Callback function for when a loading item encounters an error.\n * It removes the loading spinner from the DOM and sends an\n * 'XR_LOADING_ERROR' message to the parent window.\n * @param url - The URL of the item that failed to load.\n */\n THREE.DefaultLoadingManager.onError = (url) => {\n this.isLoading = false;\n console.warn('XRBlocks: Error loading: ' + url);\n this.hideSpinner();\n window.parent.postMessage(\n {\n type: 'XR_LOADING_ERROR',\n payload: {url, message: 'Failed to load assets.'}\n },\n '*');\n };\n }\n}\n\nexport const loadingSpinnerManager = new LoadingSpinnerManager();\n","/**\n * Utility functions for positioning and orienting objects in 3D\n * space.\n */\nimport * as THREE from 'three';\n\n// Reusable instances to avoid creating new objects in the render loop.\nconst vector3 = new THREE.Vector3();\nconst vector3a = new THREE.Vector3();\nconst vector3b = new THREE.Vector3();\nconst matrix4 = new THREE.Matrix4();\n\n/**\n * Places and orients an object at a specific intersection point on another\n * object's surface. The placed object's 'up' direction will align with the\n * surface normal at the intersection, and its 'forward' direction will point\n * towards a specified target object (e.g., the camera), but constrained to the\n * surface plane.\n *\n * This is useful for placing objects on walls or floors so they sit flat\n * against the surface but still turn to face the user.\n *\n * @param obj - The object to be placed and oriented.\n * @param intersection - The intersection data from a\n * raycast,\n * containing the point and normal of the surface. The normal is assumed to be\n * in local space.\n * @param target - The object that `obj` should face (e.g., the\n * camera).\n * @returns The modified `obj`.\n */\nexport function placeObjectAtIntersectionFacingTarget(\n obj: THREE.Object3D, intersection: THREE.Intersection,\n target: THREE.Object3D) {\n // 1. Position the object at the intersection point.\n obj.position.copy(intersection.point);\n\n // 2. Determine the world-space normal of the surface at the intersection\n // point. We must ensure the matrix of the intersected object is up-to-date.\n intersection.object.updateWorldMatrix(true, false);\n\n // 3. Determine the desired forward direction.\n // This is the vector from the object to the target, projected onto the\n // surface plane.\n const worldNormal = vector3b.copy(intersection.normal!)\n .transformDirection(intersection.object.matrixWorld);\n const forwardVector = target.getWorldPosition(vector3)\n .sub(obj.position)\n .cross(worldNormal)\n .cross(worldNormal)\n .multiplyScalar(-1)\n .normalize();\n\n // 4. Create an orthonormal basis (a new coordinate system).\n // The 'up' vector is the surface normal.\n // The 'forward' vector is the direction towards the target on the plane.\n // The 'right' vector is perpendicular to both.\n const rightVector = vector3a.crossVectors(worldNormal, forwardVector);\n matrix4.makeBasis(rightVector, worldNormal, forwardVector);\n\n // 5. Apply the rotation from the new basis to the object.\n // This aligns the object's local axes with the new basis vectors.\n // Note: Three.js objects' 'forward' is conventionally the -Z axis.\n // makeBasis sets the +Z axis to forwardVector, so models may need to be\n // authored with +Z forward, or a rotation offset can be applied here.\n obj.quaternion.setFromRotationMatrix(matrix4);\n return obj;\n}\n","import * as THREE from 'three';\n\n/**\n * Represents a single detected object in the XR environment and holds metadata\n * about the object's properties. Note: 3D object position is stored in the\n * position property of `Three.Object3D`.\n */\nexport class DetectedObject extends THREE.Object3D {\n /**\n * A semantic label for the object (e.g., 'chair', 'table').\n */\n label: string;\n\n /**\n * The cropped part of the image that contains the object, as a base64 Data\n * URL.\n */\n image: string|null;\n\n /**\n * The 2D bounding box of the detected object in normalized screen\n * coordinates. Values are between 0 and 1. Centerpoint of this bounding is\n * used for backproject to obtain 3D object position (i.e., this.position).\n */\n detection2DBoundingBox: THREE.Box2;\n\n /**\n * Allows for additional, dynamic properties to be added to the object, as\n * defined in the schema in `ObjectsOptions`.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n [key: string]: any;\n\n /**\n * @param label - The semantic label of the object.\n * @param image - The base64 encoded cropped image of the object.\n * @param boundingBox - The 2D bounding box.\n * @param additionalData - A key-value map of additional properties from the\n * detector. This includes any object proparties that is requested through the\n * schema but is not assigned a class property by default (e.g., color, size).\n */\n constructor(\n label: string, image: string|null, boundingBox: THREE.Box2,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n additionalData: {[key: string]: any} = {}) {\n super();\n this.label = label;\n this.image = image;\n this.detection2DBoundingBox = boundingBox;\n\n // Assign any additional properties to this object.\n Object.assign(this, additionalData);\n }\n}\n","import * as THREE from 'three';\n\nimport {AI} from '../../ai/AI';\nimport {AIOptions} from '../../ai/AIOptions';\nimport {Gemini} from '../../ai/Gemini';\nimport {cropImage, transformRgbUvToWorld} from '../../camera/CameraUtils';\nimport {XRDeviceCamera} from '../../camera/XRDeviceCamera';\nimport {Script} from '../../core/Script';\nimport {Depth} from '../../depth/Depth';\nimport {parseBase64DataURL} from '../../utils/utils';\nimport {WorldOptions} from '../WorldOptions';\n\nimport {DetectedObject} from './DetectedObject';\n\n/**\n * Detects objects in the user's environment using a specified backend.\n * It queries an AI model with the device camera feed and returns located\n * objects with 2D and 3D positioning data.\n */\nexport class ObjectDetector extends Script {\n static dependencies = {\n options: WorldOptions,\n ai: AI,\n aiOptions: AIOptions,\n deviceCamera: XRDeviceCamera,\n depth: Depth,\n camera: THREE.Camera,\n };\n\n /**\n * A map from the object's UUID to our custom `DetectedObject` instance.\n */\n private _detectedObjects = new Map<string, DetectedObject>();\n\n private _debugVisualsGroup?: THREE.Group;\n\n /**\n * The configuration for the Gemini backend.\n */\n private _geminiConfig!: object;\n\n // Injected dependencies\n private options!: WorldOptions;\n private ai!: AI;\n private aiOptions!: AIOptions;\n private deviceCamera!: XRDeviceCamera;\n private depth!: Depth;\n private camera!: THREE.Camera;\n\n /**\n * Initializes the ObjectDetector.\n * @override\n */\n init({options, ai, aiOptions, deviceCamera, depth, camera}: {\n options: WorldOptions,\n ai: AI,\n aiOptions: AIOptions,\n deviceCamera: XRDeviceCamera,\n depth: Depth,\n camera: THREE.Camera,\n }) {\n this.options = options;\n this.ai = ai;\n this.aiOptions = aiOptions;\n this.deviceCamera = deviceCamera;\n this.depth = depth;\n this.camera = camera;\n this._geminiConfig = this._buildGeminiConfig();\n\n if (this.options.objects.showDebugVisualizations) {\n this._debugVisualsGroup = new THREE.Group();\n // Disable raycasting for the debug group to prevent interaction errors.\n this._debugVisualsGroup.raycast = () => {};\n this.add(this._debugVisualsGroup);\n }\n }\n\n /**\n * Runs the object detection process based on the configured backend.\n * @returns A promise that resolves with an\n * array of detected `DetectedObject` instances.\n */\n async runDetection() {\n this.clear(); // Clear previous results before starting a new detection.\n\n switch (this.options.objects.backendConfig.activeBackend) {\n case 'gemini':\n return this._runGeminiDetection();\n // Future backends like 'mediapipe' will be handled here.\n // case 'mediapipe':\n // return this._runMediaPipeDetection();\n default:\n console.warn(`ObjectDetector backend '${\n this.options.objects.backendConfig\n .activeBackend}' is not supported.`);\n return [];\n }\n }\n\n /**\n * Runs object detection using the Gemini backend.\n */\n private async _runGeminiDetection() {\n if (!this.ai.isAvailable()) {\n console.error('Gemini is unavailable for object detection.');\n return [];\n }\n\n const base64Image =\n this.deviceCamera.getSnapshot({outputFormat: 'base64'}) as string |\n null;\n if (!base64Image) {\n console.warn('Could not get device camera snapshot.');\n return [];\n }\n\n const {mimeType, strippedBase64} = parseBase64DataURL(base64Image);\n\n // Cache depth and camera data to align with the captured image frame.\n const cachedDepthArray = this.depth.depthArray[0].slice(0);\n const cachedMatrixWorld = this.camera.matrixWorld.clone();\n\n // Temporarily set the Gemini config for this specific query type.\n const originalGeminiConfig = this.aiOptions.gemini.config;\n this.aiOptions.gemini.config = this._geminiConfig;\n const textPrompt = 'What do you see in this image?';\n\n try {\n const rawResponse = await (this.ai.model as Gemini).query({\n type: 'multiPart',\n parts: [\n {inlineData: {mimeType: mimeType || undefined, data: strippedBase64}},\n {text: textPrompt}\n ]\n });\n\n let parsedResponse;\n try {\n if (rawResponse && rawResponse.text) {\n parsedResponse = JSON.parse(rawResponse.text);\n } else {\n console.error(\n 'AI response is missing text field:', rawResponse,\n 'Raw response was:', rawResponse);\n return [];\n }\n } catch (e) {\n console.error(\n 'Failed to parse AI response JSON:', e,\n 'Raw response was:', rawResponse);\n return [];\n }\n\n if (!Array.isArray(parsedResponse)) {\n console.error('Parsed AI response is not an array:', parsedResponse);\n return [];\n }\n\n if (this.options.objects.showDebugVisualizations) {\n this._visualizeBoundingBoxesOnImage(base64Image, parsedResponse);\n }\n\n const detectionPromises = parsedResponse.map(async (item) => {\n const {ymin, xmin, ymax, xmax, objectName, ...additionalData} =\n item || {};\n if ([ymin, xmin, ymax, xmax].some(coord => typeof coord !== 'number')) {\n return null;\n }\n\n // Bounding box from AI is 0-1000, convert to normalized 0-1.\n const boundingBox = new THREE.Box2(\n new THREE.Vector2(xmin / 1000, ymin / 1000),\n new THREE.Vector2(xmax / 1000, ymax / 1000));\n\n const center = new THREE.Vector2();\n boundingBox.getCenter(center);\n\n const uvInput = {u: center.x, v: center.y};\n const projectionMatrix = this.deviceCamera.simulatorCamera ?\n this.camera.projectionMatrix :\n new THREE.Matrix4().fromArray(this.depth.view[0].projectionMatrix);\n const worldPosition = transformRgbUvToWorld(\n uvInput, cachedDepthArray, projectionMatrix, cachedMatrixWorld,\n this.deviceCamera, this.depth);\n\n if (worldPosition) {\n const margin = this.options.objects.objectImageMargin;\n\n // Create a new bounding box for cropping that includes the margin.\n const cropBox = boundingBox.clone();\n cropBox.min.subScalar(margin);\n cropBox.max.addScalar(margin);\n const objectImage = await cropImage(base64Image, cropBox);\n\n const object = new DetectedObject(\n objectName, objectImage, boundingBox, additionalData);\n object.position.copy(worldPosition);\n\n this.add(object);\n this._detectedObjects.set(object.uuid, object);\n\n if (this._debugVisualsGroup) {\n this._createDebugVisual(object);\n }\n return object;\n }\n });\n\n const detectedObjects =\n (await Promise.all(detectionPromises)).filter(Boolean);\n return detectedObjects;\n\n } catch (error) {\n console.error('AI query for object detection failed:', error);\n return [];\n } finally {\n // Restore the original config after the query.\n this.aiOptions.gemini.config = originalGeminiConfig;\n }\n }\n\n /**\n * Retrieves a list of currently detected objects.\n *\n * @param label - The semantic label to filter by (e.g., 'chair'). If null,\n * all objects are returned.\n * @returns An array of `Object` instances.\n */\n get(label = null) {\n const allObjects = Array.from(this._detectedObjects.values());\n if (!label) {\n return allObjects;\n }\n return allObjects.filter(obj => obj.label === label);\n }\n\n /**\n * Removes all currently detected objects from the scene and internal\n * tracking.\n */\n clear() {\n for (const obj of this._detectedObjects.values()) {\n this.remove(obj);\n }\n this._detectedObjects.clear();\n if (this._debugVisualsGroup) {\n this._debugVisualsGroup.clear();\n }\n return this;\n }\n\n /**\n * Toggles the visibility of all debug visualizations for detected objects.\n * @param visible - Whether the visualizations should be visible.\n */\n showDebugVisualizations(visible = true) {\n if (this._debugVisualsGroup) {\n this._debugVisualsGroup.visible = visible;\n }\n }\n\n /**\n * Draws the detected bounding boxes on the input image and triggers a\n * download for debugging.\n * @param base64Image - The base64 encoded input image.\n * @param detections - The array of detected objects from the\n * AI response.\n */\n private _visualizeBoundingBoxesOnImage(\n base64Image: string, detections: object[]) {\n const img = new Image();\n img.onload = () => {\n const canvas = document.createElement('canvas');\n canvas.width = img.naturalWidth;\n canvas.height = img.naturalHeight;\n const ctx = canvas.getContext('2d')!;\n\n ctx.drawImage(img, 0, 0);\n\n detections.forEach((item) => {\n const {ymin, xmin, ymax, xmax, objectName} = (item || {}) as {\n ymin?: number,\n xmin?: number,\n ymax?: number,\n xmax?: number,\n objectName?: string,\n };\n if ([ymin, xmin, ymax, xmax].some(\n (coord) => typeof coord !== 'number')) {\n return;\n }\n\n // Bounding box from AI is 0-1000, scale it to image dimensions.\n const rectX = xmin! / 1000 * canvas.width;\n const rectY = ymin! / 1000 * canvas.height;\n const rectWidth = (xmax! - xmin!) / 1000 * canvas.width;\n const rectHeight = (ymax! - ymin!) / 1000 * canvas.height;\n\n ctx.strokeStyle = '#FF0000';\n ctx.lineWidth = Math.max(2, canvas.width / 400);\n ctx.strokeRect(rectX, rectY, rectWidth, rectHeight);\n\n // Draw label.\n const text = objectName || 'unknown';\n const fontSize = Math.max(16, canvas.width / 80);\n ctx.font = `bold ${fontSize}px sans-serif`;\n ctx.textBaseline = 'bottom';\n const textMetrics = ctx.measureText(text);\n\n // Draw a background for the text for better readability.\n ctx.fillStyle = 'rgba(0, 0, 0, 0.6)';\n ctx.fillRect(\n rectX, rectY - fontSize, textMetrics.width + 8, fontSize + 4);\n\n // Draw the text itself.\n ctx.fillStyle = '#FFFFFF'; // White text\n ctx.fillText(text, rectX + 4, rectY + 2);\n });\n\n // Create a link and trigger the download.\n const timestamp =\n new Date().toISOString().slice(0, 19).replace('T', '_').replace(\n /:/g, '-');\n const link = document.createElement('a');\n link.download = `detection_debug_${timestamp}.png`;\n link.href = canvas.toDataURL('image/png');\n link.click();\n };\n img.src = base64Image;\n }\n\n /**\n * Creates a simple debug visualization for an object based on its position\n * (center of its 2D detection bounding box).\n * @param object - The detected object to visualize.\n */\n private async _createDebugVisual(object: DetectedObject) {\n // Create sphere.\n const sphere = new THREE.Mesh(\n new THREE.SphereGeometry(0.03, 16, 16),\n new THREE.MeshBasicMaterial({color: 0xff4285F4}));\n sphere.position.copy(object.position);\n\n // Create and configure the text label using Troika.\n const {Text} = await import('troika-three-text');\n const textLabel = new Text();\n textLabel.text = object.label;\n textLabel.fontSize = 0.07;\n textLabel.color = 0xffffff;\n textLabel.anchorX = 'center';\n textLabel.anchorY = 'bottom';\n\n // Position the label above the sphere\n textLabel.position.copy(sphere.position);\n textLabel.position.y += 0.04; // Offset above the sphere.\n\n this._debugVisualsGroup!.add(sphere, textLabel);\n textLabel.sync(); // Required for Troika text to appear.\n }\n\n /**\n * Builds the Gemini configuration object from the world options.\n */\n private _buildGeminiConfig() {\n const geminiOptions = this.options.objects.backendConfig.gemini;\n return {\n thinkingConfig: {\n thinkingBudget: 0,\n },\n responseMimeType: 'application/json',\n responseSchema: geminiOptions.responseSchema,\n systemInstruction: [{text: geminiOptions.systemInstruction}],\n };\n }\n}\n","import * as THREE from 'three';\n\n/**\n * Represents a single detected plane in the XR environment. It's a THREE.Mesh\n * that also holds metadata about the plane's properties.\n * Note: This requires experimental flag for Chrome.\n */\nexport class DetectedPlane extends THREE.Mesh {\n /**\n * The underlying XRPlane object from the WebXR API.\n * @see https://immersive-web.github.io/real-world-geometry/plane-detection.html#xrplane\n */\n xrPlane: XRPlane;\n\n /**\n * A semantic label for the plane (e.g., 'floor', 'wall', 'ceiling', 'table').\n * Since xrPlane.semanticLabel is readonly, this allows user authoring.\n */\n label: string;\n\n /**\n * The orientation of the plane ('Horizontal' or 'Vertical').\n */\n orientation: XRPlaneOrientation;\n\n /**\n * @param xrPlane - The plane object from the WebXR API.\n * @param material - The material for the mesh.\n */\n constructor(xrPlane: XRPlane, material: THREE.Material) {\n // Create geometry from the plane's polygon points.\n const planePolygon = xrPlane.polygon;\n const vertices = [];\n for (const point of planePolygon) {\n vertices.push(new THREE.Vector2(point.x, point.z));\n }\n const shape = new THREE.Shape(vertices);\n const geometry = new THREE.ShapeGeometry(shape);\n\n // ShapeGeometry creates a mesh in the XY plane by default.\n // We must rotate it to lie flat in the XZ plane to correctly represent\n // horizontal surfaces before applying the world pose provided by the API.\n geometry.rotateX(Math.PI / 2);\n\n super(geometry, material);\n\n this.xrPlane = xrPlane;\n this.label = xrPlane.semanticLabel || 'unknown';\n this.orientation = xrPlane.orientation;\n }\n};\n","import * as THREE from 'three';\n\nimport {Script} from '../../core/Script';\nimport {WorldOptions} from '../WorldOptions';\n\nimport {DetectedPlane} from './DetectedPlane';\n\n/**\n * Detects and manages real-world planes provided by the WebXR Plane Detection\n * API. It creates, updates, and removes `Plane` mesh objects in the scene.\n */\nexport class PlaneDetector extends Script {\n static dependencies = {options: WorldOptions, renderer: THREE.WebGLRenderer};\n\n /**\n * A map from the WebXR `XRPlane` object to our custom `DetectedPlane` mesh.\n */\n private _detectedPlanes = new Map<XRPlane, DetectedPlane>();\n\n /**\n * The material used for visualizing planes when debugging.\n */\n private _debugMaterial!: THREE.Material;\n\n /**\n * The reference space used for poses.\n */\n private _xrRefSpace?: XRReferenceSpace;\n private renderer!: THREE.WebGLRenderer;\n\n /**\n * Initializes the PlaneDetector.\n */\n override init({options, renderer}:\n {options: WorldOptions, renderer: THREE.WebGLRenderer}) {\n this.renderer = renderer;\n if (options.planes.showDebugVisualizations) {\n this._debugMaterial = new THREE.MeshBasicMaterial(\n {color: 0xffff00, wireframe: true, side: THREE.DoubleSide});\n }\n }\n\n /**\n * Processes the XRFrame to update plane information.\n */\n override update(_: number, frame: XRFrame) {\n if (!frame || !frame.detectedPlanes) return;\n\n this._xrRefSpace =\n this._xrRefSpace || this.renderer.xr.getReferenceSpace() || undefined;\n\n if (!this._xrRefSpace) return;\n\n const detectedPlanesInFrame = frame.detectedPlanes;\n const planesToRemove = new Set(this._detectedPlanes.keys());\n\n for (const xrPlane of detectedPlanesInFrame) {\n planesToRemove.delete(xrPlane); // This plane is still active.\n\n const existingPlaneMesh = this._detectedPlanes.get(xrPlane);\n\n if (existingPlaneMesh) {\n // Plane already exists, check if it needs an update.\n if (xrPlane.lastChangedTime >\n (existingPlaneMesh.xrPlane.lastChangedTime || 0)) {\n this._updatePlaneMesh(frame, existingPlaneMesh, xrPlane);\n }\n } else {\n // This is a newly detected plane.\n this._addPlaneMesh(frame, xrPlane);\n }\n }\n\n // Remove planes that are no longer detected.\n for (const xrPlane of planesToRemove) {\n this._removePlaneMesh(xrPlane);\n }\n }\n\n /**\n * Creates and adds a new `Plane` mesh to the scene.\n * @param frame - WebXR frame.\n * @param xrPlane - The new WebXR plane object.\n */\n private _addPlaneMesh(frame: XRFrame, xrPlane: XRPlane) {\n const material =\n this._debugMaterial || new THREE.MeshBasicMaterial({visible: false});\n const planeMesh = new DetectedPlane(xrPlane, material);\n\n this._updatePlanePose(frame, planeMesh, xrPlane);\n\n this._detectedPlanes.set(xrPlane, planeMesh);\n this.add(planeMesh);\n }\n\n /**\n * Updates an existing `DetectedPlane` mesh's geometry and pose.\n * @param frame - WebXR frame.\n * @param planeMesh - The mesh to update.\n * @param xrPlane - The updated plane data.\n */\n private _updatePlaneMesh(\n frame: XRFrame, planeMesh: DetectedPlane, xrPlane: XRPlane) {\n // Recreate geometry from the new polygon.\n const newVertices = xrPlane.polygon.map(p => new THREE.Vector2(p.x, p.z));\n const newShape = new THREE.Shape(newVertices);\n const newGeometry = new THREE.ShapeGeometry(newShape);\n\n planeMesh.geometry.dispose();\n planeMesh.geometry = newGeometry;\n planeMesh.xrPlane = xrPlane; // Update the reference.\n\n this._updatePlanePose(frame, planeMesh, xrPlane);\n }\n\n /**\n * Removes a `Plane` mesh from the scene and disposes of its resources.\n * @param xrPlane - The WebXR plane object to remove.\n */\n private _removePlaneMesh(xrPlane: XRPlane) {\n const planeMesh = this._detectedPlanes.get(xrPlane);\n if (planeMesh) {\n planeMesh.geometry.dispose();\n this.remove(planeMesh);\n this._detectedPlanes.delete(xrPlane);\n }\n }\n\n /**\n * Updates the position and orientation of a `DetectedPlane` mesh from its XR\n * pose.\n * @param frame - The current XRFrame.\n * @param planeMesh - The mesh to update.\n * @param xrPlane - The plane data with the pose.\n */\n private _updatePlanePose(\n frame: XRFrame, planeMesh: DetectedPlane, xrPlane: XRPlane) {\n const pose = frame.getPose(xrPlane.planeSpace, this._xrRefSpace!);\n if (pose) {\n planeMesh.position.copy(pose.transform.position);\n planeMesh.quaternion.copy(pose.transform.orientation);\n }\n }\n\n /**\n * Retrieves a list of detected planes, optionally filtered by a semantic\n * label.\n *\n * @param label - The semantic label to filter by (e.g.,\n * 'floor', 'wall').\n * If null or undefined, all detected planes are returned.\n * @returns An array of `DetectedPlane` objects\n * matching the criteria.\n */\n get(label?: string) {\n const allPlanes = Array.from(this._detectedPlanes.values());\n if (!label) {\n return allPlanes;\n }\n return allPlanes.filter(plane => plane.label === label);\n }\n\n /**\n * Toggles the visibility of the debug meshes for all planes.\n * Requires `showDebugVisualizations` to be true in the options.\n * @param visible - Whether to show or hide the planes.\n */\n showDebugVisualizations(visible = true) {\n if (this._debugMaterial) {\n this.visible = visible;\n }\n }\n}\n","import * as THREE from 'three';\n\nimport {Script} from '../core/Script';\nimport {placeObjectAtIntersectionFacingTarget} from '../utils/ObjectPlacement';\n\nimport {ObjectDetector} from './objects/ObjectDetector';\nimport {PlaneDetector} from './planes/PlaneDetector';\nimport {WorldOptions} from './WorldOptions';\n// Import other modules as they are implemented in future.\n// import { SceneMesh } from '/depth/SceneMesh.js';\n// import { LightEstimation } from '/lighting/LightEstimation.js';\n// import { HumanRecognizer } from '/human/HumanRecognizer.js';\n\n/**\n * Manages all interactions with the real-world environment perceived by the XR\n * device. This class abstracts the complexity of various perception APIs\n * (Depth, Planes, Meshes, etc.) and provides a simple, event-driven interface\n * for developers to use `this.world.depth.mesh`, `this.world.planes`.\n */\nexport class World extends Script {\n static dependencies = {\n options: WorldOptions,\n camera: THREE.Camera,\n };\n\n /**\n * Configuration options for all world-sensing features.\n */\n options!: WorldOptions;\n\n /**\n * The depth module instance. Null if not enabled.\n */\n // depth = null;\n\n /**\n * The light estimation module instance. Null if not enabled.\n */\n // lighting = null;\n\n /**\n * The plane detection module instance. Null if not enabled.\n * Not recommended for anchoring.\n */\n planes?: PlaneDetector;\n\n /**\n * The scene mesh module instance. Null if not enabled.\n * TODO: Not yet supported in Chrome.\n */\n // meshes = null;\n\n /**\n * The object recognition module instance. Null if not enabled.\n */\n objects?: ObjectDetector;\n\n /**\n * A Three.js Raycaster for performing intersection tests.\n */\n private raycaster = new THREE.Raycaster();\n\n private camera!: THREE.Camera;\n\n /**\n * Initializes the world-sensing modules based on the provided configuration.\n * This method is called automatically by the XRCore.\n */\n override async init({options, camera}:\n {options: WorldOptions, camera: THREE.Camera}) {\n this.options = options;\n this.camera = camera;\n\n if (!this.options || !this.options.enabled) {\n return;\n }\n\n // Conditionally initialize each perception module based on options.\n if (this.options.planes.enabled) {\n this.planes = new PlaneDetector();\n this.add(this.planes);\n }\n\n if (this.options.objects.enabled) {\n this.objects = new ObjectDetector();\n this.add(this.objects);\n }\n\n\n // TODO: Initialize other modules as they are available & implemented.\n /*\n if (this.options.sceneMesh.enabled) {\n this.meshes = new SceneMesh();\n }\n\n if (this.options.lighting.enabled) {\n this.lighting = new LightEstimation();\n }\n\n if (this.options.humans.enabled) {\n this.humans = new HumanRecognizer();\n }\n */\n }\n\n /**\n * Places an object at the reticle.\n */\n anchorObjectAtReticle(_object: THREE.Object3D, _reticle: THREE.Object3D) {\n throw new Error('Method not implemented');\n }\n\n /**\n * Updates all active world-sensing modules with the latest XRFrame data.\n * This method is called automatically by the XRCore on each frame.\n * @param _timestamp - The timestamp for the current frame.\n * @param frame - The current XRFrame, containing environmental\n * data.\n * @override\n */\n update(_timestamp: number, frame?: XRFrame) {\n if (!this.options?.enabled || !frame) {\n return;\n }\n\n // Note: Object detection is not run per-frame by default as it's a\n // costly operation. It should be triggered manually via\n // `this.world.objects.runDetection()`.\n\n // TODO: Update other modules as they are available & implemented.\n // this.meshes?.update(frame);\n // this.lighting?.update(frame);\n // this.humans?.update(frame);\n }\n\n /**\n * Performs a raycast from a controller against detected real-world surfaces\n * (currently planes) and places a 3D object at the intersection point,\n * oriented to face the user.\n *\n * We recommend using /templates/3_depth/ to anchor objects based on\n * depth mesh for mixed reality experience for accuracy. This function is\n * design for demonstration purposes.\n *\n * @param objectToPlace - The object to position in the\n * world.\n * @param controller - The controller to use for raycasting.\n * @returns True if the object was successfully placed, false\n * otherwise.\n */\n placeOnSurface(objectToPlace: THREE.Object3D, controller: THREE.Object3D) {\n if (!this.planes) {\n console.warn('Cannot placeOnSurface: PlaneDetector is not enabled.');\n return false;\n }\n\n const allPlanes = this.planes.get();\n if (allPlanes.length === 0) {\n return false; // No surfaces to cast against.\n }\n\n this.raycaster.setFromXRController(controller as THREE.XRTargetRaySpace);\n\n const intersections = this.raycaster.intersectObjects(allPlanes);\n\n if (intersections.length > 0) {\n const intersection = intersections[0];\n placeObjectAtIntersectionFacingTarget(\n objectToPlace, intersection, this.camera);\n return true;\n }\n\n return false;\n }\n\n /**\n * Toggles the visibility of all debug visualizations for world features.\n * @param visible - Whether the visualizations should be visible.\n */\n showDebugVisualizations(visible = true) {\n this.planes?.showDebugVisualizations(visible);\n this.objects?.showDebugVisualizations(visible);\n // this.meshes?.showDebugVisualizations(visible);\n }\n}\n","import * as THREE from 'three';\n\nimport {Options} from '../Options';\nimport {MeshScript} from '../Script';\n\n/**\n * Defines the possible XR modes.\n */\nexport type XRMode = 'AR'|'VR';\n\nexport type XRTransitionToVROptions = {\n /** The target opacity. */\n targetAlpha?: number;\n /** The target color. Defaults to `defaultBackgroundColor`. */\n color?: THREE.Color | number;\n}\n\n/**\n * Manages smooth transitions between AR (transparent) and VR (colored)\n * backgrounds within an active XR session.\n */\nexport class XRTransition extends\n MeshScript<THREE.SphereGeometry, THREE.MeshBasicMaterial> {\n ignoreReticleRaycast = true;\n static dependencies = {\n renderer: THREE.WebGLRenderer,\n camera: THREE.Camera,\n timer: THREE.Timer,\n scene: THREE.Scene,\n options: Options,\n };\n\n /** Current XR mode, either 'AR' or 'VR'. Defaults to 'AR'. */\n public currentMode: XRMode = 'AR';\n\n /** The duration in seconds for the fade-in and fade-out transitions. */\n private transitionTime = 1.5;\n private renderer!: THREE.WebGLRenderer;\n private scene!: THREE.Scene;\n private sceneCamera!: THREE.Camera;\n private timer!: THREE.Timer;\n private targetAlpha = 0;\n private defaultBackgroundColor = new THREE.Color(0xffffff);\n\n constructor() {\n const geometry = new THREE.SphereGeometry(1, 64, 32);\n const material = new THREE.MeshBasicMaterial({\n color: 0xffffff,\n transparent: true,\n opacity: 0,\n depthTest: false,\n side: THREE.BackSide, // Render on the inside of the sphere.\n });\n super(geometry, material);\n this.ignoreReticleRaycast = true;\n this.renderOrder = -Infinity;\n }\n\n init({renderer, camera, timer, scene, options}: {\n renderer: THREE.WebGLRenderer,\n camera: THREE.Camera,\n timer: THREE.Timer,\n scene: THREE.Scene,\n options: Options\n }) {\n this.renderer = renderer;\n this.sceneCamera = camera;\n this.timer = timer;\n this.scene = scene;\n this.transitionTime = options.transition.transitionTime;\n this.defaultBackgroundColor.set(options.transition.defaultBackgroundColor);\n this.material.color.copy(this.defaultBackgroundColor);\n this.scene.add(this);\n }\n\n /**\n * Starts the transition to a VR background.\n * @param options - Optional parameters.\n */\n toVR({targetAlpha = 1.0, color}: XRTransitionToVROptions = {}) {\n this.targetAlpha = THREE.MathUtils.clamp(targetAlpha, 0, 1);\n this.material.color.set(color ?? this.defaultBackgroundColor);\n this.currentMode = 'VR';\n }\n\n /**\n * Starts the transition to a transparent AR background.\n */\n toAR() {\n this.targetAlpha = 0.0;\n this.currentMode = 'AR';\n }\n\n update() {\n // Always keep the fade mesh centered on the active camera.\n if (this.renderer.xr.isPresenting) {\n this.renderer.xr.getCamera().getWorldPosition(this.position);\n } else {\n this.sceneCamera.getWorldPosition(this.position);\n }\n\n const currentOpacity = this.material.opacity;\n if (currentOpacity !== this.targetAlpha) {\n const lerpFactor = this.timer.getDelta() / this.transitionTime;\n this.material.opacity =\n THREE.MathUtils.lerp(currentOpacity, this.targetAlpha, lerpFactor);\n if (Math.abs(this.material.opacity - this.targetAlpha) < 0.01) {\n this.material.opacity = this.targetAlpha;\n }\n }\n }\n\n dispose() {\n if (this.parent) {\n this.parent.remove(this);\n }\n this.material.dispose();\n this.geometry.dispose();\n }\n}\n","import * as THREE from 'three';\n\nimport {AI} from '../ai/AI';\nimport {AIOptions} from '../ai/AIOptions';\nimport {XRDeviceCamera} from '../camera/XRDeviceCamera';\nimport {UI_OVERLAY_LAYER} from '../constants';\nimport {Depth} from '../depth/Depth';\nimport {DepthOptions} from '../depth/DepthOptions';\nimport {Hands} from '../input/Hands';\nimport {Input} from '../input/Input';\nimport {Lighting} from '../lighting/Lighting';\nimport {Physics} from '../physics/Physics';\nimport {Simulator} from '../simulator/Simulator';\nimport {SimulatorOptions} from '../simulator/SimulatorOptions';\nimport {CoreSound} from '../sound/CoreSound';\nimport {SoundOptions} from '../sound/SoundOptions';\nimport {UI} from '../ui/UI';\nimport {onDesktopUserAgent} from '../utils/BrowserUtils';\nimport {callInitWithDependencyInjection} from '../utils/DependencyInjection';\nimport {loadingSpinnerManager} from '../utils/LoadingSpinnerManager';\nimport {traverseUtil} from '../utils/SceneGraphUtils';\nimport {DragManager} from '../ux/DragManager';\nimport {World} from '../world/World';\nimport {WorldOptions} from '../world/WorldOptions';\n\nimport {Registry} from './components/Registry';\nimport {ScreenshotSynthesizer} from './components/ScreenshotSynthesizer';\nimport {ScriptsManager} from './components/ScriptsManager';\nimport {WaitFrame} from './components/WaitFrame';\nimport {IMMERSIVE_AR, WebXRSessionEventType, WebXRSessionManager} from './components/WebXRSessionManager';\nimport {XRButton} from './components/XRButton';\nimport {XREffects} from './components/XREffects';\nimport {XRTransition} from './components/XRTransition';\nimport {Options} from './Options';\nimport {Script} from './Script';\nimport {User} from './User';\n\n/**\n * Core is the central engine of the XR Blocks framework, acting as a\n * singleton manager for all XR subsystems. Its primary goal is to abstract\n * low-level WebXR and THREE.js details, providing a simplified and powerful API\n * for developers and AI agents to build interactive XR applications.\n */\nexport class Core {\n static instance?: Core;\n /**\n * Component responsible for capturing screenshots of the XR scene for AI.\n */\n screenshotSynthesizer = new ScreenshotSynthesizer();\n /**\n * Component responsible for waiting for the next frame.\n */\n waitFrame = new WaitFrame();\n /**\n * Registry used for dependency injection on existing subsystems.\n */\n registry = new Registry();\n\n /**\n * A clock for tracking time deltas. Call clock.getDeltaTime().\n */\n timer = new THREE.Timer();\n\n /** Manages hand, mouse, gaze inputs. */\n input = new Input();\n\n /** The main camera for rendering. */\n camera!: THREE.PerspectiveCamera;\n\n /** The root scene graph for all objects. */\n scene = new THREE.Scene();\n\n /** Represents the user in the XR scene. */\n user = new User();\n\n /** Manages all UI elements. */\n ui = new UI();\n\n /** Manages all (spatial) audio playback. */\n sound = new CoreSound();\n\n /** Manages the desktop XR simulator. */\n simulator = new Simulator(this.renderScene.bind(this));\n\n /** Manages drag-and-drop interactions. */\n dragManager = new DragManager();\n\n /** Manages drag-and-drop interactions. */\n world = new World();\n\n /** A shared texture loader. */\n textureLoader = new THREE.TextureLoader();\n\n private webXRSettings: XRSessionInit = {};\n\n /** Whether the XR simulator is currently active. */\n simulatorRunning = false;\n\n renderer!: THREE.WebGLRenderer;\n options!: Options;\n deviceCamera?: XRDeviceCamera;\n depth = new Depth();\n lighting?: Lighting;\n physics?: Physics;\n xrButton?: XRButton;\n effects?: XREffects;\n ai = new AI();\n transition?: XRTransition;\n currentFrame?: XRFrame;\n scriptsManager = new ScriptsManager(async (script: Script) => {\n await callInitWithDependencyInjection(script, this.registry, this);\n if (this.physics) {\n await script.initPhysics(this.physics);\n }\n });\n renderSceneOverride?:\n (renderer: THREE.WebGLRenderer, scene: THREE.Scene,\n camera: THREE.Camera) => void;\n webXRSessionManager?: WebXRSessionManager;\n\n /**\n * Core is a singleton manager that manages all XR \"blocks\".\n * It initializes core components and abstractions like the scene, camera,\n * user, UI, AI, and input managers.\n */\n constructor() {\n if (Core.instance) {\n return Core.instance;\n }\n Core.instance = this;\n\n this.scene.name = 'XR Blocks Scene';\n\n // Separate calls because spark hijacks THREE.Scene.add and only supports\n // adding objects one at a time. See\n // https://github.com/sparkjsdev/spark/blob/0edfc8d9232b8f6eb036d27af57dc40daf94e1f3/src/SparkRenderer.ts#L63\n this.scene.add(this.user);\n this.scene.add(this.dragManager);\n this.scene.add(this.ui);\n this.scene.add(this.sound);\n this.scene.add(this.world);\n\n this.registry.register(this.registry);\n this.registry.register(this.waitFrame);\n this.registry.register(this.scene);\n this.registry.register(this.timer);\n this.registry.register(this.input);\n this.registry.register(this.user);\n this.registry.register(this.ui);\n this.registry.register(this.sound);\n this.registry.register(this.dragManager);\n this.registry.register(this.user);\n this.registry.register(this.simulator);\n this.registry.register(this.scriptsManager);\n this.registry.register(this.depth);\n }\n\n /**\n * Initializes the Core system with a given set of options. This includes\n * setting up the renderer, enabling features like controllers, depth\n * sensing, and physics, and starting the render loop.\n * @param options - Configuration options for the\n * session.\n */\n async init(options = new Options()) {\n loadingSpinnerManager.showSpinner();\n\n this.registry.register(options, Options);\n this.registry.register(options.depth, DepthOptions);\n this.registry.register(options.simulator, SimulatorOptions);\n this.registry.register(options.world, WorldOptions);\n this.registry.register(options.ai, AIOptions);\n this.registry.register(options.sound, SoundOptions);\n\n if (options.transition.enabled) {\n this.transition = new XRTransition();\n this.user.add(this.transition);\n this.registry.register(this.transition);\n }\n\n this.camera = new THREE.PerspectiveCamera(\n /*fov=*/ 90, window.innerWidth / window.innerHeight,\n /*near=*/ options.camera.near, /*far=*/ options.camera.far);\n this.registry.register(this.camera, THREE.Camera);\n this.registry.register(this.camera, THREE.PerspectiveCamera);\n this.renderer = new THREE.WebGLRenderer({\n antialias: options.antialias,\n stencil: options.stencil,\n alpha: true,\n logarithmicDepthBuffer: options.logarithmicDepthBuffer\n });\n this.renderer.setPixelRatio(window.devicePixelRatio);\n this.renderer.setSize(window.innerWidth, window.innerHeight);\n this.renderer.xr.enabled = true;\n this.registry.register(this.renderer);\n\n // \"local-floor\" sets the scene origin at the user's feet,\n // \"local\" sets the scene origin near their head.\n this.renderer.xr.setReferenceSpaceType('local-floor');\n\n const xrContainer = document.createElement('div');\n document.body.appendChild(xrContainer);\n xrContainer.appendChild(this.renderer.domElement);\n\n this.options = options;\n\n // Sets up controllers.\n if (options.controllers.enabled) {\n this.input.init(\n {scene: this.scene, options: options, renderer: this.renderer});\n this.input.bindSelectStart(this.scriptsManager.callSelectStartBound);\n this.input.bindSelectEnd(this.scriptsManager.callSelectEndBound);\n this.input.bindSelect(this.scriptsManager.callSelectBound);\n this.input.bindSqueezeStart(this.scriptsManager.callSqueezeStartBound);\n this.input.bindSqueezeEnd(this.scriptsManager.callSqueezeEndBound);\n this.input.bindSqueeze(this.scriptsManager.callSqueezeBound);\n this.input.bindKeyDown(this.scriptsManager.callKeyDownBound);\n this.input.bindKeyUp(this.scriptsManager.callKeyUpBound);\n }\n\n // Sets up device camera.\n if (options.deviceCamera?.enabled) {\n this.deviceCamera = new XRDeviceCamera(options.deviceCamera);\n await this.deviceCamera.init();\n this.registry.register(this.deviceCamera);\n }\n\n const webXRRequiredFeatures: string[] = [];\n this.webXRSettings.requiredFeatures = webXRRequiredFeatures;\n // Sets up depth.\n if (options.depth.enabled) {\n webXRRequiredFeatures.push('depth-sensing');\n webXRRequiredFeatures.push('local-floor');\n this.webXRSettings.depthSensing = {\n usagePreference: ['cpu-optimized'],\n dataFormatPreference:\n [this.options.depth.useFloat32 ? 'float32' : 'luminance-alpha'],\n };\n this.depth.init(\n this.camera, options.depth, this.renderer, this.registry, this.scene);\n }\n if (options.hands.enabled) {\n webXRRequiredFeatures.push('hand-tracking');\n this.user.hands = new Hands(this.input.hands);\n }\n if (options.world.planes.enabled) {\n webXRRequiredFeatures.push('plane-detection');\n }\n\n // Sets up lighting.\n if (options.lighting.enabled) {\n webXRRequiredFeatures.push('light-estimation');\n this.lighting = new Lighting();\n this.lighting.init(\n options.lighting, this.renderer, this.scene, this.depth);\n }\n\n // Sets up physics.\n if (options.physics && options.physics.RAPIER) {\n this.physics = new Physics();\n this.registry.register(this.physics);\n await this.physics.init({physicsOptions: options.physics});\n\n if (options.depth.enabled) {\n this.depth.depthMesh?.initRapierPhysics(\n this.physics.RAPIER, this.physics.blendedWorld);\n }\n }\n\n this.webXRSessionManager = new WebXRSessionManager(\n this.renderer,\n this.webXRSettings,\n IMMERSIVE_AR,\n );\n this.webXRSessionManager.addEventListener(\n WebXRSessionEventType.SESSION_START,\n (event) => this.onXRSessionStarted(event.session),\n );\n this.webXRSessionManager.addEventListener(\n WebXRSessionEventType.SESSION_END,\n this.onXRSessionEnded.bind(this),\n );\n\n // Sets up xrButton.\n const shouldAutostartSimulator = this.options.xrButton.autostartSimulator ||\n this.options.xrButton.autostartSimulatorOnDesktop &&\n this.options.xrButton.enableSimulator && onDesktopUserAgent();\n if (!shouldAutostartSimulator && options.xrButton.enabled) {\n this.xrButton = new XRButton(\n this.webXRSessionManager,\n options.xrButton?.startText,\n options.xrButton?.endText,\n options.xrButton?.invalidText,\n options.xrButton?.startSimulatorText,\n options.xrButton?.enableSimulator,\n options.xrButton?.showSimulatorButtonOnMobile,\n this.startSimulator.bind(this),\n );\n document.body.appendChild(this.xrButton.domElement);\n }\n\n await this.webXRSessionManager.initialize();\n\n // Sets up postprocessing effects.\n if (options.usePostprocessing) {\n this.effects = new XREffects(this.renderer, this.scene, this.timer);\n this.simulator.effects = this.effects;\n }\n\n // Sets up AI services.\n if (options.ai.enabled) {\n this.registry.register(this.ai);\n this.scene.add(this.ai);\n // Manually init the script in case other scripts rely on it.\n await this.scriptsManager.initScript(this.ai);\n }\n\n await this.scriptsManager.syncScriptsWithScene(this.scene);\n\n // For desktop only:\n window.addEventListener('resize', this.onWindowResize.bind(this));\n\n this.renderer.setAnimationLoop(this.update.bind(this));\n\n if (this.physics) {\n setInterval(this.physicsStep.bind(this), 1000 * this.physics.timestep);\n }\n\n if (this.options.reticles.enabled) {\n this.input.addReticles();\n }\n\n if (shouldAutostartSimulator) {\n this.startSimulator();\n }\n\n if (!loadingSpinnerManager.isLoading) {\n loadingSpinnerManager.hideSpinner();\n }\n }\n\n /**\n * The main update loop, called every frame by the renderer. It orchestrates\n * all per-frame updates for subsystems and scripts.\n *\n * Order:\n * 1. Depth\n * 2. World Perception\n * 3. Input / Reticles / UIs\n * 4. Scripts\n * @param time - The current time in milliseconds.\n * @param frame - The WebXR frame object, if in an XR session.\n */\n private update(time: number, frame: XRFrame) {\n this.currentFrame = frame;\n this.timer.update(time);\n if (this.simulatorRunning) {\n this.simulator.simulatorUpdate();\n }\n this.depth.update(frame);\n\n if (this.lighting) {\n this.lighting.update();\n }\n\n // Traverse the scene to find all scripts.\n this.scriptsManager.syncScriptsWithScene(this.scene);\n\n // Updates reticles and UIs.\n for (const script of this.scriptsManager.scripts) {\n script.ux.reset();\n }\n this.input.update();\n\n // Updates scripts with user interactions.\n for (const controller of this.input.controllers) {\n if (controller.userData.selected) {\n for (const script of this.scriptsManager.scripts) {\n script.onSelecting({target: controller});\n }\n }\n }\n\n for (const controller of this.input.controllers) {\n if (controller.userData.squeezing) {\n for (const script of this.scriptsManager.scripts) {\n script.onSqueezing({target: controller});\n }\n }\n }\n\n // Run callbacks that use wait frame.\n this.waitFrame.onFrame();\n\n // Updates renderings.\n for (const script of this.scriptsManager.scripts) {\n script.update(time, frame);\n }\n\n this.renderSimulatorAndScene();\n this.screenshotSynthesizer.onAfterRender(this.renderer, this.deviceCamera);\n if (this.simulatorRunning) {\n this.simulator.renderSimulatorScene();\n }\n }\n\n /**\n * Advances the physics simulation by a fixed timestep and calls the\n * corresponding physics update on all active scripts.\n */\n private physicsStep() {\n this.physics!.physicsStep();\n for (const script of this.scriptsManager.scripts) {\n script.physicsStep();\n }\n }\n\n /**\n * Lifecycle callback executed when an XR session starts. Notifies all active\n * scripts.\n * @param session - The newly started WebXR session.\n */\n private onXRSessionStarted(session: XRSession) {\n this.scriptsManager.onXRSessionStarted(session);\n }\n\n private async startSimulator() {\n this.xrButton?.domElement.remove();\n this.scene.add(this.simulator);\n await this.scriptsManager.initScript(this.simulator);\n this.onSimulatorStarted();\n }\n\n /**\n * Lifecycle callback executed when an XR session ends. Notifies all active\n * scripts.\n */\n private onXRSessionEnded() {\n this.startSimulator();\n this.scriptsManager.onXRSessionEnded();\n }\n\n /**\n * Lifecycle callback executed when the desktop simulator starts. Notifies\n * all active scripts.\n */\n private onSimulatorStarted() {\n this.simulatorRunning = true;\n this.scriptsManager.onSimulatorStarted();\n if (this.lighting) {\n this.lighting.simulatorRunning = true;\n }\n }\n\n /**\n * Handles browser window resize events to keep the camera and renderer\n * synchronized.\n */\n private onWindowResize() {\n this.camera.aspect = window.innerWidth / window.innerHeight;\n this.camera.updateProjectionMatrix();\n this.renderer.setSize(window.innerWidth, window.innerHeight);\n }\n\n private renderSimulatorAndScene() {\n if (this.simulatorRunning) {\n this.simulator.renderScene();\n } else {\n this.renderScene();\n }\n }\n\n private renderScene(cameraOverride?: THREE.Camera) {\n if (this.renderSceneOverride) {\n this.renderSceneOverride(\n this.renderer, this.scene, cameraOverride ?? this.camera);\n } else if (this.effects) {\n this.effects.render();\n } else {\n this.renderer.render(this.scene, cameraOverride ?? this.camera);\n if (traverseUtil(\n this.scene,\n (node: THREE.Object3D) =>\n node.layers.isEnabled(UI_OVERLAY_LAYER))) {\n const originalLayers = this.camera.layers.mask;\n this.camera.layers.set(UI_OVERLAY_LAYER);\n this.renderer.render(this.scene, this.camera);\n this.camera.layers.mask = originalLayers;\n }\n }\n }\n};\n","import * as THREE from 'three';\nimport type {Shader} from '../../utils/Types';\n\nexport class OcclusionUtils {\n /**\n * Creates a simple material used for rendering objects into the occlusion\n * map. This material is intended to be used with `renderer.overrideMaterial`.\n * @returns A new instance of THREE.MeshBasicMaterial.\n */\n static createOcclusionMapOverrideMaterial() {\n return new THREE.MeshBasicMaterial();\n }\n\n /**\n * Modifies a material's shader in-place to incorporate distance-based\n * alpha occlusion. This is designed to be used with a material's\n * `onBeforeCompile` property. This only works with built-in three.js\n * materials.\n * @param shader - The shader object provided by onBeforeCompile.\n */\n static addOcclusionToShader(shader: Shader) {\n shader.uniforms.occlusionEnabled = {value: true};\n shader.uniforms.tOcclusionMap = {value: null};\n shader.uniforms.uOcclusionClipFromWorld = {value: new THREE.Matrix4()};\n shader.defines = {USE_UV: true, DISTANCE: true};\n shader.vertexShader =\n shader.vertexShader\n .replace(\n '#include <common>',\n [\n 'uniform mat4 uOcclusionClipFromWorld;',\n 'varying vec4 vOcclusionScreenCoord;', '#include <common>'\n ].join('\\n'))\n .replace('#include <fog_vertex>', [\n '#include <fog_vertex>',\n 'vOcclusionScreenCoord = uOcclusionClipFromWorld * worldPosition;',\n ].join('\\n'));\n shader.fragmentShader =\n shader.fragmentShader\n .replace(\n 'uniform vec3 diffuse;',\n [\n 'uniform vec3 diffuse;',\n 'uniform bool occlusionEnabled;',\n 'uniform sampler2D tOcclusionMap;',\n 'varying vec4 vOcclusionScreenCoord;',\n ].join('\\n'))\n .replace('vec4 diffuseColor = vec4( diffuse, opacity );', [\n 'vec4 diffuseColor = vec4( diffuse, opacity );',\n 'vec2 occlusion_coordinates = 0.5 + 0.5 * vOcclusionScreenCoord.xy / vOcclusionScreenCoord.w;',\n 'vec2 occlusion_sample = texture2D(tOcclusionMap, occlusion_coordinates.xy).rg;',\n 'occlusion_sample = occlusion_sample / max(0.0001, occlusion_sample.g);',\n 'float occlusion_value = clamp(occlusion_sample.r, 0.0, 1.0);',\n 'diffuseColor.a *= occlusionEnabled ? occlusion_value : 1.0;',\n ].join('\\n'));\n }\n}","import * as THREE from 'three';\n\nimport {UP, ZERO_VECTOR3} from './HelperConstants';\n\n// Reusable instances to avoid creating new objects in the render loop.\nconst euler = new THREE.Euler();\nconst matrix4 = new THREE.Matrix4();\nconst v1 = new THREE.Vector3();\n\n/**\n * Extracts only the yaw (Y-axis rotation) from a quaternion.\n * This is useful for making an object face a certain direction horizontally\n * without tilting up or down.\n *\n * @param rotation - The source quaternion from which to\n * extract the yaw.\n * @param target - The target\n * quaternion to store the result.\n * If not provided, a new quaternion will be created.\n * @returns The resulting quaternion containing only the yaw\n * rotation.\n */\nexport function extractYaw(\n rotation: Readonly<THREE.Quaternion>, target = new THREE.Quaternion()) {\n // Ensures the Y-axis rotation (yaw) is calculated first and is independent of\n // the X (pitch) and Z (roll) rotations. This prevents gimbal lock from\n // affecting the yaw value.\n euler.setFromQuaternion(rotation, 'YXZ');\n\n // Creates a new quaternion from only the yaw component (the rotation around\n // the 'up' vector).\n return target.setFromAxisAngle(UP, euler.y);\n}\n\n/**\n * Creates a rotation such that forward (0, 0, -1) points towards the forward\n * vector and the up direction is the normalized projection of the provided up\n * vector onto the plane orthogonal to the target.\n * @param forward - Forward vector\n * @param up - Up vector\n * @param target - Output\n * @returns\n */\nexport function lookAtRotation(\n forward: Readonly<THREE.Vector3>, up = UP,\n target = new THREE.Quaternion()) {\n matrix4.lookAt(ZERO_VECTOR3, forward, up);\n return target.setFromRotationMatrix(matrix4);\n}\n\n/**\n * Clamps the provided rotation's angle.\n * The rotation is modified in place.\n * @param rotation - The quaternion to clamp.\n * @param angle - The maximum allowed angle in radians.\n */\nexport function clampRotationToAngle(\n rotation: THREE.Quaternion, angle: number) {\n let currentAngle = 2 * Math.acos(rotation.w);\n currentAngle = (currentAngle + Math.PI) % (2 * Math.PI) - Math.PI;\n if (Math.abs(currentAngle) <= angle) {\n return;\n }\n const axis = v1.set(rotation.x, rotation.y, rotation.z)\n .multiplyScalar(1 / Math.sqrt(1 - rotation.w * rotation.w));\n axis.normalize();\n rotation.setFromAxisAngle(axis, angle * Math.sign(currentAngle));\n}\n","import {Injectable} from '../../utils/DependencyInjection';\n\nexport class SimulatorUserAction implements Injectable {\n static dependencies = {};\n async init(_options: object = {}) {}\n async play(_options: object = {}) {}\n}\n","import * as THREE from 'three';\n\nimport {WaitFrame} from '../../core/components/WaitFrame';\nimport {Input} from '../../input/Input';\nimport {UP} from '../../utils/HelperConstants';\nimport {clampRotationToAngle, lookAtRotation} from '../../utils/RotationUtils';\nimport {Simulator} from '../Simulator';\nimport {SimulatorControls} from '../SimulatorControls';\nimport {SimulatorUser} from '../SimulatorUser.js';\n\nimport {SimulatorUserAction} from './SimulatorUserAction';\n\nconst LOOK_AT_ANGLE_THRESHOLD = 3 * Math.PI / 180;\nconst ROTATION_SPEED_RADIANS_PER_SECOND = 1;\n\nconst controllerToTargetVector = new THREE.Vector3();\nconst targetWorldPosition = new THREE.Vector3();\nconst targetPositionRelativeToCamera = new THREE.Vector3();\nconst inverseControllerRotation = new THREE.Quaternion();\nconst finalRotation = new THREE.Quaternion();\nconst deltaRotation = new THREE.Quaternion();\n\nexport class PinchOnButtonAction extends SimulatorUserAction {\n static dependencies = {\n simulator: Simulator,\n camera: THREE.Camera,\n timer: THREE.Timer,\n input: Input,\n };\n private simulator!: Simulator;\n private camera!: THREE.Camera;\n private timer!: THREE.Timer;\n private input!: Input;\n\n constructor(private target: THREE.Object3D) {\n super();\n }\n\n async init({simulator, camera, timer, input}: {\n simulator: Simulator,\n camera: THREE.Camera,\n timer: THREE.Timer,\n input: Input\n }) {\n this.simulator = simulator;\n this.camera = camera;\n this.timer = timer;\n this.input = input\n }\n\n controllerIsPointingAtButton(\n controls: SimulatorControls, camera: THREE.Camera) {\n const controllerState = controls.simulatorControllerState;\n const controllerIndex = controllerState.currentControllerIndex;\n const localControllerPosition =\n controllerState.localControllerPositions[controllerIndex];\n const localControllerRotation =\n controllerState.localControllerOrientations[controllerIndex];\n this.target.getWorldPosition(targetWorldPosition);\n targetPositionRelativeToCamera.copy(targetWorldPosition)\n .applyMatrix4(camera.matrixWorldInverse);\n\n inverseControllerRotation.copy(localControllerRotation).invert();\n controllerToTargetVector.copy(targetPositionRelativeToCamera)\n .sub(localControllerPosition);\n lookAtRotation(controllerToTargetVector, UP, finalRotation);\n const angle = (finalRotation.angleTo(localControllerRotation) + Math.PI) %\n (2 * Math.PI) -\n Math.PI;\n return angle < LOOK_AT_ANGLE_THRESHOLD;\n }\n\n rotateControllerTowardsButton(\n controls: SimulatorControls, camera: THREE.Camera, deltaTime: number) {\n const controllerState = controls.simulatorControllerState;\n const controllerIndex = controllerState.currentControllerIndex;\n const localControllerPosition =\n controllerState.localControllerPositions[controllerIndex];\n const localControllerRotation =\n controllerState.localControllerOrientations[controllerIndex];\n this.target.getWorldPosition(targetWorldPosition);\n targetPositionRelativeToCamera.copy(targetWorldPosition)\n .applyMatrix4(camera.matrixWorldInverse);\n\n inverseControllerRotation.copy(localControllerRotation).invert();\n controllerToTargetVector.copy(targetPositionRelativeToCamera)\n .sub(localControllerPosition);\n lookAtRotation(controllerToTargetVector, UP, finalRotation);\n deltaRotation.copy(finalRotation).multiply(inverseControllerRotation);\n clampRotationToAngle(\n deltaRotation, ROTATION_SPEED_RADIANS_PER_SECOND * deltaTime);\n localControllerRotation.premultiply(deltaRotation);\n }\n\n pinchController() {\n const simulator = this.simulator;\n const controllerState = simulator.controls.simulatorControllerState;\n const newSelectingState = true;\n this.input.dispatchEvent({\n type: newSelectingState ? 'selectstart' : 'selectend',\n target: this.input.controllers[controllerState.currentControllerIndex]\n });\n if (controllerState.currentControllerIndex == 0) {\n simulator.hands.setLeftHandPinching(newSelectingState);\n } else {\n simulator.hands.setRightHandPinching(newSelectingState);\n }\n }\n\n async play({simulatorUser, journeyId, waitFrame}: {\n simulatorUser: SimulatorUser,\n journeyId: number,\n waitFrame: WaitFrame\n }) {\n let pinchedOnButton = false;\n\n while (simulatorUser.isOnJourneyId(journeyId) && (!pinchedOnButton)) {\n const deltaTime = this.timer.getDelta();\n if (!this.controllerIsPointingAtButton(\n this.simulator.controls, this.camera)) {\n this.rotateControllerTowardsButton(\n this.simulator.controls, this.camera, deltaTime);\n } else {\n this.pinchController();\n pinchedOnButton = true;\n }\n await waitFrame.waitFrame();\n }\n }\n}\n","import {Simulator} from '../Simulator';\n\nimport {SimulatorUserAction} from './SimulatorUserAction';\n\nexport class ShowHandsAction extends SimulatorUserAction {\n static dependencies = {simulator: Simulator};\n simulator!: Simulator;\n\n async init({simulator}: {simulator: Simulator}) {\n this.simulator = simulator;\n }\n\n async play() {\n if (this.simulator.hands) {\n this.simulator.hands.showHands();\n }\n }\n}\n","import * as THREE from 'three';\n\nimport {WaitFrame} from '../../core/components/WaitFrame';\nimport {UP} from '../../utils/HelperConstants';\nimport {clampRotationToAngle, lookAtRotation} from '../../utils/RotationUtils';\nimport {clamp} from '../../utils/utils';\nimport {SimulatorUser} from '../SimulatorUser';\n\nimport {SimulatorUserAction} from './SimulatorUserAction';\n\nconst NEAR_TARGET_DISTANCE = 0.5;\nconst NEAR_TARGET_THRESHOLD = 0.1;\nconst LOOK_AT_ANGLE_THRESHOLD = 3 * Math.PI / 180;\nconst MOVEMENT_SPEED_METERS_PER_SECOND = 1;\nconst ROTATION_SPEED_RADIANS_PER_SECOND = 1;\n\n// Temporary variables.\nconst targetWorldPosition = new THREE.Vector3();\nconst cameraToTargetVector = new THREE.Vector3();\n// A position close to the target to move to.\nconst closeToTargetPosition = new THREE.Vector3();\nconst deltaRotation = new THREE.Quaternion();\nconst finalRotation = new THREE.Quaternion();\nconst inverseCameraRotation = new THREE.Quaternion();\n\n/**\n * Represents a action to walk towards a panel or object.\n */\nexport class WalkTowardsPanelAction extends SimulatorUserAction {\n static dependencies = {camera: THREE.Camera, timer: THREE.Timer};\n camera!: THREE.Camera;\n timer!: THREE.Timer;\n\n constructor(private target: THREE.Object3D) {\n super();\n }\n\n async init({camera, timer}: {camera: THREE.Camera, timer: THREE.Timer}) {\n this.camera = camera;\n this.timer = timer;\n }\n\n isLookingAtTarget() {\n const camera = this.camera;\n this.target.getWorldPosition(targetWorldPosition);\n cameraToTargetVector.copy(targetWorldPosition).sub(camera.position);\n lookAtRotation(cameraToTargetVector, UP, finalRotation);\n const angle =\n (finalRotation.angleTo(camera.quaternion) + Math.PI) % (2 * Math.PI) -\n Math.PI;\n return angle < LOOK_AT_ANGLE_THRESHOLD;\n }\n\n isNearTarget() {\n const camera = this.camera;\n this.target.getWorldPosition(targetWorldPosition);\n cameraToTargetVector.copy(targetWorldPosition).sub(camera.position);\n return Math.abs(cameraToTargetVector.length() - NEAR_TARGET_DISTANCE) <\n NEAR_TARGET_THRESHOLD;\n }\n\n lookAtTarget() {\n const camera = this.camera;\n inverseCameraRotation.copy(camera.quaternion).invert();\n this.target.getWorldPosition(targetWorldPosition);\n cameraToTargetVector.copy(targetWorldPosition).sub(camera.position);\n lookAtRotation(cameraToTargetVector, UP, finalRotation);\n camera.quaternion.copy(finalRotation);\n }\n\n lookTowardsTarget() {\n const camera = this.camera;\n inverseCameraRotation.copy(camera.quaternion).invert();\n const deltaTime = this.timer.getDelta();\n this.target.getWorldPosition(targetWorldPosition);\n cameraToTargetVector.copy(targetWorldPosition).sub(camera.position);\n lookAtRotation(cameraToTargetVector, UP, finalRotation);\n deltaRotation.copy(finalRotation).multiply(inverseCameraRotation);\n clampRotationToAngle(\n deltaRotation, ROTATION_SPEED_RADIANS_PER_SECOND * deltaTime);\n camera.quaternion.premultiply(deltaRotation);\n }\n\n moveTowardsTarget() {\n const camera = this.camera;\n const deltaTime = this.timer.getDelta();\n this.target.getWorldPosition(targetWorldPosition);\n cameraToTargetVector.copy(targetWorldPosition).sub(camera.position);\n closeToTargetPosition.copy(targetWorldPosition)\n .addScaledVector(cameraToTargetVector, -NEAR_TARGET_THRESHOLD);\n const cameraToCloseToTarget = closeToTargetPosition.sub(camera.position);\n const movementDistance = clamp(\n cameraToCloseToTarget.length(), 0,\n MOVEMENT_SPEED_METERS_PER_SECOND * deltaTime);\n camera.position.addScaledVector(\n cameraToCloseToTarget,\n movementDistance / cameraToCloseToTarget.length());\n }\n\n async play({simulatorUser, journeyId, waitFrame}: {\n simulatorUser: SimulatorUser,\n journeyId: number,\n waitFrame: WaitFrame\n }) {\n let isLookingAtTarget = this.isLookingAtTarget();\n let isNearTarget = this.isNearTarget();\n let shouldContinueJourney = simulatorUser.isOnJourneyId(journeyId);\n\n while (shouldContinueJourney && (!isLookingAtTarget || !isNearTarget)) {\n if (!isLookingAtTarget) {\n this.lookTowardsTarget();\n } else {\n this.lookAtTarget();\n this.moveTowardsTarget();\n }\n await waitFrame.waitFrame();\n isLookingAtTarget = this.isLookingAtTarget();\n isNearTarget = this.isNearTarget();\n shouldContinueJourney = simulatorUser.isOnJourneyId(journeyId);\n }\n }\n}\n","import * as THREE from 'three';\n\nimport {Core} from './core/Core';\nimport {Options} from './core/Options';\nimport {Script} from './core/Script';\n\n/**\n * The global singleton instance of Core, serving as the main entry point\n * for the entire XR system.\n */\nexport const core = new Core();\n\n/**\n * A direct alias to the main `THREE.Scene` instance managed by the core.\n * Use this to add or remove objects from your XR experience.\n * @example\n * ```\n * const myObject = new THREE.Mesh();\n * scene.add(myObject);\n * ```\n */\nexport const scene = core.scene;\n\n/**\n * A direct alias to the `User` instance, which represents the user in the XR\n * scene and manages inputs like controllers and hands.\n * @example\n * ```\n * if (user.isSelecting()) {\n * console.log('User is pinching or clicking (globally)!');\n * }\n * ```\n */\nexport const user = core.user;\n\n/**\n * A direct alias to the `World` instance, which manages real-world\n * understanding features like plane detection and object detection.\n */\nexport const world = core.world;\n\n/**\n * A direct alias to the `AI` instance for integrating generative AI features,\n * including multi-modal understanding, image generation, and live conversation.\n */\nexport const ai = core.ai;\n\n// --- Function Aliases ---\n// These are bound shortcuts to frequently used methods for convenience.\n\n/**\n * A shortcut for `core.scene.add()`. Adds one or more objects to the scene.\n * @param object - The object(s) to add.\n * @see {@link three#Object3D.add}\n */\nexport function add(...object: THREE.Object3D[]) {\n return scene.add(...object);\n}\n\n/**\n * A shortcut for `core.init()`. Initializes the XR Blocks system and starts\n * the render loop. This is the main entry point for any application.\n * @param options - Configuration options for the session.\n * @see {@link Core.init}\n */\nexport function init(options: Options = new Options()) {\n return core.init(options);\n}\n\n/**\n * A shortcut for `core.scriptsManager.initScript()`. Manually initializes a\n * script and its dependencies.\n * @param script - The script to initialize.\n * @see {@link ScriptsManager.initScript}\n */\nexport function initScript(script: Script) {\n return core.scriptsManager.initScript(script);\n}\n\n/**\n * A shortcut for `core.scriptsManager.uninitScript()`. Disposes of a script\n * and removes it from the update loop.\n * @param script - The script to uninitialize.\n * @see {@link ScriptsManager.uninitScript}\n */\nexport function uninitScript(script: Script) {\n return core.scriptsManager.uninitScript(script);\n}\n\n/**\n * A shortcut for `core.clock.getDeltaTime()`. Gets the time in seconds since\n * the last frame, useful for animations.\n * @returns The delta time in seconds.\n * @see {@link Clock.getDeltaTime}\n */\nexport function getDeltaTime() {\n return core.timer.getDelta();\n}\n\n/**\n * Toggles whether the reticle can target the depth-sensing mesh.\n * @param value - True to add the depth mesh as a target, false to\n * remove it.\n */\nexport function showReticleOnDepthMesh(value: boolean) {\n if (core.depth.depthMesh) {\n core.depth.depthMesh.ignoreReticleRaycast = !value;\n }\n}\n\n/**\n * Retrieves the left camera from the stereoscopic XR camera rig.\n * @returns The left eye's camera.\n */\nexport function getXrCameraLeft() {\n return core.renderer.xr.getCamera().cameras[0];\n}\n\n/**\n * Retrieves the right camera from the stereoscopic XR camera rig.\n * @returns The right eye's camera.\n */\nexport function getXrCameraRight() {\n return core.renderer.xr.getCamera().cameras[1];\n}\n","import * as THREE from 'three';\n\nimport {LEFT_VIEW_ONLY_LAYER, RIGHT_VIEW_ONLY_LAYER} from '../constants';\n\n/**\n * Sets the given object and all its children to only be visible in the left\n * eye.\n * @param obj - Object to show only in the left eye.\n * @returns The original object.\n */\nexport function showOnlyInLeftEye<T extends THREE.Object3D>(obj: T) {\n obj.layers.set(LEFT_VIEW_ONLY_LAYER);\n obj.children.forEach((child) => {\n showOnlyInLeftEye(child);\n });\n return obj;\n}\n\n/**\n * Sets the given object and all its children to only be visible in the right\n * eye.\n * @param obj - Object to show only in the right eye.\n * @returns The original object.\n */\nexport function showOnlyInRightEye<T extends THREE.Object3D>(obj: T) {\n obj.layers.set(RIGHT_VIEW_ONLY_LAYER);\n obj.children.forEach((child) => {\n showOnlyInRightEye(child);\n });\n return obj;\n}\n\n/**\n * Loads a stereo image from a URL and returns two THREE.Texture objects, one\n * for the left eye and one for the right eye.\n * @param url - The URL of the stereo image.\n * @returns A promise that resolves to an array containing the left and right\n * eye textures.\n */\nexport async function loadStereoImageAsTextures(url: string) {\n const image = await new Promise(\n (resolve, reject) => {\n new THREE.ImageLoader().load(url, resolve, undefined, reject)});\n const leftTexture = new THREE.Texture();\n leftTexture.image = image;\n leftTexture.repeat.x = 0.5;\n leftTexture.needsUpdate = true;\n const rightTexture = leftTexture.clone();\n rightTexture.offset.x = 0.5;\n rightTexture.needsUpdate = true;\n return [leftTexture, rightTexture];\n}\n","import * as THREE from 'three';\nimport {SVGLoader, SVGResult} from 'three/addons/loaders/SVGLoader.js';\n\nimport {View} from '../core/View.js';\n\nconst SVG_BASE_PATH =\n 'https://cdn.jsdelivr.net/gh/marella/material-symbols@v0.33.0/svg/{{weight}}/{{style}}/{{icon}}.svg'\n\nexport type MaterialSymbolsViewOptions = {\n /** The name of the icon (e.g., 'sunny', 'home'). */\n icon?: string;\n /** The weight of the icon (e.g., 100, 400, 700). */\n iconWeight?: number;\n /** The style of the icon ('outlined', 'filled', or 'round'). */\n iconStyle?: string;\n /** The scale factor for the icon. */\n iconScale?: number;\n /** The color of the icon in hex format (e.g., '#FFFFFF'). */\n iconColor?: string;\n};\n\n/**\n * A View that dynamically loads and displays an icon from the Google\n * Material Symbols library as a 3D object. It constructs the icon from SVG\n * data, allowing for customization of weight, style, color, and scale.\n */\nexport class MaterialSymbolsView extends View {\n #icon = '';\n get icon() {\n return this.#icon;\n }\n set icon(value) {\n if (this.#icon == value) return;\n this.#icon = value;\n this.updateIcon();\n }\n #iconWeight = 400;\n get iconWeight() {\n return this.#iconWeight;\n }\n set iconWeight(value) {\n if (this.#iconWeight == value) return;\n this.#iconWeight = value;\n this.updateIcon();\n }\n #iconStyle = '';\n get iconStyle() {\n return this.#iconStyle;\n }\n set iconStyle(value) {\n if (this.#iconStyle == value) return;\n this.#iconStyle = value;\n this.updateIcon();\n }\n #iconColor = '';\n get iconColor() {\n return this.#iconColor;\n }\n set iconColor(value) {\n if (this.#iconColor == value) return;\n this.#iconColor = value;\n this.group?.traverse?.((child) => {\n if (child instanceof THREE.Mesh) {\n child.material?.color?.set?.(value);\n }\n });\n }\n\n iconScale = 1;\n private loadedSvgPath?: string;\n private loadingSvgPath?: string;\n private group?: THREE.Group;\n\n /**\n * Construct a Material Symbol view.\n * @param options - Options for the icon.\n */\n constructor({\n icon = 'sunny',\n iconWeight = 400,\n iconStyle = 'outlined',\n iconScale = 1,\n iconColor = '#FFFFFF'\n }: MaterialSymbolsViewOptions) {\n super({});\n this.icon = icon;\n this.iconWeight = iconWeight;\n this.iconStyle = iconStyle;\n this.iconScale = iconScale;\n this.iconColor = iconColor;\n }\n\n async init() {\n if (this.group == null) {\n await this.updateIcon();\n }\n }\n\n /**\n * Updates the icon displayed by loading the appropriate SVG from the Material\n * Symbols library based on the current `icon`, `iconWeight`, and `iconStyle`\n * properties.\n * @returns Promise<void>\n */\n async updateIcon() {\n if (!this.icon || !this.iconWeight || !this.iconStyle) {\n return;\n }\n const svgPath = SVG_BASE_PATH.replace('{{style}}', this.iconStyle)\n .replace('{{icon}}', this.icon)\n .replace('{{weight}}', String(this.iconWeight));\n if (svgPath == this.loadedSvgPath || svgPath == this.loadingSvgPath) {\n return;\n }\n this.loadingSvgPath = svgPath;\n const svgData = await new Promise<SVGResult>((resolve, reject) => {\n const loader = new SVGLoader();\n loader.load(svgPath, resolve, undefined, reject);\n });\n this.loadingSvgPath = undefined;\n this.loadedSvgPath = svgPath;\n const [viewMinX, viewMinY, viewWidth, viewHeight] =\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (svgData.xml as any).attributes.viewBox.value.split(' ');\n const paths = svgData.paths;\n const group = new THREE.Group();\n\n const scale = 1 / Math.max(viewWidth, viewHeight);\n for (let i = 0; i < paths.length; i++) {\n const path = paths[i];\n\n const material = new THREE.MeshBasicMaterial({\n color: this.iconColor,\n side: THREE.DoubleSide,\n depthWrite: false,\n depthTest: false\n });\n\n const shapes = SVGLoader.createShapes(path);\n\n for (let j = 0; j < shapes.length; j++) {\n const shape = shapes[j];\n const geometry = new THREE.ShapeGeometry(shape);\n const mesh = new THREE.Mesh(geometry, material);\n // Flip the icon over y.\n mesh.scale.set(scale, -scale, scale);\n // Center the icon\n mesh.position.x = -0.5 - viewMinX * scale;\n mesh.position.y = 0.5 + viewMinY * scale;\n group.add(mesh);\n }\n }\n if (this.group) {\n this.remove(this.group);\n this.group?.traverse?.((child) => {\n if ('dispose' in child && typeof child.dispose === 'function') {\n child.dispose?.();\n }\n if (child instanceof THREE.Mesh) {\n child.geometry?.dispose?.();\n child.material?.dispose?.();\n }\n });\n }\n this.group = group;\n group.scale.setScalar(this.iconScale);\n this.add(group);\n }\n}\n","import * as THREE from 'three';\nimport {Script} from '../../core/Script.js';\nimport {clamp} from '../../utils/utils.js';\n\n/**\n * Manages the state and animation logic for a scrolling text view.\n * It tracks the total number of lines, the current scroll position (as a line\n * number), and the target line, smoothly animating between them over time.\n */\nexport class TextScrollerState extends Script {\n static dependencies = {timer: THREE.Timer};\n scrollSpeedLinesPerSecond = 3;\n lines = 1;\n currentLine = 0;\n targetLine = 0;\n shouldUpdate = true;\n timer!: THREE.Timer;\n lineCount = 0;\n\n init({timer}: {timer: THREE.Timer}) {\n this.timer = timer;\n }\n\n update() {\n super.update();\n if (!this.shouldUpdate) {\n return false;\n }\n // Simple linear speed scrolling.\n const deltaTime = this.timer.getDelta();\n const deltaLines = this.scrollSpeedLinesPerSecond * deltaTime;\n const distanceToTargetLine = this.targetLine - this.currentLine;\n this.currentLine += clamp(distanceToTargetLine, -deltaLines, deltaLines);\n }\n}\n","import * as THREE from 'three';\n\nimport {View} from '../core/View';\n\nconst vector3 = new THREE.Vector3();\n\n/**\n * A simple container that represents a single, swipeable page\n * within a `Pager` component. It's a fundamental building block for creating\n * carousels or tabbed interfaces.\n */\nexport class Page extends View {\n constructor(options = {}) {\n super(options);\n }\n\n updateLayout() {\n // Do not update the position.\n vector3.copy(this.position);\n super.updateLayout();\n this.position.copy(vector3);\n }\n}\n","import * as THREE from 'three';\n\nimport {Script} from '../../core/Script.js';\nimport {clamp} from '../../utils/utils.js';\n\n/**\n * A state management class for a `Pager` component. It tracks the\n * total number of pages, the current scroll position, and handles the physics\n * and animation logic for smooth, inertia-based scrolling between pages.\n */\nexport class PagerState extends Script {\n static dependencies = {timer: THREE.Timer};\n currentPage = 0;\n shouldUpdate = true;\n pages = 1;\n timer!: THREE.Timer;\n\n constructor({pages = 1}) {\n super();\n this.pages = pages;\n }\n\n init({timer}: {timer: THREE.Timer}) {\n this.timer = timer;\n }\n\n update() {\n super.update();\n if (!this.shouldUpdate) {\n return false;\n }\n const velocity = Math.sin(Math.PI * (this.currentPage % 1));\n const direction = ((this.currentPage % 1) >= 0.5 ? 1 : -1) *\n Number(Math.abs(velocity) > 0.01);\n const targetPage = clamp(this.currentPage + direction, 0, this.pages - 1);\n const remainingDelta = Math.abs(targetPage - this.currentPage);\n this.currentPage +=\n direction * clamp(velocity * this.timer.getDelta(), 0, remainingDelta);\n }\n\n addPage() {\n return this.pages++;\n }\n}\n","import * as THREE from 'three';\n\nimport {SelectEvent} from '../../core/Script';\nimport {Input} from '../../input/Input';\nimport {clamp} from '../../utils/utils';\nimport {View} from '../core/View';\nimport {ViewOptions} from '../core/ViewOptions';\n\nimport {Page} from './Page';\nimport {PagerState} from './PagerState';\n\nconst vector3 = new THREE.Vector3();\nconst matrix4 = new THREE.Matrix4();\n\ntype MaybeDisposable = {\n dispose?: () => void\n};\n\nexport type PagerOptions = ViewOptions&{\n state?: PagerState;\n enableRaycastOnChildren?: boolean;\n continuousScrolling?: boolean;\n}\n\n/**\n * A layout container that manages a collection of `Page` views and\n * allows the user to navigate between them, typically through swiping\n * gestures. It clips the content of its pages to create a sliding window\n * effect.\n */\nexport class Pager extends View {\n static dependencies = {renderer: THREE.WebGLRenderer, input: Input};\n\n localClippingPlanes = [\n new THREE.Plane(new THREE.Vector3(1, 0, 0), 0.5),\n new THREE.Plane(new THREE.Vector3(-1, 0, 0), 0.5),\n ];\n raycastMesh = new THREE.Mesh(\n new THREE.PlaneGeometry(), new THREE.MeshBasicMaterial({visible: false}));\n\n state: PagerState;\n clippingPlanes: THREE.Plane[] = [];\n private selecting = false;\n private selectStartPositionLocal = new THREE.Vector3();\n private selectStartPage = 0;\n private raycastPlane = new THREE.Plane();\n private selectingRay = new THREE.Ray();\n private selectingRayTarget = new THREE.Vector3();\n private selectingController!: THREE.Object3D;\n private enableRaycastOnChildren;\n private continuousScrolling;\n private input!: Input;\n\n constructor(options: PagerOptions = {}) {\n super(options);\n const {\n state = new PagerState({pages: 1}),\n enableRaycastOnChildren = true,\n continuousScrolling = true\n } = options;\n this.state = state;\n this.enableRaycastOnChildren = enableRaycastOnChildren;\n this.continuousScrolling = continuousScrolling;\n for (let i = 0; i < this.state.pages; i++) {\n this.add(new Page());\n }\n for (let i = 0; i < this.localClippingPlanes.length; i++) {\n this.clippingPlanes.push(this.localClippingPlanes[i].clone());\n }\n }\n\n init({renderer, input}: {renderer: THREE.WebGLRenderer, input: Input}) {\n renderer.localClippingEnabled = true;\n this.input = input;\n }\n\n updatePageCount() {\n this.remove(this.raycastMesh);\n for (let i = this.children.length; i < this.state.pages; i++) {\n this.add(new Page());\n }\n for (let i = this.state.pages; i < this.children.length;) {\n (this.children[i] as MaybeDisposable).dispose?.();\n this.remove(this.children[i]);\n }\n this.add(this.raycastMesh);\n }\n\n updatePagePositions() {\n const halfNumberOfPages = Math.floor(this.state.pages / 2);\n for (let i = 0; i < this.state.pages; i++) {\n const deltaFromCurrentPage =\n this.continuousScrolling && this.state.pages > 1 ?\n ((i - this.state.currentPage + halfNumberOfPages + this.state.pages) %\n this.state.pages -\n halfNumberOfPages) :\n i - this.state.currentPage;\n this.children[i].position.x = deltaFromCurrentPage * this.rangeX;\n }\n }\n\n resetClippingPlanesToLocalSpace() {\n for (let i = 0;\n i < this.localClippingPlanes.length && i < this.clippingPlanes.length;\n i++) {\n this.clippingPlanes[i].copy(this.localClippingPlanes[i]);\n }\n }\n\n updateClippingPlanes() {\n // Map the clipping planes back to world space.\n this.resetClippingPlanesToLocalSpace();\n this.updateWorldMatrix(/*updateParents=*/ true, /*updateChildren=*/ false);\n for (const plane of this.clippingPlanes) {\n plane.applyMatrix4(this.matrixWorld);\n }\n this.traverse(child => {\n if (child instanceof THREE.Mesh) {\n child.material.clippingPlanes = this.clippingPlanes;\n }\n });\n }\n\n update() {\n this.updatePageCount();\n this.updatePagePositions();\n this.updateClippingPlanes();\n }\n\n updateLayout() {\n super.updateLayout();\n this.raycastMesh.scale.set(this.rangeX, this.rangeY, 1.0);\n }\n\n onObjectSelectStart(event: SelectEvent) {\n const controller = event.target;\n const intersections =\n this.input.intersectionsForController.get(controller)!;\n const intersectionIndex =\n intersections.findIndex(intersection => intersection.object == this);\n if (intersectionIndex == -1) return false;\n const intersection = intersections[intersectionIndex];\n this.selecting = true;\n this.selectingController = controller;\n this.updateMatrixWorld();\n this.selectStartPositionLocal.copy(intersection.point)\n .applyMatrix4(matrix4.copy(this.matrixWorld).invert());\n this.raycastPlane.normal.set(0, 0, 1.0);\n this.raycastPlane.constant = 0;\n this.raycastPlane.applyMatrix4(this.matrixWorld);\n this.selectStartPage = this.state.currentPage;\n return true;\n }\n\n protected computeSelectingDelta(\n selectingPosition: THREE.Vector3, startSelectPosition: THREE.Vector3) {\n return (selectingPosition.x - startSelectPosition.x) / this.rangeX;\n }\n\n onSelecting() {\n if (this.selecting) {\n // Raycast to the plane;\n this.selectingRay.origin.set(0.0, 0.0, 0.0);\n this.selectingRay.direction.set(0.0, 0.0, -1.0);\n this.selectingController.updateMatrixWorld();\n this.selectingRay.applyMatrix4(this.selectingController.matrixWorld);\n this.selectingRay.intersectPlane(\n this.raycastPlane, this.selectingRayTarget);\n this.updateMatrixWorld();\n this.selectingRayTarget.applyMatrix4(\n matrix4.copy(this.matrixWorld).invert());\n const deltaPage = this.computeSelectingDelta(\n this.selectingRayTarget, this.selectStartPositionLocal);\n this.state.currentPage =\n this.continuousScrolling && this.state.pages > 1 ?\n ((this.selectStartPage - deltaPage + this.state.pages) %\n this.state.pages) :\n clamp(this.selectStartPage - deltaPage, 0, this.state.pages - 1);\n }\n }\n\n onObjectSelectEnd(event: SelectEvent) {\n if (event.target == this.selectingController) {\n this.selecting = false;\n }\n return true;\n }\n\n /**\n * Raycast to the pager's raycastMesh so the user can scroll across pages.\n */\n raycast(raycaster: THREE.Raycaster, intersects: THREE.Intersection[]) {\n const thisIntersections: THREE.Intersection[] = [];\n this.raycastMesh.raycast(raycaster, thisIntersections);\n thisIntersections.forEach(intersection => {\n intersection.object = this;\n intersects.push(intersection);\n });\n // Loop through children.\n if (this.enableRaycastOnChildren) {\n const childIntersections: THREE.Intersection[] = [];\n for (const child of this.children) {\n raycaster.intersectObject(child, true, childIntersections);\n }\n // Create if the intersection is on this page.\n this.updateMatrixWorld();\n matrix4.copy(this.matrixWorld).invert();\n for (const intersection of childIntersections) {\n const pointInLocalCoordinates =\n vector3.copy(intersection.point).applyMatrix4(matrix4);\n if (Math.abs(pointInLocalCoordinates.x) < 0.5) {\n intersects.push(intersection);\n }\n }\n }\n return false;\n }\n}\n","import * as THREE from 'three';\n\nimport {Pager} from './Pager';\n\n/**\n * A specialized `Pager` that arranges its pages vertically and\n * enables vertical swiping gestures. It is commonly used as the foundation for\n * scrollable text views.\n */\nexport class VerticalPager extends Pager {\n localClippingPlanes = [\n new THREE.Plane(new THREE.Vector3(0, 1, 0), 0.5),\n new THREE.Plane(new THREE.Vector3(0, -1, 0), 0.5),\n ];\n\n updateLayout() {\n super.updateLayout();\n this.localClippingPlanes[0].constant = 0.5 * this.rangeY;\n this.localClippingPlanes[1].constant = 0.5 * this.rangeY;\n }\n\n protected computeSelectingDelta(\n selectingPosition: THREE.Vector3, startSelectPosition: THREE.Vector3) {\n return (selectingPosition.y - startSelectPosition.y) / this.rangeY;\n }\n}\n","import {View} from '../core/View';\nimport {ViewOptions} from '../core/ViewOptions';\nimport {TextScrollerState} from '../layouts/TextScrollerState';\nimport {VerticalPager} from '../layouts/VerticalPager';\n\nimport {TextView} from './TextView';\n\n/**\n * A high-quality scrolling text view that uses Troika for SDF text\n * rendering and a `VerticalPager` for clipping and scrolling. This component is\n * ideal for displaying logs, chat histories, or other long-form text content\n * that requires crisp rendering and smooth scrolling.\n *\n * It is built by composing three key components:\n * - A `TextView` to render the actual text content.\n * - A `TextScrollerState` to manage the animation and state of the scroll\n * position.\n * - A `VerticalPager` to clip the `TextView` and create the visible scroll\n * window.\n */\nexport type ScrollingTroikaTextViewOptions = ViewOptions&{\n text?: string;\n textAlign?: 'left'|'right'|'center';\n scrollerState?: TextScrollerState;\n fontSize?: number;\n};\n\nexport class ScrollingTroikaTextView extends View {\n private scrollerState: TextScrollerState;\n private pager: VerticalPager;\n private textViewWrapper: View;\n private textView: TextView;\n private onTextSyncCompleteBound = this.onTextSyncComplete.bind(this);\n private currentText = '';\n\n constructor({\n text = 'ScrollingTroikaTextView',\n textAlign = 'left',\n scrollerState = new TextScrollerState(),\n fontSize = 0.06\n }: ScrollingTroikaTextViewOptions = {}) {\n super();\n this.scrollerState = scrollerState || new TextScrollerState();\n this.pager = new VerticalPager();\n this.textViewWrapper = new View();\n this.pager.children[0].add(this.textViewWrapper);\n this.textView = new TextView({\n text: text,\n textAlign: textAlign,\n fontSize: fontSize,\n anchorX: 0,\n anchorY: 0\n });\n this.textView.x = -0.5;\n this.textView.addEventListener(\n 'synccomplete', this.onTextSyncCompleteBound);\n this.textViewWrapper.add(this.textView);\n\n this.add(this.scrollerState);\n this.add(this.pager);\n }\n\n update() {\n this.textViewWrapper.y = this.textView.lineHeight *\n this.textView.aspectRatio * this.scrollerState.currentLine;\n this.textViewWrapper.updateLayout();\n }\n\n addText(text: string) {\n this.setText(this.currentText + text);\n }\n\n setText(text: string) {\n this.currentText = text;\n this.textView.setText(this.currentText);\n }\n\n onTextSyncComplete() {\n if (this.textView.lineCount > 0) {\n this.textView.y =\n -0.5 + this.textView.lineHeight * this.textView.aspectRatio;\n this.textView.updateLayout();\n this.scrollerState.lineCount = this.textView.lineCount;\n this.scrollerState.targetLine = this.textView.lineCount - 1;\n\n this.clipToLineHeight();\n }\n }\n\n clipToLineHeight() {\n const lineHeight = this.textView.lineHeight * this.textView.aspectRatio;\n const visibleLines = Math.floor(1.0 / lineHeight);\n const newHeight = visibleLines * lineHeight;\n this.pager.localClippingPlanes[1].constant = newHeight - 0.5;\n }\n}\n","import * as THREE from 'three';\n\nimport {MouseController} from '../../input/MouseController';\nimport {clamp} from '../../utils/utils';\n\nconst positionDiff = new THREE.Vector3();\nconst rotationDiff = new THREE.Quaternion();\nconst euler = new THREE.Euler();\n\n/**\n * A non-visual helper class for calculating a slider value based on\n * a controller's movement relative to an initial pose. It can derive the value\n * from either positional (for XR hands/controllers) or rotational (for mouse)\n * input, making it a flexible tool for creating virtual sliders without a\n * visible UI element.\n */\nexport class FreestandingSlider {\n initialPosition = new THREE.Vector3();\n initialRotationInverse = new THREE.Quaternion();\n rotationScale: number;\n\n /**\n * Create a freestanding slider object.\n */\n constructor(\n public startingValue = 0.0, public minValue = 0.0, public maxValue = 1.0,\n public scale = 1.0, rotationScale?: number) {\n this.rotationScale =\n rotationScale != undefined ? rotationScale : -this.scale;\n }\n\n /**\n * Captures the initial position and rotation to serve as the reference point\n * for the gesture.\n * @param position - The starting world position.\n * @param rotation - The starting world rotation.\n */\n setInitialPose(position: THREE.Vector3, rotation: THREE.Quaternion) {\n this.initialPosition.copy(position);\n this.initialRotationInverse.copy(rotation).invert();\n }\n\n /**\n * A convenience method to capture the initial pose from a controller object.\n * @param controller - The controller to use as the reference.\n */\n setInitialPoseFromController(controller: THREE.Object3D) {\n this.setInitialPose(controller.position, controller.quaternion);\n }\n\n /**\n * Calculates the slider value based on a new world position.\n * @param position - The current world position of the input source.\n * @returns The calculated slider value, clamped within the min/max range.\n */\n getValue(position: THREE.Vector3) {\n positionDiff.copy(position)\n .sub(this.initialPosition)\n .applyQuaternion(this.initialRotationInverse);\n return clamp(\n this.startingValue + this.scale * positionDiff.x, this.minValue,\n this.maxValue);\n }\n\n /**\n * Calculates the slider value based on a new world rotation (for mouse\n * input).\n * @param rotation - The current world rotation of the input source.\n * @returns The calculated slider value, clamped within the min/max range.\n */\n getValueFromRotation(rotation: THREE.Quaternion) {\n rotationDiff.copy(rotation).multiply(this.initialRotationInverse);\n euler.setFromQuaternion(rotationDiff, 'YXZ');\n return clamp(\n this.startingValue + this.rotationScale * euler.y, this.minValue,\n this.maxValue);\n }\n\n /**\n * A polymorphic method that automatically chooses the correct calculation\n * (positional or rotational) based on the controller type.\n * @param controller - The controller providing the input.\n * @returns The calculated slider value.\n */\n getValueFromController(controller: THREE.Object3D) {\n return controller instanceof MouseController ?\n this.getValueFromRotation(controller.quaternion) :\n this.getValue(controller.position);\n }\n\n /**\n * Updates the starting value, typically after a gesture has ended.\n * @param value - The new starting value for the next gesture.\n */\n updateValue(value: number) {\n this.startingValue = value\n }\n}\n","import * as THREE from 'three';\nimport {DRACOLoader} from 'three/addons/loaders/DRACOLoader.js';\nimport {GLTF, GLTFLoader} from 'three/addons/loaders/GLTFLoader.js';\nimport {KTX2Loader} from 'three/addons/loaders/KTX2Loader.js';\n\n/**\n * The base URL for Three.js JSM examples, used for DRACO and KTX2 decoders.\n */\nconst jsmUrl =\n `https://cdn.jsdelivr.net/npm/three@0.${THREE.REVISION}.0/examples/jsm/`;\n\n/**\n * The configured GLTFLoader instance.\n */\nlet gltfLoaderInstance: GLTFLoader|undefined;\n\nfunction getGLTFLoader(\n renderer?: THREE.WebGLRenderer, manager?: THREE.LoadingManager) {\n if (gltfLoaderInstance) {\n return gltfLoaderInstance;\n }\n const dracoLoader = new DRACOLoader(manager);\n dracoLoader.setDecoderPath(jsmUrl + 'libs/draco/');\n dracoLoader.setDecoderConfig({type: 'js'});\n const ktx2Loader = new KTX2Loader(manager);\n ktx2Loader.setTranscoderPath(jsmUrl + 'libs/basis/');\n if (renderer) {\n ktx2Loader.detectSupport(renderer);\n }\n\n gltfLoaderInstance = new GLTFLoader(manager);\n gltfLoaderInstance.setDRACOLoader(dracoLoader);\n gltfLoaderInstance.setKTX2Loader(ktx2Loader);\n return gltfLoaderInstance;\n}\n\nexport type ModelLoaderLoadGLTFOptions = {\n /** The base path for the model files. */\n path?: string;\n /** The URL of the model file. */\n url: string;\n /** The renderer. */\n renderer?: THREE.WebGLRenderer;\n};\n\nexport type ModelLoaderLoadOptions = ModelLoaderLoadGLTFOptions&{\n /**\n * Optional callback for loading progress. Note: This will be ignored if a\n * LoadingManager is provided.\n */\n onProgress?: (event: ProgressEvent) => void;\n};\n\n/**\n * Manages the loading of 3D models, automatically handling dependencies\n * like DRACO and KTX2 loaders.\n */\nexport class ModelLoader {\n private manager: THREE.LoadingManager;\n\n /**\n * Creates an instance of ModelLoader.\n * @param manager - The\n * loading manager to use,\n * required for KTX2 texture support.\n */\n constructor(manager = THREE.DefaultLoadingManager) {\n this.manager = manager;\n }\n\n /**\n * Loads a model based on its file extension. Supports .gltf, .glb,\n * .ply, .spz, .splat, and .ksplat.\n * @returns A promise that resolves with the loaded model data (e.g., a glTF\n * scene or a SplatMesh).\n */\n async load({path, url = '', renderer = undefined, onProgress = undefined}:\n ModelLoaderLoadOptions) {\n if (onProgress) {\n console.warn(\n 'ModelLoader: An onProgress callback was provided to load(), ' +\n 'but a LoadingManager is in use. Progress will be reported via the ' +\n 'LoadingManager\\'s onProgress callback. The provided callback will be ignored.');\n }\n const extension = url.split('.').pop()?.toLowerCase() || '';\n const splatExtensions = ['ply', 'spz', 'splat', 'ksplat'];\n const gltfExtensions = ['gltf', 'glb'];\n\n if (gltfExtensions.includes(extension)) {\n return await this.loadGLTF({path, url, renderer});\n } else if (splatExtensions.includes(extension)) {\n return await this.loadSplat({url});\n }\n console.error('Unsupported file type: ' + extension);\n return null;\n }\n\n /**\n * Loads a 3DGS model (.ply, .spz, .splat, .ksplat).\n * @param url - The URL of the model file.\n * @returns A promise that resolves with the loaded\n * SplatMesh object.\n */\n async loadSplat({url = ''}) {\n const {SplatMesh} = await import('@sparkjsdev/spark'); // Dynamic import\n const splatMesh = new SplatMesh({url});\n await splatMesh.initialized;\n return splatMesh;\n }\n\n /**\n * Loads a GLTF or GLB model.\n * @param options - The loading options.\n * @returns A promise that resolves with the loaded glTF object.\n */\n async loadGLTF({\n path,\n url = '',\n renderer = undefined,\n }: ModelLoaderLoadGLTFOptions) {\n const loader = getGLTFLoader(renderer, this.manager);\n if (path) {\n loader.setPath(path);\n }\n return new Promise<GLTF>((resolve, reject) => {\n loader.load(\n url, (gltf) => resolve(gltf), undefined, (error) => reject(error));\n });\n }\n}\n","import * as THREE from 'three';\n\n/**\n * A custom `THREE.BufferGeometry` that creates one rounded corner\n * piece for the `ModelViewerPlatform`. Four of these are instantiated and\n * rotated to form all corners of the platform.\n */\nexport class ModelViewerPlatformCornerGeometry extends THREE.BufferGeometry {\n constructor(\n radius = 1, tube = 0.4, radialSegments = 12, tubularSegments = 48) {\n super();\n\n const indices = [];\n const vertices = [];\n const normals = [];\n const uvs = [];\n\n const center = new THREE.Vector3();\n const vertex = new THREE.Vector3();\n const normal = new THREE.Vector3();\n\n for (let j = 0; j <= radialSegments; j++) {\n for (let i = 0; i <= tubularSegments; i++) {\n const u = i / tubularSegments * Math.PI / 2;\n const v = j / radialSegments * Math.PI + 3 * Math.PI / 2;\n\n vertex.x = (radius + tube * Math.cos(v)) * Math.cos(u);\n vertex.y = (radius + tube * Math.cos(v)) * Math.sin(u);\n vertex.z = tube * Math.sin(v);\n vertices.push(vertex.x, vertex.y, vertex.z);\n\n center.x = radius * Math.cos(u);\n center.y = radius * Math.sin(u);\n normal.subVectors(vertex, center).normalize();\n normals.push(normal.x, normal.y, normal.z);\n\n uvs.push(i / tubularSegments);\n uvs.push(j / radialSegments);\n }\n }\n\n for (let j = 1; j <= radialSegments; j++) {\n for (let i = 1; i <= tubularSegments; i++) {\n const a = (tubularSegments + 1) * j + i - 1;\n const b = (tubularSegments + 1) * (j - 1) + i - 1;\n const c = (tubularSegments + 1) * (j - 1) + i;\n const d = (tubularSegments + 1) * j + i;\n\n indices.push(a, b, d);\n indices.push(b, c, d);\n }\n }\n\n this.setIndex(indices);\n this.setAttribute(\n 'position', new THREE.Float32BufferAttribute(vertices, 3));\n this.setAttribute('normal', new THREE.Float32BufferAttribute(normals, 3));\n this.setAttribute('uv', new THREE.Float32BufferAttribute(uvs, 2));\n }\n}\n","import * as THREE from 'three';\nimport * as BufferGeometryUtils from 'three/addons/utils/BufferGeometryUtils.js';\n\nimport {ModelViewerPlatformCornerGeometry} from './ModelViewerPlatformCornerGeometry.js';\n\n/**\n * A factory function that constructs the complete geometry for a\n * `ModelViewerPlatform`. It combines several sub-geometries: four rounded\n * corners, four straight side tubes, and the flat top and bottom surfaces.\n * @param width - The total width of the platform.\n * @param depth - The total depth of the platform.\n * @param thickness - The thickness of the platform.\n * @param cornerRadius - The radius of the rounded corners.\n * @returns A merged `THREE.BufferGeometry` for the entire platform.\n */\nexport function createPlatformGeometry(\n width = 1, depth = 1, thickness = 0.02, cornerRadius = 0.03,\n cornerWidthSegments = 5, radialSegments = 5) {\n const sideGeometries = createPlatformSideGeometries(\n width, depth, thickness, cornerRadius, cornerWidthSegments,\n radialSegments);\n const sideGeometriesVertexCount = sideGeometries.reduce((acc, val) => {\n return acc + val.index!.count;\n }, 0);\n const flatGeometries = createPlatformFlatGeometries(\n width, depth, thickness, cornerRadius, cornerWidthSegments);\n const flatGeometriesVertexCount = flatGeometries.reduce((acc, val) => {\n return acc + val.index!.count;\n }, 0);\n const allGeometries = [...sideGeometries, ...flatGeometries];\n const mergedGeometry = BufferGeometryUtils.mergeGeometries(allGeometries);\n allGeometries.forEach(geometry => geometry.dispose());\n mergedGeometry.addGroup(0, sideGeometriesVertexCount, 0);\n mergedGeometry.addGroup(\n sideGeometriesVertexCount, flatGeometriesVertexCount, 1);\n mergedGeometry.computeBoundingBox();\n return mergedGeometry;\n}\n\nfunction createPlatformSideGeometries(\n width = 1, depth = 1, thickness = 0.01, cornerRadius = 0.03,\n cornerWidthSegments = 5, radialSegments = 5) {\n const cornerGeometry =\n new ModelViewerPlatformCornerGeometry(\n cornerRadius, thickness / 2, radialSegments, cornerWidthSegments)\n .rotateX(Math.PI / 2);\n const cornerGeometry1 =\n cornerGeometry.clone()\n .rotateY(2 * Math.PI / 2)\n .translate(\n -(width / 2 - cornerRadius), 0, -(depth / 2 - cornerRadius));\n const cornerGeometry2 =\n cornerGeometry.clone()\n .rotateY(3 * Math.PI / 2)\n .translate(\n -(width / 2 - cornerRadius), 0, (depth / 2 - cornerRadius));\n const cornerGeometry3 =\n cornerGeometry.clone()\n .rotateY(4 * Math.PI / 2)\n .translate((width / 2 - cornerRadius), 0, (depth / 2 - cornerRadius));\n const cornerGeometry4 =\n cornerGeometry.rotateY(5 * Math.PI / 2)\n .translate(\n (width / 2 - cornerRadius), 0, -(depth / 2 - cornerRadius));\n const cornerTubes =\n [cornerGeometry1, cornerGeometry2, cornerGeometry3, cornerGeometry4];\n\n const widthTube =\n new THREE\n .CylinderGeometry(\n thickness / 2, thickness / 2, (width - 2 * cornerRadius),\n radialSegments, 1, true, 0, Math.PI)\n .rotateZ(Math.PI / 2);\n const widthTube1 =\n widthTube.clone().rotateX(-Math.PI / 2).translate(0, 0, -depth / 2);\n const widthTube2 = widthTube.rotateX(Math.PI / 2).translate(0, 0, depth / 2);\n\n const depthTube =\n new THREE\n .CylinderGeometry(\n thickness / 2, thickness / 2, (depth - 2 * cornerRadius),\n radialSegments, 1, true, 0, Math.PI)\n .rotateX(-Math.PI / 2);\n const depthTube1 =\n depthTube.clone().rotateY(Math.PI).translate(-width / 2, 0, 0);\n const depthTube2 = depthTube.translate(width / 2, 0, 0);\n const sideTubes = [widthTube1, widthTube2, depthTube1, depthTube2];\n return [...cornerTubes, ...sideTubes];\n}\n\nfunction createPlatformFlatGeometries(\n width = 1, depth = 1, thickness = 0.01, cornerRadius = 0.03,\n cornerWidthSegments = 5) {\n const widthMinusRadius = width - 2 * cornerRadius;\n const depthMinusRadius = depth - 2 * cornerRadius;\n const longQuad =\n new THREE.PlaneGeometry(width, depthMinusRadius).rotateX(-Math.PI / 2);\n const shortQuad = new THREE.PlaneGeometry(widthMinusRadius, cornerRadius)\n .rotateX(-Math.PI / 2);\n const shortQuadTranslationZ = depthMinusRadius / 2 + cornerRadius / 2;\n const shortQuad1 = shortQuad.clone().translate(0, 0, shortQuadTranslationZ);\n const shortQuad2 = shortQuad.translate(0, 0, -shortQuadTranslationZ)\n const quadGeometries = [longQuad, shortQuad1, shortQuad2];\n\n const cornerCircle =\n new THREE\n .CircleGeometry(cornerRadius, cornerWidthSegments, 0, Math.PI / 2)\n .rotateX(-Math.PI / 2);\n const circleTranslationZ = depthMinusRadius / 2;\n const circleTranslationX = widthMinusRadius / 2;\n const cornerCircle1 =\n cornerCircle.clone()\n .rotateY(3 * Math.PI / 2)\n .translate(circleTranslationX, 0, circleTranslationZ);\n const cornerCircle2 =\n cornerCircle.clone()\n .rotateY(0 * Math.PI / 2)\n .translate(circleTranslationX, 0, -circleTranslationZ);\n const cornerCircle3 =\n cornerCircle.clone()\n .rotateY(1 * Math.PI / 2)\n .translate(-circleTranslationX, 0, -circleTranslationZ);\n const cornerCircle4 =\n cornerCircle.clone()\n .rotateY(2 * Math.PI / 2)\n .translate(-circleTranslationX, 0, circleTranslationZ);\n const circleGeometries =\n [cornerCircle1, cornerCircle2, cornerCircle3, cornerCircle4];\n const topGeometries = [...quadGeometries, ...circleGeometries];\n const bottomGeometries = topGeometries.map(geometry => {\n return geometry.clone().rotateX(Math.PI).translate(0, -thickness / 2, 0);\n });\n topGeometries.forEach(geometry => geometry.translate(0, thickness / 2, 0));\n return [...topGeometries, ...bottomGeometries];\n}\n","import * as THREE from 'three';\n\nimport {DragManager} from '../../ux/DragManager.js';\n\nimport {AnimatableNumber} from './AnimatableNumber.js';\nimport {createPlatformGeometry} from './ModelViewerPlatformGeometry.js';\n\n/**\n * A specialized `THREE.Mesh` that serves as the interactive base for\n * a `ModelViewer`. It has a distinct visual appearance and handles the logic\n * for fading in and out on hover. Its `draggingMode` is set to `TRANSLATING` to\n * enable movement.\n */\nexport class ModelViewerPlatform extends\n THREE.Mesh<THREE.BufferGeometry, THREE.Material[]> {\n draggingMode = DragManager.TRANSLATING;\n opacity: AnimatableNumber;\n\n constructor(width: number, depth: number, thickness: number) {\n const geometry = createPlatformGeometry(width, depth, thickness);\n super(geometry, [\n new THREE.MeshLambertMaterial(\n {color: 0xFFFFFF, transparent: true, opacity: 0.0}),\n new THREE.MeshLambertMaterial(\n {color: 0xFFFFFF, transparent: true, opacity: 0.0})\n ]);\n this.opacity = new AnimatableNumber(0, 0, 0.5, 0);\n }\n\n update(deltaTime: number) {\n this.opacity.update(deltaTime);\n this.material[0].opacity = this.opacity.value;\n this.material[1].opacity = 0.5 * this.opacity.value;\n this.visible = this.opacity.value > 0.001;\n }\n}\n","import type {SplatMesh} from '@sparkjsdev/spark';\nimport * as THREE from 'three';\nimport type {GLTF} from 'three/addons/loaders/GLTFLoader.js';\n\nimport {OCCLUDABLE_ITEMS_LAYER} from '../../constants';\nimport {Script} from '../../core/Script';\nimport {Depth} from '../../depth/Depth';\nimport {OcclusionUtils} from '../../depth/occlusion/OcclusionUtils';\nimport {BACK, LEFT} from '../../utils/HelperConstants';\nimport {ModelLoader} from '../../utils/ModelLoader';\nimport {getGroupBoundingBox} from '../../utils/ModelUtils';\nimport type {Shader} from '../../utils/Types';\nimport {Draggable, DragManager, DragMode, HasDraggingMode} from '../../ux/DragManager';\n\nimport {ModelViewerPlatform} from './ModelViewerPlatform';\n\nconst defaultPlatformMargin = new THREE.Vector2(0.2, 0.2);\nconst vector3 = new THREE.Vector3();\nconst quaternion = new THREE.Quaternion();\nconst quaternion2 = new THREE.Quaternion();\n\nexport interface GLTFData {\n model: string;\n path: string;\n scale?: THREE.Vector3Like;\n rotation?: THREE.Vector3Like;\n position?: THREE.Vector3Like;\n verticallyAlignObject?: boolean;\n horizontallyAlignObject?: boolean;\n}\n\nexport interface SplatData {\n model: string;\n scale?: THREE.Vector3Like;\n rotation?: THREE.Vector3Like;\n position?: THREE.Vector3Like;\n verticallyAlignObject?: boolean;\n horizontallyAlignObject?: boolean;\n}\n\nexport class SplatAnchor extends THREE.Object3D implements HasDraggingMode {\n draggingMode = DragMode.ROTATING;\n}\n\nexport class RotationRaycastMesh extends\n THREE.Mesh<THREE.BufferGeometry, THREE.Material> {\n constructor(geometry: THREE.BufferGeometry, material: THREE.Material) {\n super(geometry, material);\n }\n draggingMode = DragMode.ROTATING;\n}\n\n/**\n * A comprehensive UI component for loading, displaying, and\n * interacting with 3D models (GLTF and Splats) in an XR scene. It\n * automatically creates an interactive platform for translation and provides\n * mechanisms for rotation and scaling in both desktop and XR.\n */\nexport class ModelViewer extends Script implements Draggable {\n static dependencies = {\n camera: THREE.Camera,\n depth: Depth,\n scene: THREE.Scene,\n renderer: THREE.WebGLRenderer,\n };\n\n draggable = true;\n rotatable = true;\n scalable = true;\n platformAnimationSpeed = 2;\n platformThickness = 0.02;\n isOneOneScale = false;\n initialScale = new THREE.Vector3().setScalar(1);\n startAnimationOnLoad = true;\n clipActions: THREE.AnimationAction[] = [];\n\n private data?: GLTFData|SplatData;\n private clock = new THREE.Clock();\n private animationMixer?: THREE.AnimationMixer;\n private gltfMesh?: GLTF;\n private splatMesh?: SplatMesh;\n // Anchor to act as a proxy for the splat mesh\n private splatAnchor?: SplatAnchor;\n private hoveringControllers = new Set();\n private raycastToChildren: boolean;\n private occludableShaders = new Set<Shader>();\n private camera?: THREE.Camera;\n private depth?: Depth;\n private scene?: THREE.Scene;\n private renderer?: THREE.WebGLRenderer;\n private bbox = new THREE.Box3();\n private platform?: ModelViewerPlatform;\n private controlBar?: THREE.Mesh;\n private rotationRaycastMesh?: RotationRaycastMesh;\n\n constructor({\n castShadow = true,\n receiveShadow = true,\n raycastToChildren = false,\n }) {\n super();\n this.castShadow = castShadow;\n this.receiveShadow = receiveShadow;\n this.raycastToChildren = raycastToChildren;\n }\n\n async init({camera, depth, scene, renderer}: {\n camera: THREE.Camera,\n depth: Depth,\n scene: THREE.Scene,\n renderer: THREE.WebGLRenderer,\n }) {\n this.camera = camera;\n this.depth = depth;\n this.scene = scene;\n this.renderer = renderer;\n\n for (const shader of this.occludableShaders) {\n this.depth!.occludableShaders.add(shader);\n }\n\n if (this.splatMesh) {\n await this.createSparkRendererIfNeeded();\n this.scene!.add(this.splatMesh);\n }\n }\n\n async loadSplatModel({\n data,\n onSceneLoaded = (_) => {},\n platformMargin = defaultPlatformMargin,\n setupRaycastCylinder = true,\n setupRaycastBox = false,\n setupPlatform = true,\n }: {\n data: SplatData,\n onSceneLoaded?: (scene: THREE.Object3D) => void,\n platformMargin?: THREE.Vector2,\n setupRaycastCylinder?: boolean,\n setupRaycastBox?: boolean,\n setupPlatform?: boolean\n }) {\n this.data = data;\n if (data.scale) {\n this.initialScale.copy(data.scale);\n }\n\n const splatMesh = await new ModelLoader().loadSplat({url: data.model});\n this.splatMesh = splatMesh;\n splatMesh.raycast = () => {};\n this.splatAnchor = new SplatAnchor;\n\n if (data.scale) {\n this.splatAnchor.scale.copy(data.scale);\n }\n if (data.rotation) {\n this.splatAnchor.rotation.set(\n THREE.MathUtils.degToRad(data.rotation.x),\n THREE.MathUtils.degToRad(data.rotation.y),\n THREE.MathUtils.degToRad(data.rotation.z));\n }\n if (data.position) {\n this.splatAnchor.position.copy(data.position);\n }\n\n this.add(this.splatAnchor);\n\n if (this.scene) {\n await this.createSparkRendererIfNeeded();\n this.scene.add(this.splatMesh);\n }\n\n await this.setupBoundingBox(\n data.verticallyAlignObject !== false,\n data.horizontallyAlignObject !== false);\n\n if (setupRaycastCylinder) {\n this.setupRaycastCylinder();\n } else if (setupRaycastBox) {\n this.setupRaycastBox();\n }\n if (setupPlatform) {\n this.setupPlatform(platformMargin);\n }\n\n this.setCastShadow(this.castShadow);\n this.setReceiveShadow(this.receiveShadow);\n\n // Return the anchor, as it's the interactive object in the scene graph\n return onSceneLoaded ? onSceneLoaded(this.splatAnchor) : this.splatAnchor;\n }\n\n async loadGLTFModel({\n data,\n onSceneLoaded = () => {},\n platformMargin = defaultPlatformMargin,\n setupRaycastCylinder = true,\n setupRaycastBox = false,\n setupPlatform = true,\n renderer = undefined,\n addOcclusionToShader = false\n }: {\n data: GLTFData,\n onSceneLoaded?: (scene: THREE.Object3D) => void,\n platformMargin?: THREE.Vector2,\n setupRaycastCylinder?: boolean,\n setupRaycastBox?: boolean,\n setupPlatform?: boolean,\n renderer?: THREE.WebGLRenderer,\n addOcclusionToShader?: boolean,\n }) {\n this.data = data;\n if (data.scale) {\n this.initialScale.copy(data.scale);\n }\n const gltf = await new ModelLoader().loadGLTF(\n {path: data.path, url: data.model, renderer: renderer});\n const animationMixer = new THREE.AnimationMixer(gltf.scene);\n gltf.animations.forEach((clip) => {\n if (this.startAnimationOnLoad) {\n animationMixer.clipAction(clip).play();\n } else {\n this.clipActions.push(animationMixer.clipAction(clip));\n }\n });\n (gltf.scene as unknown as HasDraggingMode).draggingMode =\n DragManager.ROTATING;\n this.gltfMesh = gltf;\n this.animationMixer = animationMixer;\n // Set the initial scale\n if (data.scale) {\n this.gltfMesh.scene.scale.copy(data.scale);\n }\n if (data.rotation) {\n gltf.scene.rotation.set(\n THREE.MathUtils.degToRad(data.rotation.x),\n THREE.MathUtils.degToRad(data.rotation.y),\n THREE.MathUtils.degToRad(data.rotation.z));\n }\n if (data.position) {\n gltf.scene.position.copy(data.position);\n }\n (gltf.scene as unknown as HasDraggingMode).draggingMode =\n DragManager.ROTATING;\n this.add(gltf.scene);\n await this.setupBoundingBox(\n data.verticallyAlignObject !== false,\n data.horizontallyAlignObject !== false);\n if (setupRaycastCylinder) {\n this.setupRaycastCylinder();\n } else if (setupRaycastBox) {\n this.setupRaycastBox();\n }\n if (setupPlatform) {\n this.setupPlatform(platformMargin);\n }\n this.setCastShadow(this.castShadow);\n this.setReceiveShadow(this.receiveShadow);\n if (addOcclusionToShader) {\n for (const material of this.platform?.material || []) {\n material.onBeforeCompile = (shader: Shader) => {\n OcclusionUtils.addOcclusionToShader(shader);\n shader.uniforms.occlusionEnabled.value = true;\n material.userData.shader = shader;\n this.occludableShaders.add(shader);\n this.depth?.occludableShaders.add(shader);\n }\n }\n this.platform?.layers.enable(OCCLUDABLE_ITEMS_LAYER);\n gltf.scene.traverse((child) => {\n if ((child as Partial<THREE.Mesh>).isMesh) {\n const mesh = child as THREE.Mesh;\n (mesh.material instanceof Array ? mesh.material : [\n mesh.material\n ]).forEach((material) => {\n material.transparent = true;\n material.onBeforeCompile = (shader) => {\n OcclusionUtils.addOcclusionToShader(shader);\n shader.uniforms.occlusionEnabled.value = true;\n this.occludableShaders.add(shader);\n this.depth?.occludableShaders.add(shader);\n };\n });\n child.layers.enable(OCCLUDABLE_ITEMS_LAYER);\n }\n });\n }\n return onSceneLoaded ? onSceneLoaded(gltf.scene) : gltf.scene;\n }\n\n async setupBoundingBox(\n verticallyAlignObject = true, horizontallyAlignObject = true) {\n if (this.splatMesh) {\n const localBbox = await this.splatMesh.getBoundingBox(false);\n if (localBbox.isEmpty()) {\n this.bbox = localBbox;\n return;\n }\n this.splatAnchor!.updateMatrix();\n const localBboxOfTransformedMesh =\n localBbox.clone().applyMatrix4(this.splatAnchor!.matrix);\n\n const translationAmount = new THREE.Vector3();\n localBboxOfTransformedMesh.getCenter(translationAmount)\n .multiplyScalar(-1);\n if (verticallyAlignObject) {\n translationAmount.y = -localBboxOfTransformedMesh.min.y;\n } else {\n translationAmount.y = 0;\n }\n if (!horizontallyAlignObject) {\n translationAmount.x = 0;\n translationAmount.z = 0;\n }\n this.splatAnchor!.position.add(translationAmount);\n this.bbox = localBboxOfTransformedMesh.translate(translationAmount);\n } else {\n const contentChildren = this.children.filter(\n (c) => c !== this.platform && c !== this.rotationRaycastMesh &&\n c !== this.controlBar);\n this.bbox = getGroupBoundingBox(contentChildren);\n if (this.bbox.isEmpty()) {\n return;\n }\n\n const translationAmount = new THREE.Vector3();\n this.bbox.getCenter(translationAmount).multiplyScalar(-1);\n if (verticallyAlignObject) {\n translationAmount.y = -this.bbox.min.y;\n } else {\n translationAmount.y = 0;\n }\n if (!horizontallyAlignObject) {\n translationAmount.x = 0;\n translationAmount.z = 0;\n }\n for (const child of contentChildren) {\n child.position.add(translationAmount);\n }\n this.bbox.translate(translationAmount);\n }\n }\n\n setupRaycastCylinder() {\n const bboxSize = new THREE.Vector3();\n this.bbox.getSize(bboxSize);\n\n const radius = 0.05 + 0.5 * Math.min(bboxSize.x, bboxSize.z);\n const rotationRaycastMesh = new RotationRaycastMesh(\n new THREE.CylinderGeometry(radius, radius, bboxSize.y),\n new THREE.MeshBasicMaterial({color: 0x990000, wireframe: true}));\n this.bbox.getCenter(rotationRaycastMesh.position);\n this.rotationRaycastMesh = rotationRaycastMesh;\n this.rotationRaycastMesh.visible = false;\n this.add(this.rotationRaycastMesh);\n }\n\n setupRaycastBox() {\n if (this.rotationRaycastMesh) {\n this.rotationRaycastMesh.removeFromParent();\n this.rotationRaycastMesh.geometry.dispose();\n this.rotationRaycastMesh.material.dispose();\n }\n const bboxSize = new THREE.Vector3();\n this.bbox.getSize(bboxSize);\n\n const rotationRaycastMesh = new RotationRaycastMesh(\n new THREE.BoxGeometry(bboxSize.x, bboxSize.y, bboxSize.z),\n new THREE.MeshBasicMaterial({color: 0x990000, wireframe: true}));\n this.bbox.getCenter(rotationRaycastMesh.position);\n this.rotationRaycastMesh = rotationRaycastMesh;\n this.rotationRaycastMesh.visible = false;\n this.add(this.rotationRaycastMesh);\n }\n\n setupPlatform(platformMargin = defaultPlatformMargin) {\n const bboxSize = new THREE.Vector3();\n this.bbox.getSize(bboxSize);\n const width = bboxSize.x + platformMargin.x;\n const depth = bboxSize.z + platformMargin.y;\n this.platform =\n new ModelViewerPlatform(width, depth, this.platformThickness);\n const center = new THREE.Vector3();\n this.bbox.getCenter(center);\n this.platform.position.set(center.x, -this.platformThickness / 2, center.z);\n this.add(this.platform);\n }\n\n update() {\n if (this.splatMesh && this.splatAnchor) {\n // Synchronize the splat mesh's transform with its anchor\n this.updateMatrixWorld(true);\n this.splatAnchor.matrixWorld.decompose(\n this.splatMesh.position, this.splatMesh.quaternion,\n this.splatMesh.scale);\n }\n const delta = this.clock.getDelta();\n if (this.animationMixer) {\n this.animationMixer.update(delta);\n }\n if (this.platform) {\n this.platform.update(delta);\n }\n const camera = this.camera;\n if (this.controlBar != null && this.controlBar.parent == this &&\n camera != null) {\n const directionToCamera =\n vector3.copy(camera.position).sub(this.position);\n const distanceToCamera = directionToCamera.length();\n const pitchAngleRadians = Math.asin(directionToCamera.normalize().y);\n directionToCamera.y = 0;\n directionToCamera.normalize();\n // Make the button face the camera.\n quaternion.copy(this.quaternion).invert();\n this.controlBar.quaternion.setFromAxisAngle(LEFT, pitchAngleRadians)\n .premultiply(quaternion2.setFromUnitVectors(BACK, directionToCamera))\n .premultiply(quaternion);\n this.controlBar.position.setScalar(0)\n .addScaledVector(directionToCamera, 0.5)\n .applyQuaternion(quaternion);\n this.controlBar.position.y = 0.0;\n this.controlBar.scale.set(\n distanceToCamera / this.scale.x, distanceToCamera / this.scale.y,\n distanceToCamera / this.scale.z);\n }\n }\n\n onObjectSelectStart() {\n return this.draggable || this.rotatable || this.scalable;\n }\n\n onObjectSelectEnd() {\n return this.draggable || this.rotatable || this.scalable;\n }\n\n onHoverEnter(controller: THREE.Object3D) {\n this.hoveringControllers.add(controller);\n if (this.platform) {\n this.platform.opacity.speed = this.platformAnimationSpeed;\n }\n }\n\n onHoverExit(controller: THREE.Object3D) {\n this.hoveringControllers.delete(controller);\n if (this.platform && this.hoveringControllers.size == 0) {\n this.platform.opacity.speed = -this.platformAnimationSpeed;\n }\n }\n\n /**\n * {@inheritDoc}\n */\n raycast(raycaster: THREE.Raycaster, intersects: THREE.Intersection[]) {\n const content = this.gltfMesh?.scene ?? this.splatMesh;\n if (this.raycastToChildren && content) {\n const childRaycasts: THREE.Intersection[] = [];\n for (const child of this.children) {\n if (child != this.rotationRaycastMesh && child != this.platform &&\n child != this.controlBar) {\n raycaster.intersectObject(child, true, childRaycasts);\n }\n }\n intersects.push(...childRaycasts);\n }\n\n if (this.rotationRaycastMesh) {\n const rotationIntersects: THREE.Intersection[] = [];\n this.rotationRaycastMesh.raycast(raycaster, rotationIntersects);\n for (const intersect of rotationIntersects) {\n intersects.push(intersect);\n }\n }\n\n if (this.platform) {\n const platformIntersects: THREE.Intersection[] = [];\n this.platform.raycast(raycaster, platformIntersects);\n for (const intersect of platformIntersects) {\n intersects.push(intersect);\n }\n }\n\n if (this.controlBar != null && this.controlBar.parent == this) {\n const controlButtonIntersects: THREE.Intersection[] = [];\n this.controlBar.raycast(raycaster, controlButtonIntersects);\n for (const intersect of controlButtonIntersects) {\n intersects.push(intersect);\n }\n }\n return false;\n }\n\n onScaleButtonClick() {\n this.scale.setScalar(1.0);\n }\n\n setCastShadow(castShadow: boolean) {\n this.castShadow = castShadow;\n if (this.gltfMesh) {\n this.gltfMesh.scene.traverse(function(child) {\n child.castShadow = castShadow;\n });\n }\n if (this.platform) {\n this.platform.castShadow = false;\n }\n }\n\n setReceiveShadow(receiveShadow: boolean) {\n this.receiveShadow = receiveShadow;\n if (this.gltfMesh) {\n this.gltfMesh.scene.traverse(function(child) {\n child.receiveShadow = receiveShadow;\n });\n }\n if (this.platform) {\n this.platform.receiveShadow = receiveShadow;\n }\n }\n\n getOcclusionEnabled() {\n for (const shader of this.occludableShaders) {\n return shader.uniforms.occlusionEnabled.value;\n }\n return false;\n }\n\n setOcclusionEnabled(enabled: boolean) {\n for (const shader of this.occludableShaders) {\n shader.uniforms.occlusionEnabled.value = enabled;\n }\n }\n\n playClipAnimationOnce() {\n if (this.startAnimationOnLoad || this.clipActions.length === 0) {\n return;\n }\n\n this.clipActions.forEach((clip) => {\n clip.reset();\n clip.clampWhenFinished = true;\n clip.loop = THREE.LoopOnce;\n clip.play();\n });\n }\n\n async createSparkRendererIfNeeded() {\n // We insert our own SparkRenderer configured to show Gaussians up to\n // Math.sqrt(5) standard deviations from the center, recommended for XR.\n const {SparkRenderer} = await import('@sparkjsdev/spark');\n let sparkRendererExists = false;\n this.scene!.traverse((child) => {\n sparkRendererExists ||= (child instanceof SparkRenderer);\n });\n if (!sparkRendererExists) {\n this.scene!.add(new SparkRenderer(\n {renderer: this.renderer!, maxStdDev: Math.sqrt(5)}));\n }\n }\n}\n","import * as THREE from 'three';\n\n/**\n * Calculates the bounding box for a group of THREE.Object3D instances.\n *\n * @param objects - An array of THREE.Object3D instances.\n * @returns The computed THREE.Box3.\n */\nexport function getGroupBoundingBox(objects: THREE.Object3D[]) {\n const bbox = new THREE.Box3();\n if (objects.length === 0) {\n return bbox;\n }\n\n const parentReferences = new Map();\n for (const child of objects) {\n if (child.parent) {\n parentReferences.set(child, child.parent);\n child.removeFromParent();\n }\n bbox.expandByObject(child, true);\n }\n\n // Restore parent references\n for (const [child, parent] of parentReferences.entries()) {\n parent.add(child);\n }\n return bbox;\n}\n","// Fork of HTMLMesh.js from three.js.\nimport * as THREE from 'three';\n\nimport {SelectEvent} from '../../core/Script';\nimport {User} from '../../core/User';\nimport {View} from '../core/View';\n\ninterface LinePoint {\n x: number;\n y: number;\n b?: boolean;\n}\n\n/**\n * A `View` that functions as a drawable canvas in 3D space. It uses\n * an HTML canvas as a texture on a plane, allowing users to draw on its surface\n * with their XR controllers. It supports basic drawing, undo, and redo\n * functionality.\n */\nexport class SketchPanel extends View {\n static dependencies = {user: User};\n private canvas: HTMLCanvasElement;\n private ctx: CanvasRenderingContext2D;\n private activeHand = -1;\n private activeLine: LinePoint[] = [];\n private activeLines: LinePoint[][] = [];\n private removedLines: LinePoint[][] = [];\n private isDrawing = false;\n\n private user!: User;\n\n material: THREE.MeshBasicMaterial;\n\n constructor() {\n const canvas = document.createElement('canvas');\n canvas.width = 1024;\n canvas.height = 1024;\n\n // Draw something on the canvas\n const ctx = canvas.getContext('2d')!;\n const texture = new THREE.CanvasTexture(canvas);\n\n const geometry =\n new THREE.PlaneGeometry(canvas.width * 0.001, canvas.height * 0.001);\n\n const material = new THREE.MeshBasicMaterial(\n {map: texture, toneMapped: false, alphaTest: 0.01});\n\n super({}, geometry, material);\n this.canvas = canvas;\n this.ctx = ctx;\n this.material = material;\n\n // view options\n this.width = canvas.width * 0.001;\n this.height = canvas.height * 0.001;\n this.scale.set(this.width, this.height, 1);\n }\n\n /**\n * Init the SketchPanel.\n */\n init({user}: {user: User}) {\n super.init();\n this.user = user;\n\n this.clearCanvas();\n }\n\n getContext() {\n return this.ctx;\n }\n\n triggerUpdate() {\n this.material.map!.needsUpdate = true;\n }\n\n onSelectStart(event: SelectEvent) {\n if (this.activeHand !== -1) {\n // do nothing, drawing is in progress\n return;\n }\n this.activeHand = event?.target?.userData?.id ?? -1;\n\n if (this.activeHand === 0 || this.activeHand === 1) {\n this.activeLine = [];\n this.ctx.beginPath();\n }\n }\n\n onSelectEnd(event: SelectEvent) {\n const id = event?.target?.userData?.id ?? -1;\n // check if user released an active hand\n if (id === this.activeHand) {\n // line could be empty, or contain select start only\n if (this.activeHand >= 0 && this.activeLine.length > 1) {\n this.activeLines.push(this.activeLine);\n // Added a new line, no more option for re-do\n this.removedLines = [];\n }\n this.isDrawing = false;\n this.activeLine = [];\n this.activeHand = -1;\n }\n }\n\n /**\n * Updates the painter's line to the current pivot position during selection.\n */\n onSelecting(event: SelectEvent) {\n const id = event.target.userData.id;\n if (id !== this.activeHand) {\n return;\n }\n\n const data = this.user.getReticleIntersection(id);\n\n if (data) {\n if (data.object instanceof SketchPanel && data.uv) {\n const x = Math.round(data.uv.x * 1024);\n const y = Math.round(1024 - data.uv.y * 1024);\n\n const ctx = this.ctx;\n if (this.isDrawing) {\n ctx.lineTo(x, y);\n ctx.strokeStyle = 'black';\n ctx.lineWidth = 6; // You can adjust the line width here\n ctx.stroke();\n\n this.triggerUpdate();\n this.activeLine.push({x, y});\n } else {\n this.activeLine.push({x, y, b: true});\n ctx.moveTo(x, y);\n this.isDrawing = true;\n }\n } else {\n // pointer exit from the SketchPanel\n this.isDrawing = false;\n }\n } else {\n // no plane at the pointer\n this.isDrawing = false;\n }\n }\n\n clearCanvas(forceUpdate = true) {\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n this.ctx.fillStyle = '#FFFFFF';\n this.ctx.fillRect(\n 0, 0, this.canvas.width, this.canvas.height); // Fill the entire canvas\n if (forceUpdate) {\n this.triggerUpdate();\n }\n }\n\n removeAll() {\n this.activeLines = [];\n this.removedLines = [];\n this.clearCanvas();\n }\n\n undo() {\n if (this.activeLines.length === 0) {\n return;\n }\n\n this.ctx = this.canvas.getContext('2d')!;\n\n const line = this.activeLines.pop()!;\n this.removedLines.push(line);\n\n this.clearCanvas(false);\n this.activeLines.forEach((line) => {\n this.#drawLine(line);\n });\n\n this.triggerUpdate();\n }\n\n redo() {\n if (this.removedLines.length === 0) {\n return;\n }\n const line = this.removedLines.pop()!;\n this.activeLines.push(line);\n this.#drawLine(line);\n this.triggerUpdate();\n }\n\n #drawLine(line: LinePoint[]) {\n // common context options\n this.ctx.beginPath();\n this.ctx.strokeStyle = 'black';\n this.ctx.lineWidth = 6;\n\n line.forEach((point) => {\n if (point.b) {\n this.ctx.moveTo(point.x, point.y);\n } else {\n this.ctx.lineTo(point.x, point.y);\n this.ctx.stroke();\n }\n });\n }\n\n update() {\n // empty\n }\n}\n","import * as THREE from 'three';\n\nimport {Pager} from './Pager';\n\n/**\n * A specialized `Pager` that arranges its pages horizontally and\n * enables horizontal swiping gestures for navigation. It clips content that\n * is outside the viewable area.\n */\nexport class HorizontalPager extends Pager {\n localClippingPlanes = [\n new THREE.Plane(new THREE.Vector3(1, 0, 0), 0.5),\n new THREE.Plane(new THREE.Vector3(-1, 0, 0), 0.5),\n ];\n\n updateLayout() {\n super.updateLayout();\n this.localClippingPlanes[0].constant = 0.5 * this.rangeX;\n this.localClippingPlanes[1].constant = 0.5 * this.rangeX;\n }\n}\n","import {TextView} from '../components/TextView';\n\nimport {PagerState} from './PagerState';\n\n/**\n * A UI component that visually displays the current page and total\n * number of pages for a `Pager`. It typically renders as a series of dots\n * (e.g., \"◦ ● ◦\") to indicate the user's position in a carousel.\n */\nexport class PageIndicator extends TextView {\n emptyPageIndicator = '◦';\n currentPageIndicator = '•';\n numberOfPages = 0;\n pagerState: PagerState;\n previousPage = 0;\n\n constructor({pagerState}: {pagerState: PagerState}) {\n super({\n text: '',\n });\n this.pagerState = pagerState;\n this.previousPage = Math.round(pagerState.currentPage);\n this.numberOfPages = pagerState.pages;\n this.updateText();\n }\n\n update() {\n super.update();\n const currentPage = Math.round(this.pagerState.currentPage);\n if (this.previousPage !== currentPage ||\n this.numberOfPages !== this.pagerState.pages) {\n this.updateText();\n }\n }\n\n updateText() {\n const currentPage =\n Math.round(this.pagerState.currentPage) % this.pagerState.pages;\n const text = new Array(this.pagerState.pages).fill(this.emptyPageIndicator);\n text[currentPage] = this.currentPageIndicator;\n this.setText(text.join(''));\n this.previousPage = currentPage;\n }\n}\n","import {StreamState, VideoStream, VideoStreamDetails, VideoStreamOptions} from './VideoStream';\n\ntype VideoFileStreamDetails = VideoStreamDetails&{\n width?: number;\n height?: number;\n aspectRatio?: number;\n videoFile?: string|File;\n}\n\nexport type VideoFileStreamOptions = VideoStreamOptions&{\n /** The video file path, URL, or File object. */\n videoFile?: string|File;\n};\n\n/**\n * VideoFileStream handles video playback from a file source.\n */\nexport class VideoFileStream extends VideoStream<VideoFileStreamDetails> {\n private videoFile_?: string|File;\n\n /**\n * @param options - Configuration for the file stream.\n */\n constructor({videoFile = undefined, willCaptureFrequently = false} = {}) {\n super({willCaptureFrequently});\n this.videoFile_ = videoFile;\n }\n\n /**\n * Initializes the file stream based on the given video file.\n */\n async init() {\n await super.init();\n if (this.videoFile_) {\n this.setState_(StreamState.INITIALIZING);\n await this.initStream_();\n } else {\n console.warn('VideoFileStream initialized without a video file.');\n this.setState_(StreamState.IDLE);\n }\n }\n\n /**\n * Initializes the video stream from the provided file.\n */\n protected async initStream_() {\n if (!this.videoFile_) {\n throw new Error('No video file has been provided.');\n }\n\n this.stop_();\n\n this.video_.srcObject = null;\n this.video_.src = typeof this.videoFile_ === 'string' ?\n this.videoFile_ :\n URL.createObjectURL(this.videoFile_);\n this.video_.loop = true;\n this.video_.muted = true;\n\n await new Promise<void>((resolve, reject) => {\n this.video_.onloadedmetadata = () => {\n this.handleVideoStreamLoadedMetadata(resolve, reject);\n };\n this.video_.onerror = () => {\n const error = new Error('Error occurred while loading the video file.');\n this.setState_(StreamState.ERROR, {error});\n reject(error);\n };\n this.video_.play();\n });\n\n // After metadata is loaded, set the final STREAMING state\n this.setState_(StreamState.STREAMING, {\n width: this.width,\n height: this.height,\n aspectRatio: this.aspectRatio,\n videoFile: this.videoFile_\n });\n }\n\n /**\n * Sets a new video file source and re-initializes the stream.\n * @param videoFile - The new video file to play.\n */\n async setSource(videoFile: string|File) {\n if (!videoFile) {\n console.warn('setSource called with no file. Stopping stream.');\n this.stop_();\n this.videoFile_ = undefined;\n return;\n }\n this.setState_(StreamState.INITIALIZING);\n this.videoFile_ = videoFile;\n await this.initStream_();\n }\n}\n"],"names":["Context","constructor","instructions","this","instruction","build","memory","tools","formattedHistory","getShortTerm","map","entry","formatEntry","join","toolDescriptions","tool","name","description","role","content","Memory","shortTermMemory","addShortTerm","push","clear","length","Agent","dependencies","ai","contextBuilder","start","prompt","isAvailable","init","aiOptions","options","run","context","response","model","query","type","text","JSON","stringify","toolCall","console","log","finalResponse","error","findTool","result","execute","args","errorMsg","find","Tool","parameters","onTriggered","Error","toJSON","required","GenerateSkyboxTool","scene","super","properties","image","generate","background","THREE","TextureLoader","load","mapping","EquirectangularReflectionMapping","e","SkyboxAgent","sound","startLiveSession","callbacks","setLiveCallbacks","functionDeclarations","systemInstruction","parts","enableAudio","stopLiveSession","disableAudio","sendToolResponse","GetWeatherTool","location","unit","enum","latitude","longitude","url","fetch","data","json","ok","temperature","current","temperature_2m","weathercode","weather_code","UX","parent","draggable","selectable","touchable","selected","hovered","touched","activeDragged","positions","distances","uvs","initialPosition","Vector3","isHovered","includes","isSelected","isDragging","update","controller","intersection","id","userData","initializeVariablesForId","object","mesh","uv","copy","point","distance","Vector2","reset","i","getPrimaryTwoControllerIds","activeControllerIds","ScriptMixin","base","ux","isXRScript","_","_time","_frame","initPhysics","_physics","physicsStep","onXRSessionStarted","_session","onXRSessionEnded","onSimulatorStarted","onSelectStart","_event","onSelectEnd","onSelect","onSelecting","onKeyDown","onKeyUp","onSqueezeStart","onSqueezeEnd","onSqueezing","onSqueeze","onObjectSelectStart","onObjectSelectEnd","onHoverEnter","_controller","onHoverExit","onHovering","onObjectTouchStart","onObjectTouching","onObjectTouchEnd","onObjectGrabStart","onObjectGrabbing","onObjectGrabEnd","dispose","ScriptMixinObject3D","Object3D","Script","ScriptMixinMeshScript","Mesh","MeshScript","geometry","material","clamp","value","min","max","Math","lerp","x","y","t","print","urlParams","URLSearchParams","window","search","getUrlParameter","get","getUrlParamBool","defaultBool","inputString","toLowerCase","getUrlParamInt","defaultNumber","inputNumber","num","parseInt","isNaN","getUrlParamFloat","parseFloat","getVec4ByColorString","colorString","hex","startsWith","slice","len","alpha","expandedHex","split","char","r","g","b","Vector4","getColorHex","fontColor","vec4","round","z","parseBase64DataURL","dataURL","match","mimeType","strippedBase64","substring","GeminiOptions","apiKey","urlParam","keyValid","enabled","config","live","voiceName","screenshotInterval","audioConfig","sampleRate","channelCount","echoCancellation","noiseSuppression","autoGainControl","OpenAIOptions","AIOptions","gemini","openai","globalUrlParams","key","BaseAIModel","createPartFromUri","createUserContent","GoogleGenAI","EndSensitivity","StartSensitivity","Modality","Gemini","inited","isLiveMode","liveCallbacks","async","genAIModule","import","errorMessage","loadGoogleGenAIModule","isLiveAvailable","params","liveSession","defaultConfig","responseModalities","AUDIO","speechConfig","voiceConfig","prebuiltVoiceConfig","outputAudioTranscription","inputAudioTranscription","onopen","onmessage","onerror","onclose","event","undefined","reason","warn","connectParams","connect","close","sendRealtimeInput","input","getLiveSessionStatus","isActive","hasSession","_tools","models","generateContent","contents","modelParams","inlineData","base64","uri","functionCalls","Array","isArray","item","header","candidates","firstCandidate","part","OpenAIApi","OpenAI","openAIModule","default","loadOpenAIModule","dangerouslyAllowBrowser","chat","completions","create","messages","choices","message","SUPPORTED_MODELS","AI","lock","loadKeysFromFile","keysCache","modelName","ModelClass","modelOptions","initializeModel","resolveApiKey","isValidApiKey","genericKey","modelKey","geminiKey64","atob","keysFromFile","modelNameWithApiKeySuffix","keyFromFile","triggerKeyPopup","createSampleKeysStructure","hasApiKey","NUM_HANDS","HAND_JOINT_COUNT","HAND_JOINT_IDX_CONNECTION_MAP","HAND_BONE_IDX_CONNECTION_MAP","VIEW_DEPTH_GAP","LEFT_VIEW_ONLY_LAYER","RIGHT_VIEW_ONLY_LAYER","OCCLUDABLE_ITEMS_LAYER","UI_OVERLAY_LAYER","DEFAULT_DEVICE_CAMERA_WIDTH","DEFAULT_DEVICE_CAMERA_HEIGHT","XR_BLOCKS_ASSETS_PATH","deepFreeze","obj","Object","freeze","getOwnPropertyNames","forEach","prop","isFrozen","deepMerge","obj1","obj2","merged","prototype","hasOwnProperty","call","val1","val2","DeviceCameraOptions","willCaptureFrequently","baseCaptureOptions","videoConstraints","width","ideal","height","xrDeviceCameraEnvironmentOptions","facingMode","xrDeviceCameraUserOptions","xrDeviceCameraEnvironmentContinuousOptions","xrDeviceCameraUserContinuousOptions","onDesktopUserAgent","test","navigator","userAgent","DepthMeshTexturedShader","vertexShader","fragmentShader","DepthMesh","camera","Camera","renderer","WebGLRenderer","isDepthMesh","depthOptions","depthTextures","depthMesh","PlaneGeometry","uniforms","useDepthTexture","showDebugTexture","uDepthTexture","uColor","Color","uResolution","uRawValueToMeters","uMinDepth","uMaxDepth","uOpacity","opacity","uDebug","uLightDirection","normalize","uUsingFloatDepth","useFloat32","ShaderMaterial","side","FrontSide","transparent","ShadowMaterial","shadowOpacity","depthWrite","ignoreReticleRaycast","worldPosition","worldQuaternion","Quaternion","updateVertexNormals","minDepth","maxDepth","minDepthPrev","maxDepthPrev","colliders","projectionMatrixInverse","Matrix4","lastColliderUpdateTime","colliderId","visible","renderShadow","performance","now","colliderUpdateFps","depthTextureMaterialUniforms","receiveShadow","castShadow","useDownsampledGeometry","downsampledGeometry","downsampledMesh","add","updateDepth","depthData","xr","getCamera","cameras","projectionMatrix","invert","updateFullResolutionGeometry","updateGeometry","attributes","position","needsUpdate","depthTextureLeft","rawValueToMeters","computeVertexNormals","updateColliderIfNeeded","depthArray","Float32Array","Uint16Array","vertexPosition","count","u","array","v","depthX","rawDepth","depth","patchHoles","patchHolesUpper","set","applyMatrix4","multiplyScalar","timeSinceLastUpdate","RAPIER","getWorldPosition","getWorldQuaternion","rigidBody","setTranslation","setRotation","vertices","indices","getIndex","shape","ColliderDesc","trimesh","setDensity","useDualCollider","blendedWorld","removeCollider","createCollider","newCollider","collider","initRapierPhysics","desc","RigidBodyDesc","fixed","createRigidBody","getDepth","raycaster","ndc","ndc2D","setFromCamera","intersects","intersectObject","raycast","intersections","intersect","normal","face","getColliderFromHandle","handle","DepthMeshOptions","DepthOptions","debugging","depthTexture","constantKernel","applyGaussianBlur","applyKawaseBlur","occlusion","xrDepthMeshOptions","xrDepthMeshVisualizationOptions","xrDepthMeshPhysicsOptions","DepthTextures","uint16Arrays","uint8Arrays","textures","createDepthTextures","view_id","typedArray","format","RedFormat","HalfFloatType","DataTexture","Uint8Array","RGFormat","UnsignedByteType","float32Data","float16Data","DataUtils","toHalfFloat","KawaseBlurShader","OcclusionShader","OcclusionMapShader","OcclusionMapMeshMaterial","MeshBasicMaterial","useFloatDepth","cameraFar","far","cameraNear","near","uFloatDepth","onBeforeCompile","shader","assign","replace","KawaseBlurMode","OcclusionPass","Pass","renderToScreen","occludableItemsLayer","occlusionMeshMaterial","occlusionMapUniforms","uUvTransform","uAlpha","tDiffuse","tDepth","occlusionMapQuad","FullScreenQuad","occlusionMapTexture","WebGLRenderTarget","kawaseBlurTargets","kawaseBlurQuads","setupKawaseBlur","DOWN","texture","UP","occlusionUniforms","tOcclusionMap","occlusionQuad","mode","inputTexture","uBlurSize","uTexelSize","kawase1Material","defines","MODE","setDepthTexture","render","writeBuffer","readBuffer","originalRenderTarget","getRenderTarget","dimensions","renderOcclusionMapFromScene","renderOcclusionMapFromReadBuffer","blurOcclusionMap","applyOcclusionMapToRenderedImage","setRenderTarget","overrideMaterial","getDrawingBufferSize","setSize","renderTarget","originalCameraLayers","from","keys","filter","element","layers","isEnabled","disableAll","enable","updateOcclusionMapUniforms","uOcclusionClipFromWorld","multiply","matrixWorldInverse","clipSpacePosition","Depth","view","occludableShaders","Set","depthClientsInitialized","depthClients","instance","registry","register","shadowMap","PCFShadowMap","occlusionPass","depthY","getProjectedDepthViewPositionFromWorldPosition","target","getVertex","updateDepthData","getTexture","frame","updateLocalDepth","renderOcclusionPass","leftCamera","session","depthActive","needsDepth","size","pauseDepthSensing","resumeDepthSensing","xrRefSpace","requestReferenceSpace","then","refSpace","addEventListener","pose","getViewerPose","views","getDepthInformation","leftDepthTexture","rightDepthTexture","xrIsPresenting","isPresenting","debugLog","arrayBuffer","uint8Array","binaryString","byte","String","fromCharCode","data_str","btoa","resumeDepth","client","pauseDepth","delete","aspectRatios","RGB","rgbToDepthParams","scale","scaleX","scaleY","translateU","translateV","k1","k2","k3","p1","p2","xc","yc","transformRgbToDepthUv","rgbUv","xrDeviceCamera","simulatorCamera","viewportAspect","innerWidth","innerHeight","cameraAspect","relativeWidth","relativeHeight","relativeScaleX","relativeScaleY","u_norm","v_norm","u_centered","v_centered","r2","radial","transformRgbUvToWorld","viewProjectionMatrix","matrixWorld","xrDepth","depthUV","depthU","depthV","rawDepthValue","depthInMeters","viewSpacePosition","viewProjectionMatrixInverse","clone","cropImage","base64Image","boundingBox","img","Image","Promise","resolve","reject","onload","err","src","canvas","document","createElement","ctx","getContext","unitBox","Box2","clampedBox","cropSize","getSize","sourceX","sourceY","sourceWidth","sourceHeight","drawImage","toDataURL","StreamState","VideoStream","loaded","state","IDLE","stream_","video_","frozenTexture_","canvas_","context_","willCaptureFrequently_","autoplay","muted","playsInline","VideoTexture","colorSpace","SRGBColorSpace","minFilter","LinearFilter","magFilter","setState_","details","force","dispatchEvent","debug","handleVideoStreamLoadedMetadata","allowRetry","videoWidth","videoHeight","aspectRatio","setTimeout","ERROR","getSnapshot","outputFormat","quality","readyState","HAVE_CURRENT_DATA","getImageData","frozenTexture","Texture","stop_","getTracks","track","stop","srcObject","URL","revokeObjectURL","XRDeviceCamera","isInitializing_","availableDevices_","currentDeviceIndex_","videoConstraints_","getAvailableVideoDevices","mediaDevices","enumerateDevices","devices","simulatorDevices","device","kind","INITIALIZING","initStream_","NO_DEVICES_FOUND","currentTrackSettings_","stream","deviceIdConstraint","deviceId","targetDeviceId","exact","d","groupId","getMedia","getUserMedia","video","videoTracks","getVideoTracks","activeTrack","getSettings","findIndex","onloadedmetadata","play","getCurrentDevice","trackSettings","STREAMING","setDeviceId","newIndex","setFacingMode","getAvailableDevices","getCurrentTrackSettings","getCurrentDeviceIndex","registerSimulatorCamera","Registry","instances","Map","registrationType","getOrCreate","factory","unregister","flipBufferVertically","buffer","bytesPerRow","tempRow","topRowOffset","bottomRowOffset","subarray","PendingScreenshotRequest","overlayOnCamera","ScreenshotSynthesizer","pendingScreenshotRequests","virtualBuffer","virtualRealBuffer","onAfterRender","deviceCamera","every","request","createVirtualImageDataURL","virtualImageDataUrl","resolveVirtualOnlyRequests","haveVirtualAndRealReqeusts","some","createVirtualRealImageDataURL","virtualRealImageDataUrl","resolveVirtualRealRequests","readRenderTargetPixelsAsync","virtualCanvas","imageData","ImageData","Uint8ClampedArray","putImageData","remainingRequests","realVirtualRenderTarget","virtualRenderTarget","quad","getFullScreenQuad","virtualRealCanvas","fullScreenQuad","getScreenshot","ScriptsManager","initScriptFunction","scripts","callSelectStartBound","callSelectStart","bind","callSelectEndBound","callSelectEnd","callSelectBound","callSelect","callSqueezeStartBound","callSqueezeStart","callSqueezeEndBound","callSqueezeEnd","callSqueezeBound","callSqueeze","callKeyDownBound","callKeyDown","callKeyUpBound","callKeyUp","initializingScripts","initScript","script","has","uninitScript","syncScriptsWithScene","seenScripts","promises","traverse","allSettled","WaitFrame","onFrame","callback","waitFrame","WebXRSessionEventType","WebXRSessionManager","EventDispatcher","sessionInit","onSessionEndedBound","onSessionEndedInternal","initialize","xrModeSupported","UNSUPPORTED","modeSupported","isSessionSupported","sessionOptions","optionalFeatures","READY","offerSession","onSessionStartedInternal","catch","startSession","currentSession","requestSession","endSession","end","isXRSupported","setSession","SESSION_START","SESSION_END","removeEventListener","XRBUTTON_CLASS","XRButton","sessionManager","startText","endText","invalidText","startSimulatorText","enableSimulator","showSimulatorButtonOnMobile","startSimulator","domElement","simulatorButtonElement","xrButtonElement","createXRButtonElement","createSimulatorButton","showXRNotSupported","onSessionReady","onSessionStarted","onSessionEnded","classList","innerText","onclick","remove","appendChild","disabled","textContent","button","style","display","innerHTML","XRPass","_renderer","_writeBuffer","_readBuffer","_deltaTime","_maskActive","_viewId","XREffects","timer","passes","renderTargets","addPass","pass","setupRenderTargets","defaultTarget","neededRenderTargets","DepthTexture","cameraAutoUpdate","renderXr","renderSimulator","xrEnabled","viewport","getViewport","deltaTime","getDelta","camIndex","cam","setViewport","autoClearColor","eye","lastRenderTargetIndex","nextRenderTargetIndex","HAND_JOINT_NAMES","Handedness","Hands","hands","dominant","RIGHT","getJoint","jointName","targetHandednessEnum","resolvedHandednessEnum","NONE","hand","joints","getIndexTip","handedness","getThumbTip","getMiddleTip","getRingTip","getPinkyTip","getWrist","toString","s","LEFT","joint","toFixed","toPositionQuaternionArray","orderedHandedness","numJoints","handDataAvailable","quaternion","w","expectedSize","isValid","handIndex","ReticleShader","setHex","uPressed","Reticle","rotationSmoothing","offset","depthTest","CircleGeometry","makeTranslation","UniformsUtils","direction","renderOrder","originalNormal","newRotation","objectRotation","normalVector","setRotationFromNormalVector","angle","angleTo","cross","setFromAxisAngle","slerp","setPoseFromIntersection","applyQuaternion","setColor","color","getColor","setPressed","pressed","setScalar","setPressedAmount","pressedAmount","ControllerRayVisual","Line","BufferGeometry","setFromPoints","AnimatableNumber","minValue","maxValue","speed","deltaTimeSeconds","GazeController","connected","reticle","activationTimeSeconds","activationAmount","lastReticlePosition","clock","Clock","updateMatrixWorld","delta","distanceTo","updateReticleScale","disconnect","MouseController","Raycaster","forwardVector","updateMousePositionFromEvent","mouse","clientX","clientY","rayDirection","ray","setFromUnitVectors","ActiveControllers","MATRIX4","Input","controllers","controllerGrips","initialized","pivotsEnabled","gazeController","mouseController","controllersEnabled","listeners","intersectionsForController","activeControllers","getController","visualization","controllerModelFactory","XRControllerModelFactory","getControllerGrip","createControllerModel","getHand","visualizeJoints","handModelFactory","XRHandModelFactory","handModel","createHandModel","visualizeMeshes","visualizeRays","bindSelectStart","defaultOnSelectStart","bindSelectEnd","defaultOnSelectEnd","bindSqueezeStart","bindSqueezeEnd","bindListener","defaultOnConnected","defaultOnDisconnected","addObject","group","Group","enablePivots","pivot","IcosahedronGeometry","addReticles","_setRaycasterFromController","performRaycastOnScene","defaultOnSqueezeStart","squeezing","defaultOnSqueezeEnd","gamepad","inputSource","leftController","rightController","listenerName","listener","unbindListener","index","indexOf","splice","bindSelect","bindSqueeze","bindKeyDown","bindKeyUp","unbindKeyDown","unbindKeyUp","intersectObjectByController","setFromXRController","intersectObjectByEvent","updateController","updateReticleFromIntersections","origin","identity","extractRotation","enableGazeController","disableGazeController","disableControllers","targetObject","enableControllers","Lighting","dirLight","DirectionalLight","ambientProbe","LightProbe","ambientLight","lightGroup","simulatorRunning","lightingOptions","xrLight","XREstimatedLight","castDirectionalLightShadow","shadow","mapSize","cameraFrustrumRadius","left","right","top","bottom","blurSamples","radius","bias","CameraHelper","useAmbientSH","useDirectionalLight","directionalLight","intensity","sh","lightProbe","coefficients","fromArray","useDynamicSoftShadow","ambientLightIntensity","ambientMonoIntensity","mainLightIntensity","ambientToMain","Physics","fps","timestep","physicsOptions","World","gravity","useEventQueue","eventQueue","EventQueue","worldStep","step","free","HandsOptions","enableHands","enableHandsVisualization","LightingOptions","PhysicsOptions","SimulatorMode","NEXT_SIMULATOR_MODE","USER","POSE","CONTROLLER","SimulatorOptions","initialCameraPosition","scenePath","initialScenePosition","defaultMode","defaultHand","modeIndicator","customInstructions","handPosePanel","geminilive","stereo","renderToRenderTexture","SpeechSynthesizerOptions","allowInterruptions","SpeechRecognizerOptions","lang","continuous","commands","interimResults","commandConfidenceThreshold","playSimulatorActivationSounds","SoundOptions","speechSynthesizer","speechRecognizer","ObjectsOptions","showDebugVisualizations","objectImageMargin","backendConfig","activeBackend","responseSchema","items","objectName","ymin","xmin","ymax","xmax","mediapipe","PlanesOptions","WorldOptions","planes","objects","enablePlaneDetection","enableObjectDetection","InputOptions","enabledMouse","ReticleOptions","XRTransitionOptions","transitionTime","defaultBackgroundColor","Options","antialias","logarithmicDepthBuffer","stencil","lighting","reticles","simulator","world","physics","transition","usePostprocessing","xrButton","autostartSimulatorOnDesktop","autostartSimulator","enableUI","enableReticles","enableDepth","enableCamera","enableHandRays","enableGeminiLive","enableAI","enableXRTransitions","SimulatorMediaDeviceInfo","label","ConstrainDomStringMatch","SimulatorCamera","cameraCreated","matchRenderingCamera","PerspectiveCamera","createSimulatorCamera","mediaStream","captureStream","videoTrack","cameraInfo","onBeforeSimulatorSceneRender","renderScene","sWidth","sHeight","croppedSourceWidth","croppedSourceHeight","sx","sy","onSimulatorSceneRendered","restartVideoTrack","constraints","constraint","matches","c","ACCEPTABLE","EXACT","UNACCEPTABLE","IDEAL","evaluateConstrainDOMString","AVERAGE_IPD_METERS","SimulatorRenderMode","Keycodes","SimulatorControllerState","localControllerPositions","localControllerOrientations","currentControllerIndex","A_CODE","D_CODE","E_CODE","Q_CODE","S_CODE","W_CODE","vector3","euler","Euler","SimulatorControlMode","simulatorControllerState","downKeys","setStereoRenderMode","toggleUserInterface","onPointerDown","onPointerUp","onPointerMove","code","DIGIT_1","STEREO_LEFT","DIGIT_2","STEREO_RIGHT","BACKQUOTE","onModeActivated","onModeDeactivated","updateCameraPosition","updateControllerPositions","cameraRotation","cameraPosition","Number","premultiply","updateMatrix","rotateOnPointerMove","objectQuaternion","multiplier","setFromQuaternion","movementX","movementY","PI_2","PI","setFromEuler","enableSimulatorHands","showHands","disableSimulatorHands","hideHands","SPACE_CODE","T_CODE","SimulatorControllerMode","buttons","controllerOrientation","toggleControllerIndex","toggleHandedness","controllerSelecting","newSelectingState","setLeftHandPinching","setRightHandPinching","SimulatorPoseMode","SimulatorUserMode","SetSimulatorModeEvent","Event","simulatorMode","bubbles","composed","preventDefault","SimulatorControls","userInterface","pointerDown","_onPointerDown","_onPointerUp","_onKeyDown","_onKeyUp","_onPointerMove","toggleInterfaceVisible","simulatorModes","simulatorModeControls","simulatorOptions","setSimulatorMode","LEFT_SHIFT_CODE","modeIndicatorElement","setModeIndicatorElement","SimulatorDepthMaterial","SimulatorDepth","simulatorScene","depthWidth","depthHeight","depthBufferSlice","createRenderTarget","depthMaterial","depthRenderTarget","FloatType","depthBuffer","renderDepthScene","bindBuffer","PIXEL_PACK_BUFFER","readRenderTargetPixels","j","i_offset","j_offset","copyWithin","SimulatorHandPoseChangeRequestEvent","SimulatorHandPose","SIMULATOR_HAND_POSE_TO_JOINTS_LEFT","RELAXED","PINCHING","FIST","THUMBS_UP","POINTING","ROCK","THUMBS_DOWN","VICTORY","SIMULATOR_HAND_POSE_TO_JOINTS_RIGHT","SIMULATOR_HAND_POSE_NAMES","SimulatorXRHand","SimulatorHands","leftHandBones","rightHandBones","leftHandPose","rightHandPose","leftHandTargetJoints","rightHandTargetJoints","lerpSpeed","onHandPoseChangeRequestBound","onHandPoseChangeRequest","leftXRHand","rightXRHand","loadMeshes","loader","GLTFLoader","setPath","gltf","leftHand","bone","getObjectByName","setLeftHandJoints","rightHand","setRightHandJoints","setLeftHandLerpPose","updateHandPosePanel","setRightHandLerpPose","jointData","lerpLeftHandPose","lerpRightHandPose","syncHandJoints","targetJoint","updateWorldMatrix","setFromMatrixPosition","setRotationFromMatrix","pinching","handPosePanelElement","handPose","setHandPosePanelElement","handPoseChangeEvent","SimulatorInterface","elements","interfaceVisible","simulatorControls","simulatorHands","createModeIndicator","showGeminiLivePanel","createHandPosePanel","showInstructions","body","handsPanelElement","hideUiElements","showUiElements","getInterfaceVisible","SimulatorScene","Scene","addLights","loadGLTF","HemisphereLight","path","callInitWithDependencyInjection","fallback","fromEntries","entries","dependency","SimulatorUser","journeyId","stopJourney","isOnJourneyId","loadJourney","actions","currentJourneyId","simulatorUser","Simulator","Timer","renderMainScene","controls","renderDepthPass","renderMode","DEFAULT","stereoCameras","renderSimulatorSceneToCanvasBound","renderSimulatorSceneToCanvas","setupStereoCameras","virtualSceneRenderTarget","stencilBuffer","virtualSceneFullScreenQuad","mainCamera","mainScene","simulatorUpdate","rightCamera","getRenderCamera","stencilEnabled","renderSimulatorScene","clearDepth","AudioListener","isCapturing","latestAudioBuffer","startCapture","onAudioData","onError","setupAudioCapture","cleanup","stopCapture","audioStream","audio","actualSampleRate","getAudioTracks","audioContext","AudioContext","setupAudioWorklet","sourceNode","createMediaStreamSource","processorNode","AudioWorkletNode","port","streamToAI","resume","blob","Blob","processorURL","createObjectURL","audioWorklet","addModule","audioBuffer","aiService","base64Audio","bytes","binary","arrayBufferToBase64","setAIStreaming","isSupported","getIsCapturing","getLatestAudioBuffer","clearLatestAudioBuffer","AudioPlayer","audioQueue","isPlaying","nextStartTime","initializeAudioContext","currentTime","playAudioChunk","base64AudioData","base64ToArrayBuffer","createBuffer","byteLength","channelData","getChannelData","int16View","Int16Array","playNextAudioBuffer","shift","startTime","source","createBufferSource","destination","onended","duration","clearQueue","getIsPlaying","getQueueLength","charCodeAt","MUSIC_LIBRARY_PATH","musicLibrary","ambient","buttonHover","buttonPress","menuDismiss","BackgroundMusic","categoryVolumes","audioLoader","AudioLoader","currentAudio","specificVolume","musicCategory","setVolume","level","MathUtils","effectiveVolume","getEffectiveVolume","playMusic","musicKey","category","soundPath","stopMusic","Audio","setBuffer","setLoop","xhr","total","destroy","VolumeCategory","CategoryVolumes","isMuted","masterVolume","volumes","values","cat","getCategoryVolume","categoryVol","clampedSpecificVolume","SOUND_PRESETS","BEEP","frequency","waveformType","CLICK","delay","ACTIVATE","DEACTIVATE","SoundSynthesizer","isInitialized","_initAudioContext","playTone","volume","oscillator","createOscillator","setValueAtTime","gainNode","createGain","gain","stopTime","fadeOutTime","exponentialRampToValueAtTime","playPresetTone","presetName","preset","toneConfig","tone","spatialSoundLibrary","paintOneShot1","soundIdCounter","SpatialAudio","soundLibrary","activeSounds","defaultRefDistance","defaultRolloffFactor","playSoundAtObject","soundKey","soundId","loop","refDistance","rolloffFactor","PositionalAudio","setRefDistance","setRolloffFactor","onEnded","_cleanupSound","uuid","stopSound","soundData","updateAllVolumes","SpeechRecognizer","soundOptions","soundSynthesizer","isListening","lastTranscript","lastConfidence","playActivationSounds","handleStartBound","_handleStart","handleResultBound","_handleResult","handleEndBound","_handleEnd","handleErrorBound","_handleError","SpeechRecognitionAPI","SpeechRecognition","webkitSpeechRecognition","recognition","onstart","onresult","onend","lastCommand","getLastTranscript","getLastCommand","getLastConfidence","interimTranscript","finalTranscript","currentConfidence","resultIndex","results","transcript","isFinal","confidence","trim","upperTranscript","toUpperCase","command","originalEvent","SpeechSynthesizer","onStartCallback","onEndCallback","onErrorCallback","synth","speechSynthesis","voices","isSpeaking","speechCategory","loadVoices","onvoiceschanged","getVoices","selectedVoice","voice","speak","pitch","rate","cancel","utterance","SpeechSynthesisUtterance","tts","speaking","CoreSound","backgroundMusic","spatialAudio","audioListener","audioPlayer","getAudioListener","setMasterVolume","getMasterVolume","setCategoryVolume","isAIStreamingEnabled","playAIAudio","stopAIAudio","isAIAudioPlaying","isAudioEnabled","muteAll","unmuteAll","DP_TO_DMM","worldScale","View","rangeX","rangeY","isQuad","isRoot","isView","weight","paddingX","paddingY","paddingZ","dpToMeters","dp","dpToLocalUnits","getWorldScale","show","child","hide","updateLayout","updateLayouts","updateLayoutsBFS","queue","currentView","children","childView","resetLayout","resetLayouts","_id","FONT_FAMILIES","MATERIAL_ICONS_FONT_FILE","TroikaImportStatus","Text","troikaImportError","troikaImportStatus","PENDING","TextView","_text","useSDFText","textObj","sync","updateHTMLText","font","maxWidth","anchorX","anchorY","textAlign","imageOffsetX","imageOffsetY","lineHeight","lineCount","_initializeTextCalled","fontSize","fontSizeDp","imageOverlay","troikaModule","SUCCESS","FAILED","importTroika","_initializeText","setText","createTextSDF","mask","createTextHTML","planeGeometry","CanvasTexture","planeMaterial","clearRect","fillStyle","padStart","textBaseline","fillText","onSyncComplete","textRenderInfo","caretPositions","numberOfChars","firstBottom","lastBottom","syncTextObj","setTextColor","IconButton","backgroundColor","defaultOpacity","hoverColor","hoverOpacity","selectedOpacity","onHoverOver","onHoverOut","IconView","ImageView","initCalled","textureLoader","DoubleSide","reload","loadedTexture","scaleImageToCorrectAspectRatio","textureWidth","textureHeight","widthScaleFactor","heightScaleFactor","minScaleFactor","LabelView","depthText","SquircleShader","uMainTex","uUseImage","uBackgroundColor","uBoxSize","uRadius","TextButton","colorVec4","boxSize","uAspect","selectedFontColor","VideoView","crossOrigin","videoAspectRatio","videoGeometry","videoMaterial","loadFromVideoTexture","HTMLVideoElement","loadFromVideoElement","loadFromURL","loadFromStream","disposeStreamListener_","streamReadyCallback_","videoElement","paused","videoTextureInstance","onLoadedMetadata","HAVE_METADATA","once","pause","removeAttribute","objectIsDescendantOf","currentNode","traverseUtil","node","User","local","numHands","panelDistance","safeSpaceRadius","objectDistance","objectAngle","pivots","hoveredObjectsForController","selectedObjectsForController","touchedObjects","grabbedObjects","setHeight","getPivot","getPivotPosition","getReticleDirection","controllerId","getReticleTarget","getReticleIntersection","isPointingAt","isSelectingAt","getIntersectionAt","getControllerPosition","getControllerObjectDistance","controllerPos","objPos","isSelecting","isSqueezing","callObjectSelectStart","selectedObject","callObjectSelectEnd","ancestor","updateForController","updateTouchState","updateGrabState","isPinching","touchedMeshes","currentlyGrabbedMeshes","previouslyGrabbedMeshesMap","newlyGrabbedMeshes","releasedMeshes","grabEvent","callObjectGrabStart","callObjectGrabEnd","callObjectGrabbing","indexTip","indexTipPosition","currentlyTouchedMeshes","isMesh","Box3","setFromObject","containsPoint","previouslyTouchedMeshes","currentMeshesSet","newlyTouchedMeshes","removedMeshes","touchingEvent","touchPosition","callObjectTouchStart","callObjectTouchEnd","callObjectTouching","currentHoverTarget","previousHoverTarget","callHoverExit","callHoverEnter","callOnHovering","select","FORWARD","BACK","ZERO_VECTOR3","_quaternion","_euler","_vector3","DragMode","DragManager","originalObjectPosition","originalObjectRotation","originalObjectScale","originalController1Position","originalController1RotationInverse","originalController1MatrixInverse","originalScalingControllerDistance","originalScalingObjectScale","TRANSLATING","ROTATING","SCALING","DO_NOT_DRAG","beginDragging","draggableObject","updateDragging","draggingMode","findDraggableObjectAndDraggingMode","beginScaling","compose","controller1","controller2","subVectors","updateTranslating","updateRotating","updateScaling","matrix","dragFacingCamera","turnPanelToFaceTheCamera","updateRotatingFromMouseController","deltaPosition","offsetRotation","multiplyQuaternions","deltaRotation","rotationYawAngle","distanceRatio","atan2","currentTarget","ExitButton","getSession","Grid","rowWeight","colWeight","leftWeight","topWeight","cols","rows","RowClass","ColClass","PanelClass","OrbiterClass","addImage","addVideo","addIconButton","iconButton","addTextButton","addIcon","iconView","addText","textView","addLabel","labelView","addOrbiter","ui","addExitButton","addPanel","panel","addRow","row","addCol","col","SpatialPanelShader","uReticleUVs","uSelected","uBorderWidth","uHighlightRadius","uOutlineWidth","PanelMesh","panelScale","setWidthHeight","setAspectRatio","DEFAULT_WIDTH_M","DEFAULT_WIDTH_DP","DEFAULT_HEIGHT_M","DEFAULT_HEIGHT_DP","Panel","user","keepFacingCamera","isPanel","useDefaultPosition","useBorderlessShader","showHighlights","_fadeState","_fadeDuration","_fadeTimer","_currentOpacity","_startOpacity","_targetOpacity","isDraggable","fadeIn","onComplete","_startFade","fadeOut","targetOpacity","onFadeComplete","_completeFade","_prepareMaterialsForFade","_applyOpacity","opacityValue","progress","addGrid","grid","parentAspectRatio","getWidth","getHeight","Col","Orbiter","Row","SpatialPanel","showEdge","_updateInteractionFeedback","id1","id2","isSelected1","isSelected2","u1","v1","u2","v2","UI","ComponentRegistry","registerComponent","typeName","componentClass","rootComponent","_composeNode","nodeJson","rotation","ComponentClass","componentInstance","childJson","childComponent","LoadingSpinner","HTMLElement","connectedCallback","attachShadow","customElements","define","LoadingSpinnerManager","isLoading","setupCallbacks","showSpinner","spinnerElement","hideSpinner","DefaultLoadingManager","onStart","_url","itemsLoaded","itemsTotal","postMessage","payload","onProgress","onLoad","loadingSpinnerManager","vector3a","vector3b","matrix4","placeObjectAtIntersectionFacingTarget","worldNormal","transformDirection","sub","rightVector","crossVectors","makeBasis","setFromRotationMatrix","DetectedObject","additionalData","detection2DBoundingBox","ObjectDetector","_detectedObjects","_geminiConfig","_buildGeminiConfig","_debugVisualsGroup","runDetection","_runGeminiDetection","cachedDepthArray","cachedMatrixWorld","originalGeminiConfig","rawResponse","parsedResponse","parse","_visualizeBoundingBoxesOnImage","detectionPromises","coord","center","getCenter","uvInput","margin","cropBox","subScalar","addScalar","objectImage","_createDebugVisual","all","Boolean","allObjects","detections","naturalWidth","naturalHeight","rectX","rectY","rectWidth","rectHeight","strokeStyle","lineWidth","strokeRect","textMetrics","measureText","fillRect","timestamp","Date","toISOString","link","download","href","click","sphere","SphereGeometry","textLabel","geminiOptions","thinkingConfig","thinkingBudget","responseMimeType","DetectedPlane","xrPlane","planePolygon","polygon","Shape","ShapeGeometry","rotateX","semanticLabel","orientation","PlaneDetector","_detectedPlanes","_debugMaterial","wireframe","detectedPlanes","_xrRefSpace","getReferenceSpace","detectedPlanesInFrame","planesToRemove","existingPlaneMesh","lastChangedTime","_updatePlaneMesh","_addPlaneMesh","_removePlaneMesh","planeMesh","_updatePlanePose","newVertices","p","newShape","newGeometry","getPose","planeSpace","transform","allPlanes","plane","anchorObjectAtReticle","_object","_reticle","_timestamp","placeOnSurface","objectToPlace","intersectObjects","XRTransition","BackSide","currentMode","targetAlpha","Infinity","sceneCamera","toVR","toAR","currentOpacity","lerpFactor","abs","Core","screenshotSynthesizer","dragManager","webXRSettings","scriptsManager","setPixelRatio","devicePixelRatio","setReferenceSpaceType","xrContainer","webXRRequiredFeatures","requiredFeatures","depthSensing","usagePreference","dataFormatPreference","webXRSessionManager","shouldAutostartSimulator","effects","onWindowResize","setAnimationLoop","setInterval","time","currentFrame","renderSimulatorAndScene","aspect","updateProjectionMatrix","cameraOverride","renderSceneOverride","originalLayers","OcclusionUtils","createOcclusionMapOverrideMaterial","addOcclusionToShader","occlusionEnabled","USE_UV","DISTANCE","extractYaw","lookAtRotation","forward","up","lookAt","clampRotationToAngle","currentAngle","acos","axis","sqrt","sign","SimulatorUserAction","_options","LOOK_AT_ANGLE_THRESHOLD","controllerToTargetVector","targetWorldPosition","targetPositionRelativeToCamera","inverseControllerRotation","finalRotation","PinchOnButtonAction","controllerIsPointingAtButton","controllerState","controllerIndex","localControllerPosition","localControllerRotation","rotateControllerTowardsButton","pinchController","pinchedOnButton","ShowHandsAction","cameraToTargetVector","closeToTargetPosition","inverseCameraRotation","WalkTowardsPanelAction","isLookingAtTarget","isNearTarget","lookAtTarget","lookTowardsTarget","moveTowardsTarget","addScaledVector","cameraToCloseToTarget","movementDistance","shouldContinueJourney","core","getDeltaTime","showReticleOnDepthMesh","getXrCameraLeft","getXrCameraRight","showOnlyInLeftEye","showOnlyInRightEye","loadStereoImageAsTextures","ImageLoader","leftTexture","repeat","rightTexture","MaterialSymbolsView","icon","updateIcon","iconWeight","iconStyle","iconColor","iconScale","svgPath","loadedSvgPath","loadingSvgPath","svgData","SVGLoader","viewMinX","viewMinY","viewWidth","viewHeight","xml","viewBox","paths","shapes","createShapes","TextScrollerState","scrollSpeedLinesPerSecond","lines","currentLine","targetLine","shouldUpdate","deltaLines","distanceToTargetLine","Page","PagerState","pages","currentPage","velocity","sin","targetPage","remainingDelta","addPage","Pager","localClippingPlanes","Plane","raycastMesh","clippingPlanes","selecting","selectStartPositionLocal","selectStartPage","raycastPlane","selectingRay","Ray","selectingRayTarget","enableRaycastOnChildren","continuousScrolling","localClippingEnabled","updatePageCount","updatePagePositions","halfNumberOfPages","floor","deltaFromCurrentPage","resetClippingPlanesToLocalSpace","updateClippingPlanes","intersectionIndex","selectingController","constant","computeSelectingDelta","selectingPosition","startSelectPosition","intersectPlane","deltaPage","thisIntersections","childIntersections","pointInLocalCoordinates","VerticalPager","ScrollingTroikaTextView","scrollerState","onTextSyncCompleteBound","onTextSyncComplete","currentText","pager","textViewWrapper","clipToLineHeight","newHeight","positionDiff","rotationDiff","FreestandingSlider","startingValue","rotationScale","initialRotationInverse","setInitialPose","setInitialPoseFromController","getValue","getValueFromRotation","getValueFromController","updateValue","jsmUrl","REVISION","gltfLoaderInstance","ModelLoader","manager","extension","pop","loadSplat","SplatMesh","splatMesh","dracoLoader","DRACOLoader","setDecoderPath","setDecoderConfig","ktx2Loader","KTX2Loader","setTranscoderPath","detectSupport","setDRACOLoader","setKTX2Loader","getGLTFLoader","ModelViewerPlatformCornerGeometry","tube","radialSegments","tubularSegments","normals","vertex","cos","a","setIndex","setAttribute","Float32BufferAttribute","createPlatformGeometry","thickness","cornerRadius","cornerWidthSegments","sideGeometries","cornerGeometry","cornerGeometry1","rotateY","translate","cornerGeometry2","cornerGeometry3","cornerGeometry4","cornerTubes","widthTube","CylinderGeometry","rotateZ","widthTube1","widthTube2","depthTube","depthTube1","depthTube2","createPlatformSideGeometries","sideGeometriesVertexCount","reduce","acc","val","flatGeometries","widthMinusRadius","depthMinusRadius","longQuad","shortQuad","shortQuadTranslationZ","shortQuad1","shortQuad2","quadGeometries","cornerCircle","circleTranslationZ","circleTranslationX","cornerCircle1","cornerCircle2","cornerCircle3","cornerCircle4","topGeometries","bottomGeometries","createPlatformFlatGeometries","flatGeometriesVertexCount","allGeometries","mergedGeometry","BufferGeometryUtils","mergeGeometries","addGroup","computeBoundingBox","ModelViewerPlatform","MeshLambertMaterial","defaultPlatformMargin","quaternion2","SplatAnchor","RotationRaycastMesh","ModelViewer","raycastToChildren","rotatable","scalable","platformAnimationSpeed","platformThickness","isOneOneScale","initialScale","startAnimationOnLoad","clipActions","hoveringControllers","bbox","createSparkRendererIfNeeded","loadSplatModel","onSceneLoaded","platformMargin","setupRaycastCylinder","setupRaycastBox","setupPlatform","splatAnchor","degToRad","setupBoundingBox","verticallyAlignObject","horizontallyAlignObject","setCastShadow","setReceiveShadow","loadGLTFModel","animationMixer","AnimationMixer","animations","clip","clipAction","gltfMesh","platform","localBbox","getBoundingBox","isEmpty","localBboxOfTransformedMesh","translationAmount","contentChildren","rotationRaycastMesh","controlBar","parentReferences","removeFromParent","expandByObject","getGroupBoundingBox","bboxSize","BoxGeometry","decompose","directionToCamera","distanceToCamera","pitchAngleRadians","asin","childRaycasts","rotationIntersects","platformIntersects","controlButtonIntersects","onScaleButtonClick","getOcclusionEnabled","setOcclusionEnabled","playClipAnimationOnce","clampWhenFinished","LoopOnce","SparkRenderer","sparkRendererExists","maxStdDev","SketchPanel","toneMapped","alphaTest","activeHand","activeLine","activeLines","removedLines","isDrawing","clearCanvas","triggerUpdate","beginPath","lineTo","stroke","moveTo","forceUpdate","removeAll","undo","line","drawLine","redo","HorizontalPager","PageIndicator","pagerState","emptyPageIndicator","currentPageIndicator","numberOfPages","previousPage","updateText","fill","VideoFileStream","videoFile","videoFile_","setSource"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"xrblocks.min.js","sources":["../src/agent/Context.ts","../src/agent/Memory.ts","../src/agent/Agent.ts","../src/agent/Tool.ts","../src/agent/tools/GenerateSkyboxTool.ts","../src/agent/SkyboxAgent.ts","../src/agent/tools/GetWeatherTool.ts","../src/ux/UX.ts","../src/core/Script.ts","../src/utils/utils.ts","../src/ai/AIOptions.ts","../src/ai/BaseAIModel.ts","../src/ai/Gemini.ts","../src/ai/OpenAI.ts","../src/ai/AI.ts","../src/constants.ts","../src/utils/OptionsUtils.ts","../src/camera/CameraOptions.ts","../src/utils/BrowserUtils.ts","../src/depth/DepthMeshTexturedShader.ts","../src/depth/DepthMesh.ts","../src/depth/DepthOptions.ts","../src/depth/DepthTextures.ts","../src/depth/occlusion/kawaseblur.glsl.ts","../src/depth/occlusion/occlusion.glsl.ts","../src/depth/occlusion/occlusion_map.glsl.ts","../src/depth/occlusion/OcclusionMapMeshMaterial.ts","../src/depth/occlusion/OcclusionPass.ts","../src/depth/Depth.ts","../src/camera/CameraUtils.ts","../src/video/VideoStream.ts","../src/camera/XRDeviceCamera.ts","../src/core/components/Registry.ts","../src/core/components/ScreenshotSynthesizer.ts","../src/core/components/ScriptsManager.ts","../src/core/components/WaitFrame.ts","../src/core/components/WebXRSessionManager.ts","../src/core/components/XRButton.ts","../src/core/components/XREffects.ts","../src/input/components/HandJointNames.ts","../src/input/Hands.ts","../src/ui/shaders/ReticleShader.ts","../src/ui/core/Reticle.ts","../src/input/components/ControllerRayVisual.ts","../src/ui/interaction/AnimatableNumber.ts","../src/input/GazeController.ts","../src/input/MouseController.ts","../src/input/Input.ts","../src/lighting/Lighting.ts","../src/physics/Physics.ts","../src/input/HandsOptions.ts","../src/lighting/LightingOptions.ts","../src/physics/PhysicsOptions.ts","../src/simulator/SimulatorOptions.ts","../src/sound/SoundOptions.ts","../src/world/objects/ObjectsOptions.ts","../src/world/planes/PlanesOptions.ts","../src/world/WorldOptions.ts","../src/core/Options.ts","../src/simulator/SimulatorMediaDeviceInfo.ts","../src/simulator/utils/CameraUtils.ts","../src/simulator/SimulatorCamera.ts","../src/simulator/SimulatorConstants.ts","../src/utils/Keycodes.ts","../src/simulator/SimulatorControllerState.ts","../src/simulator/controlModes/SimulatorControlMode.ts","../src/simulator/controlModes/SimulatorControllerMode.ts","../src/simulator/controlModes/SimulatorPoseMode.ts","../src/simulator/controlModes/SimulatorUserMode.ts","../src/simulator/events/SimulatorModeEvents.ts","../src/simulator/SimulatorControls.ts","../src/simulator/SimulatorDepthMaterial.ts","../src/simulator/SimulatorDepth.ts","../src/simulator/events/SimulatorHandEvents.ts","../src/simulator/handPoses/HandPoses.ts","../src/simulator/handPoses/RelaxedHandPoses.ts","../src/simulator/handPoses/PinchingHandPoses.ts","../src/simulator/handPoses/FistHandPoses.ts","../src/simulator/handPoses/ThumbsUpPoses.ts","../src/simulator/handPoses/PointingHandPoses.ts","../src/simulator/handPoses/RockHandPoses.ts","../src/simulator/handPoses/ThumbsDownPoses.ts","../src/simulator/handPoses/VictoryHandPoses.ts","../src/simulator/SimulatorXRHand.ts","../src/simulator/SimulatorHands.ts","../src/simulator/SimulatorInterface.ts","../src/simulator/SimulatorScene.ts","../src/utils/DependencyInjection.ts","../src/simulator/SimulatorUser.ts","../src/simulator/Simulator.ts","../src/sound/AudioListener.ts","../src/sound/AudioPlayer.ts","../src/sound/BackgroundMusic.ts","../src/sound/CategoryVolumes.ts","../src/sound/SoundSynthesizer.ts","../src/sound/SpatialAudio.ts","../src/sound/SpeechRecognizer.ts","../src/sound/SpeechSynthesizer.ts","../src/sound/CoreSound.ts","../src/ui/constants.ts","../src/ui/core/View.ts","../src/ui/components/utils/FontFamilies.ts","../src/ui/components/TextView.ts","../src/ui/components/IconButton.ts","../src/ui/components/IconView.ts","../src/ui/components/ImageView.ts","../src/ui/components/LabelView.ts","../src/ui/shaders/SquircleShader.ts","../src/ui/components/TextButton.ts","../src/ui/components/VideoView.ts","../src/utils/SceneGraphUtils.ts","../src/core/User.ts","../src/utils/HelperConstants.ts","../src/ux/DragManager.ts","../src/ui/components/ExitButton.ts","../src/ui/layouts/Grid.ts","../src/ui/shaders/SpatialPanelShader.ts","../src/ui/core/PanelMesh.ts","../src/ui/core/Panel.ts","../src/ui/layouts/Col.ts","../src/ui/layouts/Orbiter.ts","../src/ui/layouts/Row.ts","../src/ui/layouts/SpatialPanel.ts","../src/ui/UI.ts","../src/utils/CreateLoadingSpinner.ts","../src/utils/LoadingSpinnerManager.ts","../src/utils/ObjectPlacement.ts","../src/world/objects/DetectedObject.ts","../src/world/objects/ObjectDetector.ts","../src/world/planes/DetectedPlane.ts","../src/world/planes/PlaneDetector.ts","../src/world/World.ts","../src/core/components/XRTransition.ts","../src/core/Core.ts","../src/depth/occlusion/OcclusionUtils.ts","../src/utils/RotationUtils.ts","../src/simulator/userActions/SimulatorUserAction.ts","../src/simulator/userActions/PinchOnButtonAction.ts","../src/simulator/userActions/ShowHandsAction.ts","../src/simulator/userActions/WalkTowardsPanelAction.ts","../src/singletons.ts","../src/stereo/utils.ts","../src/ui/components/MaterialSymbolsView.ts","../src/ui/layouts/TextScrollerState.ts","../src/ui/layouts/Page.ts","../src/ui/layouts/PagerState.ts","../src/ui/layouts/Pager.ts","../src/ui/layouts/VerticalPager.ts","../src/ui/components/ScrollingTroikaTextView.ts","../src/ui/interaction/FreestandingSlider.ts","../src/utils/ModelLoader.ts","../src/ui/interaction/ModelViewerPlatformCornerGeometry.ts","../src/ui/interaction/ModelViewerPlatformGeometry.ts","../src/ui/interaction/ModelViewerPlatform.ts","../src/ui/interaction/ModelViewer.ts","../src/utils/ModelUtils.ts","../src/ui/interaction/SketchPanel.ts","../src/ui/layouts/HorizontalPager.ts","../src/ui/layouts/PageIndicator.ts","../src/video/VideoFileStream.ts"],"sourcesContent":["import {Memory, MemoryEntry} from './Memory';\nimport {Tool} from './Tool';\n\n/**\n * Builds the context to be sent to the AI for reasoning.\n */\nexport class Context {\n private instructions: string;\n\n constructor(instructions = 'You are a helpful assistant.') {\n this.instructions = instructions;\n }\n\n get instruction(): string {\n return this.instructions;\n }\n\n /**\n * Constructs a formatted prompt from memory and available tools.\n * @param memory - The agent's memory.\n * @param tools - The list of available tools.\n * @returns A string representing the full context for the AI.\n */\n build(memory: Memory, tools: Tool[]): string {\n const history = memory.getShortTerm();\n const formattedHistory =\n history.map(entry => this.formatEntry(entry)).join('\\n');\n\n const toolDescriptions =\n tools.map(tool => `- ${tool.name}: ${tool.description}`).join('\\n');\n\n return `${this.instructions} You have access to the following tools: ${\n toolDescriptions}\n Current Conversation history: ${\n formattedHistory}. You should reply to the user or call a tool as needed.`;\n }\n\n private formatEntry(entry: MemoryEntry): string {\n switch (entry.role) {\n case 'user':\n return `User: ${entry.content}`;\n case 'ai':\n return `AI: ${entry.content}`;\n case 'tool':\n return `Tool Output: ${entry.content}`;\n }\n }\n}\n","export interface MemoryEntry {\n role: 'user'|'ai'|'tool';\n content: string;\n}\n\n/**\n * Manages the agent's memory, including short-term, long-term, and working\n * memory.\n */\nexport class Memory {\n private shortTermMemory: MemoryEntry[] = [];\n\n /**\n * Adds a new entry to the short-term memory.\n * @param entry - The memory entry to add.\n */\n addShortTerm(entry: MemoryEntry): void {\n this.shortTermMemory.push(entry);\n }\n\n /**\n * Retrieves the short-term memory.\n * @returns An array of all short-term memory entries.\n */\n getShortTerm(): MemoryEntry[] {\n return [...this.shortTermMemory];\n }\n\n /**\n * Clears all memory components.\n */\n clear(): void {\n this.shortTermMemory.length = 0;\n }\n}\n","import {AI} from '../ai/AI';\nimport {GeminiResponse} from '../ai/AITypes';\nimport {Gemini} from '../ai/Gemini';\n\nimport {Context} from './Context';\nimport {Memory} from './Memory';\nimport {Tool} from './Tool';\n\n/**\n * Lifecycle callbacks for agent events.\n */\nexport interface AgentLifecycleCallbacks {\n /** Called when a session starts */\n onSessionStart?: () => void | Promise<void>;\n /** Called when a session ends */\n onSessionEnd?: () => void | Promise<void>;\n /** Called after a tool is executed */\n onToolExecuted?: (toolName: string, result: unknown) => void;\n /** Called when an error occurs */\n onError?: (error: Error) => void;\n}\n\n/**\n * An agent that can use an AI to reason and execute tools.\n */\nexport class Agent {\n static dependencies = {};\n ai: AI;\n tools: Tool[];\n memory: Memory;\n contextBuilder: Context;\n lifecycleCallbacks?: AgentLifecycleCallbacks;\n isSessionActive = false;\n\n constructor(\n ai: AI, tools: Tool[] = [], instruction: string = '',\n callbacks?: AgentLifecycleCallbacks) {\n this.ai = ai;\n this.tools = tools;\n this.memory = new Memory();\n this.contextBuilder = new Context(instruction);\n this.lifecycleCallbacks = callbacks;\n }\n\n /**\n * Starts the agent's reasoning loop with an initial prompt.\n * @param prompt - The initial prompt from the user.\n * @returns The final text response from the agent.\n */\n async start(prompt: string): Promise<string> {\n this.memory.addShortTerm({role: 'user', content: prompt});\n\n if (!this.ai.isAvailable()) {\n await this.ai.init({aiOptions: this.ai.options});\n }\n\n return this.run();\n }\n\n /**\n * The main reasoning and action loop of the agent for non-live mode.\n * It repeatedly builds context, queries the AI, and executes tools\n * until a final text response is generated.\n */\n private async run(): Promise<string> {\n while (true) {\n const context = this.contextBuilder.build(this.memory, this.tools);\n\n const response: GeminiResponse|null =\n await (this.ai.model as Gemini)\n .query({type: 'text', text: context}, this.tools);\n\n this.memory.addShortTerm({role: 'ai', content: JSON.stringify(response)});\n\n if (response?.toolCall) {\n console.log(`Executing tool: ${response.toolCall.name}`);\n const tool = this.findTool(response.toolCall.name);\n\n if (tool) {\n const result = await tool.execute(response.toolCall.args);\n this.memory.addShortTerm(\n {role: 'tool', content: JSON.stringify(result)});\n } else {\n const errorMsg = `Error: Tool \"${response.toolCall.name}\" not found.`;\n console.error(errorMsg);\n this.memory.addShortTerm({role: 'tool', content: errorMsg});\n }\n } else if (response?.text) {\n console.log(`Final Response: ${response.text}`);\n return response.text;\n } else {\n const finalResponse = 'The AI did not provide a valid response.';\n console.error(finalResponse);\n return finalResponse;\n }\n }\n }\n\n findTool(name: string): Tool|undefined {\n return this.tools.find(tool => tool.name === name);\n }\n\n /**\n * Get the current session state.\n * @returns Object containing session information\n */\n getSessionState() {\n return {\n isActive: this.isSessionActive,\n toolCount: this.tools.length,\n memorySize: this.memory.getShortTerm?.()?.length || 0,\n };\n }\n}\n","import type * as GoogleGenAITypes from '@google/genai';\n\nexport interface ToolCall {\n name: string;\n args: unknown;\n}\n\n/**\n * Standardized result type for tool execution.\n * @typeParam T - The type of data returned on success.\n */\nexport interface ToolResult<T = unknown> {\n /** Whether the tool execution succeeded */\n success: boolean;\n /** The result data if successful */\n data?: T;\n /** Error message if execution failed */\n error?: string;\n /** Additional metadata about the execution */\n metadata?: Record<string, unknown>;\n}\n\n// Identical to GoogleGenAITypes.Schema but replaces the Type enum with actual\n// strings so tools don't need to import the types from @google/genai.\nexport type ToolSchema = Omit<GoogleGenAITypes.Schema, 'type'|'properties'>&{\n properties?: Record<string, ToolSchema>;\n type?: keyof typeof GoogleGenAITypes.Type;\n};\n\nexport type ToolOptions = {\n /** The name of the tool. */\n name: string;\n /** A description of what the tool does. */\n description: string;\n /** The parameters of the tool */\n parameters?: ToolSchema;\n /** A callback to execute when the tool is triggered */\n onTriggered?: (args: unknown) => unknown | Promise<unknown>;\n};\n\n/**\n * A base class for tools that the agent can use.\n */\nexport class Tool {\n name: string;\n description?: string;\n parameters?: ToolSchema;\n onTriggered?: (args: unknown) => unknown;\n\n /**\n * @param options - The options for the tool.\n */\n constructor(options: ToolOptions) {\n this.name = options.name;\n this.description = options.description;\n this.parameters = options.parameters || {};\n this.onTriggered = options.onTriggered;\n }\n\n /**\n * Executes the tool's action with standardized error handling.\n * @param args - The arguments for the tool.\n * @returns A promise that resolves with a ToolResult containing success/error information.\n */\n async execute(args: unknown): Promise<ToolResult> {\n try {\n if (this.onTriggered) {\n const result = await Promise.resolve(this.onTriggered(args));\n return {\n success: true,\n data: result,\n metadata: {executedAt: Date.now(), toolName: this.name}\n };\n }\n throw new Error(\n 'The execute method must be implemented by a subclass or onTriggered must be provided.');\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n metadata: {executedAt: Date.now(), toolName: this.name}\n };\n }\n }\n\n /**\n * Returns a JSON representation of the tool.\n * @returns A valid FunctionDeclaration object.\n */\n toJSON(): GoogleGenAITypes.FunctionDeclaration {\n const result: GoogleGenAITypes.FunctionDeclaration = {name: this.name};\n if (this.description) {\n result.description = this.description;\n }\n if (this.parameters) {\n result.parameters = this.parameters as GoogleGenAITypes.Schema;\n }\n return result;\n }\n}\n","import * as THREE from 'three';\n\nimport {AI} from '../../ai/AI';\nimport {Tool, ToolResult} from '../Tool';\n\n/**\n * A tool that generates a 360-degree equirectangular skybox image\n * based on a given prompt using an AI service.\n */\nexport class GenerateSkyboxTool extends Tool {\n constructor(private ai: AI, private scene: THREE.Scene) {\n super({\n name: 'generateSkybox',\n description:\n 'Generate a 360 equirectangular skybox image for the given prompt.',\n parameters: {\n type: 'OBJECT',\n properties: {\n prompt: {\n type: 'STRING',\n description:\n 'A description of the skybox to generate, e.g. \"a sunny beach with palm trees\"',\n },\n },\n required: ['prompt'],\n },\n });\n }\n\n /**\n * Executes the tool's action.\n * @param args - The prompt to use to generate the skybox.\n * @returns A promise that resolves with a ToolResult containing success/error information.\n */\n override async execute(args: {prompt: string}): Promise<ToolResult<string>> {\n try {\n const image = await this.ai.generate(\n 'Generate a 360 equirectangular skybox image for the prompt of:' +\n args.prompt,\n 'image', 'Generate a 360 equirectangular skybox image for the prompt',\n 'gemini-2.5-flash-image-preview');\n if (image) {\n console.log('Applying texture...');\n this.scene.background = new THREE.TextureLoader().load(image);\n this.scene.background.mapping = THREE.EquirectangularReflectionMapping;\n return {\n success: true,\n data: 'Skybox generated successfully.',\n metadata: {prompt: args.prompt, timestamp: Date.now()}\n };\n } else {\n return {\n success: false,\n error: 'Failed to generate skybox image',\n metadata: {prompt: args.prompt, timestamp: Date.now()}\n };\n }\n } catch (e) {\n console.error('error:', e);\n return {\n success: false,\n error: e instanceof Error ? e.message :\n 'Unknown error while creating skybox',\n metadata: {prompt: args.prompt, timestamp: Date.now()}\n };\n }\n }\n}\n","import type * as GoogleGenAITypes from '@google/genai';\nimport * as THREE from 'three';\n\nimport {AI} from '../ai/AI';\nimport {CoreSound} from '../sound/CoreSound';\n\nimport {Agent, AgentLifecycleCallbacks} from './Agent';\nimport {GenerateSkyboxTool} from './tools/GenerateSkyboxTool';\nimport {ToolResult} from './Tool';\n\n/**\n * State information for a live session.\n */\nexport interface LiveSessionState {\n /** Whether the session is currently active */\n isActive: boolean;\n /** Timestamp when session started */\n startTime?: number;\n /** Timestamp when session ended */\n endTime?: number;\n /** Number of messages received */\n messageCount: number;\n /** Number of tool calls executed */\n toolCallCount: number;\n /** Last error message if any */\n lastError?: string;\n}\n\n/**\n * Skybox Agent for generating 360-degree equirectangular backgrounds through conversation.\n * \n * @example Basic usage\n * ```typescript\n * // 1. Enable audio (required for live sessions)\n * await xb.core.sound.enableAudio();\n * \n * // 2. Create agent\n * const agent = new xb.SkyboxAgent(xb.core.ai, xb.core.sound, xb.core.scene);\n * \n * // 3. Start session\n * await agent.startLiveSession({\n * onopen: () => console.log('Session ready'),\n * onmessage: (msg) => handleMessage(msg),\n * onclose: () => console.log('Session closed')\n * });\n * \n * // 4. Clean up when done\n * await agent.stopLiveSession();\n * xb.core.sound.disableAudio();\n * ```\n * \n * @example With lifecycle callbacks\n * ```typescript\n * const agent = new xb.SkyboxAgent(\n * xb.core.ai, \n * xb.core.sound, \n * xb.core.scene,\n * {\n * onSessionStart: () => updateUI('active'),\n * onSessionEnd: () => updateUI('inactive'),\n * onError: (error) => showError(error)\n * }\n * );\n * ```\n * \n * @remarks\n * - Audio must be enabled BEFORE starting live session using `xb.core.sound.enableAudio()`\n * - Users are responsible for managing audio lifecycle\n * - Always call `stopLiveSession()` before disabling audio\n * - Session state can be checked using `getSessionState()` and `getLiveSessionState()`\n */\nexport class SkyboxAgent extends Agent {\n private sessionState: LiveSessionState = {\n isActive: false,\n messageCount: 0,\n toolCallCount: 0\n };\n\n constructor(\n ai: AI, private sound: CoreSound, scene: THREE.Scene,\n callbacks?: AgentLifecycleCallbacks) {\n super(\n ai, [new GenerateSkyboxTool(ai, scene)],\n `You are a friendly and helpful skybox designer. The response should be short. Your only capability\n is to generate a 360-degree equirectangular skybox image based on\n a user's description. You will generate a default skybox if the user\n does not provide any description. You will use the tool 'generateSkybox'\n with the summarized description as the 'prompt' argument to create the skybox.`,\n callbacks);\n }\n\n /**\n * Starts a live AI session for real-time conversation.\n * \n * @param callbacks - Optional callbacks for session events. Can also be set using ai.setLiveCallbacks()\n * @throws If AI model is not initialized or live session is not available\n * \n * @remarks\n * Audio must be enabled separately using `xb.core.sound.enableAudio()` before starting the session.\n * This gives users control over when microphone permissions are requested.\n */\n async startLiveSession(callbacks?: GoogleGenAITypes.LiveCallbacks) {\n // Wrap callbacks to track session state\n const wrappedCallbacks = this.wrapCallbacks(callbacks);\n \n if (callbacks) {\n this.ai.setLiveCallbacks(wrappedCallbacks);\n }\n \n const functionDeclarations: GoogleGenAITypes.FunctionDeclaration[] =\n this.tools.map(tool => tool.toJSON());\n const systemInstruction: GoogleGenAITypes.ContentUnion = {\n parts: [{text: this.contextBuilder.instruction}]\n };\n \n await this.ai.startLiveSession({\n tools: functionDeclarations,\n systemInstruction: systemInstruction,\n });\n \n this.sessionState.isActive = true;\n this.sessionState.startTime = Date.now();\n this.isSessionActive = true;\n await this.lifecycleCallbacks?.onSessionStart?.();\n }\n\n /**\n * Stops the live AI session.\n * \n * @remarks\n * Audio must be disabled separately using `xb.core.sound.disableAudio()` after stopping the session.\n */\n async stopLiveSession() {\n await this.ai.stopLiveSession();\n this.sessionState.isActive = false;\n this.sessionState.endTime = Date.now();\n this.isSessionActive = false;\n await this.lifecycleCallbacks?.onSessionEnd?.();\n }\n\n /**\n * Wraps user callbacks to track session state and trigger lifecycle events.\n * @param callbacks - The callbacks to wrap.\n * @returns The wrapped callbacks.\n */\n private wrapCallbacks(\n callbacks?: GoogleGenAITypes.LiveCallbacks): GoogleGenAITypes.LiveCallbacks {\n return {\n onopen: () => {\n callbacks?.onopen?.();\n },\n onmessage: (message: GoogleGenAITypes.LiveServerMessage) => {\n this.sessionState.messageCount++;\n callbacks?.onmessage?.(message);\n },\n onerror: (error: ErrorEvent) => {\n this.sessionState.lastError = error.message;\n this.lifecycleCallbacks?.onError?.(new Error(error.message));\n callbacks?.onerror?.(error);\n },\n onclose: (event: CloseEvent) => {\n this.sessionState.isActive = false;\n this.sessionState.endTime = Date.now();\n this.isSessionActive = false;\n callbacks?.onclose?.(event);\n }\n };\n }\n\n /**\n * Sends tool execution results back to the AI.\n * \n * @param response - The tool response containing function results\n */\n async sendToolResponse(\n response: GoogleGenAITypes.LiveSendToolResponseParameters) {\n if (!this.validateToolResponse(response)) {\n console.error('Invalid tool response format:', response);\n return;\n }\n \n // Handle both single response and array of responses\n const responses = Array.isArray(response.functionResponses) ?\n response.functionResponses :\n [response.functionResponses];\n this.sessionState.toolCallCount += responses.length;\n \n console.log('Sending tool response:', response);\n this.ai.sendToolResponse(response);\n }\n\n /**\n * Validates that a tool response has the correct format.\n * @param response - The tool response to validate.\n * @returns True if the response is valid, false otherwise.\n */ \n private validateToolResponse(\n response: GoogleGenAITypes.LiveSendToolResponseParameters): boolean {\n if (!response.functionResponses) {\n return false;\n }\n\n // Handle both single response and array of responses\n const responses = Array.isArray(response.functionResponses) ?\n response.functionResponses :\n [response.functionResponses];\n\n return responses.every(\n fr => fr.id && fr.name && fr.response !== undefined);\n }\n\n /**\n * Helper to create a properly formatted tool response from a ToolResult.\n * \n * @param id - The function call ID\n * @param name - The function name\n * @param result - The ToolResult from tool execution\n * @returns A properly formatted FunctionResponse\n */\n static createToolResponse(\n id: string, name: string,\n result: ToolResult): GoogleGenAITypes.FunctionResponse {\n return {\n id,\n name,\n response: result.success ? {result: result.data} : {error: result.error}\n };\n }\n\n /**\n * Gets the current live session state.\n * \n * @returns Read-only session state information\n */\n getLiveSessionState(): Readonly<LiveSessionState> {\n return {...this.sessionState};\n }\n\n /**\n * Gets the duration of the session in milliseconds.\n * \n * @returns Duration in ms, or null if session hasn't started\n */\n getSessionDuration(): number|null {\n if (!this.sessionState.startTime) return null;\n const endTime = this.sessionState.endTime || Date.now();\n return endTime - this.sessionState.startTime;\n }\n}\n","import {Tool, ToolResult} from '../Tool';\n\nexport interface GetWeatherArgs {\n latitude: number;\n longitude: number;\n}\n\nexport interface WeatherData {\n temperature: number;\n weathercode: number;\n}\n\n/**\n * A tool that gets the current weather for a specific location.\n */\nexport class GetWeatherTool extends Tool {\n constructor() {\n super({\n name: 'get_weather',\n description: 'Gets the current weather for a specific location.',\n parameters: {\n type: 'OBJECT',\n properties: {\n location: {\n type: 'STRING',\n description: 'The city and state, e.g. San Francisco, CA',\n },\n unit: {\n type: 'STRING',\n enum: ['celsius', 'fahrenheit'],\n },\n },\n required: ['location'],\n }\n });\n }\n\n /**\n * Executes the tool's action.\n * @param args - The arguments for the tool.\n * @returns A promise that resolves with a ToolResult containing weather information.\n */\n override async execute(args: GetWeatherArgs): Promise<ToolResult<WeatherData>> {\n if (!args.latitude || !args.longitude) {\n args.latitude = 37.7749; // Default to San Francisco\n args.longitude = -122.4194;\n }\n const url = `https://api.open-meteo.com/v1/forecast?latitude=${\n args.latitude}&longitude=${\n args.longitude}¤t=weather_code,temperature_2m&temperature_unit=fahrenheit`;\n\n try {\n const response = await fetch(url);\n const data = await response.json();\n\n if (response.ok) {\n return {\n success: true,\n data: {\n temperature: data.current.temperature_2m,\n weathercode: data.current.weather_code,\n },\n metadata: {\n latitude: args.latitude,\n longitude: args.longitude,\n timestamp: Date.now()\n }\n };\n } else {\n return {\n success: false,\n error: 'Could not retrieve weather for the specified location.',\n metadata: {latitude: args.latitude, longitude: args.longitude}\n };\n }\n } catch (error) {\n console.error('Error fetching weather:', error);\n return {\n success: false,\n error: error instanceof Error ? error.message :\n 'There was an error fetching the weather.',\n metadata: {latitude: args.latitude, longitude: args.longitude}\n };\n }\n }\n}\n","import * as THREE from 'three';\n\nimport {View} from '../ui/core/View';\n\n/**\n * UX manages the user experience (UX) state for an interactive object in\n * the scene. It tracks interaction states like hover,\n * selection, and dragging for multiple controllers.\n */\nexport class UX {\n /**\n * The object this UX state manager is attached to.\n */\n parent;\n\n /**\n * Indicates if the parent object can be dragged.\n */\n draggable = false;\n\n /**\n * Indicates if the parent object can be selected.\n */\n selectable = false;\n\n /**\n * Indicates if the parent object can be touched.\n */\n touchable = false;\n\n\n // --- Interaction States ---\n\n /**\n * An array tracking the selection state for each controller.\n * `selected[i]` is true if controller `i` is selecting the object.\n */\n selected: boolean[] = [];\n\n /**\n * An array tracking the hover state for each controller.\n * `hovered[i]` is true if controller `i` is hovering over the object.\n */\n hovered: boolean[] = [];\n\n /**\n * An array tracking the touch state for each controller.\n * `touched[i]` is true if controller `i` is touching over the object.\n */\n touched: boolean[] = [];\n\n /**\n * An array tracking the drag state for each controller.\n */\n activeDragged: boolean[] = [];\n\n\n // --- Intersection Data ---\n\n /**\n * An array storing the 3D position of the last intersection for each\n * controller.\n */\n positions: THREE.Vector3[] = [];\n\n /**\n * An array storing the distance of the last intersection for each controller.\n */\n distances: number[] = [];\n\n /**\n * An array storing the UV coordinates of the last intersection for each\n * controller.\n */\n uvs: THREE.Vector2[] = [];\n\n\n // --- Drag Management State ---\n\n /**\n * The initial position of the object when a drag operation begins.\n */\n initialPosition = new THREE.Vector3();\n\n /**\n * The initial distance from the controller to the object at the start of a\n * drag for computing the relative dragging distances and angles.\n */\n initialDistance?: number;\n\n /**\n * @param parent - The script or object that owns this UX instance.\n */\n constructor(parent: THREE.Object3D) {\n this.parent = parent;\n }\n\n /**\n * Checks if the object is currently being hovered by any controller.\n */\n isHovered() {\n return this.hovered.includes(true);\n }\n\n /**\n * Checks if the object is currently being selected by any controller.\n */\n isSelected() {\n return this.selected.includes(true);\n }\n\n /**\n * Checks if the object is currently being dragged by any controller.\n */\n isDragging() {\n return this.activeDragged.includes(true);\n }\n\n /**\n * Updates the interaction state for a specific controller based on a new\n * intersection. This is internally called by the core input system when a\n * raycast hits the parent object.\n * @param controller - The controller performing the\n * interaction.\n * @param intersection - The raycast intersection data.\n */\n update(controller: THREE.Object3D, intersection: THREE.Intersection) {\n const id = controller.userData.id;\n this.initializeVariablesForId(id);\n\n if (intersection.object === this.parent ||\n intersection.object === (this.parent as Partial<View>).mesh) {\n this.hovered[id] = true;\n this.selected[id] = controller.userData.selected;\n if (intersection.uv) {\n this.uvs[id].copy(intersection.uv);\n }\n this.positions[id].copy(intersection.point);\n this.distances[id] = intersection.distance;\n\n if (!this.selected[id]) {\n this.activeDragged[id] = false;\n }\n }\n }\n\n /**\n * Ensures that the internal arrays for tracking states are large enough to\n * accommodate a given controller ID.\n * @param id - The controller ID to ensure exists.\n */\n initializeVariablesForId(id: number) {\n while (this.selected.length <= id) {\n this.selected.push(false);\n this.hovered.push(false);\n this.activeDragged.push(false);\n this.positions.push(new THREE.Vector3());\n this.distances.push(1);\n this.uvs.push(new THREE.Vector2());\n }\n }\n\n /**\n * Resets the hover and selection states for all controllers. This is\n * typically called at the beginning of each frame.\n */\n reset() {\n for (const i in this.selected) {\n this.selected[i] = false;\n this.hovered[i] = false;\n }\n }\n\n\n /**\n * Gets the IDs of up to two controllers that are currently hovering over the\n * parent object, always returning a two-element array. This is useful for\n * shaders or components like Panels that expect a fixed number of interaction\n * points.\n *\n * @returns A fixed-size two-element array. Each element is either a\n * controller ID (e.g., 0, 1) or null.\n */\n getPrimaryTwoControllerIds() {\n const activeControllerIds = [];\n // this.hovered is an array of booleans, indexed by controller ID.\n if (this.hovered) {\n for (let i = 0; i < this.hovered.length && activeControllerIds.length < 2;\n ++i) {\n if (this.hovered[i]) {\n activeControllerIds.push(i);\n }\n }\n }\n\n // Ensures the returned array always has two elements.\n const controllerId1 = activeControllerIds[0] ?? null;\n const controllerId2 = activeControllerIds[1] ?? null;\n return [controllerId1, controllerId2];\n }\n}\n","import * as THREE from 'three';\n\nimport type {Controller} from '../input/Controller';\nimport type {Physics} from '../physics/Physics';\nimport type {Injectable} from '../utils/DependencyInjection';\nimport type {Constructor} from '../utils/Types';\nimport {UX} from '../ux/UX';\n\nexport interface SelectEvent {\n target: Controller;\n}\n\nexport interface ObjectTouchEvent {\n handIndex: number;\n touchPosition: THREE.Vector3;\n}\n\nexport interface ObjectGrabEvent {\n handIndex: number;\n hand: THREE.Object3D;\n}\n\nexport interface KeyEvent {\n code: string;\n}\n\n/**\n * The Script class facilities development by providing useful life cycle\n * functions similar to MonoBehaviors in Unity.\n *\n * Each Script object is an independent THREE.Object3D entity within the\n * scene graph.\n *\n * See /docs/manual/Scripts.md for the full documentation.\n *\n * It manages user, objects, and interaction between user and objects.\n * See `/templates/0_basic/` for an example to start with.\n *\n *\n * If the class does not extends View, it can still bind the above three\n * function, where the engine ignores whether reticle exists.\n *\n * # Supported (native WebXR) functions to extend:\n *\n * onSelectStart(event)\n * onSelectEnd(event)\n *\n */\nexport function ScriptMixin<TBase extends Constructor<THREE.Object3D>>(\n base: TBase) {\n return class extends base implements Injectable {\n ux = new UX(this);\n isXRScript = true;\n\n /**\n * Initializes an instance with XR controllers, grips, hands, raycaster, and\n * default options. We allow all scripts to quickly access its user (e.g.,\n * user.isSelecting(), user.hands), world (e.g., physical depth mesh,\n * lighting estimation, and recognized objects), and scene (the root of\n * three.js's scene graph). If this returns a promise, we will wait for it.\n */\n init(_?: object): void|Promise<void> {}\n\n /**\n * Runs per frame.\n */\n update(_time?: number, _frame?: XRFrame) {}\n\n /**\n * Enables depth-aware interactions with physics. See /demos/ballpit\n */\n initPhysics(_physics: Physics): void|Promise<void> {}\n physicsStep() {}\n\n onXRSessionStarted(_session?: XRSession) {}\n onXRSessionEnded() {}\n\n onSimulatorStarted() {}\n\n // Global controller callbacks.\n // See https://developer.mozilla.org/en-US/docs/Web/API/XRInputSourceEvent\n /**\n * Called whenever pinch / mouse click starts, globally.\n * @param _event - event.target holds its controller\n */\n onSelectStart(_event: SelectEvent) {}\n\n /**\n * Called whenever pinch / mouse click discontinues, globally.\n * @param _event - event.target holds its controller\n */\n onSelectEnd(_event: SelectEvent) {}\n\n /**\n * Called whenever pinch / mouse click successfully completes, globally.\n * @param _event - event.target holds its controller.\n */\n onSelect(_event: SelectEvent) {}\n\n /**\n * Called whenever pinch / mouse click is happening, globally.\n */\n onSelecting(_event: SelectEvent) {}\n\n /**\n * Called on keyboard keypress.\n * @param _event - Event containing `.code` to read the keyboard key.\n */\n onKeyDown(_event: KeyEvent) {}\n onKeyUp(_event: KeyEvent) {}\n\n /**\n * Called whenever gamepad trigger starts, globally.\n * @param _event - event.target holds its controller.\n */\n onSqueezeStart(_event: SelectEvent) {}\n /**\n * Called whenever gamepad trigger stops, globally.\n * @param _event - event.target holds its controller.\n */\n onSqueezeEnd(_event: SelectEvent) {}\n\n /**\n * Called whenever gamepad is being triggered, globally.\n */\n onSqueezing(_event: SelectEvent) {}\n\n /**\n * Called whenever gamepad trigger successfully completes, globally.\n * @param _event - event.target holds its controller.\n */\n onSqueeze(_event: SelectEvent) {}\n\n // Object-specific controller callbacks.\n /**\n * Called when the controller starts selecting this object the script\n * represents, e.g. View, ModelView.\n * @param _event - event.target holds its controller.\n * @returns Whether the event was handled\n */\n onObjectSelectStart(_event: SelectEvent) {\n return false;\n }\n /**\n * Called when the controller stops selecting this object the script\n * represents, e.g. View, ModelView.\n * @param _event - event.target holds its controller.\n * @returns Whether the event was handled\n */\n onObjectSelectEnd(_event: SelectEvent) {\n return false; // Whether the event was handled\n }\n /**\n * Called when the controller starts hovering over this object with reticle.\n * @param _controller - An XR controller.\n */\n onHoverEnter(_controller: THREE.Object3D) {}\n /**\n * Called when the controller hovers over this object with reticle.\n * @param _controller - An XR controller.\n */\n onHoverExit(_controller: THREE.Object3D) {}\n /**\n * Called when the controller hovers over this object with reticle.\n * @param _controller - An XR controller.\n */\n onHovering(_controller: THREE.Object3D) {}\n /**\n * Called when a hand's index finger starts touching this object.\n */\n onObjectTouchStart(_event: ObjectTouchEvent) {}\n /**\n * Called every frame that a hand's index finger is touching this object.\n */\n onObjectTouching(_event: ObjectTouchEvent) {}\n /**\n * Called when a hand's index finger stops touching this object.\n */\n onObjectTouchEnd(_event: ObjectTouchEvent) {}\n /**\n * Called when a hand starts grabbing this object (touching + pinching).\n */\n onObjectGrabStart(_event: ObjectGrabEvent) {}\n /**\n * Called every frame a hand is grabbing this object.\n */\n onObjectGrabbing(_event: ObjectGrabEvent) {}\n /**\n * Called when a hand stops grabbing this object.\n */\n onObjectGrabEnd(_event: ObjectGrabEvent) {}\n\n /**\n * Called when the script is removed from the scene. Opposite of init.\n */\n dispose() {}\n };\n}\n\n/**\n * Script manages app logic or interaction between user and objects.\n */\nconst ScriptMixinObject3D = ScriptMixin(THREE.Object3D);\nexport class Script<TEventMap extends THREE.Object3DEventMap =\n THREE.Object3DEventMap> extends\n ScriptMixinObject3D<TEventMap> {}\n\n\n/**\n * MeshScript can be constructed with geometry and materials, with\n * `super(geometry, material)`; for direct access to its geometry.\n * MeshScripts hold a UX object that contains its interaction information such\n * as which controller is selecting or touching this object, as well as the\n * exact selected UV / xyz of the reticle, or touched point.\n */\nconst ScriptMixinMeshScript = ScriptMixin(THREE.Mesh);\nexport class MeshScript<\n TGeometry extends THREE.BufferGeometry = THREE.BufferGeometry,\n TMaterial extends\n THREE.Material | THREE.Material[] = THREE.Material | THREE.Material[],\n TEventMap extends THREE.Object3DEventMap =\n THREE.Object3DEventMap> extends\n ScriptMixinMeshScript<TGeometry, TMaterial, TEventMap> {\n /**\n * {@inheritDoc}\n */\n constructor(geometry?: TGeometry, material?: TMaterial) {\n super(geometry, material);\n }\n}\n","import * as THREE from 'three';\n\n/**\n * Clamps a value between a minimum and maximum value.\n */\nexport function clamp(value: number, min: number, max: number) {\n return Math.min(Math.max(value, min), max);\n}\n\n/**\n * Linearly interpolates between two numbers `x` and `y` by a given amount `t`.\n */\nexport function lerp(x: number, y: number, t: number) {\n return x + (y - x) * t;\n}\n\n/**\n * Python-style print function for debugging.\n */\nexport function print(...args: unknown[]) {\n console.log('*', ...args);\n}\n\n// Parses URL parameters using the URLSearchParams API.\nexport const urlParams = new URLSearchParams(window.location.search);\n\n/**\n * Function to get the value of a URL parameter.\n * @param name - The name of the URL parameter.\n * @returns The value of the URL parameter or null if not found.\n */\nexport function getUrlParameter(name: string) {\n const urlParams = new URLSearchParams(window.location.search);\n return urlParams.get(name);\n}\n\n/**\n * Retrieves a boolean URL parameter. Returns true for 'true' or '1', false for\n * 'false' or '0'. If the parameter is not found, returns the specified default\n * boolean value.\n * @param name - The name of the URL parameter.\n * @param defaultBool - The default boolean value if the\n * parameter is not present.\n * @returns The boolean value of the URL parameter.\n */\nexport function getUrlParamBool(name: string, defaultBool = false) {\n const inputString = urlParams.get(name)?.toLowerCase();\n // Convert the parameter value to a boolean. Returns true for 'true' or '1'.\n if (inputString === 'true' || inputString === '1') {\n return true;\n }\n // Returns false for 'false' or '0'.\n if (inputString === 'false' || inputString === '0') {\n return false;\n }\n // If the parameter is not found, returns the default boolean value.\n return defaultBool;\n}\n\n/**\n * Retrieves an integer URL parameter. If the parameter is not found or is not a\n * valid number, returns the specified default integer value.\n * @param name - The name of the URL parameter.\n * @param defaultNumber - The default integer value if the\n * parameter is not present.\n * @returns The integer value of the URL parameter.\n */\nexport function getUrlParamInt(name: string, defaultNumber = 0) {\n const inputNumber = urlParams.get(name);\n if (inputNumber) {\n // Convert the parameter value to an integer. If valid, returns it.\n const num = parseInt(inputNumber, 10);\n if (!isNaN(num)) {\n return num;\n }\n }\n // If the parameter is not found or invalid, returns the default integer\n // value.\n return defaultNumber;\n}\n\n/**\n * Retrieves a float URL parameter. If the parameter is not found or is not a\n * valid number, returns the specified default float value.\n * @param name - The name of the URL parameter.\n * @param defaultNumber - The default float value if the parameter\n * is not present.\n * @returns The float value of the URL parameter.\n */\nexport function getUrlParamFloat(name: string, defaultNumber = 0) {\n const inputNumber = urlParams.get(name);\n if (inputNumber) {\n // Convert the parameter value to a float. If valid, returns it.\n const num = parseFloat(inputNumber);\n if (!isNaN(num)) {\n return num;\n }\n }\n // If the parameter is not found or invalid, returns the default float value.\n return defaultNumber;\n}\n\n/**\n * Parses a color string (hexadecimal with optional alpha) into a THREE.Vector4.\n * Supports:\n * - #rgb (shorthand, alpha defaults to 1)\n * - #rrggbb (alpha defaults to 1)\n * - #rgba (shorthand)\n * - #rrggbbaa\n *\n * @param colorString - The color string to parse (e.g., '#66ccff',\n * '#6cf5', '#66ccff55', '#6cf').\n * @returns The parsed color as a THREE.Vector4 (r, g, b, a), with components in\n * the 0-1 range.\n * @throws If the input is not a string or if the hex string is invalid.\n */\nexport function getVec4ByColorString(colorString: string) {\n if (typeof colorString !== 'string') {\n throw new Error('colorString must be a string');\n }\n\n // Remove the '#' if it exists.\n const hex = colorString.startsWith('#') ? colorString.slice(1) : colorString;\n const len = hex.length;\n let alpha = 1.0; // Default alpha to 1\n\n let expandedHex = hex;\n if (len === 3 || len === 4) {\n // Expand shorthand: rgb -> rrgbbaa or rgba -> rrggbbaa\n expandedHex = hex.split('').map((char) => char + char).join('');\n }\n\n if (expandedHex.length === 8) {\n alpha = parseInt(expandedHex.slice(6, 8), 16) / 255;\n expandedHex = expandedHex.slice(0, 6);\n } else if (expandedHex.length === 6) {\n // Alpha is already 1.0\n } else {\n throw new Error(`Invalid hex color string format: ${colorString}`);\n }\n\n const r = parseInt(expandedHex.slice(0, 2), 16) / 255;\n const g = parseInt(expandedHex.slice(2, 4), 16) / 255;\n const b = parseInt(expandedHex.slice(4, 6), 16) / 255;\n\n if (isNaN(r) || isNaN(g) || isNaN(b) || isNaN(alpha)) {\n throw new Error(`Invalid hex values in color string: ${colorString}`);\n }\n\n return new THREE.Vector4(r, g, b, alpha);\n}\n\nexport function getColorHex(fontColor: string|number) {\n if (typeof fontColor === 'string') {\n const vec4 = getVec4ByColorString(fontColor);\n const r = Math.round(vec4.x * 255);\n const g = Math.round(vec4.y * 255);\n const b = Math.round(vec4.z * 255);\n return (r << 16) + (g << 8) + b;\n } else if (typeof fontColor === 'number') {\n return fontColor;\n } else {\n // Default to white if fontColor is invalid.\n return 0xffffff;\n }\n}\n\n/**\n * Parses a data URL (e.g., \"data:image/png;base64,...\") into its\n * stripped base64 string and MIME type.\n * This function handles common image MIME types.\n * @param dataURL - The data URL string.\n * @returns An object containing the stripped base64 string and the extracted\n * MIME type.\n */\nexport function parseBase64DataURL(dataURL: string) {\n const mimeTypeRegex = /^data:(image\\/[a-zA-Z0-9\\-+.]+);base64,/;\n const match = dataURL.match(mimeTypeRegex);\n\n if (match) {\n const mimeType = match[1];\n const strippedBase64 = dataURL.substring(match[0].length);\n return {strippedBase64, mimeType};\n } else {\n return {strippedBase64: dataURL, mimeType: null};\n }\n}\n","export interface GeminiLiveOptions {\n enabled?: boolean;\n model?: string;\n startOfSpeechSensitivity?: 'LOW'|'HIGH';\n endOfSpeechSensitivity?: 'LOW'|'HIGH';\n voiceName?: string;\n screenshotInterval?: number;\n audioConfig?: {\n sampleRate?: number;\n channelCount?: number;\n echoCancellation?: boolean;\n noiseSuppression?: boolean;\n autoGainControl?: boolean;\n };\n}\n\nexport class GeminiOptions {\n apiKey = '';\n urlParam = 'geminiKey';\n keyValid = false;\n enabled = false;\n model = 'gemini-2.0-flash';\n config = {};\n live: GeminiLiveOptions = {\n enabled: false,\n model: 'gemini-live-2.5-flash-preview',\n voiceName: 'Aoede',\n screenshotInterval: 3000,\n audioConfig: {\n sampleRate: 16000,\n channelCount: 1,\n echoCancellation: true,\n noiseSuppression: true,\n autoGainControl: true\n }\n };\n}\n\nexport class OpenAIOptions {\n apiKey = '';\n urlParam = 'openaiKey';\n model = 'gpt-4.1';\n enabled = false;\n}\n\nexport type AIModel = 'gemini'|'openai';\n\nexport class AIOptions {\n enabled = false;\n model: AIModel = 'gemini';\n gemini = new GeminiOptions();\n openai = new OpenAIOptions();\n globalUrlParams = {\n key: 'key', // Generic key parameter\n }\n}\n","import {GeminiResponse} from './AITypes';\n\nexport abstract class BaseAIModel {\n constructor() {}\n\n abstract init(): Promise<void>;\n\n abstract isAvailable(): boolean;\n\n abstract query(_input: object, _tools: []):\n Promise<GeminiResponse|string|null>;\n}\n","import * as GoogleGenAITypes from '@google/genai';\n\nimport type {Tool} from '../agent/Tool';\n\nimport {GeminiOptions} from './AIOptions';\nimport {GeminiResponse} from './AITypes';\nimport {BaseAIModel} from './BaseAIModel';\n\nlet createPartFromUri:\n ((uri: string, mimeType: string) => GoogleGenAITypes.Part);\nlet createUserContent: (\n (partOrString: GoogleGenAITypes.PartListUnion) => GoogleGenAITypes.Content)|\n undefined;\nlet GoogleGenAI: typeof GoogleGenAITypes.GoogleGenAI|undefined;\nlet EndSensitivity: typeof GoogleGenAITypes.EndSensitivity|undefined;\nlet StartSensitivity: typeof GoogleGenAITypes.StartSensitivity|undefined;\nlet Modality: typeof GoogleGenAITypes.Modality|undefined;\n\n// --- Attempt Dynamic Import ---\nasync function loadGoogleGenAIModule() {\n if (GoogleGenAI) {\n return;\n }\n try {\n const genAIModule = await import('@google/genai');\n if (genAIModule && genAIModule.GoogleGenAI) {\n createPartFromUri = genAIModule.createPartFromUri;\n createUserContent = genAIModule.createUserContent;\n GoogleGenAI = genAIModule.GoogleGenAI;\n EndSensitivity = genAIModule.EndSensitivity;\n StartSensitivity = genAIModule.StartSensitivity;\n Modality = genAIModule.Modality;\n console.log('\\'@google/genai\\' module loaded successfully.');\n } else {\n throw new Error('\\'@google/genai\\' module loaded but is not valid.');\n }\n } catch (error) {\n const errorMessage =\n `The '@google/genai' module is required for Gemini but failed to load. Error: ${\n error}`;\n console.error(errorMessage);\n throw new Error(errorMessage);\n }\n}\n\nexport interface GeminiQueryInput {\n type: 'live'|'text'|'uri'|'base64'|'multiPart';\n action?: 'start'|'stop'|'send';\n text?: string;\n uri?: string;\n base64?: string;\n mimeType?: string;\n parts?: GoogleGenAITypes.Part[];\n config?: GoogleGenAITypes.LiveConnectConfig;\n data?: GoogleGenAITypes.LiveSendRealtimeInputParameters;\n}\n\nexport type GeminiStartLiveSessionParams = {\n tools?: GoogleGenAITypes.FunctionDeclaration[];\n systemInstruction?: GoogleGenAITypes.ContentUnion | string;\n};\n\nexport class Gemini extends BaseAIModel {\n inited = false;\n liveSession?: GoogleGenAITypes.Session;\n isLiveMode = false;\n liveCallbacks: Partial<GoogleGenAITypes.LiveCallbacks> = {};\n ai?: GoogleGenAITypes.GoogleGenAI;\n\n constructor(protected options: GeminiOptions) {\n super();\n }\n\n async init() {\n await loadGoogleGenAIModule();\n }\n\n isAvailable() {\n if (!GoogleGenAI) {\n return false;\n }\n if (!this.inited) {\n this.ai = new GoogleGenAI({apiKey: this.options.apiKey});\n this.inited = true;\n }\n return true;\n }\n\n isLiveAvailable() {\n return this.isAvailable() && EndSensitivity && StartSensitivity && Modality;\n }\n\n async startLiveSession(params: GeminiStartLiveSessionParams = {}) {\n if (!this.isLiveAvailable()) {\n throw new Error(\n 'Live API not available. Make sure @google/genai module is loaded.');\n }\n\n if (this.liveSession) {\n return this.liveSession;\n }\n\n const defaultConfig: GoogleGenAITypes.LiveConnectConfig = {\n responseModalities: [Modality!.AUDIO],\n speechConfig: {\n voiceConfig: {prebuiltVoiceConfig: {voiceName: 'Aoede'}},\n },\n outputAudioTranscription: {},\n inputAudioTranscription: {}\n };\n\n if (params.tools && params.tools.length > 0) {\n defaultConfig.tools = [{functionDeclarations: params.tools}];\n }\n if (params.systemInstruction) {\n if (typeof params.systemInstruction === 'string') {\n defaultConfig.systemInstruction =\n createUserContent!(params.systemInstruction);\n } else {\n defaultConfig.systemInstruction = params.systemInstruction;\n }\n }\n\n const callbacks: GoogleGenAITypes.LiveCallbacks = {\n onopen: () => {\n this.isLiveMode = true;\n console.log('🔓 Live session opened.');\n if (this.liveCallbacks?.onopen) {\n this.liveCallbacks.onopen();\n }\n },\n onmessage: (e: GoogleGenAITypes.LiveServerMessage) => {\n if (this.liveCallbacks?.onmessage) {\n this.liveCallbacks.onmessage(e);\n }\n },\n onerror: (e: ErrorEvent) => {\n console.error('❌ Live session error:', e);\n if (this.liveCallbacks?.onerror) {\n this.liveCallbacks.onerror(e);\n }\n },\n onclose: (event: CloseEvent) => {\n this.isLiveMode = false;\n this.liveSession = undefined;\n if (event.reason) {\n console.warn('🔒 Live session closed:', event);\n } else {\n console.warn('🔒 Live session closed without reason.');\n }\n if (this.liveCallbacks?.onclose) {\n this.liveCallbacks.onclose(event);\n }\n },\n };\n try {\n const connectParams: GoogleGenAITypes.LiveConnectParameters = {\n model: 'gemini-2.5-flash-preview-native-audio-dialog',\n callbacks: callbacks,\n config: defaultConfig,\n };\n console.log('Connecting with params:', connectParams);\n this.liveSession = await this.ai!.live.connect(connectParams);\n return this.liveSession;\n } catch (error) {\n console.error('❌ Failed to start live session:', error);\n throw error;\n }\n }\n\n async stopLiveSession() {\n if (!this.liveSession) {\n return;\n }\n this.liveSession.close();\n this.liveSession = undefined;\n this.isLiveMode = false;\n }\n\n // Set Live session callbacks\n setLiveCallbacks(callbacks: GoogleGenAITypes.LiveCallbacks) {\n this.liveCallbacks = callbacks;\n }\n\n sendToolResponse(response: GoogleGenAITypes.LiveSendToolResponseParameters) {\n if (this.liveSession) {\n console.debug('Sending tool response to gemini:', response);\n this.liveSession.sendToolResponse(response);\n }\n }\n\n sendRealtimeInput(input: GoogleGenAITypes.LiveSendRealtimeInputParameters) {\n if (!this.liveSession) {\n return;\n }\n\n try {\n this.liveSession.sendRealtimeInput(input);\n } catch (error) {\n console.error('❌ Error sending realtime input:', error);\n throw error;\n }\n }\n\n getLiveSessionStatus() {\n return {\n isActive: this.isLiveMode,\n hasSession: !!this.liveSession,\n isAvailable: this.isLiveAvailable()\n };\n }\n\n async query(input: GeminiQueryInput|{prompt: string}, _tools: Tool[] = []):\n Promise<GeminiResponse|null> {\n if (!this.inited) {\n console.warn('Gemini not inited.');\n return null;\n }\n\n const options = this.options;\n const config = options.config || {};\n\n if (!('type' in input)) {\n const response = await this.ai!.models.generateContent(\n {model: options.model, contents: input.prompt!, config: config});\n return {text: response.text || null};\n }\n\n const model = this.ai!.models;\n const modelParams: GoogleGenAITypes.GenerateContentParameters = {\n model: this.options.model,\n contents: [],\n config: this.options.config || {},\n };\n\n let response = null;\n switch (input.type) {\n case 'text':\n modelParams.contents = input.text!;\n response = await model.generateContent(modelParams);\n break;\n\n case 'base64':\n if (!input.mimeType) {\n input.mimeType = 'image/png';\n }\n modelParams.contents = {\n inlineData: {\n mimeType: input.mimeType,\n data: input.base64,\n },\n };\n response = await model.generateContent(modelParams);\n break;\n\n case 'uri':\n modelParams.contents = createUserContent!([\n createPartFromUri(input.uri!, input.mimeType!),\n input.text!,\n ]);\n response = await model.generateContent(modelParams);\n break;\n\n case 'multiPart':\n modelParams.contents = [{role: 'user', parts: input.parts}];\n response = await model.generateContent(modelParams);\n break;\n }\n\n if (!response) {\n return {text: null};\n }\n\n const toolCall = response.functionCalls?.[0];\n if (toolCall && toolCall.name) {\n return {toolCall: {name: toolCall.name, args: toolCall.args}};\n }\n return {text: response.text || null};\n }\n\n async generate(\n prompt: string|string[], type: 'image' = 'image',\n systemInstruction = 'Generate an image',\n model = 'gemini-2.5-flash-image-preview') {\n if (!this.isAvailable()) return;\n\n let contents: GoogleGenAITypes.ContentListUnion;\n\n if (Array.isArray(prompt)) {\n contents = prompt.map(item => {\n if (typeof item === 'string') {\n if (item.startsWith('data:image/')) {\n const [header, data] = item.split(',');\n const mimeType = header.split(';')[0].split(':')[1];\n return {inlineData: {mimeType, data}};\n } else {\n return {text: item};\n }\n }\n // Assumes other items are already valid Part objects\n return item;\n });\n } else {\n contents = prompt;\n }\n\n const response = await this.ai!.models.generateContent(\n {model: model, contents: contents, config: {systemInstruction}});\n if (response.candidates && response.candidates.length > 0) {\n const firstCandidate = response.candidates[0];\n for (const part of firstCandidate?.content?.parts || []) {\n if (type === 'image' && part.inlineData) {\n return 'data:image/png;base64,' + part.inlineData.data;\n }\n }\n }\n }\n};\n","import type OpenAIType from 'openai';\n\nimport {OpenAIOptions} from './AIOptions';\nimport {BaseAIModel} from './BaseAIModel';\n\nlet OpenAIApi: typeof OpenAIType|null = null;\n\nasync function loadOpenAIModule() {\n if (OpenAIApi) {\n return;\n }\n try {\n const openAIModule = await import('openai');\n OpenAIApi = openAIModule.default;\n console.log('\\'openai\\' module loaded successfully.');\n } catch (error) {\n console.warn(\n '\\'openai\\' module not found. Using fallback implementations.',\n 'Error details:', error);\n }\n}\n\nexport class OpenAI extends BaseAIModel {\n openai?: OpenAIType;\n\n constructor(protected options: OpenAIOptions) {\n super();\n }\n\n async init() {\n await loadOpenAIModule();\n if (this.options.apiKey && OpenAIApi) {\n this.openai = new OpenAIApi(\n {apiKey: this.options.apiKey, dangerouslyAllowBrowser: true});\n console.log('OpenAI model initialized');\n } else {\n console.error('OpenAI API key is missing or module failed to load.');\n }\n }\n\n isAvailable() {\n return !!this.openai;\n }\n\n async query(input: {prompt: string}, _tools?: never[]) {\n if (!this.isAvailable()) {\n throw new Error('OpenAI model is not initialized.');\n }\n\n try {\n const completion = await this.openai!.chat.completions.create({\n messages: [{role: 'user', content: input.prompt}],\n model: this.options.model,\n });\n const content = completion.choices[0].message.content;\n if (content) {\n return {text: content};\n }\n return null;\n } catch (error) {\n console.error('Error querying OpenAI:', error);\n throw error;\n }\n }\n\n async generate() {\n throw new Error('Wrapper not implemented');\n }\n}\n","import type * as GoogleGenAITypes from '@google/genai';\n\nimport {Script} from '../core/Script';\nimport {getUrlParameter} from '../utils/utils';\n\nimport {AIOptions, GeminiOptions, OpenAIOptions} from './AIOptions';\nimport {GeminiResponse} from './AITypes';\nimport {Gemini, GeminiStartLiveSessionParams} from './Gemini';\nimport {OpenAI} from './OpenAI';\n\nexport type ModelClass = Gemini|OpenAI;\nexport type ModelOptions = GeminiOptions|OpenAIOptions;\n\nexport type KeysJson = {\n [key: string]:\n string|{\n apiKey?: string;\n }\n};\n\nconst SUPPORTED_MODELS = {\n gemini: Gemini,\n openai: OpenAI,\n} as const;\n\n/**\n * AI Interface to wrap different AI models (primarily Gemini)\n * Handles both traditional query-based AI interactions and real-time live\n * sessions\n *\n * Features:\n * - Text and multimodal queries\n * - Real-time audio/video AI sessions (Gemini Live)\n * - Advanced API key management with multiple sources\n * - Session locking to prevent concurrent operations\n *\n * The URL param and key.json shortcut is only for demonstration and prototyping\n * practice and we strongly suggest not using it for production or deployment\n * purposes. One should set up a proper server to converse with AI servers in\n * deployment.\n *\n * API Key Management Features:\n *\n * 1. Multiple Key Sources (Priority Order):\n * - URL Parameter: ?key=\\<api_key\\>\n * - keys.json file: Local configuration file\n * - User Prompt: Interactive fallback\n * 2. keys.json Support:\n * - Structure: \\{\"gemini\": \\{\"apiKey\": \"YOUR_KEY_HERE\"\\}\\}\n * - Automatically loads if present\n */\nexport class AI extends Script {\n static dependencies = {aiOptions: AIOptions};\n\n model?: ModelClass;\n lock = false;\n options!: AIOptions;\n keysCache?: KeysJson; // Cache for loaded keys.json\n\n /**\n * Load API keys from keys.json file if available\n * Parsed keys object or null if not found\n */\n async loadKeysFromFile(): Promise<KeysJson|null> {\n if (this.keysCache) return this.keysCache;\n\n try {\n const response = await fetch('./keys.json');\n if (response.ok) {\n this.keysCache = await response.json() as KeysJson;\n console.log('🔑 Loaded keys.json');\n return this.keysCache;\n }\n } catch {\n // Silent fail - keys.json is optional\n }\n return null;\n }\n\n async init({aiOptions}: {aiOptions: AIOptions}) {\n this.lock = false;\n this.options = aiOptions;\n\n if (!aiOptions.enabled) {\n console.log('AI is disabled in options');\n return;\n }\n\n const modelName = aiOptions.model;\n const ModelClass = SUPPORTED_MODELS[modelName];\n\n if (ModelClass) {\n const modelOptions = aiOptions[modelName];\n if (modelOptions && modelOptions.enabled) {\n await this.initializeModel(ModelClass, modelOptions);\n } else {\n console.log(`${modelName} is disabled in AI options`);\n }\n } else {\n console.error(`Unsupported AI model: ${modelName}`);\n }\n }\n\n async initializeModel(\n ModelClass: typeof Gemini|typeof OpenAI, modelOptions: ModelOptions) {\n const apiKey = await this.resolveApiKey(modelOptions);\n if (!apiKey || !this.isValidApiKey(apiKey)) {\n console.error(`No valid API key found for ${this.options.model}`);\n return;\n }\n modelOptions.apiKey = apiKey;\n this.model = new ModelClass(modelOptions as GeminiOptions & OpenAIOptions);\n try {\n await this.model.init();\n console.log(`${this.options.model} initialized`);\n } catch (error) {\n console.error(`Failed to initialize ${this.options.model}:`, error);\n this.model = undefined;\n }\n }\n\n async resolveApiKey(modelOptions: ModelOptions): Promise<string|null> {\n const modelName = this.options.model;\n\n // 1. Check options\n if (modelOptions.apiKey) {\n return modelOptions.apiKey;\n }\n\n // 2. Check URL parameters for 'key'\n const genericKey = getUrlParameter('key');\n if (genericKey) {\n return genericKey;\n }\n\n // 3. Check URL parameters for model-specific key\n const modelKey = getUrlParameter(modelOptions.urlParam);\n if (modelKey) return modelKey;\n\n // Temporary fallback to geminiKey64 for teamfood.\n const geminiKey64 = getUrlParameter('geminiKey64');\n if (geminiKey64) {\n return window.atob(geminiKey64);\n }\n\n // 3. Check keys.json file\n const keysFromFile = await this.loadKeysFromFile();\n if (keysFromFile) {\n const modelNameWithApiKeySuffix = modelName + `ApiKey`;\n let keyFromFile: string|null|undefined = null;\n if (typeof keysFromFile[modelName] === 'object') {\n keyFromFile = keysFromFile[modelName]?.apiKey;\n } else if (typeof keysFromFile[modelNameWithApiKeySuffix] === 'string') {\n keyFromFile = keysFromFile[modelNameWithApiKeySuffix];\n } else if (typeof keysFromFile[modelName] === 'string') {\n keyFromFile = keysFromFile[modelName];\n }\n if (keyFromFile) {\n console.log(`🔑 Using ${modelName} key from keys.json`);\n return keyFromFile;\n }\n }\n\n return null;\n }\n\n isValidApiKey(key: string) {\n return key && typeof key === 'string' && key.length > 0;\n }\n\n isAvailable() {\n return this.model && this.model.isAvailable() && !this.lock;\n }\n\n async query(input: {prompt: string}, tools?: never[]):\n Promise<GeminiResponse|string|null> {\n if (!this.isAvailable()) {\n throw new Error(\n 'AI is not available. Check if it\\'s enabled and properly initialized.');\n }\n return await this.model!.query(input, tools);\n }\n\n async startLiveSession(config: GeminiStartLiveSessionParams = {}) {\n if (!this.model) {\n throw new Error('AI model is not initialized.');\n }\n if (!('isLiveAvailable' in this.model) || !this.model.isLiveAvailable()) {\n throw new Error('Live session is not available for the current model.');\n }\n this.lock = true;\n try {\n const session = await this.model.startLiveSession(config);\n return session;\n } catch (error) {\n this.lock = false;\n console.error('❌ Failed to start Live session:', error);\n throw error;\n }\n }\n\n async stopLiveSession() {\n if (!this.model) return;\n try {\n await ('stopLiveSession' in this.model && this.model.stopLiveSession());\n } catch (error) {\n console.error('❌ Error stopping Live session:', error);\n } finally {\n this.lock = false;\n }\n }\n\n async setLiveCallbacks(callbacks: GoogleGenAITypes.LiveCallbacks) {\n if (this.model && 'setLiveCallbacks' in this.model) {\n this.model.setLiveCallbacks(callbacks);\n }\n }\n\n sendToolResponse(response: GoogleGenAITypes.LiveSendToolResponseParameters) {\n if (this.model && 'sendToolResponse' in this.model) {\n this.model.sendToolResponse(response);\n }\n }\n\n sendRealtimeInput(input: GoogleGenAITypes.LiveSendRealtimeInputParameters) {\n if (!this.model || !('sendRealtimeInput' in this.model)) return false;\n return this.model.sendRealtimeInput(input);\n }\n\n getLiveSessionStatus() {\n if (!this.model || !('getLiveSessionStatus' in this.model)) {\n return {isActive: false, hasSession: false, isAvailable: false};\n }\n return this.model.getLiveSessionStatus();\n }\n\n isLiveAvailable() {\n return this.model && 'isLiveAvailable' in this.model &&\n this.model.isLiveAvailable();\n }\n\n /**\n * In simulator mode, pop up a 2D UI to request Gemini key;\n * In XR mode, show a 3D UI to instruct users to get an API key.\n */\n triggerKeyPopup() {}\n\n async generate(\n prompt: string|string[], type: 'image' = 'image',\n systemInstruction = 'Generate an image',\n model = 'gemini-2.5-flash-image-preview') {\n return this.model!.generate(prompt, type, systemInstruction, model);\n }\n\n /**\n * Create a sample keys.json file structure for reference\n * @returns Sample keys.json structure\n */\n static createSampleKeysStructure() {\n return {\n 'gemini': {'apiKey': 'YOUR_GEMINI_API_KEY_HERE'},\n 'openai': {'apiKey': 'YOUR_OPENAI_API_KEY_HERE'},\n };\n }\n\n /**\n * Check if the current model has an API key available from any source\n * @returns True if API key is available\n */\n async hasApiKey() {\n if (!this.options) return false;\n const modelOptions = this.options[this.options.model];\n if (!modelOptions) return false;\n\n const apiKey = await this.resolveApiKey(modelOptions);\n return apiKey && this.isValidApiKey(apiKey);\n }\n}\n","// --- Hands ---\n/**\n * The number of hands tracked in a typical XR session (left and right).\n */\nexport const NUM_HANDS = 2;\n\n/**\n * The number of joints per hand tracked in a typical XR session.\n */\nexport const HAND_JOINT_COUNT = 25;\n\n/**\n * The pairs of joints as an adjcent list.\n */\nexport const HAND_JOINT_IDX_CONNECTION_MAP = [\n [1, 2], [2, 3], [3, 4], // Thumb has 3 bones\n [5, 6], [6, 7], [7, 8], [8, 9], // Index finger has 4 bones\n [10, 11], [11, 12], [12, 13], [13, 14], // Middle finger has 4 bones\n [15, 16], [16, 17], [17, 18], [18, 19], // Ring finger has 4 bones\n [20, 21], [21, 22], [22, 23], [23, 24], // Little finger has 4 bones\n];\n\n/**\n * The pairs of bones' ids per angle as an adjcent list.\n */\n// clang-format off\nexport const HAND_BONE_IDX_CONNECTION_MAP = [\n [0, 1], [1, 2], // Thumb has 2 angles\n [3, 4], [4, 5], [5, 6], // Index finger has 3 angles\n [7, 8], [8, 9], [9, 10], // Middle finger has 3 angles\n [11, 12], [12, 13], [13, 14], // Ring finger has 3 angles\n [15, 16], [16, 17], [17, 18], // Little finger has 3 angles\n];\n// clang-format on\n\n// --- UI ---\n/**\n * A small depth offset (in meters) applied between layered UI elements to\n * prevent Z-fighting, which is a visual artifact where surfaces at similar\n * depths appear to flicker.\n */\nexport const VIEW_DEPTH_GAP = 0.002;\n\n// --- Renderer Layer ---\n/**\n * The THREE.js rendering layer used exclusively for objects that should only be\n * visible to the left eye's camera in stereoscopic rendering.\n */\nexport const LEFT_VIEW_ONLY_LAYER = 1;\n\n/**\n * The THREE.js rendering layer used exclusively for objects that should only be\n * visible to the right eye's camera in stereoscopic rendering.\n */\nexport const RIGHT_VIEW_ONLY_LAYER = 2;\n\n/**\n * The THREE.js rendering layer for virtual objects that should be realistically\n * occluded by real-world objects when depth sensing is active.\n */\nexport const OCCLUDABLE_ITEMS_LAYER = 3;\n\n/**\n * Layer used for rendering overlaid UI text. Currently only used for LabelView.\n */\nexport const UI_OVERLAY_LAYER = 4;\n\n// --- Camera ---\n\n/**\n * The default ideal width in pixels for requesting the device camera stream.\n * Corresponds to a 720p resolution.\n */\nexport const DEFAULT_DEVICE_CAMERA_WIDTH = 1280;\n\n/**\n * The default ideal height in pixels for requesting the device camera stream.\n * Corresponds to a 720p resolution.\n */\nexport const DEFAULT_DEVICE_CAMERA_HEIGHT = 720;\n\nexport const XR_BLOCKS_ASSETS_PATH = 'https://cdn.jsdelivr.net/gh/xrblocks/assets@34228db7ec7cef66fd65ef3250ef6f4a930fe373/';\n","import type {DeepReadonly} from './Types';\n\n/**\n * Recursively freezes an object and all its nested properties, making them\n * immutable. This prevents any future changes to the object or its sub-objects.\n * @param obj - The object to freeze deeply.\n * @returns The same object that was passed in, now deeply frozen.\n */\nexport function deepFreeze<T extends object>(obj: T): DeepReadonly<T> {\n Object.freeze(obj);\n Object.getOwnPropertyNames(obj).forEach(name => {\n // We use `any` here because `T` is a generic and we can't be sure\n // what properties it has without more complex type manipulation.\n // The function's signature provides the necessary type safety for\n // consumers.\n const prop = obj[name as keyof T];\n if (prop && typeof prop === 'object' && !Object.isFrozen(prop)) {\n deepFreeze(prop);\n }\n });\n return obj as DeepReadonly<T>;\n}\n\n/**\n * Recursively merges properties from `obj2` into `obj1`.\n * If a property exists in both objects and is an object itself, it will be\n * recursively merged. Otherwise, the value from `obj2` will overwrite the\n * value in `obj1`.\n * @param obj1 - The target object to merge into.\n * @param obj2 - The source object to merge from.\n */\nexport function deepMerge<T extends object, U extends object>(\n obj1: T, obj2?: U) {\n if (obj2 == null) {\n return obj1 as T & U;\n }\n\n const merged = obj1 as Record<string, unknown>;\n\n for (const key in obj2) {\n // Ensure the key is actually on obj2, not its prototype chain.\n if (Object.prototype.hasOwnProperty.call(obj2, key)) {\n const val1 = merged[key];\n const val2 = obj2[key];\n\n if (val1 && typeof val1 === 'object' && val2 &&\n typeof val2 === 'object') {\n // If both values are objects, recurse\n deepMerge(val1, val2);\n } else {\n // Otherwise, overwrite\n merged[key] = val2;\n }\n }\n }\n}\n","\nimport {DEFAULT_DEVICE_CAMERA_HEIGHT, DEFAULT_DEVICE_CAMERA_WIDTH} from '../constants';\nimport {deepFreeze, deepMerge} from '../utils/OptionsUtils';\nimport {DeepPartial, DeepReadonly} from '../utils/Types';\n\nexport class DeviceCameraOptions {\n enabled = false;\n /**\n * Constraints for `getUserMedia`. This will guide the initial camera\n * selection. *\n */\n videoConstraints?: MediaTrackConstraints;\n /**\n * Hint for performance optimization on frequent captures.\n */\n willCaptureFrequently = false;\n\n constructor(options?: DeepReadonly<DeepPartial<DeviceCameraOptions>>) {\n deepMerge(this, options);\n }\n}\n\n// Base configuration for all common capture settings\nconst baseCaptureOptions = {\n enabled: true,\n videoConstraints: {\n width: {ideal: DEFAULT_DEVICE_CAMERA_WIDTH},\n height: {ideal: DEFAULT_DEVICE_CAMERA_HEIGHT},\n }\n};\n\nexport const xrDeviceCameraEnvironmentOptions =\n deepFreeze(new DeviceCameraOptions({\n ...baseCaptureOptions,\n videoConstraints:\n {...baseCaptureOptions.videoConstraints, facingMode: 'environment'}\n }));\n\nexport const xrDeviceCameraUserOptions = deepFreeze(new DeviceCameraOptions({\n ...baseCaptureOptions,\n videoConstraints: {...baseCaptureOptions.videoConstraints, facingMode: 'user'}\n}));\n\nexport const xrDeviceCameraEnvironmentContinuousOptions =\n deepFreeze(new DeviceCameraOptions({\n ...xrDeviceCameraEnvironmentOptions,\n willCaptureFrequently: true,\n }));\n\nexport const xrDeviceCameraUserContinuousOptions =\n deepFreeze(new DeviceCameraOptions({\n ...xrDeviceCameraUserOptions,\n willCaptureFrequently: true,\n }));\n","export function onDesktopUserAgent() {\n return !(/Mobi|Linux|Android|iPhone/i.test(navigator.userAgent));\n}\n","export const DepthMeshTexturedShader = {\n name: 'DepthMeshTexturedShader',\n vertexShader: /* glsl */ `\nvarying vec3 vNormal;\nvarying vec3 vViewPosition;\nvarying vec2 vUv;\n\nvoid main() {\n vUv = uv;\n vNormal = normal;\n\n // Computes the view position.\n vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);\n vViewPosition = -mvPosition.xyz;\n\n gl_Position = projectionMatrix * mvPosition;\n}\n`,\n fragmentShader: /* glsl */ `\n#include <packing>\n\nuniform vec3 uColor;\nuniform sampler2D uDepthTexture;\nuniform sampler2DArray uDepthTextureArray;\nuniform vec3 uLightDirection;\nuniform vec2 uResolution;\nuniform float uRawValueToMeters;\n\nvarying vec3 vNormal;\nvarying vec3 vViewPosition;\nvarying vec2 vUv;\n\nconst highp float kMaxDepthInMeters = 8.0;\nconst float kInvalidDepthThreshold = 0.01;\nuniform float uMinDepth;\nuniform float uMaxDepth;\nuniform float uDebug;\nuniform float uOpacity;\nuniform bool uUsingFloatDepth;\nuniform bool uIsTextureArray;\n\nfloat saturate(in float x) {\n return clamp(x, 0.0, 1.0);\n}\n\nvec3 TurboColormap(in float x) {\n const vec4 kRedVec4 = vec4(0.55305649, 3.00913185, -5.46192616, -11.11819092);\n const vec4 kGreenVec4 = vec4(0.16207513, 0.17712472, 15.24091500, -36.50657960);\n const vec4 kBlueVec4 = vec4(-0.05195877, 5.18000081, -30.94853351, 81.96403246);\n const vec2 kRedVec2 = vec2(27.81927491, -14.87899417);\n const vec2 kGreenVec2 = vec2(25.95549545, -5.02738237);\n const vec2 kBlueVec2 = vec2(-86.53476570, 30.23299484);\n\n // Adjusts color space via 6 degree poly interpolation to avoid pure red.\n vec4 v4 = vec4( 1.0, x, x * x, x * x * x);\n vec2 v2 = v4.zw * v4.z;\n return vec3(\n dot(v4, kRedVec4) + dot(v2, kRedVec2),\n dot(v4, kGreenVec4) + dot(v2, kGreenVec2),\n dot(v4, kBlueVec4) + dot(v2, kBlueVec2)\n );\n}\n\n// Depth is packed into the luminance and alpha components of its texture.\n// The texture is in a normalized format, storing raw values that need to be\n// converted to meters.\nfloat DepthGetMeters(in sampler2D depth_texture, in vec2 depth_uv) {\n if (uUsingFloatDepth) {\n return texture2D(depth_texture, depth_uv).r * uRawValueToMeters;\n }\n vec2 packedDepthAndVisibility = texture2D(depth_texture, depth_uv).rg;\n return dot(packedDepthAndVisibility, vec2(255.0, 256.0 * 255.0)) * uRawValueToMeters;\n}\n\nfloat DepthArrayGetMeters(in sampler2DArray depth_texture, in vec2 depth_uv) {\n return uRawValueToMeters * texture(uDepthTextureArray, vec3 (depth_uv.x, depth_uv.y, 0)).r;\n}\n\nvec3 DepthGetColorVisualization(in float x) {\n return step(kInvalidDepthThreshold, x) * TurboColormap(x);\n}\n\nvoid main() {\n vec3 lightDirection = normalize(uLightDirection);\n\n // Compute UV coordinates relative to resolution\n // vec2 uv = gl_FragCoord.xy / uResolution;\n vec2 uv = vUv;\n\n // Ambient, diffuse, and specular terms\n vec3 ambient = 0.1 * uColor;\n float diff = max(dot(vNormal, lightDirection), 0.0);\n vec3 diffuse = diff * uColor;\n\n vec3 viewDir = normalize(vViewPosition);\n vec3 reflectDir = reflect(-lightDirection, vNormal);\n float spec = pow(max(dot(viewDir, reflectDir), 0.0), 16.0);\n vec3 specular = vec3(0.5) * spec; // Adjust specular color/strength\n\n // Combine Phong lighting\n vec3 finalColor = ambient + diffuse + specular;\n // finalColor = vec3(vNormal);\n\n // Output color\n gl_FragColor = uOpacity * vec4(finalColor, 1.0);\n\n if (uDebug > 0.5) {\n return;\n }\n\n vec2 depth_uv = uv;\n depth_uv.y = 1.0 - depth_uv.y;\n\n float depth = (uIsTextureArray ? DepthArrayGetMeters(uDepthTextureArray, depth_uv) : DepthGetMeters(uDepthTexture, depth_uv)) * 8.0;\n float normalized_depth =\n saturate((depth - uMinDepth) / (uMaxDepth - uMinDepth));\n gl_FragColor = uOpacity * vec4(TurboColormap(normalized_depth), 1.0);\n}\n`\n};\n","import type RAPIER_NS from '@dimforge/rapier3d';\nimport * as THREE from 'three';\n\nimport {MeshScript} from '../core/Script';\nimport {clamp} from '../utils/utils';\n\nimport {DepthMeshTexturedShader} from './DepthMeshTexturedShader';\nimport {DepthMeshOptions, DepthOptions} from './DepthOptions';\nimport {DepthTextures} from './DepthTextures';\n\nexport class DepthMesh extends MeshScript {\n static dependencies = {\n camera: THREE.Camera,\n renderer: THREE.WebGLRenderer,\n };\n static isDepthMesh = true;\n ignoreReticleRaycast = false;\n private worldPosition = new THREE.Vector3();\n private worldQuaternion = new THREE.Quaternion();\n private updateVertexNormals = false;\n\n private minDepth = 8;\n private maxDepth = 0;\n private minDepthPrev = 8;\n private maxDepthPrev = 0;\n\n private downsampledGeometry?: THREE.BufferGeometry;\n private downsampledMesh?: THREE.Mesh;\n\n private collider?: RAPIER_NS.Collider;\n private colliders: RAPIER_NS.Collider[] = [];\n private colliderUpdateFps: number;\n\n private renderer!: THREE.WebGLRenderer;\n private camera!: THREE.Camera;\n private projectionMatrixInverse = new THREE.Matrix4();\n private lastColliderUpdateTime = 0;\n private options: DepthMeshOptions;\n private depthTextureMaterialUniforms?;\n\n private depthTarget!: THREE.WebGLRenderTarget;\n private depthTexture!: THREE.ExternalTexture;\n private depthScene!: THREE.Scene;\n private depthCamera!: THREE.OrthographicCamera;\n private gpuPixels!: Float32Array;\n\n private RAPIER?: typeof RAPIER_NS;\n private blendedWorld?: RAPIER_NS.World;\n private rigidBody?: RAPIER_NS.RigidBody;\n private colliderId = 0;\n\n constructor(\n private depthOptions: DepthOptions, width: number, height: number,\n private depthTextures?: DepthTextures) {\n const options = depthOptions.depthMesh;\n const geometry = new THREE.PlaneGeometry(1, 1, 159, 159);\n let material: THREE.Material;\n let uniforms;\n if (options.useDepthTexture || options.showDebugTexture) {\n uniforms = {\n uDepthTexture: {value: (null as THREE.Texture | null)},\n uDepthTextureArray: {value: (null as THREE.Texture | null)},\n uIsTextureArray: {value: 0.0},\n uColor: {value: new THREE.Color(0xaaaaaa)},\n uResolution: {value: new THREE.Vector2(width, height)},\n uRawValueToMeters: {value: 1.0},\n uMinDepth: {value: 0.0},\n uMaxDepth: {value: 8.0},\n uOpacity: {value: options.opacity},\n uDebug: {value: options.showDebugTexture ? 1.0 : 0.0},\n uLightDirection: {value: new THREE.Vector3(1.0, 1.0, 1.0).normalize()},\n uUsingFloatDepth: {value: depthOptions.useFloat32}\n };\n material = new THREE.ShaderMaterial({\n uniforms: uniforms,\n vertexShader: DepthMeshTexturedShader.vertexShader,\n fragmentShader: DepthMeshTexturedShader.fragmentShader,\n side: THREE.FrontSide,\n transparent: true\n });\n } else {\n material = new THREE.ShadowMaterial({opacity: options.shadowOpacity});\n material.depthWrite = false;\n }\n\n super(geometry, material);\n\n this.visible = options.showDebugTexture || options.renderShadow;\n this.options = options;\n this.projectionMatrixInverse = new THREE.Matrix4();\n this.lastColliderUpdateTime = performance.now();\n this.updateVertexNormals = options.updateVertexNormals;\n this.colliderUpdateFps = options.colliderUpdateFps;\n this.depthTextureMaterialUniforms = uniforms;\n if (options.renderShadow) {\n this.receiveShadow = true;\n this.castShadow = false;\n }\n\n // Create a downsampled geometry for raycasts and physics.\n if (options.useDownsampledGeometry) {\n this.downsampledGeometry = new THREE.PlaneGeometry(1, 1, 39, 39);\n this.downsampledMesh = new THREE.Mesh(this.downsampledGeometry, material);\n this.downsampledMesh.visible = false;\n this.add(this.downsampledMesh);\n }\n }\n\n /**\n * Initialize the depth mesh.\n */\n init({camera, renderer}:\n {camera: THREE.Camera, renderer: THREE.WebGLRenderer}) {\n this.camera = camera;\n this.renderer = renderer;\n }\n\n /**\n * Updates the depth data and geometry positions based on the provided camera\n * and depth data.\n */\n updateDepth(depthData: XRCPUDepthInformation) {\n const camera = this.renderer.xr?.getCamera?.()?.cameras?.[0] || this.camera;\n if (!camera) return;\n\n // Inverts the projection matrix.\n this.projectionMatrixInverse.copy(camera.projectionMatrix).invert();\n\n this.minDepth = 8;\n this.maxDepth = 0;\n\n if (this.options.updateFullResolutionGeometry) {\n this.updateFullResolutionGeometry(depthData);\n }\n if (this.downsampledGeometry) {\n this.updateGeometry(depthData, this.downsampledGeometry);\n }\n\n this.minDepthPrev = this.minDepth;\n this.maxDepthPrev = this.maxDepth;\n this.geometry.attributes.position.needsUpdate = true;\n\n const depthTextureLeft = this.depthTextures?.get(0);\n if (depthTextureLeft && this.depthTextureMaterialUniforms) {\n const isTextureArray = depthTextureLeft instanceof THREE.ExternalTexture;\n this.depthTextureMaterialUniforms.uIsTextureArray.value =\n isTextureArray ? 1.0 : 0;\n if (isTextureArray)\n this.depthTextureMaterialUniforms.uDepthTextureArray.value =\n depthTextureLeft;\n else\n this.depthTextureMaterialUniforms.uDepthTexture.value =\n depthTextureLeft;\n this.depthTextureMaterialUniforms.uMinDepth.value = this.minDepth;\n this.depthTextureMaterialUniforms.uMaxDepth.value = this.maxDepth;\n this.depthTextureMaterialUniforms.uRawValueToMeters.value =\n this.depthTextures!.depthData.length ?\n this.depthTextures!.depthData[0].rawValueToMeters :\n 1.0;\n }\n\n if (this.options.updateVertexNormals) {\n this.geometry.computeVertexNormals();\n }\n\n this.updateColliderIfNeeded();\n }\n\n updateGPUDepth(depthData: XRWebGLDepthInformation) {\n this.updateDepth(this.convertGPUToGPU(depthData));\n }\n\n convertGPUToGPU(depthData: XRWebGLDepthInformation) {\n if (!this.depthTarget) {\n this.depthTarget =\n new THREE.WebGLRenderTarget(depthData.width, depthData.height, {\n format: THREE.RedFormat,\n type: THREE.FloatType,\n internalFormat: 'R32F',\n minFilter: THREE.NearestFilter,\n magFilter: THREE.NearestFilter,\n depthBuffer: false\n });\n this.depthTexture = new THREE.ExternalTexture(depthData.texture);\n const textureProperties =\n this.renderer.properties.get(this.depthTexture) as {\n __webglTexture: WebGLTexture;\n __version: number;\n };\n textureProperties.__webglTexture = depthData.texture;\n this.gpuPixels = new Float32Array(depthData.width * depthData.height);\n\n const depthShader = new THREE.ShaderMaterial({\n vertexShader: `\n varying vec2 vUv;\n void main() {\n vUv = uv;\n vUv.y = 1.0-vUv.y;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n }\n `,\n fragmentShader: `\n precision highp float;\n precision highp sampler2DArray;\n\n uniform sampler2DArray uTexture;\n uniform float uCameraNear;\n varying vec2 vUv;\n\n void main() {\n float z = texture(uTexture, vec3(vUv, 0)).r;\n z = uCameraNear / (1.0 - z);\n z = clamp(z, 0.0, 20.0);\n gl_FragColor = vec4(z, 0, 0, 1.0);\n }\n `,\n uniforms: {\n uTexture: {value: this.depthTexture},\n uCameraNear:\n {value: (depthData as unknown as {depthNear: number}).depthNear}\n },\n blending: THREE.NoBlending,\n depthTest: false,\n depthWrite: false,\n side: THREE.DoubleSide\n });\n const depthMesh =\n new THREE.Mesh(new THREE.PlaneGeometry(2, 2), depthShader);\n this.depthScene = new THREE.Scene();\n this.depthScene.add(depthMesh);\n this.depthCamera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0, 1);\n }\n\n const originalRenderTarget = this.renderer.getRenderTarget();\n this.renderer.xr.enabled = false;\n this.renderer.setRenderTarget(this.depthTarget);\n this.renderer.render(this.depthScene, this.depthCamera);\n this.renderer.readRenderTargetPixels(\n this.depthTarget, 0, 0, depthData.width, depthData.height,\n this.gpuPixels, 0);\n this.renderer.xr.enabled = true;\n this.renderer.setRenderTarget(originalRenderTarget);\n\n return {\n width: depthData.width,\n height: depthData.height,\n data: this.gpuPixels.buffer,\n rawValueToMeters: depthData.rawValueToMeters\n } as XRCPUDepthInformation;\n }\n\n /**\n * Method to manually update the full resolution geometry.\n * Only needed if options.updateFullResolutionGeometry is false.\n */\n updateFullResolutionGeometry(depthData: XRCPUDepthInformation) {\n this.updateGeometry(depthData, this.geometry);\n }\n\n /**\n * Internal method to update the geometry of the depth mesh.\n */\n private updateGeometry(\n depthData: XRCPUDepthInformation, geometry: THREE.BufferGeometry) {\n const width = depthData.width;\n const height = depthData.height;\n const depthArray = this.depthOptions.useFloat32 ?\n new Float32Array(depthData.data) :\n new Uint16Array(depthData.data);\n const vertexPosition = new THREE.Vector3();\n for (let i = 0; i < geometry.attributes.position.count; ++i) {\n const u = geometry.attributes.uv.array[2 * i];\n const v = geometry.attributes.uv.array[2 * i + 1];\n\n // Grabs the nearest for now.\n const depthX = Math.round(clamp(u * width, 0, width - 1));\n const depthY = Math.round(clamp((1.0 - v) * height, 0, height - 1));\n const rawDepth = depthArray[depthY * width + depthX];\n let depth = depthData.rawValueToMeters * rawDepth;\n // Workaround for b/382679381.\n if (this.depthOptions.useFloat32) {\n depth = rawDepth;\n }\n\n // Finds global min/max.\n if (depth > 0) {\n if (depth < this.minDepth) {\n this.minDepth = depth;\n } else if (depth > this.maxDepth) {\n this.maxDepth = depth;\n }\n }\n\n // This is a wrong algorithm to patch holes but working amazingly well.\n // Per-row maximum may work better but haven't tried here.\n // A proper local maximum takes another pass.\n if (depth == 0 && this.options.patchHoles) {\n depth = this.maxDepthPrev;\n }\n\n if (this.options.patchHolesUpper && v > 0.9) {\n depth = this.minDepthPrev;\n }\n\n vertexPosition.set(2.0 * (u - 0.5), 2.0 * (v - 0.5), -1);\n\n // This relates to camera.near\n vertexPosition.applyMatrix4(this.projectionMatrixInverse);\n\n vertexPosition.multiplyScalar(-depth / vertexPosition.z);\n\n geometry.attributes.position.array[3 * i + 0] = vertexPosition.x;\n geometry.attributes.position.array[3 * i + 1] = vertexPosition.y;\n geometry.attributes.position.array[3 * i + 2] = vertexPosition.z;\n }\n }\n\n /**\n * Optimizes collider updates to run periodically based on the specified FPS.\n */\n updateColliderIfNeeded() {\n const timeSinceLastUpdate = performance.now() - this.lastColliderUpdateTime;\n if (this.RAPIER && timeSinceLastUpdate > 1000 / this.colliderUpdateFps) {\n this.getWorldPosition(this.worldPosition);\n this.getWorldQuaternion(this.worldQuaternion);\n this.rigidBody!.setTranslation(this.worldPosition, false);\n this.rigidBody!.setRotation(this.worldQuaternion, false);\n\n const geometry =\n this.downsampledGeometry ? this.downsampledGeometry : this.geometry;\n const vertices = geometry.attributes.position.array as Float32Array;\n const indices = geometry.getIndex()!.array as Uint32Array;\n // Changing the density does not fix the issue.\n const shape =\n this.RAPIER.ColliderDesc.trimesh(vertices, indices).setDensity(1.0);\n // const convextHull = this.RAPIER.ColliderDesc.convexHull(vertices);\n\n if (this.options.useDualCollider) {\n this.colliderId = (this.colliderId + 1) % 2;\n this.blendedWorld!.removeCollider(\n this.colliders[this.colliderId], false);\n this.colliders[this.colliderId] =\n this.blendedWorld!.createCollider(shape, this.rigidBody);\n } else {\n const newCollider =\n this.blendedWorld!.createCollider(shape, this.rigidBody);\n this.blendedWorld!.removeCollider(this.collider!, /*wakeUp=*/ false);\n this.collider = newCollider;\n }\n\n this.lastColliderUpdateTime = performance.now();\n }\n }\n\n initRapierPhysics(RAPIER: typeof RAPIER_NS, blendedWorld: RAPIER_NS.World) {\n this.getWorldPosition(this.worldPosition);\n this.getWorldQuaternion(this.worldQuaternion);\n const desc = RAPIER.RigidBodyDesc.fixed()\n .setTranslation(\n this.worldPosition.x, this.worldPosition.y,\n this.worldPosition.z)\n .setRotation(this.worldQuaternion);\n this.rigidBody = blendedWorld.createRigidBody(desc);\n const vertices = this.geometry.attributes.position.array as Float32Array;\n const indices = this.geometry.getIndex()!.array as Uint32Array;\n const shape = RAPIER.ColliderDesc.trimesh(vertices, indices);\n\n if (this.options.useDualCollider) {\n this.colliders = [];\n this.colliders.push(\n blendedWorld.createCollider(shape, this.rigidBody),\n blendedWorld.createCollider(shape, this.rigidBody));\n this.colliderId = 0;\n } else {\n this.collider = blendedWorld.createCollider(shape, this.rigidBody);\n }\n\n this.RAPIER = RAPIER;\n this.blendedWorld = blendedWorld;\n this.lastColliderUpdateTime = performance.now();\n }\n\n getDepth(\n raycaster: THREE.Raycaster, ndc: THREE.Vector2, camera: THREE.Camera) {\n // Convert the point from blendedWorld space to normalized device\n // coordinates (NDC) const ndc = point.clone().project(camera);\n\n // Create a Vector2 for the NDC x, y coordinates (used by the Raycaster)\n const ndc2D = new THREE.Vector2(ndc.x, ndc.y);\n\n // Set up the Raycaster to cast a ray from the camera through the NDC point\n raycaster.setFromCamera(ndc2D, camera);\n\n // Check for intersections with the mesh\n const intersects = raycaster.intersectObject(this);\n\n // If an intersection is found, calculate the distance from the point to the\n // intersection\n if (intersects.length > 0) {\n const distance = intersects[0].distance;\n return distance;\n } else {\n return -1;\n }\n }\n\n /**\n * Customizes raycasting to compute normals for intersections.\n * @param raycaster - The raycaster object.\n * @param intersects - Array to store intersections.\n * @returns - True if intersections are found.\n */\n raycast(raycaster: THREE.Raycaster, intersects: THREE.Intersection[]) {\n const intersections: THREE.Intersection[] = [];\n if (this.downsampledMesh) {\n this.downsampledMesh.raycast(raycaster, intersections)\n } else {\n super.raycast(raycaster, intersections);\n }\n\n intersections.forEach(intersect => {\n intersect.object = this;\n });\n if (!this.updateVertexNormals) {\n // Use the face normals instead of attribute normals.\n intersections.forEach(intersect => {\n if (intersect.normal && intersect.face) {\n intersect.normal.copy(intersect.face.normal);\n }\n });\n }\n\n intersects.push(...intersections);\n return true;\n }\n\n getColliderFromHandle(handle: RAPIER_NS.ColliderHandle) {\n if (this.collider?.handle == handle) {\n return this.collider;\n }\n for (const collider of this.colliders) {\n if (collider?.handle == handle) {\n return collider;\n }\n }\n return undefined;\n }\n};\n","import {deepFreeze, deepMerge} from '../utils/OptionsUtils.js';\nimport {DeepPartial, DeepReadonly} from '../utils/Types';\n\nexport class DepthMeshOptions {\n enabled = false;\n updateVertexNormals = false;\n showDebugTexture = false;\n useDepthTexture = false;\n renderShadow = false;\n shadowOpacity = 0.25;\n patchHoles = false;\n patchHolesUpper = false;\n // Opacity of the debug material.\n opacity = 1.0;\n useDualCollider = false\n // Use downsampled geometry for raycast and collisions\n useDownsampledGeometry = true;\n // Whether to always update the full resolution geometry.\n updateFullResolutionGeometry = false;\n colliderUpdateFps = 5;\n}\n\nexport class DepthOptions {\n debugging = false;\n enabled = false;\n depthMesh = new DepthMeshOptions();\n depthTexture = {\n enabled: false,\n constantKernel: false,\n applyGaussianBlur: false,\n applyKawaseBlur: false,\n };\n // Occlusion pass.\n occlusion = {enabled: false};\n useFloat32 = true;\n\n constructor(options?: DeepReadonly<DeepPartial<DepthOptions>>) {\n deepMerge(this, options);\n }\n}\n\nexport const xrDepthMeshOptions = deepFreeze(new DepthOptions({\n enabled: true,\n depthMesh: {\n enabled: true,\n updateVertexNormals: false,\n showDebugTexture: false,\n useDepthTexture: false,\n renderShadow: false,\n shadowOpacity: 0.25,\n patchHoles: true,\n // Use downsampled geometry for raycast and collisions\n useDownsampledGeometry: true,\n // Whether to always update the full resolution geometry.\n updateFullResolutionGeometry: false,\n colliderUpdateFps: 5,\n }\n}));\n\n\nexport const xrDepthMeshVisualizationOptions = deepFreeze(new DepthOptions({\n enabled: true,\n depthMesh: {\n enabled: true,\n updateVertexNormals: true,\n showDebugTexture: true,\n useDepthTexture: true,\n renderShadow: false,\n shadowOpacity: 0.25,\n patchHoles: true,\n opacity: 0.1,\n // Use downsampled geometry for raycast and collisions\n useDownsampledGeometry: true,\n // Whether to always update the full resolution geometry.\n updateFullResolutionGeometry: true,\n colliderUpdateFps: 5,\n },\n depthTexture: {\n enabled: true,\n constantKernel: true,\n applyGaussianBlur: true,\n applyKawaseBlur: true,\n },\n}));\n\nexport const xrDepthMeshPhysicsOptions = deepFreeze(new DepthOptions({\n enabled: true,\n depthMesh: {\n enabled: true,\n updateVertexNormals: false,\n showDebugTexture: false,\n useDepthTexture: false,\n renderShadow: true,\n shadowOpacity: 0.25,\n patchHoles: true,\n patchHolesUpper: true,\n useDualCollider: false,\n // Use downsampled geometry for raycast and collisions\n useDownsampledGeometry: true,\n // Whether to always update the full resolution geometry.\n updateFullResolutionGeometry: false,\n colliderUpdateFps: 5,\n },\n}));\n","import * as THREE from 'three';\n\nimport {DepthOptions} from './DepthOptions';\n\nexport class DepthTextures {\n private uint16Arrays: Uint16Array[] = [];\n private uint8Arrays: Uint8Array[] = [];\n private dataTextures: THREE.DataTexture[] = [];\n private nativeTextures: THREE.ExternalTexture[] = [];\n public depthData: XRCPUDepthInformation[] = [];\n\n constructor(private options: DepthOptions) {}\n\n private createDataDepthTextures(\n depthData: XRCPUDepthInformation, view_id: number) {\n if (this.dataTextures[view_id]) {\n this.dataTextures[view_id].dispose();\n }\n if (this.options.useFloat32) {\n const typedArray = new Uint16Array(depthData.width * depthData.height);\n const format = THREE.RedFormat;\n const type = THREE.HalfFloatType;\n this.uint16Arrays[view_id] = typedArray;\n this.dataTextures[view_id] = new THREE.DataTexture(\n typedArray, depthData.width, depthData.height, format, type);\n } else {\n const typedArray = new Uint8Array(depthData.width * depthData.height * 2);\n const format = THREE.RGFormat;\n const type = THREE.UnsignedByteType;\n this.uint8Arrays[view_id] = typedArray;\n this.dataTextures[view_id] = new THREE.DataTexture(\n typedArray, depthData.width, depthData.height, format, type);\n }\n }\n\n updateData(depthData: XRCPUDepthInformation, view_id: number) {\n if (this.dataTextures.length < view_id + 1 ||\n this.dataTextures[view_id].image.width !== depthData.width ||\n this.dataTextures[view_id].image.height !== depthData.height) {\n this.createDataDepthTextures(depthData, view_id);\n }\n if (this.options.useFloat32) {\n const float32Data = new Float32Array(depthData.data);\n const float16Data = new Uint16Array(float32Data.length);\n for (let i = 0; i < float16Data.length; i++) {\n float16Data[i] = THREE.DataUtils.toHalfFloat(float32Data[i]);\n }\n this.uint16Arrays[view_id].set(float16Data);\n } else {\n this.uint8Arrays[view_id].set(new Uint8Array(depthData.data));\n }\n this.dataTextures[view_id].needsUpdate = true;\n this.depthData[view_id] = depthData;\n }\n\n updateNativeTexture(depthData: XRWebGLDepthInformation, renderer: THREE.WebGLRenderer, view_id: number) {\n if (this.dataTextures.length < view_id + 1) {\n this.nativeTextures[view_id] = new THREE.ExternalTexture(depthData.texture);\n } else {\n this.nativeTextures[view_id].sourceTexture = depthData.texture;\n }\n // fixed in newer revision of three\n const textureProperties = renderer.properties.get(this.nativeTextures[view_id]) as {\n __webglTexture: WebGLTexture;\n __version: number;\n };\n textureProperties.__webglTexture = depthData.texture;\n textureProperties.__version = 1;\n }\n\n get(view_id: number) {\n if (this.dataTextures.length > 0) {\n return this.dataTextures[view_id];\n }\n\n return this.nativeTextures[view_id];\n }\n};\n","export const KawaseBlurShader = {\n name: 'KawaseBlurShader',\n defines: {\n MODE: \"0\"\n },\n vertexShader: /* glsl */ `\n uniform float uBlurSize;\n uniform vec2 uTexelSize;\n varying vec2 vTexCoord;\n varying vec4 uv1;\n varying vec4 uv2;\n varying vec4 uv3;\n varying vec4 uv4;\n\n void vertCopy(vec2 uv) {}\n\n void vertUpsample(vec2 uv) {\n vec2 halfPixel = uTexelSize * 0.5;\n vec2 offset = vec2(uBlurSize);\n uv1.xy = uv + vec2(-halfPixel.x * 2.0, 0.0) * offset;\n uv1.zw = uv + vec2(-halfPixel.x, halfPixel.y) * offset;\n uv2.xy = uv + vec2(0.0, halfPixel.y * 2.0) * offset;\n uv2.zw = uv + halfPixel * offset;\n uv3.xy = uv + vec2(halfPixel.x * 2.0, 0.0) * offset;\n uv3.zw = uv + vec2(halfPixel.x, -halfPixel.y) * offset;\n uv4.xy = uv + vec2(0.0, -halfPixel.y * 2.0) * offset;\n uv4.zw = uv - halfPixel * offset;\n }\n\n void vertDownsample(vec2 uv) {\n vec2 halfPixel = uTexelSize * 0.5;\n vec2 offset = vec2(uBlurSize);\n uv1.xy = uv - halfPixel * offset;\n uv1.zw = uv + halfPixel * offset;\n uv2.xy = uv - vec2(halfPixel.x, -halfPixel.y) * offset;\n uv2.zw = uv + vec2(halfPixel.x, -halfPixel.y) * offset;\n }\n\n void main() {\n vTexCoord = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n if (MODE == 0) {\n vertCopy(uv);\n } else if (MODE == 1) {\n vertDownsample(uv);\n } else {\n vertUpsample(uv);\n }\n }\n`,\n fragmentShader: /* glsl */ `\n uniform sampler2D tDiffuse;\n varying vec2 vTexCoord;\n varying vec4 uv1;\n varying vec4 uv2;\n varying vec4 uv3;\n varying vec4 uv4;\n\n vec2 getUV0() {\n return vTexCoord;\n }\n\n vec4 fragCopy() {\n return texture2D(tDiffuse, getUV0());\n }\n\n vec4 fragDownsample() {\n vec4 sum = texture2D(tDiffuse, getUV0()) * 4.0;\n sum += texture2D(tDiffuse, uv1.xy);\n sum += texture2D(tDiffuse, uv1.zw);\n sum += texture2D(tDiffuse, uv2.xy);\n sum += texture2D(tDiffuse, uv2.zw);\n return sum * 0.125;\n }\n\n vec4 fragUpsample() {\n vec4 sum = texture2D(tDiffuse, uv1.xy);\n sum += texture2D(tDiffuse, uv1.zw) * 2.0;\n sum += texture2D(tDiffuse, uv2.xy);\n sum += texture2D(tDiffuse, uv2.zw) * 2.0;\n sum += texture2D(tDiffuse, uv3.xy);\n sum += texture2D(tDiffuse, uv3.zw) * 2.0;\n sum += texture2D(tDiffuse, uv4.xy);\n sum += texture2D(tDiffuse, uv4.zw) * 2.0;\n return sum * 0.0833;\n }\n\n void main(void) {\n if (MODE == 0) {\n gl_FragColor = fragCopy();\n } else if (MODE == 1) {\n gl_FragColor = fragDownsample();\n } else {\n gl_FragColor = fragUpsample();\n }\n }\n`\n};\n","// Postprocessing shader which applies occlusion onto the entire rendered frame.\nexport const OcclusionShader = {\n name: 'OcclusionShader',\n defines: {},\n vertexShader: /* glsl */ `\nvarying vec2 vTexCoord;\n\nvoid main() {\n vTexCoord = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}\n `,\n fragmentShader: /* glsl */ `\nprecision mediump float;\n\nuniform sampler2D tDiffuse;\nuniform sampler2D tOcclusionMap;\n\nvarying vec2 vTexCoord;\n\nvoid main(void) {\n vec4 diffuse = texture2D(tDiffuse, vTexCoord);\n vec4 occlusion = texture2D(tOcclusionMap, vTexCoord);\n float occlusionValue = occlusion.r / max(0.0001, occlusion.g);\n occlusionValue = clamp(occlusionValue, 0.0, 1.0);\n gl_FragColor = occlusionValue * diffuse;\n\n gl_FragColor = sRGBTransferOETF( gl_FragColor );\n}\n`\n};\n","// Postprocessing to convert a render texture + depth map into an occlusion map.\nexport const OcclusionMapShader = {\n name: 'OcclusionMapShader',\n defines: {},\n\n vertexShader: /* glsl */ `\nvarying vec2 vTexCoord;\n\nvoid main() {\n vTexCoord = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}\n `,\n\n fragmentShader: /* glsl */ `\n#include <packing>\n\nprecision mediump float;\n\nuniform sampler2D uDepthTexture;\nuniform mat4 uUvTransform;\nuniform float uRawValueToMeters;\nuniform float uAlpha;\nuniform float uViewId;\nuniform bool uFloatDepth;\n\nuniform sampler2D tDiffuse;\nuniform sampler2D tDepth;\nuniform float cameraNear;\nuniform float cameraFar;\n\nvarying vec2 vTexCoord;\n\nfloat DepthGetMeters(in sampler2D depth_texture, in vec2 depth_uv) {\n // Depth is packed into the luminance and alpha components of its texture.\n // The texture is in a normalized format, storing raw values that need to be\n // converted to meters.\n vec2 packedDepthAndVisibility = texture2D(depth_texture, depth_uv).rg;\n if (uFloatDepth) {\n return packedDepthAndVisibility.r * uRawValueToMeters;\n }\n return dot(packedDepthAndVisibility, vec2(255.0, 256.0 * 255.0)) * uRawValueToMeters;\n}\n\nfloat readOrthographicDepth( sampler2D depthSampler, vec2 coord ) {\n float fragCoordZ = texture2D( depthSampler, coord ).x;\n // See https://github.com/mrdoob/three.js/issues/23072.\n #ifdef USE_LOGDEPTHBUF\n float viewZ = 1.0 - exp2(fragCoordZ * log(cameraFar + 1.0) / log(2.0));\n #else\n float viewZ = perspectiveDepthToViewZ(fragCoordZ, cameraNear, cameraFar);\n #endif\n return viewZToOrthographicDepth( viewZ, cameraNear, cameraFar );\n}\n\nvoid main(void) {\n vec4 texCoord = vec4(vTexCoord, 0, 1);\n vec2 uv = texCoord.xy;\n uv.y = 1.0 - uv.y;\n\n vec4 diffuse = texture2D( tDiffuse, texCoord.xy );\n highp float real_depth = DepthGetMeters(uDepthTexture, uv);\n highp float virtual_depth =\n (readOrthographicDepth(tDepth, texCoord.xy ) *\n (cameraFar - cameraNear) + cameraNear);\n gl_FragColor = vec4(step(virtual_depth, real_depth), step(0.001, diffuse.a), 0.0, 0.0);\n}\n`\n\n};\n","\nimport * as THREE from 'three';\n\nexport class OcclusionMapMeshMaterial extends THREE.MeshBasicMaterial {\n uniforms: {[uniform: string]: THREE.IUniform};\n\n constructor(camera: THREE.PerspectiveCamera, useFloatDepth: boolean) {\n super();\n this.uniforms = {\n uDepthTexture: {value: null},\n uDepthTextureArray: {value: null},\n uViewId: {value: 0.0},\n uIsTextureArray: {value: 0.0},\n uRawValueToMeters: {value: 8.0 / 65536.0},\n cameraFar: {value: camera.far},\n cameraNear: {value: camera.near},\n uFloatDepth: {value: useFloatDepth},\n // Used for interpreting Quest 3 depth.\n uDepthNear: {value: 0}\n };\n this.onBeforeCompile = (shader) => {\n Object.assign(shader.uniforms, this.uniforms);\n this.uniforms = shader.uniforms;\n shader.vertexShader =\n shader.vertexShader\n .replace(\n '#include <common>',\n [\n 'varying vec2 vTexCoord;', 'varying float vVirtualDepth;',\n '#include <common>'\n ].join('\\n'))\n .replace('#include <fog_vertex>', [\n '#include <fog_vertex>',\n 'vec4 view_position = modelViewMatrix * vec4( position, 1.0 );',\n 'vVirtualDepth = -view_position.z;',\n 'gl_Position = gl_Position / gl_Position.w;',\n 'vTexCoord = 0.5 + 0.5 * gl_Position.xy;'\n ].join('\\n'));\n shader.fragmentShader =\n shader.fragmentShader\n .replace(\n 'uniform vec3 diffuse;',\n [\n 'uniform vec3 diffuse;', 'uniform sampler2D uDepthTexture;',\n 'uniform sampler2DArray uDepthTextureArray;',\n 'uniform float uRawValueToMeters;',\n 'uniform float cameraNear;', 'uniform float cameraFar;',\n 'uniform bool uFloatDepth;',\n 'uniform bool uIsTextureArray;',\n 'uniform float uDepthNear;', 'uniform int uViewId;',\n 'varying vec2 vTexCoord;', 'varying float vVirtualDepth;'\n ].join('\\n'))\n .replace(\n '#include <clipping_planes_pars_fragment>',\n [\n '#include <clipping_planes_pars_fragment>', `\n float DepthGetMeters(in sampler2D depth_texture, in vec2 depth_uv) {\n // Depth is packed into the luminance and alpha components of its texture.\n // The texture is in a normalized format, storing raw values that need to be\n // converted to meters.\n vec2 packedDepthAndVisibility = texture2D(depth_texture, depth_uv).rg;\n if (uFloatDepth) {\n return packedDepthAndVisibility.r * uRawValueToMeters;\n }\n return dot(packedDepthAndVisibility, vec2(255.0, 256.0 * 255.0)) * uRawValueToMeters;\n }\n float DepthArrayGetMeters(in sampler2DArray depth_texture, in vec2 depth_uv) {\n float textureValue = texture(depth_texture, vec3(depth_uv.x, depth_uv.y, uViewId)).r;\n return uRawValueToMeters * uDepthNear / (1.0 - textureValue);\n }\n`\n ].join('\\n'))\n .replace('#include <dithering_fragment>', [\n '#include <dithering_fragment>',\n 'vec4 texCoord = vec4(vTexCoord, 0, 1);',\n 'vec2 uv = vec2(texCoord.x, uIsTextureArray?texCoord.y:(1.0 - texCoord.y));',\n 'highp float real_depth = uIsTextureArray ? DepthArrayGetMeters(uDepthTextureArray, uv) : DepthGetMeters(uDepthTexture, uv);',\n 'gl_FragColor = vec4(step(vVirtualDepth, real_depth), 1.0, 0.0, 1.0);'\n ].join('\\n'));\n };\n }\n}\n","import * as THREE from 'three';\nimport {FullScreenQuad, Pass} from 'three/addons/postprocessing/Pass.js';\n\nimport {OCCLUDABLE_ITEMS_LAYER} from '../../constants';\nimport type {ShaderUniforms} from '../../utils/Types';\n\nimport {KawaseBlurShader} from './kawaseblur.glsl';\nimport {OcclusionShader} from './occlusion.glsl';\nimport {OcclusionMapShader} from './occlusion_map.glsl';\nimport {OcclusionMapMeshMaterial} from './OcclusionMapMeshMaterial';\n\nenum KawaseBlurMode {\n COPY = 0,\n DOWN = 1,\n UP = 2\n}\n\n/**\n * Occlusion postprocessing shader pass.\n * This is used to generate an occlusion map.\n * There are two modes:\n * Mode A: Generate an occlusion map for individual materials to use.\n * Mode B: Given a rendered frame, run as a postprocessing pass, occluding all\n * items in the frame. The steps are\n * 1. Compute an occlusion map between the real and virtual depth.\n * 2. Blur the occlusion map using Kawase blur.\n * 3. (Mode B only) Apply the occlusion map to the rendered frame.\n */\nexport class OcclusionPass extends Pass {\n private depthTextures: THREE.Texture[] = [];\n private occlusionMeshMaterial: OcclusionMapMeshMaterial;\n private occlusionMapUniforms: ShaderUniforms;\n private occlusionMapQuad: FullScreenQuad;\n private occlusionMapTexture: THREE.WebGLRenderTarget;\n private kawaseBlurQuads: FullScreenQuad[];\n private kawaseBlurTargets: THREE.WebGLRenderTarget[];\n private occlusionUniforms: ShaderUniforms;\n private occlusionQuad: FullScreenQuad;\n private depthNear: (number|undefined)[] = [];\n\n constructor(\n private scene: THREE.Scene, private camera: THREE.PerspectiveCamera,\n useFloatDepth = true, public renderToScreen = false,\n private occludableItemsLayer = OCCLUDABLE_ITEMS_LAYER) {\n super();\n\n this.occlusionMeshMaterial =\n new OcclusionMapMeshMaterial(camera, useFloatDepth);\n\n this.occlusionMapUniforms = {\n uDepthTexture: {value: null},\n uDepthTextureArray: {value: null},\n uViewId: {value: 0.0},\n uIsTextureArray: {value: 0.0},\n uUvTransform: {value: new THREE.Matrix4()},\n uRawValueToMeters: {value: 8.0 / 65536.0},\n uAlpha: {value: 0.75},\n tDiffuse: {value: null},\n tDepth: {value: null},\n uFloatDepth: {value: useFloatDepth},\n cameraFar: {value: camera.far},\n cameraNear: {value: camera.near},\n };\n this.occlusionMapQuad = new FullScreenQuad(new THREE.ShaderMaterial({\n name: 'OcclusionMapShader',\n uniforms: this.occlusionMapUniforms,\n vertexShader: OcclusionMapShader.vertexShader,\n fragmentShader: OcclusionMapShader.fragmentShader,\n }));\n this.occlusionMapTexture = new THREE.WebGLRenderTarget();\n\n this.kawaseBlurTargets = [\n new THREE.WebGLRenderTarget(), // 1/2 resolution\n new THREE.WebGLRenderTarget(), // 1/4 resolution\n new THREE.WebGLRenderTarget(), // 1/8 resolution\n ];\n this.kawaseBlurQuads = [\n this.setupKawaseBlur(\n KawaseBlurMode.DOWN, this.occlusionMapTexture.texture),\n this.setupKawaseBlur(\n KawaseBlurMode.DOWN, this.kawaseBlurTargets[0].texture),\n this.setupKawaseBlur(\n KawaseBlurMode.DOWN, this.kawaseBlurTargets[1].texture),\n this.setupKawaseBlur(\n KawaseBlurMode.UP, this.kawaseBlurTargets[2].texture),\n this.setupKawaseBlur(\n KawaseBlurMode.UP, this.kawaseBlurTargets[1].texture),\n this.setupKawaseBlur(\n KawaseBlurMode.UP, this.kawaseBlurTargets[0].texture),\n ];\n\n this.occlusionUniforms = {\n tDiffuse: {value: null},\n tOcclusionMap: {value: this.occlusionMapTexture.texture},\n };\n this.occlusionQuad = new FullScreenQuad(new THREE.ShaderMaterial({\n name: 'OcclusionShader',\n uniforms: this.occlusionUniforms,\n vertexShader: OcclusionShader.vertexShader,\n fragmentShader: OcclusionShader.fragmentShader,\n }));\n\n this.occludableItemsLayer = occludableItemsLayer;\n }\n\n private setupKawaseBlur(mode: KawaseBlurMode, inputTexture: THREE.Texture) {\n const uniforms = {\n uBlurSize: {value: 7.0},\n uTexelSize: {value: new THREE.Vector2()},\n tDiffuse: {value: inputTexture}\n };\n const kawase1Material = new THREE.ShaderMaterial({\n name: 'Kawase',\n uniforms: uniforms,\n vertexShader: KawaseBlurShader.vertexShader,\n fragmentShader: KawaseBlurShader.fragmentShader,\n defines: {MODE: mode}\n });\n return new FullScreenQuad(kawase1Material);\n }\n\n setDepthTexture(\n depthTexture: THREE.Texture, rawValueToMeters: number, viewId: number,\n depthNear?: number) {\n this.depthTextures[viewId] = depthTexture;\n this.occlusionMapUniforms.uRawValueToMeters.value = rawValueToMeters;\n this.occlusionMeshMaterial.uniforms.uRawValueToMeters.value =\n rawValueToMeters;\n this.depthNear[viewId] = depthNear;\n depthTexture.needsUpdate = true;\n }\n\n /**\n * Render the occlusion map.\n * @param renderer - The three.js renderer.\n * @param writeBuffer - The buffer to write the final result.\n * @param readBuffer - The buffer for the current of virtual depth.\n * @param viewId - The view to render.\n */\n render(\n renderer: THREE.WebGLRenderer, writeBuffer?: THREE.WebGLRenderTarget,\n readBuffer?: THREE.WebGLRenderTarget, viewId = 0) {\n const originalRenderTarget = renderer.getRenderTarget();\n const dimensions = new THREE.Vector2();\n if (readBuffer == null) {\n this.renderOcclusionMapFromScene(renderer, dimensions, viewId);\n } else {\n this.renderOcclusionMapFromReadBuffer(\n renderer, readBuffer, dimensions, viewId);\n }\n\n // Blur the occlusion map\n this.blurOcclusionMap(renderer, dimensions);\n\n // Fuse the rendered image and the occlusion map.\n this.applyOcclusionMapToRenderedImage(renderer, readBuffer, writeBuffer);\n renderer.setRenderTarget(originalRenderTarget);\n }\n\n renderOcclusionMapFromScene(\n renderer: THREE.WebGLRenderer, dimensions: THREE.Vector2,\n viewId: number) {\n // Compute our own read buffer.\n const texture = this.depthTextures[viewId];\n const isTextureArray = texture instanceof THREE.ExternalTexture;\n this.occlusionMeshMaterial.uniforms.uIsTextureArray.value =\n isTextureArray ? 1.0 : 0;\n this.occlusionMeshMaterial.uniforms.uViewId.value = viewId;\n if (isTextureArray) {\n this.occlusionMeshMaterial.uniforms.uDepthTextureArray.value = texture;\n this.occlusionMeshMaterial.uniforms.uDepthNear.value =\n this.depthNear[viewId];\n } else {\n this.occlusionMeshMaterial.uniforms.uDepthTexture.value = texture;\n }\n this.scene.overrideMaterial = this.occlusionMeshMaterial;\n renderer.getDrawingBufferSize(dimensions);\n this.occlusionMapTexture.setSize(dimensions.x, dimensions.y);\n const renderTarget = this.occlusionMapTexture;\n renderer.setRenderTarget(renderTarget);\n const camera = renderer.xr.getCamera().cameras[viewId] || this.camera;\n const originalCameraLayers =\n Array.from(Array(32).keys())\n .filter(element => camera.layers.isEnabled(element));\n camera.layers.set(this.occludableItemsLayer);\n renderer.render(this.scene, camera);\n camera.layers.disableAll();\n originalCameraLayers.forEach(element => {\n camera.layers.enable(element);\n });\n this.scene.overrideMaterial = null;\n }\n\n renderOcclusionMapFromReadBuffer(\n renderer: THREE.WebGLRenderer, readBuffer: THREE.RenderTarget,\n dimensions: THREE.Vector2, viewId: number) {\n // Convert the readBuffer into an occlusion map.\n // Render depth into texture\n this.occlusionMapUniforms.tDiffuse.value = readBuffer.texture;\n this.occlusionMapUniforms.tDepth.value = readBuffer.depthTexture;\n const texture = this.depthTextures[viewId];\n const isTextureArray = texture instanceof THREE.ExternalTexture;\n this.occlusionMeshMaterial.uniforms.uIsTextureArray.value =\n isTextureArray ? 1.0 : 0;\n this.occlusionMeshMaterial.uniforms.uViewId.value = viewId;\n if (isTextureArray) {\n this.occlusionMeshMaterial.uniforms.uDepthTextureArray.value = texture;\n this.occlusionMeshMaterial.uniforms.uDepthNear.value =\n this.depthNear[viewId];\n } else {\n this.occlusionMeshMaterial.uniforms.uDepthTexture.value = texture;\n }\n // First render the occlusion map to an intermediate buffer.\n renderer.getDrawingBufferSize(dimensions);\n this.occlusionMapTexture.setSize(dimensions.x, dimensions.y);\n renderer.setRenderTarget(this.occlusionMapTexture);\n this.occlusionMapQuad.render(renderer);\n }\n\n blurOcclusionMap(renderer: THREE.WebGLRenderer, dimensions: THREE.Vector2) {\n for (let i = 0; i < 3; i++) {\n this.kawaseBlurTargets[i].setSize(\n dimensions.x / (2 ** i), dimensions.y / (2 ** i));\n }\n for (let i = 0; i < 3; i++) {\n (this.kawaseBlurQuads[i].material as THREE.ShaderMaterial)\n .uniforms.uTexelSize.value.set(\n 1 / (dimensions.x / (2 ** i)), 1 / (dimensions.y / (2 ** i)));\n (this.kawaseBlurQuads[this.kawaseBlurQuads.length - 1 - i].material as\n THREE.ShaderMaterial)\n .uniforms.uTexelSize.value.set(\n 1 / (dimensions.x / (2 ** (i - 1))),\n 1 / (dimensions.y / (2 ** (i - 1))));\n }\n renderer.setRenderTarget(this.kawaseBlurTargets[0]);\n this.kawaseBlurQuads[0].render(renderer);\n renderer.setRenderTarget(this.kawaseBlurTargets[1]);\n this.kawaseBlurQuads[1].render(renderer);\n renderer.setRenderTarget(this.kawaseBlurTargets[2]);\n this.kawaseBlurQuads[2].render(renderer);\n renderer.setRenderTarget(this.kawaseBlurTargets[1]);\n this.kawaseBlurQuads[3].render(renderer);\n renderer.setRenderTarget(this.kawaseBlurTargets[0]);\n this.kawaseBlurQuads[4].render(renderer);\n renderer.setRenderTarget(this.occlusionMapTexture);\n this.kawaseBlurQuads[5].render(renderer);\n }\n\n applyOcclusionMapToRenderedImage(\n renderer: THREE.WebGLRenderer, readBuffer?: THREE.WebGLRenderTarget,\n writeBuffer?: THREE.WebGLRenderTarget) {\n if (readBuffer && (this.renderToScreen || writeBuffer)) {\n this.occlusionUniforms.tDiffuse.value = readBuffer.texture;\n renderer.setRenderTarget(\n writeBuffer && !this.renderToScreen ? writeBuffer : null);\n this.occlusionQuad.render(renderer);\n }\n }\n\n dispose() {\n this.occlusionMeshMaterial.dispose();\n this.occlusionMapTexture.dispose();\n for (let i = 0; i < this.kawaseBlurQuads.length; i++) {\n this.kawaseBlurQuads[i].dispose();\n }\n }\n\n updateOcclusionMapUniforms(\n uniforms: ShaderUniforms, renderer: THREE.WebGLRenderer) {\n const camera = renderer.xr.getCamera().cameras[0] || this.camera;\n uniforms.tOcclusionMap.value = this.occlusionMapTexture.texture;\n uniforms.uOcclusionClipFromWorld.value.copy(camera.projectionMatrix)\n .multiply(camera.matrixWorldInverse);\n }\n}\n","import * as THREE from 'three';\n\nimport {Registry} from '../core/components/Registry';\nimport {onDesktopUserAgent} from '../utils/BrowserUtils';\nimport type {Shader} from '../utils/Types';\nimport {clamp} from '../utils/utils';\n\nimport {DepthMesh} from './DepthMesh';\nimport {DepthOptions} from './DepthOptions';\nimport {DepthTextures} from './DepthTextures';\nimport {OcclusionPass} from './occlusion/OcclusionPass';\n\nconst DEFAULT_DEPTH_WIDTH = 160;\nconst DEFAULT_DEPTH_HEIGHT = DEFAULT_DEPTH_WIDTH;\nconst clipSpacePosition = new THREE.Vector3();\n\nexport type DepthArray = Float32Array|Uint16Array;\n\nexport class Depth {\n static instance?: Depth;\n\n // The main camera.\n private camera!: THREE.Camera;\n private renderer!: THREE.WebGLRenderer;\n private scene!: THREE.Scene;\n private projectionMatrixInverse = new THREE.Matrix4();\n private xrRefSpace?: XRReferenceSpace|XRBoundedReferenceSpace;\n\n view: XRView[] = [];\n cpuDepthData: XRCPUDepthInformation[] = [];\n gpuDepthData: XRWebGLDepthInformation[] = [];\n depthArray: DepthArray[] = [];\n depthMesh?: DepthMesh;\n private depthTextures?: DepthTextures;\n options = new DepthOptions();\n width = DEFAULT_DEPTH_WIDTH;\n height = DEFAULT_DEPTH_HEIGHT;\n rawValueToMeters = 0.0010000000474974513;\n occludableShaders = new Set<Shader>();\n private occlusionPass?: OcclusionPass;\n\n\n // Whether we're counting the number of depth clients.\n private depthClientsInitialized = false;\n private depthClients = new Set<object>();\n\n /**\n * Depth is a lightweight manager based on three.js to simply prototyping\n * with Depth in WebXR.\n */\n constructor() {\n if (Depth.instance) {\n return Depth.instance;\n }\n Depth.instance = this;\n }\n\n /**\n * Initialize Depth manager.\n */\n init(\n camera: THREE.PerspectiveCamera, options: DepthOptions,\n renderer: THREE.WebGLRenderer, registry: Registry, scene: THREE.Scene) {\n this.camera = camera;\n this.options = options;\n this.renderer = renderer;\n this.scene = scene;\n\n if (this.options.depthTexture.enabled) {\n this.depthTextures = new DepthTextures(options);\n registry.register(this.depthTextures);\n }\n\n if (this.options.depthMesh.enabled) {\n this.depthMesh =\n new DepthMesh(options, this.width, this.height, this.depthTextures);\n registry.register(this.depthMesh);\n if (this.options.depthMesh.renderShadow) {\n this.renderer.shadowMap.enabled = true;\n this.renderer.shadowMap.type = THREE.PCFShadowMap;\n }\n camera.add(this.depthMesh);\n scene.add(camera);\n }\n\n if (this.options.occlusion.enabled) {\n this.occlusionPass = new OcclusionPass(scene, camera);\n }\n }\n\n /**\n * Retrieves the depth at normalized coordinates (u, v).\n * @param u - Normalized horizontal coordinate.\n * @param v - Normalized vertical coordinate.\n * @returns Depth value at the specified coordinates.\n */\n getDepth(u: number, v: number) {\n if (!this.depthArray[0]) return 0.0;\n const depthX = Math.round(clamp(u * this.width, 0, this.width - 1));\n const depthY =\n Math.round(clamp((1.0 - v) * this.height, 0, this.height - 1));\n const rawDepth = this.depthArray[0][depthY * this.width + depthX];\n return this.rawValueToMeters * rawDepth;\n }\n\n /**\n * Projects the given world position to clip space and then to view\n * space using the depth.\n * @param position - The world position to project.\n */\n getProjectedDepthViewPositionFromWorldPosition(\n position: THREE.Vector3, target = new THREE.Vector3()) {\n const camera = this.renderer.xr?.getCamera?.()?.cameras?.[0] || this.camera;\n clipSpacePosition.copy(position)\n .applyMatrix4(camera.matrixWorldInverse)\n .applyMatrix4(camera.projectionMatrix);\n const u = 0.5 * (clipSpacePosition.x + 1.0);\n const v = 0.5 * (clipSpacePosition.y + 1.0);\n const depth = this.getDepth(u, v);\n target.set(2.0 * (u - 0.5), 2.0 * (v - 0.5), -1);\n target.applyMatrix4(camera.projectionMatrixInverse);\n target.multiplyScalar((target.z - depth) / target.z);\n return target;\n }\n\n /**\n * Retrieves the depth at normalized coordinates (u, v).\n * @param u - Normalized horizontal coordinate.\n * @param v - Normalized vertical coordinate.\n * @returns Vertex at (u, v)\n */\n getVertex(u: number, v: number) {\n if (!this.depthArray[0]) return null;\n\n const depthX = Math.round(clamp(u * this.width, 0, this.width - 1));\n const depthY =\n Math.round(clamp((1.0 - v) * this.height, 0, this.height - 1));\n const rawDepth = this.depthArray[0][depthY * this.width + depthX];\n const depth = this.rawValueToMeters * rawDepth;\n const vertexPosition =\n new THREE.Vector3(2.0 * (u - 0.5), 2.0 * (v - 0.5), -1);\n vertexPosition.applyMatrix4(this.projectionMatrixInverse);\n vertexPosition.multiplyScalar(-depth / vertexPosition.z);\n return vertexPosition;\n }\n\n updateCPUDepthData(depthData: XRCPUDepthInformation, view_id = 0) {\n this.cpuDepthData[view_id] = depthData;\n // Workaround for b/382679381.\n this.rawValueToMeters = depthData.rawValueToMeters;\n if (this.options.useFloat32) {\n this.rawValueToMeters = 1.0;\n }\n\n // Updates Depth Array.\n if (this.depthArray[view_id] == null) {\n this.depthArray[view_id] = this.options.useFloat32 ?\n new Float32Array(depthData.data) :\n new Uint16Array(depthData.data);\n this.width = depthData.width;\n this.height = depthData.height;\n } else {\n // Copies the data from an ArrayBuffer to the existing TypedArray.\n this.depthArray[view_id].set(\n this.options.useFloat32 ? new Float32Array(depthData.data) :\n new Uint16Array(depthData.data));\n }\n\n // Updates Depth Texture.\n if (this.options.depthTexture.enabled && this.depthTextures) {\n this.depthTextures.updateData(depthData, view_id);\n }\n\n if (this.options.depthMesh.enabled && this.depthMesh && view_id == 0) {\n this.depthMesh.updateDepth(depthData);\n }\n }\n\n updateGPUDepthData(depthData: XRWebGLDepthInformation, view_id = 0) {\n this.gpuDepthData[view_id] = depthData;\n // Workaround for b/382679381.\n this.rawValueToMeters = depthData.rawValueToMeters;\n if (this.options.useFloat32) {\n this.rawValueToMeters = 1.0;\n }\n\n // For now, assume that we need cpu depth only if depth mesh is enabled.\n // In the future, add a separate option.\n const needCpuDepth = this.options.depthMesh.enabled;\n const cpuDepth = needCpuDepth && this.depthMesh ?\n this.depthMesh.convertGPUToGPU(depthData) :\n null;\n if (cpuDepth) {\n if (this.depthArray[view_id] == null) {\n this.depthArray[view_id] = this.options.useFloat32 ?\n new Float32Array(cpuDepth.data) :\n new Uint16Array(cpuDepth.data);\n this.width = cpuDepth.width;\n this.height = cpuDepth.height;\n } else {\n // Copies the data from an ArrayBuffer to the existing TypedArray.\n this.depthArray[view_id].set(\n this.options.useFloat32 ? new Float32Array(cpuDepth.data) :\n new Uint16Array(cpuDepth.data));\n }\n }\n\n // Updates Depth Texture.\n if (this.options.depthTexture.enabled && this.depthTextures) {\n this.depthTextures.updateNativeTexture(depthData, this.renderer, view_id);\n }\n\n if (this.options.depthMesh.enabled && this.depthMesh && view_id == 0) {\n if (cpuDepth) {\n this.depthMesh.updateDepth(cpuDepth);\n } else {\n this.depthMesh.updateGPUDepth(depthData);\n }\n }\n }\n\n getTexture(view_id: number) {\n if (!this.options.depthTexture.enabled) return undefined;\n return this.depthTextures?.get(view_id);\n }\n\n update(frame: XRFrame) {\n if (!this.options.enabled) return;\n\n this.updateLocalDepth(frame);\n if (this.options.occlusion.enabled) {\n this.renderOcclusionPass();\n }\n }\n\n updateLocalDepth(frame: XRFrame) {\n if (onDesktopUserAgent()) {\n return;\n }\n\n const leftCamera = this.renderer.xr?.getCamera?.()?.cameras?.[0];\n if (leftCamera && this.depthMesh && this.depthMesh.parent != leftCamera) {\n leftCamera.add(this.depthMesh);\n this.scene.add(leftCamera);\n }\n\n if (!frame) return;\n const session = frame.session;\n const binding = this.renderer.xr.getBinding();\n\n // Enable or disable depth based on the number of clients.\n const pausingDepthSupported = session.depthActive !== undefined;\n if (pausingDepthSupported && this.depthClientsInitialized) {\n const needsDepth = this.depthClients.size > 0;\n if (session.depthActive && !needsDepth) {\n session.pauseDepthSensing?.();\n } else if (!session.depthActive && needsDepth) {\n session.resumeDepthSensing?.();\n }\n if (this.depthClients.size == 0) {\n return;\n }\n }\n\n if (this.xrRefSpace == null) {\n session.requestReferenceSpace('local').then((refSpace) => {\n this.xrRefSpace = refSpace;\n });\n session.addEventListener('end', () => {\n this.xrRefSpace = undefined;\n });\n } else {\n const pose = frame.getViewerPose(this.xrRefSpace);\n if (pose) {\n for (let view_id = 0; view_id < pose.views.length; ++view_id) {\n const view = pose.views[view_id];\n this.view[view_id] = view;\n\n if (session.depthUsage === 'gpu-optimized') {\n const depthData = binding.getDepthInformation(view);\n if (!depthData) {\n return;\n }\n this.updateGPUDepthData(depthData, view_id);\n } else {\n const depthData = frame.getDepthInformation(view);\n if (!depthData) {\n return;\n }\n this.updateCPUDepthData(depthData, view_id);\n }\n }\n } else {\n console.error('Pose unavailable in the current frame.');\n }\n }\n }\n\n renderOcclusionPass() {\n const leftDepthTexture = this.getTexture(0);\n if (leftDepthTexture) {\n this.occlusionPass!.setDepthTexture(\n leftDepthTexture, this.rawValueToMeters, 0,\n (this.gpuDepthData[0] as unknown as {depthNear: number} | undefined)\n ?.depthNear);\n }\n const rightDepthTexture = this.getTexture(1);\n if (rightDepthTexture) {\n this.occlusionPass!.setDepthTexture(\n rightDepthTexture, this.rawValueToMeters, 1,\n (this.gpuDepthData[1] as unknown as {depthNear: number} | undefined)\n ?.depthNear);\n }\n const xrIsPresenting = this.renderer.xr.isPresenting;\n this.renderer.xr.isPresenting = false;\n this.occlusionPass!.render(this.renderer, undefined, undefined, 0);\n this.renderer.xr.isPresenting = xrIsPresenting;\n for (const shader of this.occludableShaders) {\n this.occlusionPass!.updateOcclusionMapUniforms(\n shader.uniforms, this.renderer);\n }\n }\n\n debugLog() {\n const arrayBuffer = this.cpuDepthData[0].data;\n const uint8Array = new Uint8Array(arrayBuffer);\n // Convert Uint8Array to a string where each character represents a byte\n const binaryString =\n Array.from(uint8Array, byte => String.fromCharCode(byte)).join('');\n // Convert binary string to base64\n const data_str = btoa(binaryString);\n console.log(data_str);\n }\n\n resumeDepth(client: object) {\n this.depthClientsInitialized = true;\n this.depthClients.add(client);\n }\n\n pauseDepth(client: object) {\n this.depthClientsInitialized = true;\n this.depthClients.delete(client);\n }\n};\n","import * as THREE from 'three';\n\nimport {Depth} from '../depth/Depth';\nimport {clamp} from '../utils/utils';\n\nimport {XRDeviceCamera} from './XRDeviceCamera';\n\nexport const aspectRatios = {\n depth: 1.0,\n RGB: 4 / 3\n};\n\n/**\n * Parameters for RGB to depth UV mapping (manually calibrated for aspect\n * ratios. For RGB and depth, 4:3 and 1:1, respectively.\n */\nexport const rgbToDepthParams = {\n scale: 1,\n scaleX: 0.75,\n scaleY: 0.63,\n translateU: 0.2,\n translateV: -0.02,\n k1: -0.046,\n k2: 0,\n k3: 0,\n p1: 0,\n p2: 0,\n xc: 0,\n yc: 0,\n};\n\n/**\n * Maps a UV coordinate from a RGB space to a destination depth space,\n * applying Brown-Conrady distortion and affine transformations based on\n * aspect ratios. If the simulator camera is used, no transformation is applied.\n *\n * @param rgbUv - The RGB UV coordinate, e.g., \\{ u: 0.5, v: 0.5 \\}.\n * @param xrDeviceCamera - The device camera instance.\n * @returns The transformed UV coordinate in the depth image space, or null if\n * inputs are invalid.\n */\nexport function transformRgbToDepthUv(\n rgbUv: {u: number, v: number}, xrDeviceCamera?: XRDeviceCamera) {\n if (xrDeviceCamera?.simulatorCamera) {\n // The simulator camera crops the viewport image to match its aspect ratio,\n // while the depth map covers the entire viewport, so we adjust for this.\n const viewportAspect = window.innerWidth / window.innerHeight;\n const cameraAspect = xrDeviceCamera.simulatorCamera.width /\n xrDeviceCamera.simulatorCamera.height;\n let {u, v} = rgbUv;\n\n if (viewportAspect > cameraAspect) {\n // The camera image is a centered vertical slice of the full render.\n const relativeWidth = cameraAspect / viewportAspect;\n u = u * relativeWidth + (1.0 - relativeWidth) / 2.0;\n } else {\n // The camera image is a centered horizontal slice of the full render.\n const relativeHeight = viewportAspect / cameraAspect;\n v = v * relativeHeight + (1.0 - relativeHeight) / 2.0;\n }\n return {u, v: 1.0 - v};\n }\n\n if (!aspectRatios || !aspectRatios.depth || !aspectRatios.RGB) {\n console.error('Invalid aspect ratios provided.');\n return null;\n }\n\n // Determine the relative scaling required to fit the overlay within the base\n let relativeScaleX, relativeScaleY;\n if (aspectRatios.depth > aspectRatios.RGB) {\n // Base is wider than overlay (\"letterboxing\")\n relativeScaleY = 1.0;\n relativeScaleX = aspectRatios.RGB / aspectRatios.depth;\n } else {\n // Base is narrower than overlay (\"pillarboxing\")\n relativeScaleX = 1.0;\n relativeScaleY = aspectRatios.depth / aspectRatios.RGB;\n }\n\n // Convert input source UV [0, 1] to a normalized coordinate space [-0.5, 0.5]\n const u_norm = rgbUv.u - 0.5;\n const v_norm = rgbUv.v - 0.5;\n\n // Apply the FORWARD Brown-Conrady distortion model\n const u_centered = u_norm - rgbToDepthParams.xc;\n const v_centered = v_norm - rgbToDepthParams.yc;\n const r2 = u_centered * u_centered + v_centered * v_centered;\n const radial = 1 + rgbToDepthParams.k1 * r2 + rgbToDepthParams.k2 * r2 * r2 +\n rgbToDepthParams.k3 * r2 * r2 * r2;\n const tanX = 2 * rgbToDepthParams.p1 * u_centered * v_centered +\n rgbToDepthParams.p2 * (r2 + 2 * u_centered * u_centered);\n const tanY = rgbToDepthParams.p1 * (r2 + 2 * v_centered * v_centered) +\n 2 * rgbToDepthParams.p2 * u_centered * v_centered;\n const u_distorted = u_centered * radial + tanX + rgbToDepthParams.xc;\n const v_distorted = v_centered * radial + tanY + rgbToDepthParams.yc;\n\n // Apply initial aspect ratio scaling and translation\n const u_fitted = u_distorted * relativeScaleX + rgbToDepthParams.translateU;\n const v_fitted = v_distorted * relativeScaleY + rgbToDepthParams.translateV;\n\n // Apply the final user-controlled scaling (zoom and stretch)\n const finalNormX =\n u_fitted * rgbToDepthParams.scale * rgbToDepthParams.scaleX;\n const finalNormY =\n v_fitted * rgbToDepthParams.scale * rgbToDepthParams.scaleY;\n\n // Convert the final normalized coordinate back to a UV coordinate [0, 1]\n const finalU = finalNormX + 0.5;\n const finalV = finalNormY + 0.5;\n\n return {u: finalU, v: 1.0 - finalV};\n}\n\n/**\n * Retrieves the world space position of a given RGB UV coordinate.\n * Note: it is essential that the coordinates, depth array, and projection\n * matrix all correspond to the same view ID (e.g., 0 for left). It is also\n * advised that all of these are obtained at the same time.\n *\n * @param rgbUv - The RGB UV coordinate, e.g., \\{ u: 0.5, v: 0.5 \\}.\n * @param depthArray - Array containing depth data.\n * @param viewProjectionMatrix - XRView object with corresponding\n * projection matrix.\n * @param matrixWorld - Matrix for view-to-world translation.\n * @param xrDeviceCamera - The device camera instance.\n * @param xrDepth - The SDK's Depth module.\n * @returns Vertex at (u, v) in world space.\n */\nexport function transformRgbUvToWorld(\n rgbUv: {u: number, v: number},\n depthArray: number[]|Uint16Array|Float32Array,\n viewProjectionMatrix: THREE.Matrix4, matrixWorld: THREE.Matrix4,\n xrDeviceCamera?: XRDeviceCamera, xrDepth = Depth.instance) {\n if (!depthArray || !viewProjectionMatrix || !matrixWorld || !xrDepth)\n return null;\n const depthUV = transformRgbToDepthUv(rgbUv, xrDeviceCamera);\n if (!depthUV) {\n return null;\n }\n\n const {u: depthU, v: depthV} = depthUV;\n const depthX =\n Math.round(clamp(depthU * xrDepth.width, 0, xrDepth.width - 1));\n\n // Invert depthV for array access, as image arrays are indexed from top-left.\n const depthY =\n Math.round(clamp((1.0 - depthV) * xrDepth.height, 0, xrDepth.height - 1));\n const rawDepthValue = depthArray[depthY * xrDepth.width + depthX];\n const depthInMeters = xrDepth.rawValueToMeters * rawDepthValue;\n\n // Convert UV to normalized device coordinates and create a point on the near\n // plane.\n const viewSpacePosition =\n new THREE.Vector3(2.0 * (depthU - 0.5), 2.0 * (depthV - 0.5), -1);\n\n const viewProjectionMatrixInverse = viewProjectionMatrix.clone().invert();\n\n // Unproject the point from clip space to view space and scale it along the\n // ray from the camera to the correct depth. Camera looks down -Z axis.\n viewSpacePosition.applyMatrix4(viewProjectionMatrixInverse);\n viewSpacePosition.multiplyScalar(-depthInMeters / viewSpacePosition.z);\n\n const worldPosition = viewSpacePosition.clone().applyMatrix4(matrixWorld);\n return worldPosition;\n}\n\n/**\n * Asynchronously crops a base64 encoded image using a THREE.Box2 bounding box.\n * This function creates an in-memory image, draws a specified portion of it to\n * a canvas, and then returns the canvas content as a new base64 string.\n * @param base64Image - The base64 string of the source image. Can be a raw\n * string or a full data URI.\n * @param boundingBox - The bounding box with relative coordinates (0-1) for\n * cropping.\n * @returns A promise that resolves with the base64 string of the cropped image.\n */\nexport async function cropImage(base64Image: string, boundingBox: THREE.Box2) {\n if (!base64Image) {\n throw new Error('No image data provided for cropping.');\n }\n\n const img = new Image();\n await new Promise((resolve, reject) => {\n img.onload = resolve;\n img.onerror = (err) => {\n console.error('Error loading image for cropping:', err);\n reject(new Error('Failed to load image for cropping.'));\n };\n img.src = base64Image.startsWith('data:image') ?\n base64Image :\n `data:image/png;base64,${base64Image}`;\n });\n\n const canvas = document.createElement('canvas');\n const ctx = canvas.getContext('2d')!;\n\n // Create a unit box and find the intersection to clamp coordinates.\n const unitBox =\n new THREE.Box2(new THREE.Vector2(0, 0), new THREE.Vector2(1, 1));\n const clampedBox = boundingBox.clone().intersect(unitBox);\n\n const cropSize = new THREE.Vector2();\n clampedBox.getSize(cropSize);\n\n // If the resulting crop area has no size, return an empty image.\n if (cropSize.x === 0 || cropSize.y === 0) {\n return 'data:image/png;base64,';\n }\n\n // Calculate absolute pixel values from relative coordinates.\n const sourceX = img.width * clampedBox.min.x;\n const sourceY = img.height * clampedBox.min.y;\n const sourceWidth = img.width * cropSize.x;\n const sourceHeight = img.height * cropSize.y;\n\n // Set canvas size to the cropped image size.\n canvas.width = sourceWidth;\n canvas.height = sourceHeight;\n\n // Draw the cropped portion of the source image onto the canvas.\n ctx.drawImage(\n img, sourceX, sourceY, sourceWidth, sourceHeight, // Source rectangle\n 0, 0, sourceWidth, sourceHeight // Destination rectangle\n );\n\n return canvas.toDataURL('image/png');\n}\n","import * as THREE from 'three';\n\nimport {Script} from '../core/Script';\n\n/**\n * Enum for video stream states.\n */\nexport enum StreamState {\n IDLE = 'idle',\n INITIALIZING = 'initializing',\n STREAMING = 'streaming',\n ERROR = 'error',\n NO_DEVICES_FOUND = 'no_devices_found',\n}\n\nexport type VideoStreamDetails = {\n force?: boolean;\n error?: Error;\n}\n\nexport interface VideoStreamEventMap<T> extends THREE.Object3DEventMap {\n statechange: {state: StreamState, details?: T};\n}\n\nexport type VideoStreamGetSnapshotOptions = {\n /** The target width, defaults to the video width. */\n width?: number;\n /** The target height, defaults to the video height. */\n height?: number;\n /** The output format, defaults to 'texture'. */\n outputFormat?: 'texture' | 'base64' | 'imageData';\n /** The MIME type for base64 output. */\n mimeType?: string;\n /** The quality for base64 output. */\n quality?: number;\n};\n\nexport type VideoStreamOptions = {\n /** Hint for performance optimization for frequent captures. */\n willCaptureFrequently?: boolean;\n};\n\n/**\n * The base class for handling video streams (from camera or file), managing\n * the underlying <video> element, streaming state, and snapshot logic.\n */\nexport class VideoStream<T extends VideoStreamDetails =\n VideoStreamDetails> extends\n Script<VideoStreamEventMap<T>> {\n loaded = false;\n width?: number;\n height?: number;\n aspectRatio?: number;\n texture: THREE.VideoTexture;\n state = StreamState.IDLE;\n\n protected stream_: MediaStream|null = null;\n protected video_ = document.createElement('video');\n\n private willCaptureFrequently_: boolean;\n private frozenTexture_: THREE.Texture|null = null;\n private canvas_: HTMLCanvasElement|null = null;\n private context_: CanvasRenderingContext2D|null = null;\n\n\n /**\n * @param options - The configuration options.\n */\n constructor({willCaptureFrequently = false}: VideoStreamOptions = {}) {\n super();\n\n this.willCaptureFrequently_ = willCaptureFrequently;\n this.video_.autoplay = true;\n this.video_.muted = true;\n this.video_.playsInline = true;\n\n this.texture = new THREE.VideoTexture(this.video_);\n this.texture.colorSpace = THREE.SRGBColorSpace;\n this.texture.minFilter = THREE.LinearFilter;\n this.texture.magFilter = THREE.LinearFilter;\n }\n\n /**\n * Sets the stream's state and dispatches a 'statechange' event.\n * @param state - The new state.\n * @param details - Additional data for the event payload.\n */\n protected setState_(state: StreamState, details: VideoStreamDetails|T = {}) {\n if (this.state === state && !details.force) return;\n this.state = state;\n this.dispatchEvent({type: 'statechange', state: this.state, ...details});\n console.debug(\n `VideoStream state changed to ${state} with details:`, details);\n }\n\n /**\n * Processes video metadata, sets dimensions, and resolves a promise.\n * @param resolve - The resolve function of the wrapping Promise.\n * @param reject - The reject function of the wrapping Promise.\n * @param allowRetry - Whether to allow a retry attempt on failure.\n */\n protected handleVideoStreamLoadedMetadata(\n resolve: () => void, reject: (_: Error) => void, allowRetry = false) {\n try {\n if (this.video_.videoWidth > 0 && this.video_.videoHeight > 0) {\n this.width = this.video_.videoWidth;\n this.height = this.video_.videoHeight;\n this.aspectRatio = this.width / this.height;\n this.loaded = true;\n resolve();\n } else if (allowRetry) {\n setTimeout(() => {\n this.handleVideoStreamLoadedMetadata(resolve, reject, false);\n }, 500);\n } else {\n const error = new Error('Failed to get valid video dimensions.');\n this.setState_(StreamState.ERROR, {error});\n reject(error);\n }\n } catch (error) {\n if (error instanceof Error) {\n this.setState_(StreamState.ERROR, {error});\n reject(error);\n }\n }\n }\n\n /**\n * Captures the current video frame.\n * @param options - The options for the snapshot.\n * @returns The captured data.\n */\n getSnapshot({\n width = this.width,\n height = this.height,\n outputFormat = 'texture',\n mimeType = 'image/jpeg',\n quality = 0.9\n }: VideoStreamGetSnapshotOptions = {}) {\n if (!this.loaded || !width || !height ||\n this.video_.readyState < this.video_.HAVE_CURRENT_DATA) {\n return null;\n }\n\n if (width > this.width! || height > this.height!) {\n console.warn(`The requested snapshot width (${width}px x ${\n height}px) is larger than the source video width (${this.width}px x ${\n this.height}px). The snapshot will be upscaled.`);\n }\n\n try {\n // Re-initialize canvas only if dimensions have changed.\n if (!this.canvas_ || this.canvas_.width !== width ||\n this.canvas_.height !== height) {\n this.canvas_ = document.createElement('canvas');\n this.canvas_.width = width;\n this.canvas_.height = height;\n this.context_ =\n this.canvas_.getContext(\n '2d', {willCaptureFrequently: this.willCaptureFrequently_}) as\n CanvasRenderingContext2D;\n }\n\n this.context_!.drawImage(this.video_, 0, 0, width, height);\n switch (outputFormat) {\n case 'imageData':\n return this.context_!.getImageData(0, 0, width, height);\n case 'base64':\n return this.canvas_.toDataURL(mimeType, quality);\n case 'texture':\n default: {\n const frozenTexture = new THREE.Texture(this.canvas_);\n frozenTexture.needsUpdate = true;\n frozenTexture.colorSpace = THREE.SRGBColorSpace;\n this.frozenTexture_ = frozenTexture;\n return this.frozenTexture_;\n }\n }\n } catch (error) {\n console.error('Error capturing snapshot:', error);\n return null;\n }\n }\n\n /**\n * Stops the current video stream tracks.\n */\n protected stop_() {\n if (this.stream_) {\n this.stream_.getTracks().forEach(track => track.stop());\n this.stream_ = null;\n }\n if (this.video_.srcObject) {\n this.video_.srcObject = null;\n }\n if (this.video_.src && this.video_.src.startsWith('blob:')) {\n URL.revokeObjectURL(this.video_.src);\n }\n this.video_.src = '';\n this.loaded = false;\n this.setState_(StreamState.IDLE);\n }\n\n /**\n * Disposes of all resources used by this stream.\n */\n override dispose() {\n this.stop_();\n this.texture?.dispose();\n this.frozenTexture_?.dispose();\n this.canvas_ = null;\n this.context_ = null;\n super.dispose();\n }\n}\n","import {SimulatorCamera} from '../simulator/SimulatorCamera';\nimport {SimulatorMediaDeviceInfo} from '../simulator/SimulatorMediaDeviceInfo';\nimport {StreamState, VideoStream, VideoStreamDetails} from '../video/VideoStream';\n\nimport {DeviceCameraOptions} from './CameraOptions';\n\nexport type MediaOrSimulatorMediaDeviceInfo =\n MediaDeviceInfo|SimulatorMediaDeviceInfo;\n\ntype XRDeviceCameraDetails = VideoStreamDetails&{\n width?: number;\n height?: number;\n aspectRatio?: number;\n device?: MediaOrSimulatorMediaDeviceInfo;\n}\n\n/**\n * Handles video capture from a device camera, manages the device list,\n * and reports its state using VideoStream's event model.\n */\nexport class XRDeviceCamera extends VideoStream<XRDeviceCameraDetails> {\n simulatorCamera?: SimulatorCamera;\n protected videoConstraints_: MediaTrackConstraints;\n private isInitializing_ = false;\n private availableDevices_: MediaOrSimulatorMediaDeviceInfo[] = [];\n private currentDeviceIndex_ = -1;\n private currentTrackSettings_?: MediaTrackSettings;\n\n /**\n * @param options - The configuration options.\n */\n constructor({\n videoConstraints = {facingMode: 'environment'},\n willCaptureFrequently = false\n }: Partial<DeviceCameraOptions> = {}) {\n super({willCaptureFrequently});\n this.videoConstraints_ = {...videoConstraints};\n }\n\n /**\n * Retrieves the list of available video input devices.\n * @returns A promise that resolves with an\n * array of video devices.\n */\n async getAvailableVideoDevices() {\n if (!navigator.mediaDevices?.enumerateDevices) {\n console.warn(\n 'navigator.mediaDevices.enumerateDevices() is not supported.');\n return [];\n }\n const devices: MediaOrSimulatorMediaDeviceInfo[] =\n [...await navigator.mediaDevices.enumerateDevices()];\n if (this.simulatorCamera) {\n const simulatorDevices = await this.simulatorCamera.enumerateDevices();\n devices.push(...simulatorDevices);\n }\n return devices.filter(device => device.kind === 'videoinput');\n }\n\n /**\n * Initializes the camera based on the initial constraints.\n */\n async init() {\n this.setState_(StreamState.INITIALIZING);\n try {\n this.availableDevices_ = await this.getAvailableVideoDevices();\n\n if (this.availableDevices_.length > 0) {\n await this.initStream_();\n } else {\n this.setState_(StreamState.NO_DEVICES_FOUND);\n console.warn('No video devices found.');\n }\n } catch (error) {\n this.setState_(StreamState.ERROR, {error: error as Error});\n console.error('Error initializing XRDeviceCamera:', error);\n throw error;\n }\n }\n\n /**\n * Initializes the media stream from the user's camera. After the stream\n * starts, it updates the current device index based on the stream's active\n * track.\n */\n protected async initStream_() {\n if (this.isInitializing_) return;\n this.isInitializing_ = true;\n this.setState_(StreamState.INITIALIZING);\n\n // Reset state for the new stream\n this.currentTrackSettings_ = undefined;\n this.currentDeviceIndex_ = -1;\n try {\n console.debug(\n 'Requesting media stream with constraints:', this.videoConstraints_);\n let stream = null;\n\n const deviceIdConstraint = this.videoConstraints_.deviceId;\n const targetDeviceId = typeof deviceIdConstraint === 'string' ?\n deviceIdConstraint :\n Array.isArray(deviceIdConstraint) ? deviceIdConstraint[0] :\n deviceIdConstraint?.exact;\n\n const useSimulatorCamera = !!this.simulatorCamera &&\n ((targetDeviceId &&\n this.availableDevices_.find(d => d.deviceId === targetDeviceId)\n ?.groupId === 'simulator') ||\n (!targetDeviceId &&\n this.videoConstraints_.facingMode === 'environment'));\n\n if (useSimulatorCamera) {\n stream = this.simulatorCamera!.getMedia(this.videoConstraints_);\n if (!stream) {\n throw new Error('Simulator camera failed to provide a media stream.');\n }\n } else {\n // Otherwise, request the stream from the browser.\n stream = await navigator.mediaDevices.getUserMedia(\n {video: this.videoConstraints_});\n }\n\n const videoTracks = stream?.getVideoTracks() || [];\n\n if (!videoTracks.length) {\n throw new Error('MediaStream has no video tracks.');\n }\n\n // After the stream is active, we can get the ID of the track\n const activeTrack = videoTracks[0];\n this.currentTrackSettings_ = activeTrack.getSettings();\n console.debug('Active track settings:', this.currentTrackSettings_);\n\n if (this.currentTrackSettings_.deviceId) {\n this.currentDeviceIndex_ = this.availableDevices_.findIndex(\n device => device.deviceId === this.currentTrackSettings_!.deviceId);\n } else {\n console.warn('Stream started without deviceId as it was unavailable');\n }\n\n this.stop_(); // Stop any previous stream before starting new one\n this.stream_ = stream;\n this.video_.srcObject = stream;\n this.video_.src = ''; // Required for some browsers to reset the src\n\n await new Promise<void>((resolve, reject) => {\n this.video_.onloadedmetadata = () => {\n this.handleVideoStreamLoadedMetadata(resolve, reject, true);\n };\n this.video_.onerror = () => {\n const error = new Error('Error playing camera stream.');\n this.setState_(StreamState.ERROR, {error});\n reject(error);\n };\n this.video_.play();\n });\n\n // Once the stream is loaded and dimensions are known, set the final state\n const details = {\n width: this.width,\n height: this.height,\n aspectRatio: this.aspectRatio,\n device: this.getCurrentDevice(),\n facingMode: this.currentTrackSettings_.facingMode,\n trackSettings: this.currentTrackSettings_,\n };\n this.setState_(StreamState.STREAMING, details);\n } catch (error) {\n this.setState_(StreamState.ERROR, {error: error as Error});\n throw error;\n } finally {\n this.isInitializing_ = false;\n }\n }\n\n /**\n * Sets the active camera by its device ID. Removes potentially conflicting\n * constraints such as facingMode.\n * @param deviceId - Device id.\n */\n async setDeviceId(deviceId: string) {\n const newIndex = this.availableDevices_.findIndex(\n device => device.deviceId === deviceId);\n if (newIndex === -1) {\n throw new Error(`Device with ID ${deviceId} not found.`);\n }\n if (newIndex === this.currentDeviceIndex_) {\n console.log(`Device ${deviceId} is already active.`);\n return;\n }\n delete this.videoConstraints_.facingMode;\n this.videoConstraints_.deviceId = {exact: deviceId};\n await this.initStream_();\n }\n\n /**\n * Sets the active camera by its facing mode ('user' or 'environment').\n * @param facingMode - facing mode\n */\n async setFacingMode(facingMode: VideoFacingModeEnum) {\n delete this.videoConstraints_.deviceId;\n this.videoConstraints_.facingMode = facingMode;\n this.currentDeviceIndex_ = -1;\n await this.initStream_();\n }\n\n /**\n * Gets the list of enumerated video devices.\n */\n getAvailableDevices() {\n return this.availableDevices_;\n }\n\n /**\n * Gets the currently active device info, if available.\n */\n getCurrentDevice() {\n if (this.currentDeviceIndex_ === -1 || !this.availableDevices_.length) {\n return undefined;\n }\n return this.availableDevices_[this.currentDeviceIndex_];\n }\n\n /**\n * Gets the settings of the currently active video track.\n */\n getCurrentTrackSettings() {\n return this.currentTrackSettings_;\n }\n\n /**\n * Gets the index of the currently active device.\n */\n getCurrentDeviceIndex() {\n return this.currentDeviceIndex_;\n }\n\n registerSimulatorCamera(simulatorCamera: SimulatorCamera) {\n this.simulatorCamera = simulatorCamera;\n this.init();\n }\n}\n","import type {Constructor} from '../../utils/Types';\n\nexport class Registry {\n private instances = new Map<Constructor, object>();\n\n /**\n * Registers an new instanceof a given type.\n * If an existing instance of the same type is already registered, it will be\n * overwritten.\n * @param instance - The instance to register.\n * @param type - Type to register the instance as. Will default to\n * `instance.constructor` if not defined.\n */\n register<T extends object>(instance: T, type?: Constructor<T>) {\n const registrationType = type ?? instance.constructor as Constructor<T>;\n if (instance instanceof registrationType) {\n this.instances.set(registrationType, instance);\n } else {\n throw new Error(`Instance of type '${\n instance.constructor\n .name}' is not an instance of the registration type '${\n registrationType.name}'.`);\n }\n }\n\n /**\n * Gets an existing instance of a registered type.\n * @param type - The constructor function of the type to retrieve.\n * @returns The instance of the requested type.\n */\n get<T extends object>(type: Constructor<T>): T|undefined {\n return this.instances.get(type) as T | undefined;\n }\n\n /**\n * Gets an existing instance of a registered type, or creates a new one if it\n * doesn't exist.\n * @param type - The constructor function of the type to retrieve.\n * @param factory - A function that creates a new instance of the type if it\n * doesn't already exist.\n * @returns The instance of the requested type.\n */\n getOrCreate<T extends object>(type: Constructor<T>, factory: () => T): T {\n let instance = this.get(type);\n if (instance === undefined) {\n instance = factory();\n if (!(instance instanceof type)) {\n throw new Error(`Factory for type ${\n type.name} returned an incompatible instance of type ${\n (instance.constructor as Constructor).name}.`);\n }\n // Register the new instance with the requested type.\n this.register(instance, type);\n }\n return instance;\n }\n\n /**\n * Unregisters an instance of a given type.\n * @param type - The type to unregister.\n */\n unregister(type: Constructor): void {\n this.instances.delete(type);\n }\n}\n","import * as THREE from 'three';\nimport {FullScreenQuad} from 'three/addons/postprocessing/Pass.js';\n\nimport {XRDeviceCamera} from '../../camera/XRDeviceCamera.js';\n\n// Use a small canvas since a full size canvas can consume a lot of memory and\n// cause toDataUrl to be slow.\nconst DEFAULT_CANVAS_WIDTH = 640;\n\nfunction flipBufferVertically(\n buffer: Uint8Array, width: number, height: number) {\n const bytesPerRow = width * 4;\n const tempRow = new Uint8Array(bytesPerRow);\n for (let y = 0; y < height / 2; y++) {\n const topRowY = y;\n const bottomRowY = height - 1 - y;\n const topRowOffset = topRowY * bytesPerRow;\n const bottomRowOffset = bottomRowY * bytesPerRow;\n tempRow.set(buffer.subarray(topRowOffset, topRowOffset + bytesPerRow));\n buffer.set(\n buffer.subarray(bottomRowOffset, bottomRowOffset + bytesPerRow),\n topRowOffset);\n buffer.set(tempRow, bottomRowOffset);\n }\n}\n\nclass PendingScreenshotRequest {\n constructor(\n public resolve: (value: string) => void,\n public reject: (reason?: Error) => void,\n public overlayOnCamera: boolean) {}\n}\n\nexport class ScreenshotSynthesizer {\n private pendingScreenshotRequests: PendingScreenshotRequest[] = [];\n private virtualCanvas?: HTMLCanvasElement;\n private virtualBuffer = new Uint8Array();\n // Smaller resolution render target than the main render target.\n private virtualRenderTarget?: THREE.WebGLRenderTarget;\n private virtualRealCanvas?: HTMLCanvasElement;\n private virtualRealBuffer = new Uint8Array();\n private virtualRealRenderTarget?: THREE.WebGLRenderTarget;\n private fullScreenQuad?: FullScreenQuad;\n private renderTargetWidth = DEFAULT_CANVAS_WIDTH;\n\n async onAfterRender(\n renderer: THREE.WebGLRenderer, renderSceneFn: () => void,\n deviceCamera?: XRDeviceCamera) {\n if (this.pendingScreenshotRequests.length == 0) {\n return;\n }\n\n const renderTarget = renderer.getRenderTarget();\n if (renderTarget == null) {\n throw new Error('Expecting render target');\n }\n const haveVirtualOnlyRequests = this.pendingScreenshotRequests.every(\n (request) => !request.overlayOnCamera);\n if (haveVirtualOnlyRequests) {\n this.createVirtualImageDataURL(renderer, renderSceneFn)\n .then((virtualImageDataUrl) => {\n this.resolveVirtualOnlyRequests(virtualImageDataUrl);\n });\n }\n\n const haveVirtualAndRealReqeusts = this.pendingScreenshotRequests.some(\n (request) => request.overlayOnCamera);\n if (haveVirtualAndRealReqeusts && deviceCamera) {\n this.createVirtualRealImageDataURL(renderer, renderSceneFn, deviceCamera)\n .then((virtualRealImageDataUrl) => {\n if (virtualRealImageDataUrl) {\n this.resolveVirtualRealRequests(virtualRealImageDataUrl);\n }\n });\n } else if (haveVirtualAndRealReqeusts) {\n throw new Error('No device camera provided');\n }\n }\n\n private async createVirtualImageDataURL(\n renderer: THREE.WebGLRenderer, renderSceneFn: () => void) {\n const mainRenderTarget = renderer.getRenderTarget()!;\n const isRenderingStereo =\n renderer.xr.isPresenting && renderer.xr.getCamera().cameras.length == 2;\n const mainRenderTargetSingleViewWidth =\n isRenderingStereo ? mainRenderTarget.width / 2 : mainRenderTarget.width;\n const scaledHeight = Math.round(\n mainRenderTarget.height *\n (this.renderTargetWidth / mainRenderTargetSingleViewWidth));\n if (!this.virtualRenderTarget ||\n this.virtualRenderTarget.width != this.renderTargetWidth) {\n this.virtualRenderTarget?.dispose();\n this.virtualRenderTarget = new THREE.WebGLRenderTarget(\n this.renderTargetWidth, scaledHeight,\n {colorSpace: THREE.SRGBColorSpace});\n }\n const xrIsPresenting = renderer.xr.isPresenting;\n renderer.xr.isPresenting = false;\n const virtualRenderTarget = this.virtualRenderTarget;\n renderer.setRenderTarget(virtualRenderTarget);\n renderer.clearColor();\n renderer.clearDepth();\n renderSceneFn();\n renderer.setRenderTarget(mainRenderTarget);\n renderer.xr.isPresenting = xrIsPresenting;\n\n const expectedBufferLength =\n virtualRenderTarget.width * virtualRenderTarget.height * 4;\n if (this.virtualBuffer.length != expectedBufferLength) {\n this.virtualBuffer = new Uint8Array(expectedBufferLength);\n }\n const buffer = this.virtualBuffer;\n await renderer.readRenderTargetPixelsAsync(\n virtualRenderTarget, 0, 0, virtualRenderTarget.width,\n virtualRenderTarget.height, buffer);\n\n flipBufferVertically(\n buffer, virtualRenderTarget.width, virtualRenderTarget.height);\n const canvas = this.virtualCanvas ||\n (this.virtualCanvas = document.createElement('canvas'));\n canvas.width = virtualRenderTarget.width;\n canvas.height = virtualRenderTarget.height;\n const context = canvas.getContext('2d');\n if (!context) {\n throw new Error('Failed to get 2D context');\n }\n const imageData = new ImageData(\n new Uint8ClampedArray(buffer), virtualRenderTarget.width,\n virtualRenderTarget.height);\n context.putImageData(imageData, 0, 0);\n return canvas.toDataURL();\n }\n\n private resolveVirtualOnlyRequests(virtualImageDataUrl: string) {\n let remainingRequests = 0;\n for (let i = 0; i < this.pendingScreenshotRequests.length; i++) {\n const request = this.pendingScreenshotRequests[i];\n if (!request.overlayOnCamera) {\n request.resolve(virtualImageDataUrl);\n } else {\n this.pendingScreenshotRequests[remainingRequests++] = request;\n }\n }\n this.pendingScreenshotRequests.length = remainingRequests;\n }\n\n private async createVirtualRealImageDataURL(\n renderer: THREE.WebGLRenderer, renderSceneFn: () => void,\n deviceCamera: XRDeviceCamera) {\n if (!deviceCamera.loaded) {\n console.debug('Waiting for device camera to be loaded');\n return null;\n }\n const mainRenderTarget = renderer.getRenderTarget()!;\n const isRenderingStereo =\n renderer.xr.isPresenting && renderer.xr.getCamera().cameras.length == 2;\n const mainRenderTargetSingleViewWidth =\n isRenderingStereo ? mainRenderTarget.width / 2 : mainRenderTarget.width;\n const scaledHeight = Math.round(\n mainRenderTarget.height *\n (this.renderTargetWidth / mainRenderTargetSingleViewWidth));\n if (!this.virtualRealRenderTarget ||\n this.virtualRealRenderTarget.height != scaledHeight) {\n this.virtualRealRenderTarget?.dispose();\n this.virtualRealRenderTarget = new THREE.WebGLRenderTarget(\n this.renderTargetWidth, scaledHeight,\n {colorSpace: THREE.SRGBColorSpace});\n }\n\n const renderTarget = this.virtualRealRenderTarget;\n renderer.setRenderTarget(renderTarget);\n const xrIsPresenting = renderer.xr.isPresenting;\n renderer.xr.isPresenting = false;\n const quad = this.getFullScreenQuad();\n (quad.material as THREE.MeshBasicMaterial).map = deviceCamera.texture;\n quad.render(renderer);\n renderSceneFn();\n renderer.xr.isPresenting = xrIsPresenting;\n renderer.setRenderTarget(mainRenderTarget);\n\n if (this.virtualRealBuffer.length !=\n renderTarget.width * renderTarget.height * 4) {\n this.virtualRealBuffer =\n new Uint8Array(renderTarget.width * renderTarget.height * 4);\n }\n const buffer = this.virtualRealBuffer;\n await renderer.readRenderTargetPixelsAsync(\n renderTarget, 0, 0, renderTarget.width, renderTarget.height, buffer);\n\n flipBufferVertically(buffer, renderTarget.width, renderTarget.height);\n const canvas = this.virtualRealCanvas ||\n (this.virtualRealCanvas = document.createElement('canvas'));\n canvas.width = renderTarget.width;\n canvas.height = renderTarget.height;\n const context = canvas.getContext('2d');\n if (!context) {\n throw new Error('Failed to get 2D context');\n }\n const imageData = new ImageData(\n new Uint8ClampedArray(buffer), renderTarget.width, renderTarget.height);\n context.putImageData(imageData, 0, 0);\n return canvas.toDataURL();\n }\n\n private resolveVirtualRealRequests(virtualRealImageDataUrl: string) {\n let remainingRequests = 0;\n for (let i = 0; i < this.pendingScreenshotRequests.length; i++) {\n const request = this.pendingScreenshotRequests[i];\n if (request.overlayOnCamera) {\n request.resolve(virtualRealImageDataUrl);\n } else {\n this.pendingScreenshotRequests[remainingRequests++] = request;\n }\n }\n this.pendingScreenshotRequests.length = remainingRequests;\n }\n\n private getFullScreenQuad() {\n if (!this.fullScreenQuad) {\n this.fullScreenQuad =\n new FullScreenQuad(new THREE.MeshBasicMaterial({transparent: true}));\n }\n return this.fullScreenQuad;\n }\n\n /**\n * Requests a screenshot from the scene as a DataURL.\n * @param overlayOnCamera - If true, overlays the image on a camera image\n * without any projection or aspect ratio correction.\n * @returns Promise which returns the screenshot.\n */\n async getScreenshot(overlayOnCamera = false) {\n return await new Promise((resolve, reject) => {\n this.pendingScreenshotRequests.push(\n new PendingScreenshotRequest(resolve, reject, overlayOnCamera));\n });\n }\n}\n","import * as THREE from 'three';\n\nimport {KeyEvent, Script, SelectEvent} from '../Script';\n\ntype MaybeScript = THREE.Object3D&{isXRScript?: boolean};\n\nexport class ScriptsManager {\n /** The set of all currently initialized scripts. */\n scripts = new Set<Script>();\n\n callSelectStartBound = this.callSelectStart.bind(this);\n callSelectEndBound = this.callSelectEnd.bind(this);\n callSelectBound = this.callSelect.bind(this);\n callSqueezeStartBound = this.callSqueezeStart.bind(this);\n callSqueezeEndBound = this.callSqueezeEnd.bind(this);\n callSqueezeBound = this.callSqueeze.bind(this);\n callKeyDownBound = this.callKeyDown.bind(this);\n callKeyUpBound = this.callKeyUp.bind(this);\n\n /** The set of scripts currently being initialized. */\n private initializingScripts = new Set<Script>();\n\n constructor(private initScriptFunction: (script: Script) => Promise<void>) {}\n\n /**\n * Initializes a script and adds it to the set of scripts which will receive\n * callbacks. This will be called automatically by Core when a script is found\n * in the scene but can also be called manually.\n * @param script - The script to initialize\n * @returns A promise which resolves when the script is initialized.\n */\n async initScript(script: Script) {\n if (this.scripts.has(script) || this.initializingScripts.has(script)) {\n return;\n }\n this.initializingScripts.add(script);\n await this.initScriptFunction(script);\n this.scripts.add(script);\n this.initializingScripts.delete(script);\n }\n\n /**\n * Uninitializes a script calling dispose and removes it from the set of\n * scripts which will receive callbacks.\n * @param script - The script to uninitialize.\n */\n uninitScript(script: Script) {\n if (!this.scripts.has(script)) {\n return;\n }\n script.dispose();\n this.scripts.delete(script);\n this.initializingScripts.delete(script);\n }\n\n /**\n * Finds all scripts in the scene and initializes them or uninitailizes them.\n * Returns a promise which resolves when all new scripts are finished\n * initalizing.\n * @param scene - The main scene which is used to find scripts.\n */\n async syncScriptsWithScene(scene: THREE.Scene) {\n const seenScripts = new Set<Script>();\n const promises: Promise<void>[] = [];\n scene.traverse((obj) => {\n if ((obj as MaybeScript).isXRScript) {\n const script = obj as Script;\n promises.push(this.initScript(script));\n seenScripts.add(script);\n }\n });\n await Promise.allSettled(promises);\n // Delete missing scripts.\n for (const script of this.scripts) {\n if (!seenScripts.has(script)) {\n this.uninitScript(script);\n }\n }\n }\n\n callSelectStart(event: SelectEvent) {\n for (const script of this.scripts) {\n script.onSelectStart(event);\n }\n }\n\n callSelectEnd(event: SelectEvent) {\n for (const script of this.scripts) {\n script.onSelectEnd(event);\n }\n }\n\n callSelect(event: SelectEvent) {\n for (const script of this.scripts) {\n script.onSelect(event);\n }\n }\n\n callSqueezeStart(event: SelectEvent) {\n for (const script of this.scripts) {\n script.onSqueezeStart(event);\n }\n }\n\n callSqueezeEnd(event: SelectEvent) {\n for (const script of this.scripts) {\n script.onSqueezeEnd(event);\n }\n }\n\n callSqueeze(event: SelectEvent) {\n for (const script of this.scripts) {\n script.onSqueeze(event);\n }\n }\n\n callKeyDown(event: KeyEvent) {\n for (const script of this.scripts) {\n script.onKeyDown(event);\n }\n }\n\n callKeyUp(event: KeyEvent) {\n for (const script of this.scripts) {\n script.onKeyUp(event);\n }\n }\n\n onXRSessionStarted(session: XRSession) {\n for (const script of this.scripts) {\n script.onXRSessionStarted(session);\n }\n }\n\n onXRSessionEnded() {\n for (const script of this.scripts) {\n script.onXRSessionEnded();\n }\n }\n\n onSimulatorStarted() {\n for (const script of this.scripts) {\n script.onSimulatorStarted();\n }\n }\n}\n","export class WaitFrame {\n private callbacks: (() => void)[] = [];\n\n /**\n * Executes all registered callbacks and clears the list.\n */\n onFrame() {\n this.callbacks.forEach((callback) => {\n try {\n callback();\n } catch (e) {\n console.error(e);\n }\n });\n this.callbacks.length = 0;\n }\n\n /**\n * Wait for the next frame.\n */\n async waitFrame() {\n return new Promise<void>((resolve) => {\n this.callbacks.push(resolve);\n });\n }\n}\n","import * as THREE from 'three';\n\nexport const IMMERSIVE_AR = 'immersive-ar';\nexport const IMMERSIVE_VR = 'immersive-vr';\n\ndeclare global {\n interface XRSystem {\n offerSession?: (\n mode: XRSessionMode,\n sessionInit?: XRSessionInit,\n ) => Promise<XRSession>;\n }\n}\n\n// Event type definitions for clarity\nexport enum WebXRSessionEventType {\n UNSUPPORTED = 'unsupported',\n READY = 'ready',\n SESSION_START = 'sessionstart',\n SESSION_END = 'sessionend',\n}\n\nexport type WebXRSessionManagerEventMap = THREE.Object3DEventMap&{\n [WebXRSessionEventType.UNSUPPORTED]: object;\n [WebXRSessionEventType.READY]: {sessionOptions: XRSessionInit};\n [WebXRSessionEventType.SESSION_START]: {session: XRSession};\n [WebXRSessionEventType.SESSION_END]: object;\n}\n\n/**\n * Manages the WebXR session lifecycle by extending THREE.EventDispatcher\n * to broadcast its state to any listener.\n */\nexport class WebXRSessionManager extends\n THREE.EventDispatcher<WebXRSessionManagerEventMap> {\n public currentSession?: XRSession;\n private sessionOptions?: XRSessionInit;\n private onSessionEndedBound = this.onSessionEndedInternal.bind(this);\n private xrModeSupported?: boolean;\n\n constructor(\n private renderer: THREE.WebGLRenderer,\n private sessionInit: XRSessionInit,\n private mode: XRSessionMode,\n ) {\n super(); // Initialize the EventDispatcher\n }\n\n /**\n * Checks for WebXR support and availability of the requested session mode.\n * This should be called to initialize the manager and trigger the first\n * events.\n */\n public async initialize() {\n if (!('xr' in navigator)) {\n console.warn('WebXR not supported');\n this.xrModeSupported = false;\n this.dispatchEvent({type: WebXRSessionEventType.UNSUPPORTED});\n return;\n }\n\n let modeSupported = false;\n try {\n modeSupported =\n (await navigator.xr!.isSessionSupported(this.mode)) || false;\n } catch (e) {\n console.error('Error getting isSessionSupported', e);\n this.xrModeSupported = false;\n this.dispatchEvent({type: WebXRSessionEventType.UNSUPPORTED});\n return;\n }\n\n if (modeSupported) {\n this.xrModeSupported = true;\n this.sessionOptions = {\n ...this.sessionInit,\n optionalFeatures: [\n 'local-floor',\n ...(this.sessionInit.optionalFeatures || []),\n ],\n };\n\n // Fire the 'ready' event with the sessionOptions in the data payload\n this.dispatchEvent({\n type: WebXRSessionEventType.READY,\n sessionOptions: this.sessionOptions,\n });\n\n // Automatically start session if 'offerSession' is available\n if (navigator.xr!.offerSession !== undefined) {\n navigator.xr!.offerSession!(this.mode, this.sessionOptions)\n .then(this.onSessionStartedInternal.bind(this))\n .catch((err) => {\n console.warn(err);\n });\n }\n } else {\n console.log(`${this.mode} not supported`);\n this.xrModeSupported = false;\n this.dispatchEvent({type: WebXRSessionEventType.UNSUPPORTED});\n }\n }\n\n /**\n * Ends the WebXR session.\n */\n public startSession() {\n if (this.xrModeSupported === undefined) {\n throw new Error('Initialize not yet complete');\n } else if (!this.xrModeSupported) {\n throw new Error('WebXR not supported');\n } else if (this.currentSession) {\n throw new Error('Session already started');\n }\n navigator.xr!.requestSession(this.mode, this.sessionOptions)\n .then(this.onSessionStartedInternal.bind(this));\n }\n\n /**\n * Ends the WebXR session.\n */\n public endSession() {\n if (!this.currentSession) {\n throw new Error('No session to end');\n }\n this.currentSession.end();\n this.currentSession = undefined;\n }\n\n /**\n * Returns whether XR is supported. Will be undefined until initialize is\n * complete.\n */\n public isXRSupported() {\n return this.xrModeSupported;\n }\n\n /** Internal callback for when a session successfully starts. */\n private async onSessionStartedInternal(session: XRSession) {\n session.addEventListener('end', this.onSessionEndedBound);\n await this.renderer.xr.setSession(session);\n this.currentSession = session;\n\n // Fire the 'sessionstart' event with the session in the data payload\n this.dispatchEvent({\n type: WebXRSessionEventType.SESSION_START,\n session: session,\n });\n }\n\n /** Internal callback for when the session ends. */\n private onSessionEndedInternal(/*event*/) {\n // Fire the 'sessionend' event\n this.dispatchEvent({type: WebXRSessionEventType.SESSION_END});\n\n this.currentSession?.removeEventListener('end', this.onSessionEndedBound);\n this.currentSession = undefined;\n }\n}\n","import {onDesktopUserAgent} from '../../utils/BrowserUtils';\n\nimport {WebXRSessionEventType, WebXRSessionManager} from './WebXRSessionManager';\n\nconst XRBUTTON_WRAPPER_ID = 'XRButtonWrapper';\nconst XRBUTTON_CLASS = 'XRButton';\n\nexport class XRButton {\n public domElement = document.createElement('div');\n public simulatorButtonElement = document.createElement('button');\n public xrButtonElement = document.createElement('button');\n\n constructor(\n private sessionManager: WebXRSessionManager,\n private startText = 'ENTER XR',\n private endText = 'END XR',\n private invalidText = 'XR NOT SUPPORTED',\n private startSimulatorText = 'START SIMULATOR',\n enableSimulator = false,\n showSimulatorButtonOnMobile = false,\n public startSimulator = () => {},\n ) {\n this.domElement.id = XRBUTTON_WRAPPER_ID;\n this.createXRButtonElement();\n\n if (enableSimulator &&\n (onDesktopUserAgent() || showSimulatorButtonOnMobile)) {\n this.createSimulatorButton();\n }\n\n this.sessionManager.addEventListener(\n WebXRSessionEventType.UNSUPPORTED,\n this.showXRNotSupported.bind(this),\n );\n this.sessionManager.addEventListener(\n WebXRSessionEventType.READY,\n () => this.onSessionReady(),\n );\n this.sessionManager.addEventListener(\n WebXRSessionEventType.SESSION_START,\n () => this.onSessionStarted(),\n );\n this.sessionManager.addEventListener(\n WebXRSessionEventType.SESSION_END,\n this.onSessionEnded.bind(this),\n );\n }\n\n private createSimulatorButton() {\n this.simulatorButtonElement.classList.add(XRBUTTON_CLASS);\n this.simulatorButtonElement.innerText = this.startSimulatorText;\n this.simulatorButtonElement.onclick = () => {\n this.domElement.remove();\n this.startSimulator();\n };\n this.domElement.appendChild(this.simulatorButtonElement);\n }\n\n private createXRButtonElement() {\n this.xrButtonElement.classList.add(XRBUTTON_CLASS);\n this.xrButtonElement.disabled = true;\n this.xrButtonElement.textContent = '...';\n this.domElement.appendChild(this.xrButtonElement);\n }\n\n private onSessionReady() {\n const button = this.xrButtonElement;\n button.style.display = '';\n button.innerHTML = this.startText;\n button.disabled = false;\n\n button.onclick = () => {\n this.sessionManager.startSession();\n };\n }\n\n private showXRNotSupported() {\n this.xrButtonElement.textContent = this.invalidText;\n this.xrButtonElement.disabled = true;\n }\n\n private async onSessionStarted() {\n this.xrButtonElement.innerHTML = this.endText;\n }\n\n private onSessionEnded() {\n this.xrButtonElement.innerHTML = this.startText;\n }\n}\n","import * as THREE from 'three';\nimport {Pass} from 'three/addons/postprocessing/Pass.js';\n\nexport class XRPass extends Pass {\n render(\n _renderer: THREE.WebGLRenderer, _writeBuffer: THREE.WebGLRenderTarget,\n _readBuffer: THREE.WebGLRenderTarget, _deltaTime: number,\n _maskActive: boolean, _viewId: number = 0) {}\n}\n\n/**\n * XREffects manages the XR rendering pipeline.\n * Use core.effects\n * It handles multiple passes and render targets for applying effects to XR\n * scenes.\n */\nexport class XREffects {\n passes: XRPass[] = [];\n renderTargets: THREE.WebGLRenderTarget[] = [];\n dimensions = new THREE.Vector2();\n\n constructor(\n private renderer: THREE.WebGLRenderer, private scene: THREE.Scene,\n private timer: THREE.Timer) {};\n\n /**\n * Adds a pass to the effect pipeline.\n */\n addPass(pass: XRPass) {\n pass.renderToScreen = false;\n this.passes.push(pass);\n }\n\n /**\n * Sets up render targets for the effect pipeline.\n */\n setupRenderTargets(dimensions: THREE.Vector2) {\n const defaultTarget = this.renderer.getRenderTarget();\n if (defaultTarget == null) {\n return;\n }\n const neededRenderTargets = this.renderer.xr.isPresenting ? 4 : 2;\n for (let i = 0; i < neededRenderTargets; i++) {\n if (i >= this.renderTargets.length ||\n this.renderTargets[i].width != dimensions.x ||\n this.renderTargets[i].height != dimensions.y) {\n this.renderTargets[i]?.depthTexture?.dispose();\n this.renderTargets[i]?.dispose();\n this.renderTargets[i] = defaultTarget.clone();\n this.renderTargets[i].depthTexture =\n new THREE.DepthTexture(dimensions.x, dimensions.y);\n }\n }\n for (let i = neededRenderTargets; i < this.renderTargets.length; i++) {\n this.renderTargets[i].depthTexture?.dispose();\n this.renderTargets[i].dispose();\n }\n }\n\n /**\n * Renders the XR effects.\n */\n render() {\n this.renderer.getDrawingBufferSize(this.dimensions);\n this.setupRenderTargets(this.dimensions);\n this.renderer.xr.cameraAutoUpdate = false;\n const defaultTarget = this.renderer.getRenderTarget();\n if (!defaultTarget) {\n return;\n }\n if (this.renderer.xr.isPresenting) {\n this.renderXr();\n } else {\n this.renderSimulator();\n }\n }\n\n private renderXr() {\n const defaultTarget = this.renderer.getRenderTarget()!;\n const renderer = this.renderer;\n const xrEnabled = renderer.xr.enabled;\n const xrIsPresenting = renderer.xr.isPresenting;\n const renderTargets = this.renderTargets;\n const viewport = new THREE.Vector4();\n renderer.getViewport(viewport);\n renderer.xr.cameraAutoUpdate = false;\n renderer.xr.enabled = false;\n const deltaTime = this.timer.getDelta();\n if (renderer.xr.getCamera().cameras.length == 2) {\n for (let camIndex = 0; camIndex < 2; ++camIndex) {\n const cam = renderer.xr.getCamera().cameras[camIndex];\n renderer.setViewport(cam.viewport);\n renderer.setRenderTarget(renderTargets[camIndex]);\n renderer.clear();\n renderer.xr.isPresenting = true;\n renderer.render(this.scene, cam);\n }\n renderer.setRenderTarget(defaultTarget);\n renderer.clear();\n renderer.xr.isPresenting = false;\n renderer.autoClearColor = false;\n for (let eye = 0; eye < 2; eye++) {\n for (let i = 0; i < this.passes.length - 1; ++i) {\n const lastRenderTargetIndex = i % 2;\n const nextRenderTargetIndex = (i + 1) % 2;\n defaultTarget.viewport.set(\n eye * this.dimensions.x / 2, 0, this.dimensions.x / 2,\n this.dimensions.y);\n this.passes[i].render(\n renderer, this.renderTargets[2 * nextRenderTargetIndex + eye],\n this.renderTargets[2 * lastRenderTargetIndex + eye], deltaTime,\n /*maskActive=*/ false, /*viewId=*/ eye);\n }\n if (this.passes.length > 0) {\n const lastRenderTargetIndex = (this.passes.length - 1) % 2;\n defaultTarget.viewport.set(\n eye * this.dimensions.x / 2, 0, this.dimensions.x / 2,\n this.dimensions.y);\n this.passes[this.passes.length - 1].render(\n renderer, defaultTarget,\n this.renderTargets[2 * lastRenderTargetIndex + eye], deltaTime,\n /*maskActive=*/ false, /*viewId=*/ eye);\n }\n }\n renderer.xr.enabled = xrEnabled;\n renderer.xr.isPresenting = xrIsPresenting;\n }\n }\n\n private renderSimulator() {\n const defaultTarget = this.renderer.getRenderTarget()!;\n const renderer = this.renderer;\n const xrEnabled = renderer.xr.enabled;\n const xrIsPresenting = renderer.xr.isPresenting;\n const viewport = new THREE.Vector4();\n renderer.getViewport(viewport);\n renderer.xr.cameraAutoUpdate = false;\n renderer.xr.enabled = false;\n const deltaTime = this.timer.getDelta();\n renderer.setRenderTarget(defaultTarget);\n renderer.clear();\n renderer.xr.isPresenting = false;\n renderer.autoClearColor = false;\n for (let i = 0; i < this.passes.length - 1; ++i) {\n const lastRenderTargetIndex = i % 2;\n const nextRenderTargetIndex = (i + 1) % 2;\n this.passes[i].render(\n renderer, this.renderTargets[nextRenderTargetIndex],\n this.renderTargets[lastRenderTargetIndex], deltaTime,\n /*maskActive=*/ false, /*viewId=*/ 0);\n }\n if (this.passes.length > 0) {\n const lastRenderTargetIndex = (this.passes.length - 1) % 2;\n this.passes[this.passes.length - 1].render(\n renderer, defaultTarget, this.renderTargets[lastRenderTargetIndex],\n deltaTime,\n /*maskActive=*/ false, /*viewId=*/ 0);\n }\n renderer.xr.enabled = xrEnabled;\n renderer.xr.isPresenting = xrIsPresenting;\n }\n}\n","export const HAND_JOINT_NAMES = [\n 'wrist',\n 'thumb-metacarpal',\n 'thumb-phalanx-proximal',\n 'thumb-phalanx-distal',\n 'thumb-tip',\n 'index-finger-metacarpal',\n 'index-finger-phalanx-proximal',\n 'index-finger-phalanx-intermediate',\n 'index-finger-phalanx-distal',\n 'index-finger-tip',\n 'middle-finger-metacarpal',\n 'middle-finger-phalanx-proximal',\n 'middle-finger-phalanx-intermediate',\n 'middle-finger-phalanx-distal',\n 'middle-finger-tip',\n 'ring-finger-metacarpal',\n 'ring-finger-phalanx-proximal',\n 'ring-finger-phalanx-intermediate',\n 'ring-finger-phalanx-distal',\n 'ring-finger-tip',\n 'pinky-finger-metacarpal',\n 'pinky-finger-phalanx-proximal',\n 'pinky-finger-phalanx-intermediate',\n 'pinky-finger-phalanx-distal',\n 'pinky-finger-tip'\n] as const;\n","import * as THREE from 'three';\n\nimport {HAND_JOINT_NAMES} from './components/HandJointNames.js';\n\ntype JointName = typeof HAND_JOINT_NAMES[number];\n\n/**\n * Utility class for managing WebXR hand tracking data based on\n * reported Handedness.\n */\n\n/**\n * Enum for handedness, using WebXR standard strings.\n */\nexport enum Handedness {\n NONE = -1, // Represents unknown or unspecified handedness\n LEFT = 0,\n RIGHT = 1,\n}\n\n/**\n * Represents and provides access to WebXR hand tracking data.\n * Uses the 'handedness' property of input hands for identification.\n */\nexport class Hands {\n dominant = Handedness.RIGHT;\n\n /**\n * @param hands - An array containing XRHandSpace objects from Three.js.\n */\n constructor(public hands: THREE.XRHandSpace[]) {}\n\n /**\n * Retrieves a specific joint object for a given hand.\n * @param jointName - The name of the joint to retrieve (e.g.,\n * 'index-finger-tip').\n * @param targetHandednessEnum - The hand enum value\n * (Handedness.LEFT or Handedness.RIGHT)\n * to retrieve the joint from. If Handedness.NONE, uses the dominant\n * hand.\n * @returns The requested joint object, or null if not\n * found or invalid input.\n */\n getJoint(jointName: JointName, targetHandednessEnum: Handedness) {\n let resolvedHandednessEnum = targetHandednessEnum;\n if (resolvedHandednessEnum === Handedness.NONE) {\n resolvedHandednessEnum = this.dominant;\n }\n\n const hand = this.hands[resolvedHandednessEnum];\n if (!hand) {\n console.log('no hand');\n return undefined;\n }\n\n if (!hand.joints || !(jointName in hand.joints)) {\n return undefined;\n }\n\n return hand.joints[jointName];\n }\n\n /**\n * Gets the index finger tip joint.\n * @param handedness - Optional handedness\n * ('left'/'right'),\n * defaults to NONE (uses dominant hand).\n * @returns The joint object or null.\n */\n getIndexTip(handedness = Handedness.NONE) {\n return this.getJoint('index-finger-tip', handedness);\n }\n\n /**\n * Gets the thumb tip joint.\n * @param handedness - Optional handedness\n * ('left'/'right'),\n * defaults to NONE (uses dominant hand).\n * @returns The joint object or null.\n */\n getThumbTip(handedness = Handedness.NONE) {\n return this.getJoint('thumb-tip', handedness);\n }\n\n /**\n * Gets the middle finger tip joint.\n * @param handedness - Optional handedness\n * ('left'/'right'),\n * defaults to NONE (uses dominant hand).\n * @returns The joint object or null.\n */\n getMiddleTip(handedness = Handedness.NONE) {\n return this.getJoint('middle-finger-tip', handedness);\n }\n\n /**\n * Gets the ring finger tip joint.\n * @param handedness - Optional handedness\n * ('left'/'right'),\n * defaults to NONE (uses dominant hand).\n * @returns The joint object or null.\n */\n getRingTip(handedness = Handedness.NONE) {\n return this.getJoint('ring-finger-tip', handedness);\n }\n\n /**\n * Gets the pinky finger tip joint.\n * @param handedness - Optional handedness\n * ('left'/'right'),\n * defaults to NONE (uses dominant hand).\n * @returns The joint object or null.\n */\n getPinkyTip(handedness = Handedness.NONE) {\n return this.getJoint('pinky-finger-tip', handedness);\n }\n\n /**\n * Gets the wrist joint.\n * @param handedness - Optional handedness enum value\n * (LEFT/RIGHT/NONE),\n * defaults to NONE (uses dominant hand).\n * @returns The joint object or null.\n */\n getWrist(handedness = Handedness.NONE) {\n return this.getJoint('wrist', handedness);\n }\n\n /**\n * Generates a string representation of the hand joint data for both hands.\n * Always lists LEFT hand data first, then RIGHT hand data, if available.\n * @returns A string containing position data for all available\n * joints.\n */\n toString() {\n let s = '';\n const orderedHandedness = [Handedness.LEFT, Handedness.RIGHT];\n\n orderedHandedness.forEach((handedness) => {\n const hand = this.hands[handedness];\n\n if (!hand || !hand.joints) {\n s += `${handedness} Hand: Data unavailable\\n`;\n return; // Continue to the next handedness\n }\n\n HAND_JOINT_NAMES.forEach((jointName) => {\n const joint = hand.joints[jointName];\n if (joint) {\n if (joint.position) {\n s += `${handedness} - ${jointName}: ${\n joint.position.x.toFixed(3)}, ${joint.position.y.toFixed(3)}, ${\n joint.position.z.toFixed(3)}\\n`;\n } else {\n s += `${handedness} - ${jointName}: Position unavailable\\n`;\n }\n } else {\n s += `${handedness} - ${jointName}: Joint unavailable\\n`;\n }\n });\n });\n return s;\n }\n\n /**\n * Converts the pose data (position and quaternion) of all joints for both\n * hands into a single flat array. Each joint is represented by 7 numbers\n * (3 for position, 4 for quaternion). Missing joints or hands are represented\n * by zeros. Ensures a consistent output order: all left hand joints first,\n * then all right hand joints.\n * @returns A flat array containing position (x, y, z) and\n * quaternion (x, y, z, w) data for all joints, ordered [left...,\n * right...]. Size is always 2 * HAND_JOINT_NAMES.length * 7.\n */\n toPositionQuaternionArray() {\n const data = [];\n const orderedHandedness = [Handedness.LEFT, Handedness.RIGHT];\n const numJoints = HAND_JOINT_NAMES.length;\n const numValuesPerJoint = 7; // 3 position + 4 quaternion\n\n orderedHandedness.forEach((handedness) => {\n const hand = this.hands[handedness];\n\n // Check if hand and joints data exist for this handedness\n const handDataAvailable = hand && hand.joints;\n\n HAND_JOINT_NAMES.forEach((jointName) => {\n const joint = handDataAvailable ? hand.joints[jointName] : null;\n\n // Check if specific joint and its properties exist\n if (joint && joint.position && joint.quaternion) {\n data.push(joint.position.x, joint.position.y, joint.position.z);\n data.push(\n joint.quaternion.x, joint.quaternion.y, joint.quaternion.z,\n joint.quaternion.w);\n } else {\n // If hand, joints, joint, or properties missing, push zeros\n for (let i = 0; i < numValuesPerJoint; i++) {\n data.push(0);\n }\n }\n });\n });\n\n // The final array should always have the same size\n const expectedSize =\n orderedHandedness.length * numJoints * numValuesPerJoint;\n if (data.length !== expectedSize) {\n // This case should theoretically not happen with the logic above,\n // but added as a safeguard during development/debugging.\n console.error(\n `XRHands.toPositionQuaternionArray: Output array size mismatch. Expected ${\n expectedSize}, got ${data.length}. Padding with zeros.`);\n // Pad with zeros if necessary, though ideally the logic prevents this\n while (data.length < expectedSize) {\n data.push(0);\n }\n }\n\n return data;\n }\n\n /**\n * Checks for the availability of hand data.\n * If an integer (0 for LEFT, 1 for RIGHT) is provided, it checks for that\n * specific hand. If no integer is provided, it checks that data for *both*\n * hands is available.\n * @param handIndex - Optional. The index of the hand to validate\n * (0 or 1).\n * @returns `true` if the specified hand(s) have data, `false`\n * otherwise.\n */\n isValid(handIndex?: number): boolean {\n if (!this.hands || !Array.isArray(this.hands) || this.hands.length !== 2) {\n return false;\n }\n\n if (handIndex === 0 || handIndex === 1) {\n return !!this.hands[handIndex];\n }\n\n return !!this.hands[Handedness.LEFT] && !!this.hands[Handedness.RIGHT];\n }\n}\n","import * as THREE from 'three';\n\n/**\n * Shader for the Reticle UI component.\n *\n * This shader renders a dynamic, anti-aliased circle that provides visual\n * feedback for user interaction. It can smoothly transition between a hollow\n * ring (idle/hover state) and a solid, shrinking circle (pressed state).\n * The anti-aliasing is achieved using screen-space derivatives (fwidth) to\n * ensure crisp edges at any resolution or distance.\n */\nexport const ReticleShader = {\n name: 'ReticleShader',\n uniforms: {\n 'uColor': {value: new THREE.Color().setHex(0xFFFFFF)},\n 'uPressed': {value: 0.0},\n },\n\n vertexShader: /* glsl */ `\n varying vec2 vTexCoord;\n\n void main() {\n vTexCoord = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n // Makes the position slightly closer to avoid z fighting.\n gl_Position.z -= 0.1;\n }\n`,\n fragmentShader: /* glsl */ `\n precision mediump float;\n\n uniform sampler2D uDepthTexture;\n uniform vec3 uColor;\n uniform float uPressed;\n\n varying vec2 vTexCoord;\n\n void main(void) {\n // Distance from center of quad.\n highp float dist = distance(vTexCoord, vec2(0.5f, 0.5f));\n if (dist > 0.45) discard;\n\n // Get the rate of change of dist on x and y.\n highp vec2 dist_grad = vec2(dFdx(dist), dFdy(dist));\n highp float grad_magnitude = length(dist_grad);\n highp float antialias_dist = max(grad_magnitude, 0.001f);\n\n // Outer radius is 0.5, but we want to bring it in a few pixels so we have room\n // for a gradient outward to anti-alias the circle.\n // These \"few pixels\" are determined by our derivative calculation above.\n highp float outerradius = 0.5f - antialias_dist;\n highp float delta_to_outer = dist - outerradius;\n highp float clamped_outer_delta = clamp(delta_to_outer, 0.0f, antialias_dist);\n highp float outer_alpha = 1.0f - (clamped_outer_delta / antialias_dist);\n\n // #FFFFFF = (1,1,1)\n // #FFFFFF with 0.5 alpha = (((1,1,1) * 0.5), 0.5)\n vec4 inner_base_color = vec4(0.5 * uColor, 0.5);\n vec4 pressed_inner_color = vec4(uColor, 1.0);\n // #505050 = (0.077,0.077,0.077)\n // #505050 with 0.7 alpha = (((0.077,0.077,0.077)*0.7), 0.7)\n const vec4 inner_gradient_color = vec4(0.054, 0.054, 0.054, 1.0);\n const vec4 outer_ring_color = vec4(0.077, 0.077, 0.077, 1.0);\n // 0.5 - stoke_width (0.75dp = 0.04 approx)\n const float gradient_end = 0.46;\n // 73% of gradient_end\n const float gradient_start = 0.33;\n // gradient_end - 130% stoke_width. Additional 30% to account for the down scaling.\n const float pressed_inner_radius = 0.41;\n\n vec4 unpressed_inner_color =\n mix(inner_base_color, inner_gradient_color,\n smoothstep(gradient_start, gradient_end, dist));\n vec4 unpressed_color =\n mix(unpressed_inner_color, outer_ring_color,\n step(gradient_end, dist));\n\n // Builds a smooth gradient to fade between colors.\n highp float smooth_distance = antialias_dist * 4.0;\n float percent_to_inner_rad = max(pressed_inner_radius - dist, 0.0) / pressed_inner_radius;\n highp float pressed_color_t = 1.0 - percent_to_inner_rad;\n pressed_color_t -= (1.0 - smooth_distance);\n pressed_color_t *= (1.0 / smooth_distance);\n pressed_color_t = clamp(pressed_color_t, 0.0, 1.0);\n vec4 pressed_color = mix(pressed_inner_color, outer_ring_color, pressed_color_t);\n\n vec4 final_color = mix(unpressed_color, pressed_color, uPressed);\n gl_FragColor = final_color * outer_alpha;\n // Converts to straight alpha.\n gl_FragColor.rgb = gl_FragColor.rgb / max(gl_FragColor.a, 0.001);\n }\n`\n};\n","import * as THREE from 'three';\n\nimport {lerp} from '../../utils/utils';\nimport {ReticleShader} from '../shaders/ReticleShader';\n\n/**\n * A 3D visual marker used to indicate a user's aim or interaction\n * point in an XR scene. It orients itself to surfaces it intersects with and\n * provides visual feedback for states like \"pressed\".\n */\nexport class Reticle extends\n THREE.Mesh<THREE.BufferGeometry, THREE.ShaderMaterial> {\n /** Text description of the PanelMesh */\n name = 'Reticle';\n\n /** Prevents the reticle itself from being a target for raycasting. */\n ignoreReticleRaycast = true;\n\n /** The world-space direction vector of the ray that hit the target. */\n direction = new THREE.Vector3();\n\n /** Ensures the reticle is drawn on top of other transparent objects. */\n renderOrder = 1000;\n\n /** The smoothing factor for rotational slerp interpolation. */\n rotationSmoothing: number;\n\n /** The z-offset to prevent visual artifacts (z-fighting). */\n offset: number;\n\n /** The most recent intersection data that positioned this reticle. */\n intersection?: THREE.Intersection;\n\n /** Object on which the reticle is hovering. */\n targetObject?: THREE.Object3D;\n\n // --- Private properties for performance optimization ---\n private readonly originalNormal = new THREE.Vector3(0, 0, 1);\n private readonly newRotation = new THREE.Quaternion();\n private readonly objectRotation = new THREE.Quaternion();\n private readonly normalVector = new THREE.Vector3();\n\n /**\n * Creates an instance of Reticle.\n * @param rotationSmoothing - A factor between 0.0 (no smoothing) and\n * 1.0 (no movement) to smoothly animate orientation changes.\n * @param offset - A small z-axis offset to prevent z-fighting.\n * @param size - The radius of the reticle's circle geometry.\n * @param depthTest - Determines if the reticle should be occluded by other\n * objects. Defaults to `false` to ensure it is always visible.\n */\n constructor(\n rotationSmoothing = 0.8, offset = 0.001, size = 0.019,\n depthTest = false) {\n const geometry = new THREE.CircleGeometry(size, 32);\n geometry.applyMatrix4(new THREE.Matrix4().makeTranslation(0, 0, offset));\n\n super(geometry, new THREE.ShaderMaterial({\n uniforms: THREE.UniformsUtils.clone(ReticleShader.uniforms),\n vertexShader: ReticleShader.vertexShader,\n fragmentShader: ReticleShader.fragmentShader,\n depthTest: depthTest,\n transparent: true\n }));\n\n this.rotationSmoothing = rotationSmoothing;\n this.offset = offset;\n }\n\n /**\n * Orients the reticle to be flush with a surface, based on the surface\n * normal. It smoothly interpolates the rotation for a polished visual effect.\n * @param normal - The world-space normal of the surface.\n */\n setRotationFromNormalVector(normal: THREE.Vector3) {\n const angle = this.originalNormal.angleTo(normal);\n\n // Calculate the rotation axis by taking the cross product.\n // Note: this.originalNormal is modified here but reset by the next line.\n this.originalNormal.cross(normal).normalize();\n this.newRotation.setFromAxisAngle(this.originalNormal, angle);\n this.originalNormal.set(0, 0, 1); // Reset for next use.\n\n // Smoothly interpolate from the current rotation to the new rotation.\n this.quaternion.slerp(this.newRotation, 1.0 - this.rotationSmoothing);\n }\n\n /**\n * Updates the reticle's complete pose (position and rotation) from a\n * raycaster intersection object.\n * @param intersection - The intersection data from a raycast.\n */\n setPoseFromIntersection(intersection: THREE.Intersection) {\n if (!intersection || !intersection.normal) return;\n\n this.intersection = intersection;\n this.position.copy(intersection.point);\n\n // The intersection normal is in the local space of the intersected object.\n // It must be transformed into world space to correctly orient the reticle.\n intersection.object.getWorldQuaternion(this.objectRotation);\n this.normalVector.copy(intersection.normal)\n .applyQuaternion(this.objectRotation);\n this.setRotationFromNormalVector(this.normalVector);\n }\n\n /**\n * Sets the color of the reticle via its shader uniform.\n * @param color - The color to apply.\n */\n setColor(color: THREE.Color|number|string) {\n this.material.uniforms.uColor.value.set(color);\n }\n\n /**\n * Gets the current color of the reticle.\n * @returns The current color from the shader uniform.\n */\n getColor(): THREE.Color {\n return this.material.uniforms.uColor.value;\n }\n\n /**\n * Sets the visual state of the reticle to \"pressed\" or \"unpressed\".\n * This provides visual feedback to the user during interaction.\n * @param pressed - True to show the pressed state, false otherwise.\n */\n setPressed(pressed: boolean) {\n this.material.uniforms.uPressed.value = pressed ? 1.0 : 0.0;\n this.scale.setScalar(pressed ? 0.7 : 1.0);\n }\n\n /**\n * Sets the pressed state as a continuous value for smooth animations.\n * @param pressedAmount - A value from 0.0 (unpressed) to 1.0 (fully\n * pressed).\n */\n setPressedAmount(pressedAmount: number) {\n this.material.uniforms.uPressed.value = pressedAmount;\n this.scale.setScalar(lerp(1.0, 0.7, pressedAmount));\n }\n\n /**\n * Overrides the default raycast method to make the reticle ignored by\n * raycasters.\n */\n raycast() {}\n}\n","import * as THREE from 'three';\n\nexport class ControllerRayVisual extends THREE.Line {\n constructor() {\n const geometry = new THREE.BufferGeometry().setFromPoints(\n [new THREE.Vector3(0, 0, 0), new THREE.Vector3(0, 0, -1)]);\n\n super(geometry);\n this.scale.z = 5;\n }\n\n // Ignore raycasts to this line.\n raycast() {}\n}\n","import {clamp} from '../../utils/utils';\n\n/**\n * A simple utility class for linearly animating a numeric value over\n * time. It clamps the value within a specified min/max range and updates it\n * based on a given speed.\n */\nexport class AnimatableNumber {\n constructor(\n public value = 0, public minValue = 0, public maxValue = 1,\n public speed = 1) {}\n\n /**\n * Updates the value based on the elapsed time.\n * @param deltaTimeSeconds - The time elapsed since the last update, in\n * seconds.\n */\n update(deltaTimeSeconds: number) {\n this.value = clamp(\n this.value + deltaTimeSeconds * this.speed, this.minValue,\n this.maxValue);\n }\n}\n","import * as THREE from 'three';\n\nimport {Script} from '../core/Script';\nimport {Reticle} from '../ui/core/Reticle';\nimport {AnimatableNumber} from '../ui/interaction/AnimatableNumber';\n\nimport {Controller} from './Controller';\n\n/**\n * A threshold for gaze movement speed (in units per second) to determine if the\n * user's gaze is stable. If the reticle moves faster than this, the selection\n * timer resets.\n */\nconst PRESS_MOVEMENT_THRESHOLD = 0.2;\n\ninterface GazeControllerEventMap extends THREE.Object3DEventMap {\n connected: {target: GazeController};\n disconnected: {target: GazeController};\n selectstart: {target: GazeController};\n selectend: {target: GazeController};\n}\n\n/**\n * Implements a gaze-based controller for XR interactions.\n * This allows users to select objects by looking at them for a set duration.\n * It functions as a virtual controller that is always aligned with the user's\n * camera (head pose).\n * WebXR Eye Tracking is not yet available. This API simulates a reticle\n * at the center of the field of view for simulating gaze-based interaction.\n */\nexport class GazeController extends Script<GazeControllerEventMap> implements\n Controller {\n static dependencies = {camera: THREE.Camera};\n\n /**\n * User data for the controller, including its connection status, unique ID,\n * and selection state.\n */\n userData = {connected: false, id: 2, selected: false};\n\n /**\n * The visual indicator for where the user is looking.\n */\n reticle = new Reticle();\n\n /**\n * The time in seconds the user must gaze at an object to trigger a selection.\n */\n activationTimeSeconds = 1.5;\n\n /**\n * An animatable number that tracks the progress of the gaze selection, from\n * 0.0 to 1.0.\n */\n activationAmount =\n new AnimatableNumber(0.0, 0.0, 1.0, 1.0 / this.activationTimeSeconds);\n\n /**\n * Stores the reticle's position from the previous frame to calculate movement\n * speed.\n */\n lastReticlePosition = new THREE.Vector3();\n\n /**\n * A clock to measure the time delta between frames for smooth animation and\n * movement calculation.\n */\n clock = new THREE.Clock();\n\n camera!: THREE.Camera;\n\n init({camera}: {camera: THREE.Camera}) {\n this.camera = camera;\n }\n\n /**\n * The main update loop, called every frame by the core engine.\n * It handles syncing the controller with the camera and manages the gaze\n * selection logic.\n */\n update() {\n super.update();\n this.position.copy(this.camera.position);\n this.quaternion.copy(this.camera.quaternion);\n this.updateMatrixWorld();\n const delta = this.clock.getDelta();\n this.activationAmount.update(delta);\n const movement =\n this.lastReticlePosition.distanceTo(this.reticle.position) / delta;\n if (movement > PRESS_MOVEMENT_THRESHOLD) {\n this.activationAmount.value = 0.0;\n if (this.userData.selected) {\n this.callSelectEnd();\n }\n this.userData.selected = false;\n }\n if (this.activationAmount.value == 1.0 && !this.userData.selected) {\n this.callSelectStart();\n }\n this.updateReticleScale();\n this.lastReticlePosition.copy(this.reticle.position);\n }\n\n /**\n * Updates the reticle's scale and shader uniforms to provide visual feedback\n * for gaze activation. The reticle shrinks and fills in as the activation\n * timer progresses.\n */\n updateReticleScale() {\n this.reticle.setPressedAmount(this.activationAmount.value);\n }\n\n /**\n * Dispatches a 'selectstart' event, signaling that a gaze selection has been\n * initiated.\n */\n callSelectStart() {\n this.dispatchEvent({type: 'selectstart', target: this});\n }\n\n /**\n * Dispatches a 'selectend' event, signaling that a gaze selection has been\n * released (e.g., by moving gaze).\n */\n callSelectEnd() {\n this.dispatchEvent({type: 'selectend', target: this});\n }\n\n /**\n * Connects the gaze controller to the input system.\n */\n connect() {\n this.dispatchEvent({type: 'connected', target: this});\n }\n\n /**\n * Disconnects the gaze controller from the input system.\n */\n disconnect() {\n this.dispatchEvent({type: 'disconnected', target: this});\n }\n}\n","import * as THREE from 'three';\n\nimport {Script} from '../core/Script.js';\n\nimport {Controller} from './Controller.js';\n\n/** Defines the event map for the MouseController's custom events. */\ninterface MouseControllerEventMap extends THREE.Object3DEventMap {\n connected: {target: MouseController};\n disconnected: {target: MouseController};\n selectstart: {target: MouseController};\n selectend: {target: MouseController};\n}\n\n/**\n * Simulates an XR controller using the mouse for desktop\n * environments. This class translates 2D mouse movements on the screen into a\n * 3D ray in the scene, allowing for point-and-click interactions in a\n * non-immersive context. It functions as a virtual controller that is always\n * aligned with the user's pointer.\n */\nexport class MouseController extends Script<MouseControllerEventMap> implements\n Controller {\n static dependencies = {\n camera: THREE.Camera,\n };\n\n /**\n * User data for the controller, including its connection status, unique ID,\n * and selection state (mouse button pressed).\n */\n userData = {id: 3, connected: false, selected: false};\n\n /** A THREE.Raycaster used to determine the 3D direction of the mouse. */\n raycaster = new THREE.Raycaster();\n\n /** A normalized vector representing the default forward direction. */\n forwardVector = new THREE.Vector3(0, 0, -1);\n\n /** A reference to the main scene camera. */\n camera!: THREE.Camera;\n\n constructor() {\n super();\n }\n\n /**\n * Initialize the MouseController\n */\n init({camera}: {camera: THREE.Camera}) {\n this.camera = camera;\n }\n\n /**\n * The main update loop, called every frame.\n * If connected, it syncs the controller's origin point with the camera's\n * position.\n */\n update() {\n super.update();\n if (!this.userData.connected) {\n return;\n }\n this.position.copy(this.camera.position);\n }\n\n /**\n * Updates the controller's transform based on the mouse's position on the\n * screen. This method sets both the position and rotation, ensuring the\n * object has a valid world matrix for raycasting.\n * @param event - The mouse event containing clientX and clientY coordinates.\n */\n updateMousePositionFromEvent(event: MouseEvent) {\n // The controller's origin point is always the camera's position.\n this.position.copy(this.camera.position);\n\n const mouse = new THREE.Vector2();\n // Converts mouse coordinates from screen space (pixels) to normalized\n // device coordinates (-1 to +1).\n mouse.x = (event.clientX / window.innerWidth) * 2 - 1;\n mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;\n\n // Updates the raycaster and sets the controller's new rotation.\n this.raycaster.setFromCamera(mouse, this.camera);\n const rayDirection = this.raycaster.ray.direction;\n this.quaternion.setFromUnitVectors(this.forwardVector, rayDirection);\n this.updateMatrixWorld();\n }\n\n /**\n * Dispatches a 'selectstart' event, simulating the start of a controller\n * press (e.g., mouse down).\n */\n callSelectStart() {\n this.dispatchEvent({type: 'selectstart', target: this});\n }\n\n /**\n * Dispatches a 'selectend' event, simulating the end of a controller press\n * (e.g., mouse up).\n */\n callSelectEnd() {\n this.dispatchEvent({type: 'selectend', target: this});\n }\n\n /**\n * \"Connects\" the virtual controller, notifying the input system that it is\n * active.\n */\n connect() {\n this.dispatchEvent({type: 'connected', target: this});\n }\n\n /**\n * \"Disconnects\" the virtual controller.\n */\n disconnect() {\n this.dispatchEvent({type: 'disconnected', target: this});\n }\n}\n","import * as THREE from 'three';\nimport {XRControllerModelFactory} from 'three/addons/webxr/XRControllerModelFactory.js';\nimport {XRHandModelFactory} from 'three/addons/webxr/XRHandModelFactory.js';\n\nimport {NUM_HANDS} from '../constants';\nimport {Options} from '../core/Options.js';\nimport {KeyEvent, Script} from '../core/Script';\nimport {Reticle} from '../ui/core/Reticle.js';\n\nimport {ControllerRayVisual} from './components/ControllerRayVisual';\nimport type {Controller, ControllerEvent, ControllerEventMap} from './Controller';\nimport {GazeController} from './GazeController';\nimport {MouseController} from './MouseController';\n\nexport class ActiveControllers extends THREE.Object3D {};\n\nexport type HasIgnoreReticleRaycast = {\n ignoreReticleRaycast: boolean;\n};\nexport type MaybeHasIgnoreReticleRaycast = Partial<HasIgnoreReticleRaycast>;\n\n// Reusable objects for performance.\nconst MATRIX4 = new THREE.Matrix4();\n\n/**\n * The XRInput class holds all the controllers and performs raycasts through the\n * scene each frame.\n */\nexport class Input {\n options!: Options;\n controllers: Controller[] = [];\n controllerGrips: THREE.Group[] = [];\n hands: THREE.XRHandSpace[] = [];\n raycaster = new THREE.Raycaster();\n initialized = false;\n pivotsEnabled = false;\n gazeController = new GazeController();\n mouseController = new MouseController();\n controllersEnabled = true;\n listeners = new Map();\n intersectionsForController = new Map<Controller, THREE.Intersection[]>();\n intersections = [];\n activeControllers = new ActiveControllers();\n leftController?: Controller;\n rightController?: Controller;\n scene!: THREE.Scene;\n\n /**\n * Initializes an instance with XR controllers, grips, hands, raycaster, and\n * default options. Only called by Core.\n */\n init({scene, options, renderer}: {\n scene: THREE.Scene,\n options: Options,\n renderer: THREE.WebGLRenderer\n }) {\n scene.add(this.activeControllers);\n\n this.options = options;\n this.scene = scene;\n\n const controllers = this.controllers;\n const controllerGrips = this.controllerGrips;\n\n for (let i = 0; i < NUM_HANDS; ++i) {\n controllers.push(renderer.xr.getController(i));\n controllers[i].userData.id = i;\n this.activeControllers.add(this.controllers[i]);\n }\n controllers.push(this.gazeController);\n controllers.push(this.mouseController);\n this.activeControllers.add(this.mouseController);\n\n for (const controller of controllers) {\n this.intersectionsForController.set(controller, []);\n }\n\n if (options.controllers.enabled) {\n if (options.controllers.visualization) {\n const controllerModelFactory = new XRControllerModelFactory();\n for (let i = 0; i < NUM_HANDS; ++i) {\n controllerGrips.push(renderer.xr.getControllerGrip(i));\n controllerGrips[i].add(\n controllerModelFactory.createControllerModel(controllerGrips[i]));\n this.activeControllers.add(controllerGrips[i]);\n }\n }\n\n // TODO: Separate logic to XR Hands.\n if (options.hands.enabled) {\n for (let i = 0; i < NUM_HANDS; ++i) {\n this.hands.push(renderer.xr.getHand(i));\n this.activeControllers.add(this.hands[i]);\n }\n\n if (options.hands.visualization) {\n if (options.hands.visualizeJoints) {\n console.log('Visualize hand joints.');\n const handModelFactory = new XRHandModelFactory();\n for (let i = 0; i < NUM_HANDS; ++i) {\n const handModel =\n handModelFactory.createHandModel(this.hands[i], 'boxes');\n (handModel as MaybeHasIgnoreReticleRaycast).ignoreReticleRaycast =\n true;\n this.hands[i].add(handModel);\n }\n }\n if (options.hands.visualizeMeshes) {\n console.log('Visualize hand meshes.');\n const handModelFactory = new XRHandModelFactory();\n for (let i = 0; i < NUM_HANDS; ++i) {\n const handModel =\n handModelFactory.createHandModel(this.hands[i], 'mesh');\n (handModel as MaybeHasIgnoreReticleRaycast).ignoreReticleRaycast =\n true;\n this.hands[i].add(handModel);\n }\n }\n }\n }\n }\n\n if (options.controllers.visualizeRays) {\n for (let i = 0; i < NUM_HANDS; ++i) {\n controllers[i].add(new ControllerRayVisual());\n }\n }\n\n this.bindSelectStart(this.defaultOnSelectStart.bind(this));\n this.bindSelectEnd(this.defaultOnSelectEnd.bind(this));\n this.bindSqueezeStart(this.defaultOnSelectStart.bind(this));\n this.bindSqueezeEnd(this.defaultOnSelectEnd.bind(this));\n this.bindListener('connected', this.defaultOnConnected.bind(this));\n this.bindListener('disconnected', this.defaultOnDisconnected.bind(this));\n }\n\n /**\n * Retrieves the controller object by its ID.\n * @param id - The ID of the controller.\n * @returns The controller with the specified ID.\n */\n get(id: number): THREE.Object3D {\n return this.controllers[id];\n }\n\n /**\n * Adds an object to both controllers by creating a new group and cloning it.\n * @param obj - The object to add to each controller.\n */\n addObject(obj: THREE.Object3D) {\n const group = new THREE.Group();\n group.add(obj);\n // Clones the group for each controller, adding it to the controller.\n for (let i = 0; i < this.controllers.length; ++i) {\n this.controllers[i].add(group.clone());\n }\n }\n\n /**\n * Creates a pivot point for each hand, primarily used as a reference\n * point.\n */\n enablePivots() {\n if (this.pivotsEnabled) return;\n this.pivotsEnabled = true;\n const pivot = new THREE.Mesh(new THREE.IcosahedronGeometry(0.01, 3));\n pivot.name = 'pivot';\n pivot.position.z = -0.05;\n this.addObject(pivot);\n }\n\n /**\n * Adds reticles to the controllers and scene, with initial visibility set to\n * false.\n */\n addReticles() {\n let id = 0;\n for (const controller of this.controllers) {\n if (controller.reticle == null) {\n controller.reticle = new Reticle();\n controller.reticle.name = 'Reticle ' + id;\n ++id;\n }\n controller.reticle.visible = false;\n this.scene.add(controller.reticle);\n }\n }\n\n /**\n * Default action to handle the start of a selection, setting the selecting\n * state to true.\n */\n defaultOnSelectStart(event: ControllerEvent) {\n const controller = event.target;\n controller.userData.selected = true;\n this._setRaycasterFromController(controller);\n this.performRaycastOnScene(controller);\n }\n\n /**\n * Default action to handle the end of a selection, setting the selecting\n * state to false.\n */\n defaultOnSelectEnd(event: ControllerEvent) {\n const controller = event.target;\n controller.userData.selected = false;\n }\n\n defaultOnSqueezeStart(event: ControllerEvent) {\n const controller = event.target;\n controller.userData.squeezing = true;\n }\n\n defaultOnSqueezeEnd(event: ControllerEvent) {\n const controller = event.target;\n controller.userData.squeezing = false;\n }\n\n defaultOnConnected(event: ControllerEvent) {\n const controller = event.target;\n controller.userData.connected = true;\n controller.gamepad = event.data?.gamepad;\n controller.inputSource = event.data;\n switch (event.data?.handedness) {\n case 'left':\n this.leftController = controller;\n break;\n case 'right':\n this.rightController = controller;\n break;\n }\n }\n\n defaultOnDisconnected(event: ControllerEvent) {\n const controller = event.target;\n controller.userData.connected = false;\n if (controller.reticle) {\n controller.reticle.visible = false;\n }\n delete controller?.gamepad;\n switch (event.data?.handedness) {\n case 'left':\n this.leftController = undefined;\n break;\n case 'right':\n this.rightController = undefined;\n break;\n }\n }\n\n /**\n * Binds a listener to both controllers.\n * @param listenerName - Event name\n * @param listener - Function to call\n */\n bindListener(\n listenerName: keyof ControllerEventMap,\n listener: (event: ControllerEvent) => void) {\n for (const controller of this.controllers) {\n controller.addEventListener(listenerName, listener);\n }\n if (!this.listeners.has(listenerName)) {\n this.listeners.set(listenerName, []);\n }\n this.listeners.get(listenerName).push(listener);\n }\n\n unbindListener(\n listenerName: keyof ControllerEventMap,\n listener: (event: ControllerEvent) => void) {\n if (this.listeners.has(listenerName)) {\n const listeners = this.listeners.get(listenerName);\n const index = listeners.indexOf(listener);\n if (index !== -1) {\n listeners.splice(index, 1);\n }\n }\n for (const controller of this.controllers) {\n controller.removeEventListener(listenerName, listener);\n }\n }\n\n dispatchEvent(event: ControllerEvent) {\n if (this.listeners.has(event.type)) {\n for (const listener of this.listeners.get(event.type)) {\n listener(event);\n }\n }\n }\n\n /**\n * Binds an event listener to handle 'selectstart' events for both\n * controllers.\n * @param event - The event listener function.\n */\n bindSelectStart(event: (event: ControllerEvent) => void) {\n this.bindListener('selectstart', event);\n }\n\n /**\n * Binds an event listener to handle 'selectend' events for both controllers.\n * @param event - The event listener function.\n */\n bindSelectEnd(event: (event: ControllerEvent) => void) {\n this.bindListener('selectend', event);\n }\n\n /**\n * Binds an event listener to handle 'select' events for both controllers.\n * @param event - The event listener function.\n */\n bindSelect(event: (event: ControllerEvent) => void) {\n this.bindListener('select', event);\n }\n\n /**\n * Binds an event listener to handle 'squeezestart' events for both\n * controllers.\n * @param event - The event listener function.\n */\n bindSqueezeStart(event: (event: ControllerEvent) => void) {\n this.bindListener('squeezestart', event);\n }\n\n /**\n * Binds an event listener to handle 'squeezeend' events for both controllers.\n * @param event - The event listener function.\n */\n bindSqueezeEnd(event: (event: ControllerEvent) => void) {\n this.bindListener('squeezeend', event);\n }\n\n bindSqueeze(event: (event: ControllerEvent) => void) {\n this.bindListener('squeeze', event);\n }\n\n bindKeyDown(event: (event: KeyEvent) => void) {\n window.addEventListener('keydown', event);\n }\n\n bindKeyUp(event: (event: KeyEvent) => void) {\n window.addEventListener('keyup', event);\n }\n\n unbindKeyDown(event: (event: KeyEvent) => void) {\n window.removeEventListener('keydown', event);\n }\n\n unbindKeyUp(event: (event: KeyEvent) => void) {\n window.removeEventListener('keyup', event);\n }\n\n /**\n * Finds intersections between a controller's ray and a specified object.\n * @param controller - The controller casting the ray.\n * @param obj - The object to intersect.\n * @returns Array of intersection points, if any.\n */\n intersectObjectByController(controller: THREE.Object3D, obj: THREE.Object3D):\n THREE.Intersection[] {\n controller.updateMatrixWorld();\n this.raycaster.setFromXRController(controller as THREE.XRTargetRaySpace);\n return this.raycaster.intersectObject(obj, false);\n }\n\n /**\n * Finds intersections based on an event's target controller and a specified\n * object.\n * @param event - The event containing the controller reference.\n * @param obj - The object to intersect.\n * @returns Array of intersection points, if any.\n */\n intersectObjectByEvent(event: ControllerEvent, obj: THREE.Object3D):\n THREE.Intersection[] {\n return this.intersectObjectByController(event.target, obj);\n }\n\n /**\n * Finds intersections with an object from either controller.\n * @param obj - The object to intersect.\n * @returns Array of intersection points, if any.\n */\n intersectObject(obj: THREE.Object3D): THREE.Intersection[] {\n // Checks for intersections from the first controller.\n const intersection =\n this.intersectObjectByController(this.controllers[0], obj);\n if (intersection.length > 0) {\n return intersection;\n }\n // Checks for intersections from the second controller if no intersection\n // found.\n return this.intersectObjectByController(this.controllers[1], obj);\n }\n\n update() {\n if (this.controllersEnabled) {\n for (const controller of this.controllers) {\n this.updateController(controller);\n }\n }\n }\n\n updateController(controller: Controller) {\n if (controller.userData.connected === false) {\n return;\n }\n controller.updateMatrixWorld();\n this._setRaycasterFromController(controller);\n this.performRaycastOnScene(controller);\n this.updateReticleFromIntersections(controller);\n }\n\n\n /**\n * Sets the raycaster's origin and direction from any Object3D that\n * represents a controller. This replaces the non-standard\n * `setFromXRController`.\n * @param controller - The controller to cast a ray from.\n */\n private _setRaycasterFromController(controller: THREE.Object3D) {\n controller.getWorldPosition(this.raycaster.ray.origin);\n MATRIX4.identity().extractRotation(controller.matrixWorld);\n this.raycaster.ray.direction.set(0, 0, -1)\n .applyMatrix4(MATRIX4)\n .normalize();\n }\n\n updateReticleFromIntersections(controller: Controller) {\n if (!controller.reticle) return;\n const reticle = controller.reticle;\n const intersection =\n this.intersectionsForController.get(controller)?.find(intersection => {\n let target: THREE.Object3D|null = intersection.object;\n while (target) {\n if ((target as MaybeHasIgnoreReticleRaycast)\n .ignoreReticleRaycast === true) {\n return false;\n }\n target = target.parent;\n }\n return true;\n });\n if (!intersection) {\n reticle.visible = false;\n return;\n }\n reticle.visible = true;\n\n // Here isXRScript is semantically equals to isInteractable.\n if ((intersection.object as Partial<Script>)?.isXRScript) {\n (intersection.object as Script).ux.update(controller, intersection);\n } else if ((intersection.object?.parent as Partial<Script>)?.isXRScript) {\n (intersection.object.parent as Script)\n .ux.update(controller, intersection);\n }\n\n reticle.intersection = intersection;\n reticle.direction.copy(this.raycaster.ray.direction).normalize();\n reticle.setPoseFromIntersection(intersection);\n reticle.setPressed(controller.userData.selected);\n }\n\n enableGazeController() {\n this.activeControllers.add(this.gazeController);\n this.gazeController.connect();\n }\n\n disableGazeController() {\n this.gazeController.disconnect();\n this.activeControllers.remove(this.gazeController);\n }\n\n disableControllers() {\n this.controllersEnabled = false;\n for (const controller of this.controllers) {\n controller.userData.selected = false\n if (controller.reticle) {\n controller.reticle.visible = false;\n controller.reticle.targetObject = undefined;\n }\n }\n }\n\n enableControllers() {\n this.controllersEnabled = true;\n }\n\n // Performs the raycast assuming the raycaster is already set up.\n performRaycastOnScene(controller: Controller) {\n if (!this.intersectionsForController.has(controller)) {\n this.intersectionsForController.set(controller, []);\n }\n const intersections = this.intersectionsForController.get(controller)!;\n intersections.length = 0;\n this.raycaster.intersectObject(this.scene, true, intersections);\n }\n};\n","import * as THREE from 'three';\nimport {XREstimatedLight} from 'three/addons/webxr/XREstimatedLight.js';\n\nimport {Depth} from '../depth/Depth.js';\n\nimport {LightingOptions} from './LightingOptions.js';\n\nconst DEBUGGING = false;\n\n/**\n * Lighting provides XR lighting capabilities within the XR Blocks framework.\n * It uses webXR to propvide estimated lighting that matches the environment\n * and supports casting shadows from the estimated light.\n */\nexport class Lighting {\n static instance?: Lighting;\n /** WebXR estimated lighting. */\n private xrLight?: XREstimatedLight;\n /** Main Directional light. */\n dirLight = new THREE.DirectionalLight();\n /** Ambient spherical harmonics light. */\n ambientProbe = new THREE.LightProbe();\n /** Ambient RGB light. */\n ambientLight = new THREE.Vector3();\n /** Opacity of cast shadow. */\n private shadowOpacity = 0.0;\n /** Light group to attach to scene. */\n private lightGroup = new THREE.Group();\n /** Lighting options. Set during initialiation.*/\n private options!: LightingOptions;\n /** Depth manager. Used to get depth mesh on which to cast shadow. */\n private depth?: Depth;\n /** Flag to indicate if simulator is running. Controlled by Core. */\n simulatorRunning = false;\n\n /**\n * Lighting is a lightweight manager based on three.js to simply prototyping\n * with Lighting features within the XR Blocks framework.\n */\n constructor() {\n if (Lighting.instance) {\n return Lighting.instance;\n }\n Lighting.instance = this;\n }\n\n /**\n * Initializes the lighting module with the given options. Sets up lights and\n * shadows and adds necessary components to the scene.\n * @param lightingOptions - Lighting options.\n * @param renderer - Main renderer.\n * @param scene - Main scene.\n * @param depth - Depth manager.\n */\n init(\n lightingOptions: LightingOptions, renderer: THREE.WebGLRenderer,\n scene: THREE.Scene, depth?: Depth) {\n this.options = lightingOptions;\n this.depth = depth;\n\n if (this.options.enabled) {\n this.xrLight = new XREstimatedLight(renderer);\n\n if (this.options.castDirectionalLightShadow) {\n renderer.shadowMap.enabled = true;\n renderer.shadowMap.type = THREE.PCFShadowMap;\n }\n\n if (this.options.castDirectionalLightShadow) {\n const dirLight = this.dirLight;\n dirLight.castShadow = true;\n dirLight.shadow.mapSize.width = 2048;\n dirLight.shadow.mapSize.height = 2048;\n dirLight.shadow.camera.near = 0.3;\n dirLight.shadow.camera.far = 50.0;\n const cameraFrustrumRadius = 4.0;\n dirLight.shadow.camera.left = -cameraFrustrumRadius;\n dirLight.shadow.camera.right = cameraFrustrumRadius;\n dirLight.shadow.camera.top = cameraFrustrumRadius;\n dirLight.shadow.camera.bottom = -cameraFrustrumRadius;\n dirLight.shadow.blurSamples = 25;\n dirLight.shadow.radius = 5.0;\n dirLight.shadow.bias = 0.0;\n\n this.lightGroup.add(dirLight.target);\n\n if (this.options.debugging || DEBUGGING) {\n scene.add(new THREE.CameraHelper(dirLight.shadow.camera));\n }\n }\n\n if (this.options.useAmbientSH) {\n this.lightGroup.add(this.ambientProbe);\n }\n if (this.options.useDirectionalLight) {\n this.lightGroup.add(this.dirLight);\n }\n scene.add(this.lightGroup);\n\n this.xrLight.addEventListener('estimationend', () => {\n scene.remove(this.xrLight!);\n });\n }\n }\n\n /**\n * Updates the lighting and shadow setup used to render. Called every frame\n * in the render loop.\n */\n update() {\n // Update lights from WebXR estimated light.\n if (this.options.enabled) {\n this.dirLight.position.copy(this.xrLight!.directionalLight.position)\n .multiplyScalar(20.0);\n this.dirLight.target.position.setScalar(0.0);\n this.dirLight.color = this.xrLight!.directionalLight.color;\n this.dirLight.intensity = this.xrLight!.directionalLight.intensity;\n this.ambientProbe.sh.copy(this.xrLight!.lightProbe.sh);\n this.ambientProbe.intensity = this.xrLight!.lightProbe.intensity;\n this.ambientLight.copy(this.xrLight!.lightProbe.sh.coefficients[0]);\n\n // Replace lights with harcoded default if using simulator.\n if (this.simulatorRunning) {\n this.dirLight.position.set(-10.0, 10.0, -2.0);\n this.dirLight.target.position.set(0.0, 0.0, -0.5);\n this.dirLight.color.setHex(0xffffff);\n this.dirLight.intensity = 3.8;\n this.ambientProbe.sh.fromArray([\n 0.22636516392230988, 0.2994415760040283, 0.2827182114124298,\n 0.03430574759840965, 0.029604531824588776, -0.002050594426691532,\n 0.016114741563796997, 0.004344218410551548, 0.07621686905622482,\n 0.024204734712839127, -0.02397896535694599, -0.07645703107118607,\n 0.15790101885795593, 0.16706973314285278, 0.18418270349502563,\n -0.13088643550872803, -0.1461198776960373, -0.1411236822605133,\n 0.04788218438625336, 0.08909443765878677, 0.10185115039348602,\n 0.020251473411917686, -0.002100071171298623, -0.06455840915441513,\n -0.12393051385879517, -0.05158703774213791, -0.00532124936580658\n ]);\n this.ambientProbe.intensity = 1.0;\n this.ambientLight.copy(this.ambientProbe.sh.coefficients[0]);\n }\n\n if (this.options.castDirectionalLightShadow &&\n this.options.useDynamicSoftShadow) {\n const ambientLightIntensity = this.ambientLight;\n const ambientMonoIntensity = 0.21 * ambientLightIntensity.x +\n 0.72 * ambientLightIntensity.y + 0.07 * ambientLightIntensity.z;\n const mainLightIntensity =\n new THREE\n .Vector3(\n this.dirLight.color.r, this.dirLight.color.g,\n this.dirLight.color.b)\n .multiplyScalar(this.dirLight.intensity);\n const mainMonoIntensity = 0.21 * mainLightIntensity.x +\n 0.72 * mainLightIntensity.y + 0.07 * mainLightIntensity.z;\n const ambientToMain = ambientMonoIntensity / mainMonoIntensity;\n this.dirLight.shadow.radius =\n Math.min(Math.max(1.0, ambientToMain * 30), 10.0);\n this.shadowOpacity =\n Math.max(Math.min((10.0 - ambientToMain * 30) * 0.7, 0.7), 0.3);\n\n // Override depth material opacity with shadowOpacity\n if (this.depth?.options?.enabled &&\n this.depth.options.depthMesh.enabled &&\n this.depth.depthMesh?.material instanceof THREE.ShadowMaterial) {\n this.depth.depthMesh.material.opacity = this.shadowOpacity;\n }\n }\n }\n\n if (this.options.debugging || DEBUGGING) {\n this.debugLog();\n }\n }\n\n /**\n * Logs current estimate light parameters for debugging.\n */\n debugLog() {\n console.log('Lighting.dirLight', this.dirLight);\n console.log('Lighting.ambientProbe', this.ambientProbe);\n console.log('Lighting.ambientLight', this.ambientLight);\n }\n};\n","import type RAPIER from 'rapier3d';\n\nimport {PhysicsOptions, RAPIERCompat} from './PhysicsOptions';\n\n/**\n * Integrates the RAPIER physics engine into the XRCore lifecycle.\n * It sets up the physics in a blended world that combines virtual and physical\n * objects, steps the simulation forward in sync with the application's\n * framerate, and manages the lifecycle of physics-related objects.\n */\nexport class Physics {\n initialized = false;\n options?: PhysicsOptions;\n RAPIER!: RAPIERCompat;\n fps: number = 0;\n blendedWorld!: RAPIER.World;\n eventQueue!: RAPIER.EventQueue;\n\n get timestep() {\n return 1 / this.fps;\n }\n\n /**\n * Asynchronously initializes the RAPIER physics engine and creates the\n * blendedWorld. This is called in Core before the physics simulation starts.\n */\n async init({physicsOptions}: {physicsOptions: PhysicsOptions}) {\n this.options = physicsOptions;\n this.RAPIER = this.options.RAPIER!;\n this.fps = this.options.fps;\n if (this.RAPIER.init) {\n await this.RAPIER.init();\n }\n this.blendedWorld = new this.RAPIER!.World(this.options.gravity);\n this.blendedWorld.timestep = this.timestep;\n if (this.options.useEventQueue) {\n this.eventQueue = new this.RAPIER!.EventQueue(true);\n }\n this.initialized = true;\n }\n\n /**\n * Advances the physics simulation by one step.\n */\n physicsStep() {\n if (this.options?.worldStep && this.blendedWorld) {\n this.blendedWorld.step(this.eventQueue);\n }\n }\n\n /**\n * Frees the memory allocated by the RAPIER physics blendedWorld and event\n * queue. This is crucial for preventing memory leaks when the XR session\n * ends.\n */\n dispose() {\n if (this.eventQueue) {\n this.eventQueue.free();\n }\n if (this.blendedWorld) {\n this.blendedWorld.free();\n }\n }\n};\n","import {deepMerge} from '../utils/OptionsUtils';\nimport {DeepPartial, DeepReadonly} from '../utils/Types';\n\nexport class HandsOptions {\n /** Whether hand tracking is enabled. */\n enabled = false;\n /** Whether to show any hand visualization. */\n visualization = false;\n /** Whether to show the tracked hand joints. */\n visualizeJoints = false;\n /** Whether to show the virtual hand meshes. */\n visualizeMeshes = false;\n\n debugging = false;\n\n constructor(options?: DeepReadonly<DeepPartial<HandsOptions>>) {\n deepMerge(this, options);\n }\n\n /**\n * Enables hands tracking.\n * @returns The instance for chaining.\n */\n enableHands() {\n this.enabled = true;\n return this;\n }\n\n enableHandsVisualization() {\n this.enabled = true;\n this.visualization = true;\n return this;\n }\n}\n","import {deepMerge} from '../utils/OptionsUtils.js';\nimport {DeepPartial, DeepReadonly} from '../utils/Types';\n\n/**\n * Default options for controlling Lighting module features.\n */\nexport class LightingOptions {\n /** Enables debugging renders and logs. */\n debugging = false;\n /** Enables XR lighting. */\n enabled = false;\n /** Add ambient spherical harmonics to lighting. */\n useAmbientSH = false;\n /** Add main diredtional light to lighting. */\n useDirectionalLight = false;\n /** Cast shadows using diretional light. */\n castDirectionalLightShadow = false;\n /**\n * Adjust hardness of shadows according to relative brightness of main light.\n */\n useDynamicSoftShadow = false; // experimental\n\n constructor(options?: DeepReadonly<DeepPartial<LightingOptions>>) {\n deepMerge(this, options);\n }\n}\n","import type RAPIER from 'rapier3d';\n\nexport type RAPIERCompat = typeof RAPIER&{\n init?: () => Promise<void>;\n}\n\nexport class PhysicsOptions {\n /**\n * The target frames per second for the physics simulation loop.\n */\n fps = 45;\n\n /**\n * The global gravity vector applied to the physics world.\n */\n gravity = {x: 0.0, y: -9.81, z: 0.0};\n\n /**\n * If true, the `Physics` manager will automatically call `world.step()`\n * on its fixed interval. Set to false if you want to control the\n * simulation step manually.\n */\n worldStep = true;\n\n /**\n * If true, an event queue will be created and passed to `world.step()`,\n * enabling the handling of collision and contact events.\n */\n useEventQueue = false\n\n /**\n * Instance of RAPIER.\n */\n RAPIER?: RAPIERCompat;\n}\n","import type {TemplateResult} from 'lit';\n\nimport {XR_BLOCKS_ASSETS_PATH} from '../constants';\nimport {Handedness} from '../input/Hands';\nimport {deepMerge} from '../utils/OptionsUtils';\nimport {DeepPartial, DeepReadonly} from '../utils/Types';\n\nexport enum SimulatorMode {\n USER = 'User',\n POSE = 'Navigation',\n CONTROLLER = 'Hands',\n}\n\nexport const NEXT_SIMULATOR_MODE = {\n [SimulatorMode.USER]: SimulatorMode.POSE,\n [SimulatorMode.POSE]: SimulatorMode.CONTROLLER,\n [SimulatorMode.CONTROLLER]: SimulatorMode.USER,\n};\n\nexport interface SimulatorCustomInstruction {\n header: string|TemplateResult;\n videoSrc?: string;\n description: string|TemplateResult;\n}\n\nexport class SimulatorOptions {\n initialCameraPosition = {x: 0, y: 1.5, z: 0};\n scenePath = XR_BLOCKS_ASSETS_PATH +\n 'simulator/scenes/XREmulatorsceneV5_livingRoom.glb';\n initialScenePosition = {x: -1.6, y: 0.3, z: 0};\n defaultMode = SimulatorMode.USER;\n defaultHand = Handedness.LEFT;\n modeIndicator = {\n enabled: true,\n element: 'xrblocks-simulator-mode-indicator',\n };\n instructions = {\n enabled: true,\n element: 'xrblocks-simulator-instructions',\n customInstructions: [] as SimulatorCustomInstruction[],\n };\n handPosePanel = {\n enabled: true,\n element: 'xrblocks-simulator-hand-pose-panel',\n };\n geminilive = false;\n stereo = {\n enabled: false,\n };\n // Whether to render the main scene to a render texture or directly to the\n // canvas.\n // This is a temporary option until we figure out why splats look faded.\n renderToRenderTexture = true;\n // Blending mode when rendering the virtual scene.\n blendingMode: 'normal'|'screen' = 'normal';\n\n constructor(options?: DeepReadonly<DeepPartial<SimulatorOptions>>) {\n deepMerge(this, options);\n }\n};\n","export class SpeechSynthesizerOptions {\n enabled = false;\n /** If true, a new call to speak() will interrupt any ongoing speech. */\n allowInterruptions = false;\n}\n\nexport class SpeechRecognizerOptions {\n enabled = true;\n /** Recognition language (e.g., 'en-US'). */\n lang = 'en-US';\n /** If true, recognition continues after a pause. */\n continuous = false;\n /** Keywords to detect as commands. */\n commands: string[] = [];\n /** If true, provides interim results. */\n interimResults = false;\n /** Minimum confidence (0-1) for a command. */\n commandConfidenceThreshold = 0.7;\n /** If true, play activation sounds in simulator. */\n playSimulatorActivationSounds = true;\n}\n\nexport class SoundOptions {\n speechSynthesizer = new SpeechSynthesizerOptions();\n speechRecognizer = new SpeechRecognizerOptions();\n}\n","import {deepMerge} from '../../utils/OptionsUtils';\nimport {DeepPartial} from '../../utils/Types';\n\n/**\n * Configuration options for the ObjectDetector.\n */\nexport class ObjectsOptions {\n debugging = false;\n enabled = false;\n showDebugVisualizations = false;\n\n /**\n * Margin to add when cropping the object image, as a percentage of image\n * size.\n */\n objectImageMargin = 0.05;\n\n /**\n * Configuration for the detection backends.\n */\n backendConfig = {\n /** The active backend to use for detection. */\n activeBackend: 'gemini' as 'gemini' | 'mediapipe',\n gemini: {\n systemInstruction:\n `Please provide me with the bounding box coordinates for the primary objects in the given image, prioritizing objects that are nearby. For each bounding box, include ymin, xmin, ymax, and xmax. These coordinates should be absolute values ranging from 0 to 1000, corresponding to the image as if it were resized to 1000x1000 pixels. The origin (xmin:0; ymin:0) is the top-left corner of the image, and (xmax:1000; ymax:1000) is the bottom-right corner. List a maximum of 5 objects. Ignore hands and other human body parts, as well as any UI elements attached to them (e.g., a blue circle attached to a finger).`,\n responseSchema: {\n type: 'ARRAY',\n items: {\n type: 'OBJECT',\n required: ['objectName', 'ymin', 'xmin', 'ymax', 'xmax'],\n properties: {\n objectName: {type: 'STRING'},\n ymin: {type: 'NUMBER'},\n xmin: {type: 'NUMBER'},\n ymax: {type: 'NUMBER'},\n xmax: {type: 'NUMBER'},\n },\n },\n },\n },\n /** Placeholder for a future MediaPipe backend configuration. */\n mediapipe: {},\n };\n\n\n constructor(options?: DeepPartial<ObjectsOptions>) {\n if (options) {\n deepMerge(this, options);\n }\n }\n\n /**\n * Enables the object detector.\n */\n enable() {\n this.enabled = true;\n return this;\n }\n}\n","import {deepMerge} from '../../utils/OptionsUtils';\nimport {DeepPartial} from '../../utils/Types'\n\nexport class PlanesOptions {\n debugging = false;\n enabled = false;\n showDebugVisualizations = false;\n\n constructor(options?: DeepPartial<PlanesOptions>) {\n if (options) {\n deepMerge(this, options);\n }\n }\n\n enable() {\n this.enabled = true;\n return this;\n }\n}\n","import {deepMerge} from '../utils/OptionsUtils';\nimport {DeepPartial} from '../utils/Types'\n\nimport {ObjectsOptions} from './objects/ObjectsOptions';\nimport {PlanesOptions} from './planes/PlanesOptions';\n\nexport class WorldOptions {\n debugging = false;\n enabled = false;\n planes = new PlanesOptions();\n objects = new ObjectsOptions();\n\n constructor(options?: DeepPartial<WorldOptions>) {\n if (options) {\n deepMerge(this, options);\n }\n }\n\n /**\n * Enables plane detection.\n */\n enablePlaneDetection() {\n this.enabled = true;\n this.planes.enable();\n return this;\n }\n\n /**\n * Enables object detection.\n */\n enableObjectDetection() {\n this.enabled = true;\n this.objects.enable();\n return this;\n }\n}\n","import {AIOptions} from '../ai/AIOptions';\nimport {DeviceCameraOptions, xrDeviceCameraEnvironmentOptions, xrDeviceCameraUserOptions} from '../camera/CameraOptions.js';\nimport {DepthOptions, xrDepthMeshOptions} from '../depth/DepthOptions.js';\nimport {HandsOptions} from '../input/HandsOptions.js';\nimport {LightingOptions} from '../lighting/LightingOptions.js';\nimport {PhysicsOptions} from '../physics/PhysicsOptions';\nimport {SimulatorOptions} from '../simulator/SimulatorOptions';\nimport {SoundOptions} from '../sound/SoundOptions';\nimport {deepMerge} from '../utils/OptionsUtils';\nimport {DeepPartial, DeepReadonly} from '../utils/Types';\nimport {WorldOptions} from '../world/WorldOptions';\n\n/**\n * Default options for XR controllers, which encompass hands by default in\n * Android XR, mouse input on desktop, tracked controllers, and gamepads.\n */\nexport class InputOptions {\n /** Whether controller input is enabled. */\n enabled = true;\n /** Whether mouse input should act as a controller on desktop. */\n enabledMouse = true;\n /** Whether to enable debugging features for controllers. */\n debug = false;\n /** Whether to show controller models. */\n visualization = false;\n /** Whether to show the ray lines extending from the controllers. */\n visualizeRays = false;\n};\n\n/**\n * Default options for the reticle (pointing cursor).\n */\nexport class ReticleOptions {\n enabled = true;\n}\n\n/**\n * Options for the XR transition effect.\n */\nexport class XRTransitionOptions {\n /** Whether the transition effect is enabled. */\n enabled = false;\n /** The duration of the transition in seconds. */\n transitionTime = 0.5;\n /** The default background color for VR transitions. */\n defaultBackgroundColor = 0xffffff;\n}\n\n/**\n * A central configuration class for the entire XR Blocks system. It aggregates\n * all settings and provides chainable methods for enabling common features.\n */\nexport class Options {\n /**\n * Whether to use antialiasing.\n */\n antialias = true;\n /**\n * Whether to use a logarithmic depth buffer. Useful for depth-aware\n * occlusions.\n */\n logarithmicDepthBuffer = false;\n /**\n * Global flag for enabling various debugging features.\n */\n debugging = false;\n /**\n * Whether to request a stencil buffer.\n */\n stencil = false;\n /**\n * Canvas element to use for rendering.\n * If not defined, a new element will be added to document body.\n */\n canvas?: HTMLCanvasElement;\n\n /**\n * Any additional required features when initializing webxr.\n */\n webxrRequiredFeatures: string[] = [];\n\n // \"local-floor\" sets the scene origin at the user's feet,\n // \"local\" sets the scene origin near their head.\n referenceSpaceType: XRReferenceSpaceType = 'local-floor';\n\n controllers = new InputOptions();\n depth = new DepthOptions();\n lighting = new LightingOptions();\n deviceCamera = new DeviceCameraOptions();\n hands = new HandsOptions();\n reticles = new ReticleOptions();\n sound = new SoundOptions();\n ai = new AIOptions();\n simulator = new SimulatorOptions();\n world = new WorldOptions();\n physics = new PhysicsOptions();\n transition = new XRTransitionOptions();\n camera = {\n near: 0.01,\n far: 500,\n }\n\n /**\n * Whether to use post-processing effects.\n */\n usePostprocessing = false;\n\n /**\n * Configuration for the XR session button.\n */\n xrButton = {\n enabled: true,\n startText: 'Enter XR',\n endText: 'Exit XR',\n invalidText: 'XR Not Supported',\n startSimulatorText: 'Enter Simulator',\n enableSimulator: true,\n showSimulatorButtonOnMobile: false,\n autostartSimulatorOnDesktop: true,\n // Whether to always autostart the simulator.\n autostartSimulator: false\n };\n\n /**\n * Constructs the Options object by merging default values with provided\n * custom options.\n * @param options - A custom options object to override the defaults.\n */\n constructor(options?: DeepReadonly<DeepPartial<Options>>) {\n deepMerge(this, options)\n }\n\n /**\n * Enables a standard set of options for a UI-focused experience.\n * @returns The instance for chaining.\n */\n enableUI() {\n this.antialias = true;\n this.reticles.enabled = true;\n return this;\n }\n\n /**\n * Enables reticles for visualizing targets of hand rays in WebXR.\n * @returns The instance for chaining.\n */\n enableReticles() {\n this.reticles.enabled = true;\n return this;\n }\n\n /**\n * Enables depth sensing in WebXR with default options.\n * @returns The instance for chaining.\n */\n enableDepth() {\n this.depth = new DepthOptions(xrDepthMeshOptions);\n return this;\n }\n\n /**\n * Enables plane detection.\n * @returns The instance for chaining.\n */\n enablePlaneDetection() {\n this.world.enablePlaneDetection();\n return this;\n }\n\n /**\n * Enables object detection.\n * @returns The instance for chaining.\n */\n enableObjectDetection() {\n this.world.enableObjectDetection();\n return this;\n }\n\n\n /**\n * Enables device camera (passthrough) with a specific facing mode.\n * @param facingMode - The desired camera facing mode, either 'environment' or\n * 'user'.\n * @returns The instance for chaining.\n */\n enableCamera(facingMode: 'environment'|'user' = 'environment') {\n this.deviceCamera = new DeviceCameraOptions(\n facingMode === 'environment' ? xrDeviceCameraEnvironmentOptions :\n xrDeviceCameraUserOptions);\n return this;\n }\n\n /**\n * Enables hand tracking.\n * @returns The instance for chaining.\n */\n enableHands() {\n this.hands.enabled = true;\n return this;\n }\n\n /**\n * Enables the visualization of rays for hand tracking.\n * @returns The instance for chaining.\n */\n enableHandRays() {\n this.controllers.visualizeRays = true;\n return this;\n }\n\n /**\n * Enables the Gemini Live feature.\n * @returns The instance for chaining.\n */\n enableGeminiLive() {\n this.simulator.geminilive = true;\n return this;\n }\n\n /**\n * Enables a standard set of AI features, including Gemini Live.\n * @returns The instance for chaining.\n */\n enableAI() {\n this.ai.enabled = true;\n this.ai.gemini.enabled = true;\n this.ai.gemini.live.enabled = true;\n return this;\n }\n\n /**\n * Enables the XR transition component for toggling VR.\n * @returns The instance for chaining.\n */\n enableXRTransitions() {\n this.transition.enabled = true;\n return this;\n }\n}\n","export class SimulatorMediaDeviceInfo {\n constructor(\n public deviceId = 'simulator', public groupId = 'simulator',\n public kind: MediaDeviceKind = 'videoinput',\n public label = 'Simulator Camera') {}\n}\n","export enum ConstrainDomStringMatch {\n EXACT = 0,\n IDEAL = 1,\n ACCEPTABLE = 2,\n UNACCEPTABLE = 3\n}\n\n/**\n * Evaluates how a string value satisfies a ConstrainDOMString constraint.\n *\n * @param constraint - The ConstrainDOMString to check against.\n * @param value - The string value to test.\n * @returns A `ConstrainDomStringMatch` enum indicating the match level.\n */\nexport function evaluateConstrainDOMString(\n constraint: ConstrainDOMString, value: string): ConstrainDomStringMatch {\n // Helper to check for a match against a string or string array.\n const matches = (c: string|string[], v: string): boolean => {\n return typeof c === 'string' ? v === c : c.includes(v);\n };\n\n // If no constraint is given, the value is simply acceptable.\n if (constraint == null) {\n return ConstrainDomStringMatch.ACCEPTABLE;\n }\n\n // A standalone string or array is treated as an implicit 'exact' requirement.\n if (typeof constraint === 'string' || Array.isArray(constraint)) {\n return matches(constraint, value) ? ConstrainDomStringMatch.EXACT :\n ConstrainDomStringMatch.UNACCEPTABLE;\n }\n\n // Handle the object-based constraint.\n if (typeof constraint === 'object') {\n // The 'exact' property is a hard requirement that overrides all others.\n if (constraint.exact !== undefined) {\n return matches(constraint.exact, value) ?\n ConstrainDomStringMatch.EXACT :\n ConstrainDomStringMatch.UNACCEPTABLE;\n }\n\n // If there's no 'exact' constraint, check 'ideal'.\n if (constraint.ideal !== undefined) {\n if (matches(constraint.ideal, value)) {\n return ConstrainDomStringMatch.IDEAL;\n }\n }\n\n // If the value doesn't match 'ideal' (or if 'ideal' wasn't specified),\n // it's still acceptable because 'ideal' is only a preference.\n return ConstrainDomStringMatch.ACCEPTABLE;\n }\n\n // Fallback for any unknown constraint types.\n return ConstrainDomStringMatch.UNACCEPTABLE;\n}\n","import * as THREE from 'three';\n\nimport {SimulatorMediaDeviceInfo} from './SimulatorMediaDeviceInfo';\nimport {ConstrainDomStringMatch, evaluateConstrainDOMString} from './utils/CameraUtils';\n\nexport class SimulatorCamera {\n private cameraCreated = false;\n private cameraInfo?: SimulatorMediaDeviceInfo;\n private mediaStream?: MediaStream;\n private canvas?: HTMLCanvasElement;\n private context?: CanvasRenderingContext2D|null;\n private fps = 30;\n matchRenderingCamera = true;\n width = 512;\n height = 512;\n camera = new THREE.PerspectiveCamera();\n\n constructor(private renderer: THREE.WebGLRenderer) {}\n\n init() {\n this.createSimulatorCamera();\n }\n\n createSimulatorCamera() {\n if (this.cameraCreated) {\n return;\n }\n this.canvas = document.createElement('canvas');\n this.canvas.width = this.width;\n this.canvas.height = this.height;\n this.context = this.canvas.getContext('2d');\n this.mediaStream = this.canvas.captureStream(this.fps);\n const videoTrack = this.mediaStream.getVideoTracks()[0];\n const id = this.mediaStream.getVideoTracks()[0].getSettings().deviceId;\n this.cameraInfo = new SimulatorMediaDeviceInfo(/*deviceId=*/ id);\n videoTrack.stop();\n this.cameraCreated = true;\n }\n\n async enumerateDevices() {\n if (this.cameraInfo) {\n return [this.cameraInfo];\n }\n return [];\n }\n\n onBeforeSimulatorSceneRender(\n camera: THREE.Camera, renderScene: (_: THREE.Camera) => void) {\n if (!this.cameraCreated) {\n return;\n }\n if (!this.matchRenderingCamera) {\n this.camera.position.copy(camera.position);\n this.camera.quaternion.copy(camera.quaternion);\n renderScene(this.camera);\n const sWidth = this.renderer.domElement.width;\n const sHeight = this.renderer.domElement.height;\n const aspectRatio = this.width / this.height;\n const croppedSourceWidth = Math.min(sWidth, sHeight * aspectRatio);\n const croppedSourceHeight = Math.min(sHeight, sWidth / aspectRatio);\n const sx = (sWidth - croppedSourceWidth) / 2;\n const sy = (sHeight - croppedSourceHeight) / 2;\n this.context!.drawImage(\n this.renderer.domElement, sx, sy, croppedSourceWidth,\n croppedSourceHeight, 0, 0, this.width, this.height);\n }\n }\n\n onSimulatorSceneRendered() {\n if (!this.cameraCreated) {\n return;\n }\n if (this.matchRenderingCamera) {\n const sWidth = this.renderer.domElement.width;\n const sHeight = this.renderer.domElement.height;\n const aspectRatio = this.width / this.height;\n const croppedSourceWidth = Math.min(sWidth, sHeight * aspectRatio);\n const croppedSourceHeight = Math.min(sHeight, sWidth / aspectRatio);\n const sx = (sWidth - croppedSourceWidth) / 2;\n const sy = (sHeight - croppedSourceHeight) / 2;\n this.context!.drawImage(\n this.renderer.domElement, sx, sy, croppedSourceWidth,\n croppedSourceHeight, 0, 0, this.width, this.height);\n }\n }\n\n restartVideoTrack() {\n if (!this.cameraCreated) {\n return;\n }\n this.mediaStream = this.canvas!.captureStream(this.fps);\n const id = this.mediaStream.getVideoTracks()[0].getSettings().deviceId;\n this.cameraInfo!.deviceId = id || '';\n }\n\n getMedia(constraints: MediaTrackConstraints = {}) {\n if (!this.cameraCreated) {\n return;\n }\n if (!constraints?.deviceId ||\n evaluateConstrainDOMString(\n constraints?.deviceId, this.cameraInfo!.deviceId) !=\n ConstrainDomStringMatch.UNACCEPTABLE) {\n const videoTrack = this.mediaStream!.getVideoTracks()[0];\n if (videoTrack.readyState == 'ended') {\n this.restartVideoTrack();\n }\n return this.mediaStream;\n }\n return null;\n }\n}\n","export const AVERAGE_IPD_METERS = 0.063;\nexport enum SimulatorRenderMode {\n DEFAULT = 'default',\n STEREO_LEFT = 'left',\n STEREO_RIGHT = 'right',\n}","/**\n * A frozen object containing standardized string values for `event.code`.\n * Used for desktop simulation.\n */\nexport enum Keycodes {\n // --- Movement Keys ---\n W_CODE = 'KeyW',\n A_CODE = 'KeyA',\n S_CODE = 'KeyS',\n D_CODE = 'KeyD',\n UP = 'ArrowUp',\n DOWN = 'ArrowDown',\n LEFT = 'ArrowLeft',\n RIGHT = 'ArrowRight',\n\n // --- Vertical Movement / Elevation ---\n Q_CODE = 'KeyQ', // Often used for 'down' or 'strafe left'\n E_CODE = 'KeyE', // Often used for 'up' or 'strafe right'\n PAGE_UP = 'PageUp',\n PAGE_DOWN = 'PageDown',\n\n // --- Action & Interaction Keys ---\n SPACE_CODE = 'Space',\n ENTER_CODE = 'Enter',\n T_CODE = 'KeyT', // General purpose 'toggle' or 'tool' key\n\n // --- Modifier Keys ---\n LEFT_SHIFT_CODE = 'ShiftLeft',\n RIGHT_SHIFT_CODE = 'ShiftRight',\n LEFT_CTRL_CODE = 'ControlLeft',\n RIGHT_CTRL_CODE = 'ControlRight',\n LEFT_ALT_CODE = 'AltLeft',\n RIGHT_ALT_CODE = 'AltRight',\n CAPS_LOCK_CODE = 'CapsLock',\n\n // --- UI & System Keys ---\n ESCAPE_CODE = 'Escape',\n TAB_CODE = 'Tab',\n\n // --- Alphabet Keys ---\n B_CODE = 'KeyB',\n C_CODE = 'KeyC',\n F_CODE = 'KeyF',\n G_CODE = 'KeyG',\n H_CODE = 'KeyH',\n I_CODE = 'KeyI',\n J_CODE = 'KeyJ',\n K_CODE = 'KeyK',\n L_CODE = 'KeyL',\n M_CODE = 'KeyM',\n N_CODE = 'KeyN',\n O_CODE = 'KeyO',\n P_CODE = 'KeyP',\n R_CODE = 'KeyR',\n U_CODE = 'KeyU',\n V_CODE = 'KeyV',\n X_CODE = 'KeyX',\n Y_CODE = 'KeyY',\n Z_CODE = 'KeyZ',\n\n // --- Number Keys ---\n DIGIT_0 = 'Digit0',\n DIGIT_1 = 'Digit1',\n DIGIT_2 = 'Digit2',\n DIGIT_3 = 'Digit3',\n DIGIT_4 = 'Digit4',\n DIGIT_5 = 'Digit5',\n DIGIT_6 = 'Digit6',\n DIGIT_7 = 'Digit7',\n DIGIT_8 = 'Digit8',\n DIGIT_9 = 'Digit9',\n\n BACKQUOTE = 'Backquote',\n}\n","import * as THREE from 'three';\n\nexport class SimulatorControllerState {\n localControllerPositions =\n [new THREE.Vector3(-0.3, -0.1, -0.3), new THREE.Vector3(0.3, -0.1, -0.3)];\n localControllerOrientations =\n [new THREE.Quaternion(), new THREE.Quaternion()];\n\n currentControllerIndex = 0;\n}","import * as THREE from 'three';\n\nimport {Input} from '../../input/Input.js';\nimport {Keycodes} from '../../utils/Keycodes';\nimport {SimulatorRenderMode} from '../SimulatorConstants';\nimport {SimulatorControllerState} from '../SimulatorControllerState';\nimport {SimulatorHands} from '../SimulatorHands.js';\n\nconst {A_CODE, D_CODE, E_CODE, Q_CODE, S_CODE, W_CODE} = Keycodes;\nconst vector3 = new THREE.Vector3();\nconst euler = new THREE.Euler();\n\nexport class SimulatorControlMode {\n camera!: THREE.Camera;\n input!: Input;\n timer!: THREE.Timer;\n\n /**\n * Create a SimulatorControlMode\n */\n constructor(\n protected simulatorControllerState: SimulatorControllerState,\n protected downKeys: Set<Keycodes>, protected hands: SimulatorHands,\n protected setStereoRenderMode: (_: SimulatorRenderMode) => void,\n protected toggleUserInterface: () => void) {}\n\n /**\n * Initialize the simulator control mode.\n */\n init({camera, input, timer}:\n {camera: THREE.Camera, input: Input, timer: THREE.Timer}) {\n this.camera = camera;\n this.input = input;\n this.timer = timer;\n }\n\n onPointerDown(_: MouseEvent) {}\n onPointerUp(_: MouseEvent) {}\n onPointerMove(_: MouseEvent) {}\n onKeyDown(event: KeyboardEvent) {\n if (event.code == Keycodes.DIGIT_1) {\n this.setStereoRenderMode(SimulatorRenderMode.STEREO_LEFT);\n } else if (event.code == Keycodes.DIGIT_2) {\n this.setStereoRenderMode(SimulatorRenderMode.STEREO_RIGHT);\n } else if (event.code == Keycodes.BACKQUOTE) {\n this.toggleUserInterface();\n }\n }\n onModeActivated() {}\n onModeDeactivated() {}\n\n update() {\n this.updateCameraPosition();\n this.updateControllerPositions();\n }\n\n updateCameraPosition() {\n const deltaTime = this.timer.getDelta();\n const cameraRotation = this.camera.quaternion;\n const cameraPosition = this.camera.position;\n const downKeys = this.downKeys;\n vector3\n .set(\n Number(downKeys.has(D_CODE)) - Number(downKeys.has(A_CODE)),\n Number(downKeys.has(Q_CODE)) - Number(downKeys.has(E_CODE)),\n Number(downKeys.has(S_CODE)) - Number(downKeys.has(W_CODE)),\n )\n .multiplyScalar(deltaTime)\n .applyQuaternion(cameraRotation)\n cameraPosition.add(vector3);\n }\n\n updateControllerPositions() {\n this.camera.updateMatrixWorld();\n for (let i = 0; i < 2; i++) {\n const controller = this.input.controllers[i];\n controller.position\n .copy(this.simulatorControllerState.localControllerPositions[i])\n .applyMatrix4(this.camera.matrixWorld);\n controller.quaternion\n .copy(this.simulatorControllerState.localControllerOrientations[i])\n .premultiply(this.camera.quaternion);\n controller.updateMatrix();\n const mesh =\n i == 0 ? this.hands.leftController : this.hands.rightController;\n mesh.position.copy(controller.position);\n mesh.quaternion.copy(controller.quaternion);\n }\n }\n\n rotateOnPointerMove(\n event: MouseEvent, objectQuaternion: THREE.Quaternion,\n multiplier = 0.002) {\n euler.setFromQuaternion(objectQuaternion, 'YXZ');\n euler.y += event.movementX * multiplier;\n euler.x += event.movementY * multiplier;\n\n // Clamp camera pitch to +/-90 deg (+/-1.57 rad) with a 0.01 rad (0.573 deg)\n // buffer to prevent gimbal lock.\n const PI_2 = Math.PI / 2;\n euler.x = Math.max(-PI_2 + 0.01, Math.min(PI_2 - 0.01, euler.x));\n\n objectQuaternion.setFromEuler(euler);\n }\n\n enableSimulatorHands() {\n this.hands.showHands();\n this.input.dispatchEvent({\n type: 'connected',\n target: this.input.controllers[0],\n data: {handedness: 'left'}\n });\n this.input.dispatchEvent({\n type: 'connected',\n target: this.input.controllers[1],\n data: {handedness: 'right'}\n });\n }\n\n disableSimulatorHands() {\n this.hands.hideHands();\n this.input.dispatchEvent({\n type: 'disconnected',\n target: this.input.controllers[0],\n data: {handedness: 'left'}\n });\n this.input.dispatchEvent({\n type: 'disconnected',\n target: this.input.controllers[1],\n data: {handedness: 'right'}\n });\n }\n}\n","import * as THREE from 'three';\n\nimport {Keycodes} from '../../utils/Keycodes';\n\nimport {SimulatorControlMode} from './SimulatorControlMode';\n\nconst vector3 = new THREE.Vector3();\nconst {A_CODE, D_CODE, E_CODE, Q_CODE, S_CODE, SPACE_CODE, T_CODE, W_CODE} =\n Keycodes;\n\nexport class SimulatorControllerMode extends SimulatorControlMode {\n onPointerMove(event: MouseEvent) {\n if (event.buttons) {\n const controllerOrientation =\n this.simulatorControllerState\n .localControllerOrientations[this.simulatorControllerState\n .currentControllerIndex];\n this.rotateOnPointerMove(event, controllerOrientation, -0.002);\n }\n }\n\n override update() {\n this.updateControllerPositions();\n }\n\n onModeActivated() {\n this.enableSimulatorHands();\n }\n\n updateControllerPositions() {\n const deltaTime = this.timer.getDelta();\n const downKeys = this.downKeys;\n vector3\n .set(\n Number(downKeys.has(D_CODE)) - Number(downKeys.has(A_CODE)),\n Number(downKeys.has(Q_CODE)) - Number(downKeys.has(E_CODE)),\n Number(downKeys.has(S_CODE)) - Number(downKeys.has(W_CODE)),\n )\n .multiplyScalar(deltaTime);\n this.simulatorControllerState\n .localControllerPositions[this.simulatorControllerState\n .currentControllerIndex]\n .add(vector3);\n super.updateControllerPositions();\n }\n\n toggleControllerIndex() {\n this.hands.toggleHandedness();\n }\n\n onKeyDown(event: KeyboardEvent) {\n super.onKeyDown(event);\n if (event.code == T_CODE) {\n this.toggleControllerIndex();\n } else if (event.code == SPACE_CODE) {\n const controllerSelecting =\n this.input\n .controllers[this.simulatorControllerState.currentControllerIndex]\n .userData?.selected;\n const newSelectingState = !controllerSelecting;\n if (this.simulatorControllerState.currentControllerIndex == 0) {\n this.hands.setLeftHandPinching(newSelectingState);\n } else {\n this.hands.setRightHandPinching(newSelectingState);\n }\n }\n }\n}\n","\nimport {SimulatorControlMode} from './SimulatorControlMode.js';\n\nexport class SimulatorPoseMode extends SimulatorControlMode {\n onModeActivated() {\n this.enableSimulatorHands();\n }\n\n onPointerMove(event: MouseEvent) {\n if (event.buttons) {\n this.rotateOnPointerMove(event, this.camera.quaternion);\n }\n }\n}\n","import {SimulatorControlMode} from './SimulatorControlMode.js';\n\nexport class SimulatorUserMode extends SimulatorControlMode {\n onModeActivated() {\n this.disableSimulatorHands();\n this.input.mouseController.connect();\n }\n\n onModeDeactivated() {\n this.input.mouseController.disconnect();\n }\n\n onPointerDown(event: MouseEvent) {\n if (event.buttons & 1) {\n this.input.mouseController.callSelectStart();\n }\n }\n\n onPointerUp() {\n if (this.input.mouseController.userData.selected) {\n this.input.mouseController.callSelectEnd();\n }\n }\n\n onPointerMove(event: MouseEvent) {\n this.input.mouseController.updateMousePositionFromEvent(event);\n if (event.buttons & 2) {\n this.rotateOnPointerMove(event, this.camera.quaternion);\n }\n }\n}\n","import {SimulatorMode} from '../SimulatorOptions';\n\nexport class SetSimulatorModeEvent extends Event {\n static type = 'setSimulatorMode';\n constructor(public simulatorMode: SimulatorMode) {\n super(SetSimulatorModeEvent.type, {bubbles: true, composed: true});\n }\n}\n","import * as THREE from 'three';\n\nimport {Handedness} from '../input/Hands';\nimport {Input} from '../input/Input';\nimport {Keycodes} from '../utils/Keycodes';\n\nimport {SimulatorControllerMode} from './controlModes/SimulatorControllerMode'\nimport {SimulatorControlMode} from './controlModes/SimulatorControlMode';\nimport {SimulatorPoseMode} from './controlModes/SimulatorPoseMode';\nimport {SimulatorUserMode} from './controlModes/SimulatorUserMode';\nimport {SetSimulatorModeEvent} from './events/SimulatorModeEvents';\nimport {SimulatorRenderMode} from './SimulatorConstants';\nimport {SimulatorControllerState} from './SimulatorControllerState';\nimport {SimulatorHands} from './SimulatorHands';\nimport {SimulatorInterface} from './SimulatorInterface';\nimport {NEXT_SIMULATOR_MODE, SimulatorMode, SimulatorOptions} from './SimulatorOptions';\n\nfunction preventDefault(event: Event) {\n event.preventDefault();\n}\n\nexport type SimulatorModeIndicatorElement = HTMLElement&{\n simulatorMode: SimulatorMode;\n}\n\nexport class SimulatorControls {\n pointerDown = false;\n downKeys = new Set<Keycodes>();\n\n // Custom HTML element indicating the simulator control mode.\n modeIndicatorElement?: SimulatorModeIndicatorElement;\n\n simulatorMode = SimulatorMode.USER;\n\n simulatorModeControls: SimulatorControlMode;\n simulatorModes: {[key: string]: SimulatorControlMode};\n renderer!: THREE.WebGLRenderer;\n\n private _onPointerDown = this.onPointerDown.bind(this);\n private _onPointerUp = this.onPointerUp.bind(this);\n private _onKeyDown = this.onKeyDown.bind(this);\n private _onKeyUp = this.onKeyUp.bind(this);\n private _onPointerMove = this.onPointerMove.bind(this);\n\n /**\n * Create the simulator controls.\n * @param hands - The simulator hands manager.\n * @param setStereoRenderMode - A function to set the stereo mode.\n * @param userInterface - The simulator user interface manager.\n */\n constructor(\n public simulatorControllerState: SimulatorControllerState,\n public hands: SimulatorHands,\n setStereoRenderMode: (_: SimulatorRenderMode) => void,\n private userInterface: SimulatorInterface) {\n const toggleUserInterface = () => {\n this.userInterface.toggleInterfaceVisible();\n };\n this.simulatorModes = {\n [SimulatorMode.USER]: new SimulatorUserMode(\n this.simulatorControllerState, this.downKeys, hands,\n setStereoRenderMode, toggleUserInterface),\n [SimulatorMode.POSE]: new SimulatorPoseMode(\n this.simulatorControllerState, this.downKeys, hands,\n setStereoRenderMode, toggleUserInterface),\n [SimulatorMode.CONTROLLER]: new SimulatorControllerMode(\n this.simulatorControllerState, this.downKeys, hands,\n setStereoRenderMode, toggleUserInterface),\n };\n\n this.simulatorModeControls = this.simulatorModes[this.simulatorMode];\n }\n\n /**\n * Initialize the simulator controls.\n */\n init({camera, input, timer, renderer, simulatorOptions}: {\n camera: THREE.Camera,\n input: Input,\n timer: THREE.Timer,\n renderer: THREE.WebGLRenderer,\n simulatorOptions: SimulatorOptions\n }) {\n for (const mode in this.simulatorModes) {\n this.simulatorModes[mode].init({camera, input, timer});\n }\n this.renderer = renderer;\n this.setSimulatorMode(simulatorOptions.defaultMode);\n this.simulatorControllerState.currentControllerIndex =\n simulatorOptions.defaultHand === Handedness.LEFT ? 0 : 1;\n this.connect();\n }\n\n connect() {\n const domElement = this.renderer.domElement;\n document.addEventListener('keyup', this._onKeyUp);\n document.addEventListener('keydown', this._onKeyDown);\n domElement.addEventListener('pointermove', this._onPointerMove);\n domElement.addEventListener('pointerdown', this._onPointerDown);\n domElement.addEventListener('pointerup', this._onPointerUp);\n domElement.addEventListener('contextmenu', preventDefault);\n }\n\n update() {\n this.simulatorModeControls.update();\n }\n\n\n onPointerMove(event: MouseEvent) {\n this.simulatorModeControls.onPointerMove(event);\n }\n\n onPointerDown(event: MouseEvent) {\n this.simulatorModeControls.onPointerDown(event);\n this.pointerDown = true;\n }\n\n onPointerUp(event: MouseEvent) {\n this.simulatorModeControls.onPointerUp(event);\n this.pointerDown = false;\n }\n\n onKeyDown(event: KeyboardEvent) {\n this.downKeys.add(event.code as Keycodes);\n if (event.code == Keycodes.LEFT_SHIFT_CODE) {\n this.setSimulatorMode(NEXT_SIMULATOR_MODE[this.simulatorMode]);\n }\n this.simulatorModeControls.onKeyDown(event);\n }\n\n onKeyUp(event: KeyboardEvent) {\n this.downKeys.delete(event.code as Keycodes);\n }\n\n setSimulatorMode(mode: SimulatorMode) {\n this.simulatorMode = mode;\n this.simulatorModeControls.onModeDeactivated();\n this.simulatorModeControls = this.simulatorModes[this.simulatorMode];\n this.simulatorModeControls.onModeActivated();\n if (this.modeIndicatorElement) {\n this.modeIndicatorElement.simulatorMode = mode;\n }\n }\n\n setModeIndicatorElement(element: SimulatorModeIndicatorElement) {\n element.simulatorMode = this.simulatorMode;\n element.addEventListener('setSimulatorMode', (event) => {\n if (event instanceof SetSimulatorModeEvent) {\n this.setSimulatorMode(event.simulatorMode);\n }\n });\n this.modeIndicatorElement = element;\n }\n}\n","import * as THREE from 'three';\n\nexport class SimulatorDepthMaterial extends THREE.MeshBasicMaterial {\n override onBeforeCompile(\n shader:\n {vertexShader: string, fragmentShader: string, uniforms: object}) {\n shader.vertexShader =\n shader.vertexShader\n .replace(\n '#include <clipping_planes_pars_vertex>',\n [\n '#include <clipping_planes_pars_vertex>',\n 'varying vec4 vViewCoordinates;'\n ].join('\\n'))\n .replace('#include <project_vertex>', [\n '#include <project_vertex>', 'vViewCoordinates = mvPosition;'\n ].join('\\n'));\n shader.fragmentShader =\n shader.fragmentShader\n .replace(\n '#include <clipping_planes_pars_fragment>',\n [\n '#include <clipping_planes_pars_fragment>',\n 'varying vec4 vViewCoordinates;'\n ].join('\\n'))\n .replace('#include <dithering_fragment>', [\n '#include <dithering_fragment>',\n 'gl_FragColor = vec4(-vViewCoordinates.z, 0.0, 0.0, 1.0);'\n ].join('\\n'));\n }\n}","import * as THREE from 'three';\n\nimport {Depth} from '../depth/Depth';\n\nimport {SimulatorDepthMaterial} from './SimulatorDepthMaterial';\nimport {SimulatorScene} from './SimulatorScene';\n\nexport class SimulatorDepth {\n renderer!: THREE.WebGLRenderer;\n camera!: THREE.Camera;\n depth!: Depth;\n depthWidth = 160;\n depthHeight = 160;\n depthBufferSlice = new Float32Array();\n depthMaterial!: SimulatorDepthMaterial;\n depthRenderTarget!: THREE.WebGLRenderTarget;\n depthBuffer!: Float32Array;\n\n constructor(private simulatorScene: SimulatorScene) {}\n\n /**\n * Initialize Simulator Depth.\n */\n init(renderer: THREE.WebGLRenderer, camera: THREE.Camera, depth: Depth) {\n this.renderer = renderer;\n this.camera = camera;\n this.depth = depth;\n\n this.createRenderTarget();\n this.depthMaterial = new SimulatorDepthMaterial();\n }\n\n createRenderTarget() {\n this.depthRenderTarget =\n new THREE.WebGLRenderTarget(this.depthWidth, this.depthHeight, {\n format: THREE.RedFormat,\n type: THREE.FloatType,\n });\n this.depthBuffer = new Float32Array(this.depthWidth * this.depthHeight);\n }\n\n update() {\n this.renderDepthScene();\n this.updateDepth();\n }\n\n renderDepthScene() {\n const originalRenderTarget = this.renderer.getRenderTarget();\n this.renderer.setRenderTarget(this.depthRenderTarget);\n this.simulatorScene.overrideMaterial = this.depthMaterial;\n this.renderer.render(this.simulatorScene, this.camera);\n this.simulatorScene.overrideMaterial = null;\n this.renderer.setRenderTarget(originalRenderTarget);\n }\n\n updateDepth() {\n // We preventively unbind the PIXEL_PACK_BUFFER before reading from the\n // render target in case external libraries (Spark.js) left it bound.\n const context = this.renderer.getContext() as WebGL2RenderingContext;\n context.bindBuffer(context.PIXEL_PACK_BUFFER, null);\n\n this.renderer.readRenderTargetPixels(\n this.depthRenderTarget, 0, 0, this.depthWidth, this.depthHeight,\n this.depthBuffer);\n\n // Flip the depth buffer.\n if (this.depthBufferSlice.length != this.depthWidth) {\n this.depthBufferSlice = new Float32Array(this.depthWidth);\n }\n for (let i = 0; i < this.depthHeight / 2; ++i) {\n const j = this.depthHeight - 1 - i;\n const i_offset = i * this.depthWidth;\n const j_offset = j * this.depthWidth;\n\n // Copy row i to a temp slice\n this.depthBufferSlice.set(\n this.depthBuffer.subarray(i_offset, i_offset + this.depthWidth));\n // Copy row j to row i\n this.depthBuffer.copyWithin(\n i_offset, j_offset, j_offset + this.depthWidth);\n // Copy the temp slice (original row i) to row j\n this.depthBuffer.set(this.depthBufferSlice, j_offset);\n }\n\n const depthData = {\n width: this.depthWidth,\n height: this.depthHeight,\n data: this.depthBuffer.buffer,\n rawValueToMeters: 1.0,\n };\n\n this.depth.updateCPUDepthData(depthData as XRCPUDepthInformation, 0);\n }\n}\n","import {SimulatorHandPose} from '../handPoses/HandPoses';\n\n// Request to change the hand pose.\nexport class SimulatorHandPoseChangeRequestEvent extends Event {\n static type = 'SimulatorHandPoseChangeRequestEvent';\n constructor(public pose: SimulatorHandPose) {\n super(\n SimulatorHandPoseChangeRequestEvent.type,\n {bubbles: true, composed: true});\n }\n}\n","import type {DeepReadonly} from '../../utils/Types';\n\nimport {LEFT_HAND_FIST, RIGHT_HAND_FIST} from './FistHandPoses';\nimport type {SimulatorHandPoseJoints} from './HandPoseJoints';\nimport {LEFT_HAND_PINCHING, RIGHT_HAND_PINCHING} from './PinchingHandPoses';\nimport {LEFT_HAND_POINTING, RIGHT_HAND_POINTING} from './PointingHandPoses';\nimport {LEFT_HAND_RELAXED, RIGHT_HAND_RELAXED} from './RelaxedHandPoses';\nimport {LEFT_HAND_ROCK, RIGHT_HAND_ROCK} from './RockHandPoses';\nimport {LEFT_HAND_THUMBS_DOWN, RIGHT_HAND_THUMBS_DOWN} from './ThumbsDownPoses';\nimport {LEFT_HAND_THUMBS_UP, RIGHT_HAND_THUMBS_UP} from './ThumbsUpPoses';\nimport {LEFT_HAND_VICTORY, RIGHT_HAND_VICTORY} from './VictoryHandPoses';\n\n// Enum of hand poses.\nexport enum SimulatorHandPose {\n RELAXED = 'relaxed',\n PINCHING = 'pinching',\n FIST = 'fist',\n THUMBS_UP = 'thumbs_up',\n POINTING = 'pointing',\n ROCK = 'rock',\n THUMBS_DOWN = 'thumbs_down',\n VICTORY = 'victory'\n}\n\nexport const SIMULATOR_HAND_POSE_TO_JOINTS_LEFT:\n DeepReadonly<Record<SimulatorHandPose, SimulatorHandPoseJoints>> =\n Object.freeze({\n [SimulatorHandPose.RELAXED]: LEFT_HAND_RELAXED,\n [SimulatorHandPose.PINCHING]: LEFT_HAND_PINCHING,\n [SimulatorHandPose.FIST]: LEFT_HAND_FIST,\n [SimulatorHandPose.THUMBS_UP]: LEFT_HAND_THUMBS_UP,\n [SimulatorHandPose.POINTING]: LEFT_HAND_POINTING,\n [SimulatorHandPose.ROCK]: LEFT_HAND_ROCK,\n [SimulatorHandPose.THUMBS_DOWN]: LEFT_HAND_THUMBS_DOWN,\n [SimulatorHandPose.VICTORY]: LEFT_HAND_VICTORY\n } as const);\n\nexport const SIMULATOR_HAND_POSE_TO_JOINTS_RIGHT:\n DeepReadonly<Record<SimulatorHandPose, SimulatorHandPoseJoints>> =\n Object.freeze({\n [SimulatorHandPose.RELAXED]: RIGHT_HAND_RELAXED,\n [SimulatorHandPose.PINCHING]: RIGHT_HAND_PINCHING,\n [SimulatorHandPose.FIST]: RIGHT_HAND_FIST,\n [SimulatorHandPose.THUMBS_UP]: RIGHT_HAND_THUMBS_UP,\n [SimulatorHandPose.POINTING]: RIGHT_HAND_POINTING,\n [SimulatorHandPose.ROCK]: RIGHT_HAND_ROCK,\n [SimulatorHandPose.THUMBS_DOWN]: RIGHT_HAND_THUMBS_DOWN,\n [SimulatorHandPose.VICTORY]: RIGHT_HAND_VICTORY\n });\n\nexport const SIMULATOR_HAND_POSE_NAMES:\n Readonly<Record<SimulatorHandPose, string>> = Object.freeze({\n [SimulatorHandPose.RELAXED]: 'Relaxed',\n [SimulatorHandPose.PINCHING]: 'Pinching',\n [SimulatorHandPose.FIST]: 'Fist',\n [SimulatorHandPose.THUMBS_UP]: 'Thumbs Up',\n [SimulatorHandPose.POINTING]: 'Pointing',\n [SimulatorHandPose.ROCK]: 'Rock',\n [SimulatorHandPose.THUMBS_DOWN]: 'Thumbs Down',\n [SimulatorHandPose.VICTORY]: 'Victory'\n });\n","export const LEFT_HAND_RELAXED = [\n {'t': [-0.05, -0.08, -0.1], 'r': [0.5373, 0, 0, 0.8434]},\n {'t': [-0.0281, -0.0594, -0.1165], 'r': [0.3943, -0.2036, -0.3103, 0.8407]},\n {'t': [0.0026, -0.0299, -0.1518], 'r': [0.3476, -0.1049, -0.5285, 0.7674]},\n {'t': [0.0169, -0.0181, -0.1728], 'r': [0.3521, 0.0515, -0.635, 0.6857]},\n {'t': [0.0268, -0.0018, -0.1966], 'r': [0.3521, 0.0515, -0.635, 0.6857]},\n {'t': [-0.0369, -0.0541, -0.1121], 'r': [0.5882, -0.1036, 0.0205, 0.8018]},\n {'t': [-0.024, 0.0143, -0.1465], 'r': [0.3269, -0.0887, -0.0003, 0.9409]},\n {'t': [-0.0172, 0.0394, -0.1765], 'r': [-0.0114, -0.0813, -0.0286, 0.9962]},\n {'t': [-0.0138, 0.0388, -0.1986], 'r': [-0.1994, -0.0379, -0.0372, 0.9785]},\n {'t': [-0.0125, 0.0287, -0.2199], 'r': [-0.1994, -0.0379, -0.0372, 0.9785]},\n {'t': [-0.0499, -0.0528, -0.1125], 'r': [0.5569, -0.0203, 0.0319, 0.8297]},\n {'t': [-0.0496, 0.0131, -0.1445], 'r': [0.3908, -0.0273, 0.1089, 0.9136]},\n {'t': [-0.0513, 0.0438, -0.1738], 'r': [0.0747, -0.0923, 0.0634, 0.9909]},\n {'t': [-0.0462, 0.0488, -0.2036], 'r': [-0.1936, -0.1156, 0.0299, 0.9738]},\n {'t': [-0.0404, 0.0387, -0.2253], 'r': [-0.1936, -0.1156, 0.0299, 0.9738]},\n {'t': [-0.0612, -0.0561, -0.1138], 'r': [0.5095, 0.0572, 0.0274, 0.8581]},\n {'t': [-0.0698, 0.0022, -0.1468], 'r': [0.4396, -0.0068, 0.1748, 0.881]},\n {'t': [-0.0751, 0.0329, -0.1719], 'r': [0.071, -0.0911, 0.1344, 0.9842]},\n {'t': [-0.0703, 0.0383, -0.2029], 'r': [-0.1764, -0.1244, 0.0831, 0.9729]},\n {'t': [-0.0641, 0.0302, -0.2227], 'r': [-0.1764, -0.1244, 0.0831, 0.9729]},\n {'t': [-0.0708, -0.0616, -0.1145], 'r': [0.4571, 0.1437, 0.0457, 0.8765]},\n {'t': [-0.0889, -0.0132, -0.148], 'r': [0.3971, 0.0569, 0.2436, 0.883]},\n {'t': [-0.098, 0.0096, -0.1727], 'r': [0.1604, -0.0085, 0.243, 0.9566]},\n {'t': [-0.0997, 0.0171, -0.194], 'r': [-0.0034, -0.0735, 0.1859, 0.9798]},\n {'t': [-0.0979, 0.0165, -0.2131], 'r': [-0.0034, -0.0735, 0.1859, 0.9798]}\n] as const;\n\nexport const RIGHT_HAND_RELAXED = [\n {'t': [0.05, -0.08, -0.1], 'r': [0.5373, 0, 0, 0.8434]},\n {'t': [0.0279, -0.0592, -0.1167], 'r': [0.3237, 0.1161, 0.293, 0.8921]},\n {'t': [0.0026, -0.0313, -0.158], 'r': [0.2171, 0.0194, 0.5207, 0.8254]},\n {'t': [-0.0042, -0.0219, -0.1837], 'r': [0.2597, -0.0685, 0.6498, 0.711]},\n {'t': [-0.01, -0.0084, -0.2107], 'r': [0.2597, -0.0685, 0.6498, 0.711]},\n {'t': [0.037, -0.0539, -0.1123], 'r': [0.5808, 0.1164, -0.0414, 0.8046]},\n {'t': [0.0238, 0.0151, -0.147], 'r': [0.3081, 0.0484, -0.0273, 0.9497]},\n {'t': [0.0206, 0.0393, -0.1786], 'r': [-0.0461, 0.0526, -0.0104, 0.9975]},\n {'t': [0.0185, 0.0373, -0.201], 'r': [-0.1674, 0.0162, -0.0064, 0.9857]},\n {'t': [0.0177, 0.0287, -0.223], 'r': [-0.1674, 0.0162, -0.0064, 0.9857]},\n {'t': [0.05, -0.0527, -0.1126], 'r': [0.5619, 0.0306, -0.0478, 0.8252]},\n {'t': [0.0497, 0.0138, -0.1449], 'r': [0.353, 0.0474, -0.1014, 0.9289]},\n {'t': [0.0491, 0.0425, -0.1767], 'r': [0.0777, 0.1076, -0.0559, 0.9896]},\n {'t': [0.0431, 0.0478, -0.2066], 'r': [-0.0679, 0.1248, -0.0343, 0.9893]},\n {'t': [0.0369, 0.0436, -0.2302], 'r': [-0.0679, 0.1248, -0.0343, 0.9893]},\n {'t': [0.0614, -0.0561, -0.1136], 'r': [0.5303, -0.05, -0.0384, 0.8455]},\n {'t': [0.0699, 0.0028, -0.1472], 'r': [0.4168, 0.0427, -0.1662, 0.8926]},\n {'t': [0.0722, 0.0331, -0.1739], 'r': [0.1339, 0.1107, -0.1236, 0.977]},\n {'t': [0.0665, 0.0425, -0.2041], 'r': [-0.0175, 0.1318, -0.0809, 0.9878]},\n {'t': [0.0606, 0.0413, -0.2257], 'r': [-0.0175, 0.1318, -0.0809, 0.9878]},\n {'t': [0.0711, -0.0618, -0.1145], 'r': [0.4891, -0.1378, -0.0535, 0.8596]},\n {'t': [0.0892, -0.0127, -0.1484], 'r': [0.3439, 0.0196, -0.23, 0.9102]},\n {'t': [0.0924, 0.0087, -0.1761], 'r': [0.1965, 0.0585, -0.2173, 0.9543]},\n {'t': [0.0921, 0.0184, -0.1968], 'r': [0.0936, 0.1069, -0.1575, 0.9773]},\n {'t': [0.0896, 0.0217, -0.2157], 'r': [0.0936, 0.1069, -0.1575, 0.9773]}\n] as const;\n","export const LEFT_HAND_PINCHING = [\n {'t': [-0.05, -0.08, -0.1], 'r': [0.5373, 0, 0, 0.8434], 's': [1, 1, 1]},\n {\n 't': [-0.0281, -0.0594, -0.1165],\n 'r': [0.3072, -0.0483, -0.257, 0.915],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0083, -0.0299, -0.1581],\n 'r': [0.1832, 0.0632, -0.4718, 0.8602],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0069, -0.0195, -0.1841],\n 'r': [0.2232, 0.1362, -0.6112, 0.747],\n 's': [1, 1, 0.9999]\n },\n {\n 't': [-0.0063, -0.0051, -0.2109],\n 'r': [0.2232, 0.1362, -0.6112, 0.747],\n 's': [1, 1, 0.9999]\n },\n {\n 't': [-0.0369, -0.0541, -0.112],\n 'r': [0.5858, -0.1038, 0.0205, 0.8035],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.024, 0.0142, -0.1465],\n 'r': [0.1342, -0.1392, -0.0707, 0.9786],\n 's': [1.0001, 1, 0.9999]\n },\n {\n 't': [-0.0122, 0.0248, -0.1828],\n 'r': [-0.2614, -0.0983, -0.1184, 0.9529],\n 's': [1.0001, 0.9999, 0.9999]\n },\n {\n 't': [-0.0095, 0.0131, -0.2017],\n 'r': [-0.3454, -0.0506, -0.1338, 0.9275],\n 's': [1, 0.9999, 1]\n },\n {\n 't': [-0.0098, -0.0028, -0.219],\n 'r': [-0.3454, -0.0506, -0.1338, 0.9275],\n 's': [1, 0.9999, 1]\n },\n {\n 't': [-0.0498, -0.0529, -0.1126],\n 'r': [0.5552, -0.0196, 0.0307, 0.8309],\n 's': [1.0001, 1, 1]\n },\n {\n 't': [-0.0496, 0.0131, -0.1444],\n 'r': [0.3957, -0.0669, 0.0916, 0.9113],\n 's': [1, 0.9999, 1]\n },\n {\n 't': [-0.0477, 0.0443, -0.173],\n 'r': [0.0284, -0.1256, 0.0276, 0.9913],\n 's': [1, 1, 0.9999]\n },\n {\n 't': [-0.0403, 0.0463, -0.2027],\n 'r': [-0.1956, -0.1387, -0.007, 0.9708],\n 's': [1.0001, 1, 1]\n },\n {\n 't': [-0.0339, 0.036, -0.224],\n 'r': [-0.1956, -0.1387, -0.007, 0.9708],\n 's': [1.0001, 1, 1]\n },\n {\n 't': [-0.0612, -0.0561, -0.1137],\n 'r': [0.5088, 0.0591, 0.0245, 0.8585],\n 's': [1, 1.0001, 1]\n },\n {\n 't': [-0.0697, 0.0021, -0.1467],\n 'r': [0.464, -0.0595, 0.1601, 0.8692],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0713, 0.0348, -0.1698],\n 'r': [0.0595, -0.1373, 0.0948, 0.9842],\n 's': [1.0001, 1.0001, 1]\n },\n {\n 't': [-0.0633, 0.0395, -0.2003],\n 'r': [-0.1735, -0.159, 0.0354, 0.9713],\n 's': [1, 1, 0.9999]\n },\n {\n 't': [-0.0561, 0.0313, -0.2197],\n 'r': [-0.1735, -0.159, 0.0354, 0.9713],\n 's': [1, 1, 0.9999]\n },\n {\n 't': [-0.0707, -0.0617, -0.1146],\n 'r': [0.4573, 0.1467, 0.0408, 0.8762],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0889, -0.0132, -0.148],\n 'r': [0.4065, 0.0051, 0.2314, 0.8838],\n 's': [1, 0.9999, 1.0001]\n },\n {\n 't': [-0.0946, 0.0109, -0.1723],\n 'r': [0.1595, -0.0578, 0.2175, 0.9612],\n 's': [1, 0.9999, 1]\n },\n {\n 't': [-0.094, 0.019, -0.1934],\n 'r': [-0.0122, -0.1189, 0.1509, 0.9813],\n 's': [1.0001, 1, 1]\n },\n {\n 't': [-0.0904, 0.0182, -0.2123],\n 'r': [-0.0122, -0.1189, 0.1509, 0.9813],\n 's': [1.0001, 1, 1]\n }\n] as const;\n\nexport const RIGHT_HAND_PINCHING = [\n {'t': [0.05, -0.08, -0.1], 'r': [0.5373, 0, 0, 0.8434], 's': [1, 1, 1]},\n {\n 't': [0.0279, -0.0593, -0.1166],\n 'r': [0.307, 0.046, 0.2483, 0.9176],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0082, -0.0291, -0.1587],\n 'r': [0.1833, -0.0669, 0.4657, 0.8632],\n 's': [0.9999, 1, 1]\n },\n {\n 't': [0.0071, -0.0186, -0.185],\n 'r': [0.2256, -0.1369, 0.6093, 0.7477],\n 's': [1, 1, 0.9999]\n },\n {\n 't': [0.0064, -0.0039, -0.212],\n 'r': [0.2256, -0.1369, 0.6093, 0.7477],\n 's': [1, 1, 0.9999]\n },\n {\n 't': [0.037, -0.0539, -0.1122],\n 'r': [0.5831, 0.1146, -0.0388, 0.8034],\n 's': [1, 0.9999, 1]\n },\n {\n 't': [0.0237, 0.0153, -0.147],\n 'r': [0.1209, 0.0891, 0.0196, 0.9885],\n 's': [1, 0.9999, 1]\n },\n {\n 't': [0.0163, 0.0257, -0.1849],\n 'r': [-0.2747, 0.0723, 0.0511, 0.9574],\n 's': [1, 0.9999, 0.9999]\n },\n {\n 't': [0.014, 0.0138, -0.204],\n 'r': [-0.3165, 0.0337, 0.0633, 0.9459],\n 's': [1, 0.9999, 1]\n },\n {\n 't': [0.0136, -0.0012, -0.2226],\n 'r': [-0.3165, 0.0337, 0.0633, 0.9459],\n 's': [1, 0.9999, 1]\n },\n {\n 't': [0.0501, -0.0527, -0.1126],\n 'r': [0.5625, 0.0291, -0.0455, 0.825],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0497, 0.0141, -0.1449],\n 'r': [0.3465, 0.0658, -0.0921, 0.9312],\n 's': [1.0001, 0.9999, 0.9999]\n },\n {\n 't': [0.0473, 0.0424, -0.177],\n 'r': [0.0559, 0.1235, -0.0403, 0.9899],\n 's': [1.0001, 1, 0.9999]\n },\n {\n 't': [0.0402, 0.0463, -0.2069],\n 'r': [-0.0703, 0.1381, -0.0195, 0.9877],\n 's': [1.0001, 1, 0.9999]\n },\n {\n 't': [0.0335, 0.0419, -0.2304],\n 'r': [-0.0703, 0.1381, -0.0195, 0.9877],\n 's': [1.0001, 1, 0.9999]\n },\n {\n 't': [0.0615, -0.0561, -0.1136],\n 'r': [0.5287, -0.0513, -0.0363, 0.8465],\n 's': [1.0001, 1, 0.9999]\n },\n {\n 't': [0.07, 0.003, -0.1472],\n 'r': [0.4197, 0.0598, -0.1607, 0.8913],\n 's': [1, 1, 0.9999]\n },\n {\n 't': [0.0709, 0.0336, -0.1737],\n 'r': [0.1329, 0.1258, -0.1128, 0.9766],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0643, 0.0431, -0.2038],\n 'r': [-0.0172, 0.145, -0.068, 0.9869],\n 's': [1.0001, 0.9999, 1]\n },\n {\n 't': [0.0577, 0.0418, -0.2253],\n 'r': [-0.0172, 0.145, -0.068, 0.9869],\n 's': [1.0001, 0.9999, 1]\n },\n {\n 't': [0.0711, -0.0617, -0.1145],\n 'r': [0.4861, -0.139, -0.0517, 0.8612],\n 's': [1.0001, 0.9999, 1]\n },\n {\n 't': [0.0893, -0.0125, -0.1485],\n 'r': [0.317, 0.0459, -0.2224, 0.9208],\n 's': [1.0001, 0.9999, 1]\n },\n {\n 't': [0.0902, 0.0078, -0.1772],\n 'r': [0.1921, 0.0784, -0.2077, 0.9559],\n 's': [1, 1, 0.9999]\n },\n {\n 't': [0.0889, 0.0174, -0.1979],\n 'r': [0.0936, 0.1253, -0.1462, 0.9768],\n 's': [1.0001, 1, 1]\n },\n {\n 't': [0.0857, 0.0208, -0.2167],\n 'r': [0.0936, 0.1253, -0.1462, 0.9768],\n 's': [1.0001, 1, 1]\n }\n] as const;\n","export const LEFT_HAND_FIST = [\n {'t': [-0.0933, -0.0266, -0.1338], 'r': [0.1346, -0.1437, 0.0038, 0.9804]},\n {'t': [-0.0648, -0.0265, -0.1529], 'r': [0.0354, -0.3351, -0.1786, 0.9244]},\n {'t': [-0.0318, -0.0293, -0.1932], 'r': [0.0407, -0.2202, -0.5685, 0.7916]},\n {'t': [-0.0212, -0.0345, -0.2179], 'r': [0.0132, -0.12, -0.576, 0.8084]},\n {'t': [-0.0161, -0.039, -0.2469], 'r': [0.0132, -0.12, -0.576, 0.8084]},\n {'t': [-0.0731, -0.0197, -0.1569], 'r': [0.0999, -0.2377, 0.0822, 0.9627]},\n {'t': [-0.0399, -0.0023, -0.2221], 'r': [-0.4356, -0.1075, -0.0127, 0.8936]},\n {'t': [-0.0325, -0.0319, -0.246], 'r': [0.9331, 0.066, 0.0832, -0.3436]},\n {'t': [-0.035, -0.0462, -0.2296], 'r': [0.9874, 0.021, 0.128, -0.0903]},\n {'t': [-0.0408, -0.0496, -0.2076], 'r': [0.9874, 0.021, 0.128, -0.0903]},\n {'t': [-0.0853, -0.0187, -0.1614], 'r': [0.115, -0.1594, 0.0889, 0.9765]},\n {'t': [-0.0646, -0.0007, -0.2271], 'r': [-0.4919, -0.1197, 0.0382, 0.8616]},\n {'t': [-0.0544, -0.0353, -0.2477], 'r': [0.9309, 0.1571, 0.0605, -0.324]},\n {'t': [-0.0548, -0.0542, -0.2244], 'r': [0.9835, 0.1315, 0.1097, 0.0583]},\n {'t': [-0.0607, -0.051, -0.2013], 'r': [0.9835, 0.1315, 0.1097, 0.0583]},\n {'t': [-0.0972, -0.0213, -0.1628], 'r': [0.0881, -0.0966, 0.0847, 0.9878]},\n {'t': [-0.0856, -0.0088, -0.2263], 'r': [-0.4818, -0.1075, 0.1033, 0.8635]},\n {'t': [-0.0742, -0.0406, -0.246], 'r': [0.9378, 0.1774, 0.0089, -0.2983]},\n {'t': [-0.0715, -0.0585, -0.2205], 'r': [0.9769, 0.1847, 0.0804, 0.0714]},\n {'t': [-0.0757, -0.0552, -0.1994], 'r': [0.9769, 0.1847, 0.0804, 0.0714]},\n {'t': [-0.1078, -0.0253, -0.162], 'r': [0.0535, -0.0126, 0.0933, 0.9941]},\n {'t': [-0.1069, -0.0188, -0.2215], 'r': [-0.4433, -0.1294, 0.1523, 0.8738]},\n {'t': [-0.0939, -0.0444, -0.2398], 'r': [0.9002, 0.2018, -0.0275, -0.385]},\n {'t': [-0.0891, -0.0599, -0.2248], 'r': [0.9644, 0.2553, 0.0425, -0.0538]},\n {'t': [-0.0914, -0.0623, -0.2063], 'r': [0.9644, 0.2553, 0.0425, -0.0538]}\n] as const;\n\nexport const RIGHT_HAND_FIST = [\n {'t': [0.0504, -0.0155, -0.1083], 'r': [0.1392, 0.117, -0.058, 0.9816]},\n {'t': [0.022, -0.0122, -0.1291], 'r': [-0.0068, 0.3422, 0.1705, 0.924]},\n {'t': [-0.011, -0.019, -0.1691], 'r': [-0.0952, 0.2257, 0.5977, 0.7634]},\n {'t': [-0.0171, -0.0305, -0.1932], 'r': [-0.249, 0.0162, 0.627, 0.738]},\n {'t': [-0.0073, -0.0427, -0.2185], 'r': [-0.249, 0.0162, 0.627, 0.738]},\n {'t': [0.0314, -0.0068, -0.133], 'r': [0.1126, 0.213, -0.1468, 0.9594]},\n {'t': [0.0035, 0.014, -0.1987], 'r': [-0.5177, 0.1865, 0.0124, 0.8349]},\n {'t': [-0.0086, -0.0192, -0.2148], 'r': [0.9671, -0.1129, -0.1466, -0.1747]},\n {'t': [-0.0031, -0.0274, -0.1952], 'r': [0.9714, -0.0492, -0.2057, 0.1081]},\n {'t': [0.0063, -0.0222, -0.1749], 'r': [0.9714, -0.0492, -0.2057, 0.1081]},\n {'t': [0.0441, -0.0073, -0.137], 'r': [0.1251, 0.1341, -0.1467, 0.972]},\n {'t': [0.0283, 0.0126, -0.2028], 'r': [-0.5227, 0.1469, -0.0852, 0.8354]},\n {'t': [0.0144, -0.0224, -0.2202], 'r': [0.9399, -0.2078, -0.0451, -0.2671]},\n {'t': [0.0137, -0.0382, -0.1948], 'r': [0.9665, -0.181, -0.1188, 0.1381]},\n {'t': [0.0207, -0.0318, -0.1726], 'r': [0.9665, -0.181, -0.1188, 0.1381]},\n {'t': [0.0559, -0.0112, -0.1379], 'r': [0.0948, 0.0732, -0.1351, 0.9836]},\n {'t': [0.0482, 0.0022, -0.2011], 'r': [-0.5015, 0.1223, -0.1588, 0.8416]},\n {'t': [0.0337, -0.0294, -0.2191], 'r': [0.9432, -0.2267, 0.0156, -0.2423]},\n {'t': [0.0294, -0.0438, -0.1916], 'r': [0.9569, -0.2379, -0.08, 0.1464]},\n {'t': [0.0346, -0.0376, -0.1714], 'r': [0.9569, -0.2379, -0.08, 0.1464]},\n {'t': [0.0662, -0.0164, -0.1368], 'r': [0.0546, -0.0084, -0.1349, 0.9893]},\n {'t': [0.068, -0.0102, -0.1955], 'r': [-0.4587, 0.1335, -0.2099, 0.853]},\n {'t': [0.0529, -0.0353, -0.2127], 'r': [0.9107, -0.2444, 0.0606, -0.3274]},\n {'t': [0.0466, -0.0483, -0.1959], 'r': [0.9518, -0.3056, -0.0236, 0.0063]},\n {'t': [0.0488, -0.0485, -0.1773], 'r': [0.9518, -0.3056, -0.0236, 0.0063]}\n] as const;\n","export const LEFT_HAND_THUMBS_UP = [\n {'t': [-0.011, -0.0299, -0.0701], 'r': [0.1224, -0.1562, 0.6052, 0.771]},\n {'t': [0.0025, -0.0017, -0.0854], 'r': [0.3796, -0.3776, 0.3843, 0.7521]},\n {'t': [0.0162, 0.041, -0.1065], 'r': [0.6152, -0.1749, 0.0935, 0.763]},\n {'t': [0.0204, 0.0676, -0.1116], 'r': [0.5992, -0.1247, 0.1335, 0.7795]},\n {'t': [0.0225, 0.096, -0.1202], 'r': [0.5992, -0.1247, 0.1335, 0.7795]},\n {'t': [-0.0042, -0.008, -0.0928], 'r': [0.1427, -0.2467, 0.6763, 0.6793]},\n {'t': [0.0063, 0.0312, -0.155], 'r': [-0.4551, -0.5645, 0.3425, 0.5974]},\n {'t': [0.0447, 0.0257, -0.1538], 'r': [0.7509, 0.6277, 0.1981, -0.053]},\n {'t': [0.0396, 0.0184, -0.1338], 'r': [0.7246, 0.5124, 0.4244, 0.1797]},\n {'t': [0.0207, 0.0148, -0.1212], 'r': [0.7246, 0.5124, 0.4244, 0.1797]},\n {'t': [-0.0078, -0.0192, -0.0982], 'r': [0.109, -0.1737, 0.6698, 0.7137]},\n {'t': [-0.0006, 0.0083, -0.163], 'r': [-0.4929, -0.5301, 0.4215, 0.5462]},\n {'t': [0.0407, 0.0046, -0.1614], 'r': [0.705, 0.703, 0.0897, -0.0263]},\n {'t': [0.0382, -0.0005, -0.132], 'r': [0.6279, 0.5816, 0.4074, 0.3186]},\n {'t': [0.0165, -0.0021, -0.1217], 'r': [0.6279, 0.5816, 0.4074, 0.3186]},\n {'t': [-0.0092, -0.031, -0.0993], 'r': [0.0472, -0.1416, 0.6514, 0.7439]},\n {'t': [0.0006, -0.0142, -0.1626], 'r': [-0.5202, -0.4929, 0.4819, 0.5042]},\n {'t': [0.0398, -0.0159, -0.1611], 'r': [0.6996, 0.7076, 0.0706, 0.0696]},\n {'t': [0.0338, -0.0161, -0.1304], 'r': [0.5876, 0.6289, 0.3607, 0.3593]},\n {'t': [0.0143, -0.0168, -0.1208], 'r': [0.5876, 0.6289, 0.3607, 0.3593]},\n {'t': [-0.0081, -0.0426, -0.0982], 'r': [-0.0269, -0.0934, 0.6476, 0.7558]},\n {'t': [0.0026, -0.0377, -0.1578], 'r': [0.5435, 0.4612, -0.5243, -0.4658]},\n {'t': [0.0366, -0.0376, -0.1559], 'r': [0.6991, 0.7017, 0.0384, 0.1318]},\n {'t': [0.032, -0.0347, -0.1344], 'r': [0.575, 0.6796, 0.2522, 0.3795]},\n {'t': [0.0166, -0.0342, -0.1237], 'r': [0.575, 0.6796, 0.2522, 0.3795]}\n] as const;\n\nexport const RIGHT_HAND_THUMBS_UP = [\n {'t': [0.0317, -0.0212, -0.089], 'r': [0.2199, 0.1003, -0.594, 0.7673]},\n {'t': [0.0223, 0.009, -0.1042], 'r': [0.4294, 0.285, -0.3619, 0.7768]},\n {'t': [0.0158, 0.0521, -0.1273], 'r': [0.6012, 0.067, -0.0513, 0.7947]},\n {'t': [0.0145, 0.0784, -0.1348], 'r': [0.597, 0.0134, -0.0918, 0.7968]},\n {'t': [0.0163, 0.1065, -0.1446], 'r': [0.597, 0.0134, -0.0918, 0.7968]},\n {'t': [0.0303, 0.0032, -0.1103], 'r': [0.2434, 0.2002, -0.656, 0.6858]},\n {'t': [0.0337, 0.0475, -0.1698], 'r': [-0.3298, 0.4729, -0.4297, 0.6949]},\n {'t': [-0.0026, 0.0462, -0.1835], 'r': [0.7134, -0.6368, -0.0002, -0.2925]},\n {'t': [-0.0107, 0.0369, -0.1654], 'r': [0.7745, -0.5891, -0.2133, -0.0877]},\n {'t': [-0.0047, 0.0282, -0.145], 'r': [0.7745, -0.5891, -0.2133, -0.0877]},\n {'t': [0.0347, -0.0077, -0.1158], 'r': [0.2088, 0.1254, -0.6589, 0.7117]},\n {'t': [0.0416, 0.0251, -0.1782], 'r': [-0.3597, 0.4829, -0.4746, 0.6421]},\n {'t': [0.0018, 0.0251, -0.19], 'r': [-0.673, 0.7069, -0.0014, 0.2177]},\n {'t': [-0.0077, 0.0162, -0.163], 'r': [0.6957, -0.6456, -0.2988, 0.0994]},\n {'t': [0.0063, 0.0104, -0.1443], 'r': [0.6957, -0.6456, -0.2988, 0.0994]},\n {'t': [0.0361, -0.0196, -0.1178], 'r': [0.1467, 0.0923, -0.6537, 0.7367]},\n {'t': [0.0398, 0.0027, -0.1801], 'r': [-0.3611, 0.446, -0.5466, 0.6099]},\n {'t': [0.0028, 0.0047, -0.193], 'r': [-0.6782, 0.7246, -0.0014, 0.1226]},\n {'t': [-0.003, -0.0006, -0.1628], 'r': [-0.652, 0.6801, 0.2937, -0.1613]},\n {'t': [0.0108, -0.0046, -0.1465], 'r': [-0.652, 0.6801, 0.2937, -0.1613]},\n {'t': [0.0343, -0.0315, -0.1182], 'r': [0.0757, 0.0463, -0.6692, 0.7378]},\n {'t': [0.0363, -0.021, -0.1779], 'r': [-0.3141, 0.3981, -0.6168, 0.602]},\n {'t': [0.0062, -0.0166, -0.1931], 'r': [-0.6691, 0.7354, -0.0331, 0.1021]},\n {'t': [0.0012, -0.0185, -0.1716], 'r': [-0.6175, 0.7316, 0.235, -0.168]},\n {'t': [0.0116, -0.0223, -0.1564], 'r': [-0.6175, 0.7316, 0.235, -0.168]}\n] as const;\n","export const LEFT_HAND_POINTING = [\n {'t': [-0.0283, -0.0376, -0.0293], 'r': [0.1372, -0.208, 0.241, 0.938]},\n {'t': [0.0016, -0.0246, -0.0431], 'r': [0.0106, -0.3992, -0.0014, 0.9168]},\n {'t': [0.0392, -0.0237, -0.0781], 'r': [-0.1, -0.2869, -0.466, 0.831]},\n {'t': [0.0496, -0.0357, -0.1004], 'r': [-0.1511, -0.183, -0.4918, 0.8377]},\n {'t': [0.0533, -0.0497, -0.1265], 'r': [-0.1511, -0.183, -0.4918, 0.8377]},\n {'t': [-0.0078, -0.0226, -0.0496], 'r': [0.1168, -0.3031, 0.3253, 0.8881]},\n {'t': [0.0265, 0.0074, -0.1082], 'r': [0.0563, -0.1303, 0.2725, 0.9516]},\n {'t': [0.0346, 0.0153, -0.1453], 'r': [-0.0635, -0.1606, 0.2541, 0.9516]},\n {'t': [0.0419, 0.0144, -0.1659], 'r': [-0.1073, -0.1342, 0.2464, 0.9538]},\n {'t': [0.0494, 0.0105, -0.1873], 'r': [-0.1073, -0.1342, 0.2464, 0.9538]},\n {'t': [-0.0184, -0.0273, -0.0562], 'r': [0.1156, -0.2249, 0.3238, 0.9117]},\n {'t': [0.0052, -0.0021, -0.1177], 'r': [-0.4452, -0.2871, 0.2041, 0.8233]},\n {'t': [0.0324, -0.0274, -0.1363], 'r': [0.8476, 0.3909, 0.031, -0.3574]},\n {'t': [0.0392, -0.0465, -0.1142], 'r': [0.9167, 0.3645, 0.16, -0.0352]},\n {'t': [0.032, -0.0501, -0.0915], 'r': [0.9167, 0.3645, 0.16, -0.0352]},\n {'t': [-0.028, -0.0348, -0.0593], 'r': [0.0757, -0.1724, 0.308, 0.9326]},\n {'t': [-0.01, -0.0186, -0.1201], 'r': [-0.5151, -0.3075, 0.2332, 0.7654]},\n {'t': [0.018, -0.0439, -0.1306], 'r': [0.8841, 0.4115, 0.0419, -0.2175]},\n {'t': [0.0214, -0.0572, -0.1026], 'r': [0.8915, 0.3885, 0.1955, 0.1266]},\n {'t': [0.0111, -0.0549, -0.0835], 'r': [0.8915, 0.3885, 0.1955, 0.1266]},\n {'t': [-0.0357, -0.0434, -0.0601], 'r': [0.0242, -0.0998, 0.3079, 0.9459]},\n {'t': [-0.0254, -0.037, -0.1183], 'r': [-0.4608, -0.35, 0.2807, 0.7658]},\n {'t': [0.0022, -0.0544, -0.1281], 'r': [0.8346, 0.4535, 0.0038, -0.3127]},\n {'t': [0.0089, -0.0663, -0.1107], 'r': [0.8657, 0.4769, 0.1519, -0.0059]},\n {'t': [0.003, -0.0699, -0.0932], 'r': [0.8657, 0.4769, 0.1519, -0.0059]}\n] as const;\n\nexport const RIGHT_HAND_POINTING = [\n {'t': [-0.0042, -0.0248, -0.0222], 'r': [0.1163, -0.0095, -0.3006, 0.9466]},\n {'t': [-0.024, -0.0114, -0.048], 'r': [-0.052, 0.2376, -0.0719, 0.9673]},\n {'t': [-0.0482, -0.0149, -0.0937], 'r': [-0.2324, 0.2162, 0.3797, 0.869]},\n {'t': [-0.0535, -0.0306, -0.1155], 'r': [-0.2846, 0.1212, 0.4068, 0.8595]},\n {'t': [-0.0521, -0.0492, -0.1388], 'r': [-0.2846, 0.1212, 0.4068, 0.8595]},\n {'t': [-0.0129, -0.0119, -0.0508], 'r': [0.1258, 0.0866, -0.3895, 0.9083]},\n {'t': [-0.0173, 0.01, -0.1215], 'r': [0.1174, -0.0564, -0.3421, 0.9306]},\n {'t': [-0.0097, 0.018, -0.1587], 'r': [-0.0512, 0.0028, -0.347, 0.9365]},\n {'t': [-0.0105, 0.0158, -0.1805], 'r': [-0.1583, 0.003, -0.3458, 0.9249]},\n {'t': [-0.0137, 0.0085, -0.2021], 'r': [-0.1583, 0.003, -0.3458, 0.9249]},\n {'t': [-0.0017, -0.019, -0.052], 'r': [0.1155, 0.0062, -0.386, 0.9152]},\n {'t': [0.0038, -0.0037, -0.1206], 'r': [-0.2494, 0.0619, -0.3947, 0.8822]},\n {'t': [-0.0086, -0.0197, -0.1569], 'r': [-0.7146, 0.3231, -0.2612, 0.5628]},\n {'t': [-0.0306, -0.0389, -0.1502], 'r': [0.8643, -0.4054, 0.1306, -0.2676]},\n {'t': [-0.0406, -0.0469, -0.1297], 'r': [0.8643, -0.4054, 0.1306, -0.2676]},\n {'t': [0.0068, -0.0279, -0.0499], 'r': [0.0671, -0.0438, -0.3807, 0.9212]},\n {'t': [0.0155, -0.022, -0.1146], 'r': [-0.3096, 0.1005, -0.4385, 0.8377]},\n {'t': [-0.0022, -0.0389, -0.1452], 'r': [0.7388, -0.369, 0.2794, -0.4899]},\n {'t': [-0.0264, -0.0553, -0.1341], 'r': [0.852, -0.4611, 0.1257, -0.214]},\n {'t': [-0.0346, -0.0602, -0.1146], 'r': [0.852, -0.4611, 0.1257, -0.214]},\n {'t': [0.0126, -0.0374, -0.0464], 'r': [0.0105, -0.1129, -0.3882, 0.9146]},\n {'t': [0.0254, -0.0415, -0.1045], 'r': [-0.3088, 0.1125, -0.4825, 0.8119]},\n {'t': [0.0078, -0.0548, -0.1304], 'r': [-0.6368, 0.3211, -0.3767, 0.5912]},\n {'t': [-0.0112, -0.0661, -0.1307], 'r': [0.7535, -0.4639, 0.2523, -0.3916]},\n {'t': [-0.0244, -0.0737, -0.1196], 'r': [0.7535, -0.4639, 0.2523, -0.3916]}\n] as const;\n","export const LEFT_HAND_ROCK = [\n {\n 't': [-0.0123, -0.0183, -0.0267],\n 'r': [0.5149, -0.0845, -0.1158, 0.8452],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0153, -0.0052, -0.0437],\n 'r': [0.2665, -0.0899, -0.3721, 0.8846],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0335, 0.0154, -0.0867],\n 'r': [0.0177, 0.1842, -0.6731, 0.716],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0267, 0.0228, -0.1122],\n 'r': [0.0728, 0.2226, -0.6735, 0.7011],\n 's': [1, 1, 1]\n },\n {\n 't': [0.019, 0.0341, -0.1386],\n 'r': [0.0728, 0.2226, -0.6735, 0.7011],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0067, 0.0029, -0.0406],\n 'r': [0.475, -0.2118, -0.0726, 0.851],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0388, 0.061, -0.0749],\n 'r': [0.5779, -0.1002, -0.0602, 0.8077],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0481, 0.097, -0.086],\n 'r': [0.5059, -0.0922, -0.0672, 0.855],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0529, 0.1158, -0.0964],\n 'r': [0.4458, -0.0565, -0.053, 0.8918],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0562, 0.1334, -0.1107],\n 'r': [0.4458, -0.0565, -0.053, 0.8918],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0052, 0.0075, -0.0412],\n 'r': [0.5055, -0.126, -0.0623, 0.8513],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0144, 0.0671, -0.0735],\n 'r': [0.1227, -0.0631, -0.0269, 0.9901],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0199, 0.0775, -0.1133],\n 'r': [-0.4479, -0.0687, -0.0876, 0.8871],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0211, 0.0534, -0.1312],\n 'r': [-0.6828, -0.0523, -0.1046, 0.7212],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0192, 0.0294, -0.1316],\n 'r': [-0.6828, -0.0523, -0.1046, 0.7212],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0167, 0.0074, -0.0424],\n 'r': [0.491, -0.0372, -0.0778, 0.8669],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0075, 0.0623, -0.0758],\n 'r': [0.1717, -0.0904, 0.0273, 0.9806],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0007, 0.0753, -0.1121],\n 'r': [-0.3257, -0.1136, -0.0418, 0.9377],\n 's': [1, 1, 1]\n },\n {\n 't': [0.005, 0.0561, -0.1361],\n 'r': [-0.5492, -0.1111, -0.0905, 0.8233],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0066, 0.0356, -0.1433],\n 'r': [-0.5492, -0.1111, -0.0905, 0.8233],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0273, 0.0051, -0.0431],\n 'r': [0.4566, 0.0629, -0.0766, 0.8841],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0297, 0.0531, -0.0769],\n 'r': [0.3942, -0.0035, 0.1163, 0.9116],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0317, 0.0768, -0.1013],\n 'r': [0.4582, 0.0006, 0.1099, 0.882],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0341, 0.0951, -0.1136],\n 'r': [0.4085, -0.0179, 0.0535, 0.911],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0354, 0.1086, -0.1266],\n 'r': [0.4085, -0.0179, 0.0535, 0.911],\n 's': [1, 1, 1]\n }\n] as const;\n\nexport const RIGHT_HAND_ROCK = [\n {\n 't': [0.0015, -0.0417, -0.0513],\n 'r': [0.5617, 0.0123, 0.1355, 0.8161],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0235, -0.025, -0.07],\n 'r': [0.2818, 0.0046, 0.4006, 0.8718],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0354, -0.0001, -0.1128],\n 'r': [-0.0257, -0.2764, 0.6652, 0.6931],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0238, 0.0089, -0.1359],\n 'r': [-0.0006, -0.3419, 0.6556, 0.6733],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0088, 0.0215, -0.1584],\n 'r': [-0.0006, -0.3419, 0.6556, 0.6733],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.015, -0.0179, -0.0645],\n 'r': [0.5302, 0.1299, 0.1154, 0.8299],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0403, 0.0456, -0.0947],\n 'r': [0.5874, 0.0115, 0.0813, 0.8051],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0451, 0.0825, -0.1058],\n 'r': [0.5048, 0.001, 0.0806, 0.8595],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0468, 0.1015, -0.1165],\n 'r': [0.4494, -0.0352, 0.0601, 0.8906],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0465, 0.1195, -0.1308],\n 'r': [0.4494, -0.0352, 0.0601, 0.8906],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0029, -0.0139, -0.063],\n 'r': [0.5567, 0.046, 0.0996, 0.8234],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.016, 0.0502, -0.0895],\n 'r': [0.1657, -0.0189, 0.0053, 0.986],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0146, 0.0642, -0.1285],\n 'r': [-0.4455, 0.0104, 0.0258, 0.8948],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0143, 0.0404, -0.1468],\n 'r': [-0.7027, 0.0133, 0.0292, 0.7107],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0137, 0.0163, -0.146],\n 'r': [-0.7027, 0.0133, 0.0292, 0.7107],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0087, -0.0144, -0.0627],\n 'r': [0.5389, -0.0411, 0.1061, 0.8346],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0058, 0.0446, -0.0897],\n 'r': [0.2331, 0.0139, -0.0389, 0.9716],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0052, 0.0621, -0.1248],\n 'r': [-0.3041, 0.0513, -0.0024, 0.9512],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0022, 0.0442, -0.1503],\n 'r': [-0.5472, 0.0609, 0.0335, 0.8341],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0009, 0.0239, -0.1579],\n 'r': [-0.5472, 0.0609, 0.0335, 0.8341],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0194, -0.0172, -0.0627],\n 'r': [0.5054, -0.1365, 0.0899, 0.8473],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0276, 0.0346, -0.0893],\n 'r': [0.4597, -0.0527, -0.1093, 0.8797],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0334, 0.0611, -0.1099],\n 'r': [0.5162, -0.056, -0.0989, 0.8489],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0378, 0.0805, -0.1194],\n 'r': [0.4448, -0.0407, -0.0462, 0.8935],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0411, 0.0949, -0.1311],\n 'r': [0.4448, -0.0407, -0.0462, 0.8935],\n 's': [1, 1, 1]\n }\n] as const;\n","export const LEFT_HAND_THUMBS_DOWN = [\n {\n 't': [-0.0169, 0.0317, -0.0845],\n 'r': [0.2721, -0.3488, -0.6314, 0.6369],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0019, 0.008, -0.1021],\n 'r': [-0.0533, 0.5043, 0.7891, -0.3467],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0208, -0.0318, -0.1276],\n 'r': [-0.2229, 0.6138, 0.7555, 0.0539],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0282, -0.0578, -0.1318],\n 'r': [-0.2724, 0.6476, 0.7112, 0.0242],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0389, -0.0856, -0.1338],\n 'r': [-0.2724, 0.6476, 0.7112, 0.0242],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0046, 0.0177, -0.0997],\n 'r': [0.1919, -0.3993, -0.6438, 0.6238],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0618, -0.0034, -0.1463],\n 'r': [-0.1884, 0.0883, -0.6795, 0.7035],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0481, -0.0093, -0.1821],\n 'r': [0.6204, -0.5352, 0.4297, -0.3794],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0275, -0.0094, -0.1746],\n 'r': [0.6806, -0.6532, 0.2814, -0.176],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0141, -0.0064, -0.1561],\n 'r': [0.6806, -0.6532, 0.2814, -0.176],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0062, 0.0299, -0.1019],\n 'r': [0.2399, -0.3631, -0.598, 0.6731],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0621, 0.0218, -0.1466],\n 'r': [-0.241, 0.1225, -0.6156, 0.7403],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0427, 0.0133, -0.1823],\n 'r': [0.7097, -0.4862, 0.373, -0.3475],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0165, 0.0095, -0.1681],\n 'r': [0.7968, -0.5892, 0.1321, -0.0209],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0119, 0.0128, -0.1447],\n 'r': [0.7968, -0.5892, 0.1321, -0.0209],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0033, 0.0406, -0.1037],\n 'r': [0.2574, -0.3085, -0.5681, 0.7183],\n 's': [1, 1, 1]\n },\n {\n 't': [0.052, 0.0419, -0.1485],\n 'r': [-0.2306, 0.1278, -0.5499, 0.7925],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0339, 0.0328, -0.182],\n 'r': [0.7575, -0.4754, 0.2861, -0.344],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0099, 0.025, -0.1634],\n 'r': [0.843, -0.5293, 0.0926, -0.0248],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0068, 0.0266, -0.142],\n 'r': [0.843, -0.5293, 0.0926, -0.0248],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0018, 0.0508, -0.104],\n 'r': [0.2798, -0.2351, -0.5355, 0.7614],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0378, 0.0613, -0.1483],\n 'r': [-0.1652, 0.0952, -0.5046, 0.842],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0259, 0.054, -0.1792],\n 'r': [0.7429, -0.4404, 0.2677, -0.4273],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0084, 0.0449, -0.169],\n 'r': [0.8704, -0.4542, 0.1121, -0.1532],\n 's': [1, 1, 1]\n },\n {\n 't': [0.002, 0.0431, -0.1514],\n 'r': [0.8704, -0.4542, 0.1121, -0.1532],\n 's': [1, 1, 1]\n }\n] as const;\n\nexport const RIGHT_HAND_THUMBS_DOWN = [\n {\n 't': [0.0237, 0.033, -0.083],\n 'r': [0.325, 0.2979, 0.5612, 0.7004],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0039, 0.0142, -0.1018],\n 'r': [0.0744, 0.4501, 0.7672, 0.4508],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0239, -0.0191, -0.133],\n 'r': [0.2089, 0.5732, 0.7915, 0.0363],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0341, -0.0435, -0.1401],\n 'r': [0.2664, 0.6251, 0.7316, 0.0555],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0476, -0.0698, -0.144],\n 'r': [0.2664, 0.6251, 0.7316, 0.0555],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0003, 0.0251, -0.0989],\n 'r': [0.2488, 0.3591, 0.5717, 0.6944],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0603, 0.0201, -0.1463],\n 'r': [-0.2217, -0.1036, 0.5936, 0.7667],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.045, 0.0116, -0.1809],\n 'r': [0.681, 0.4806, -0.3657, -0.4143],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0253, 0.0071, -0.1724],\n 'r': [0.7487, 0.5817, -0.2444, -0.2032],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0121, 0.0068, -0.1535],\n 'r': [0.7487, 0.5817, -0.2444, -0.2032],\n 's': [1, 1, 1]\n },\n {\n 't': [0.001, 0.0374, -0.1005],\n 'r': [0.2971, 0.3158, 0.527, 0.7309],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0548, 0.0447, -0.1454],\n 'r': [-0.2475, -0.1117, 0.5236, 0.8076],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0369, 0.0331, -0.181],\n 'r': [0.759, 0.413, -0.3155, -0.3922],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0126, 0.0231, -0.1665],\n 'r': [0.8595, 0.4988, -0.1065, -0.0339],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0084, 0.0248, -0.1428],\n 'r': [0.8595, 0.4988, -0.1065, -0.0339],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0064, 0.0472, -0.1018],\n 'r': [0.3122, 0.2567, 0.4998, 0.766],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0402, 0.0619, -0.1463],\n 'r': [-0.22, -0.1072, 0.4537, 0.8569],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.025, 0.0506, -0.1806],\n 'r': [0.8003, 0.3914, -0.2353, -0.3886],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0035, 0.0369, -0.1624],\n 'r': [0.8979, 0.4322, -0.0728, -0.0395],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0008, 0.0373, -0.1409],\n 'r': [0.8979, 0.4322, -0.0728, -0.0395],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0136, 0.0558, -0.1017],\n 'r': [0.3278, 0.1772, 0.4672, 0.8018],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0219, 0.0775, -0.1452],\n 'r': [-0.1811, -0.0932, 0.4016, 0.8929],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0108, 0.0677, -0.1758],\n 'r': [0.7842, 0.3582, -0.2073, -0.4623],\n 's': [1, 1, 1]\n },\n {\n 't': [0.004, 0.0547, -0.1656],\n 'r': [0.9158, 0.3542, -0.0821, -0.1706],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0096, 0.0511, -0.1481],\n 'r': [0.9158, 0.3542, -0.0821, -0.1706],\n 's': [1, 1, 1]\n }\n] as const;\n","export const LEFT_HAND_VICTORY = [\n {\n 't': [-0.0485, -0.0629, -0.0748],\n 'r': [0.5235, 0.0269, -0.0122, 0.8515],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0274, -0.0424, -0.0935],\n 'r': [0.2683, -0.0091, -0.2476, 0.9309],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0197, -0.0171, -0.1372],\n 'r': [-0.0874, 0.2587, -0.5403, 0.7959],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0337, -0.0134, -0.1604],\n 'r': [-0.1021, 0.3471, -0.5231, 0.7717],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0538, -0.0084, -0.1819],\n 'r': [-0.1021, 0.3471, -0.5231, 0.7717],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0376, -0.037, -0.0897],\n 'r': [0.5048, -0.107, 0.0348, 0.8559],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0266, 0.0281, -0.1246],\n 'r': [0.567, -0.0696, 0.0098, 0.8207],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0224, 0.0646, -0.1371],\n 'r': [0.5031, -0.0677, 0.0059, 0.8615],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0201, 0.0836, -0.1477],\n 'r': [0.4589, -0.0365, 0.0223, 0.8874],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.019, 0.1018, -0.1617],\n 'r': [0.4589, -0.0365, 0.0223, 0.8874],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0503, -0.0361, -0.0891],\n 'r': [0.5225, -0.0136, 0.0382, 0.8517],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0515, 0.0267, -0.1211],\n 'r': [0.5428, 0.1035, 0.1149, 0.8255],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0638, 0.0631, -0.1369],\n 'r': [0.5306, 0.067, 0.0906, 0.8401],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0702, 0.0896, -0.1495],\n 'r': [0.5467, 0.0608, 0.081, 0.8312],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0747, 0.1108, -0.1601],\n 'r': [0.5467, 0.0608, 0.081, 0.8312],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0613, -0.0396, -0.0891],\n 'r': [0.4925, 0.0763, 0.0204, 0.8667],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0712, 0.0158, -0.1219],\n 'r': [0.2546, -0.0246, 0.1592, 0.9535],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0722, 0.0349, -0.1561],\n 'r': [-0.2354, -0.1181, 0.1042, 0.959],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0638, 0.0217, -0.1832],\n 'r': [-0.4573, -0.1496, 0.0503, 0.8752],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0571, 0.0041, -0.1941],\n 'r': [-0.4573, -0.1496, 0.0503, 0.8752],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0706, -0.045, -0.0892],\n 'r': [0.4433, 0.1733, 0.0233, 0.8791],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0898, 0.0006, -0.1216],\n 'r': [0.0458, -0.1976, 0.107, 0.9733],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0762, 0.0038, -0.1526],\n 'r': [-0.348, -0.2273, 0.0117, 0.9095],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0668, -0.0095, -0.1675],\n 'r': [-0.5475, -0.2656, -0.0806, 0.7894],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0618, -0.0269, -0.1725],\n 'r': [-0.5475, -0.2656, -0.0806, 0.7894],\n 's': [1, 1, 1]\n }\n] as const;\n\nexport const RIGHT_HAND_VICTORY = [\n {\n 't': [-0.0017, -0.0652, -0.0663],\n 'r': [0.5651, 0.0392, -0.0573, 0.8221],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0247, -0.042, -0.0786],\n 'r': [0.3207, 0.0849, 0.243, 0.9115],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0407, -0.0141, -0.1186],\n 'r': [-0.0285, -0.1953, 0.5625, 0.8029],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.031, -0.0094, -0.1439],\n 'r': [-0.0751, -0.3079, 0.5331, 0.7845],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0133, -0.0043, -0.1673],\n 'r': [-0.0751, -0.3079, 0.5331, 0.7845],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0136, -0.0376, -0.076],\n 'r': [0.5464, 0.1682, -0.0848, 0.8161],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0272, 0.0313, -0.1019],\n 'r': [0.6129, 0.1411, -0.0752, 0.7738],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.032, 0.0692, -0.1089],\n 'r': [0.5643, 0.143, -0.0679, 0.8103],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0353, 0.0897, -0.1161],\n 'r': [0.5256, 0.1162, -0.0834, 0.8386],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.038, 0.11, -0.1265],\n 'r': [0.5256, 0.1162, -0.0834, 0.8386],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0009, -0.0372, -0.0776],\n 'r': [0.5593, 0.0765, -0.0968, 0.8197],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0021, 0.0287, -0.1033],\n 'r': [0.6072, -0.0412, -0.1868, 0.7712],\n 's': [1, 1, 1]\n },\n {\n 't': [0.01, 0.0671, -0.1136],\n 'r': [0.5687, 0.0002, -0.1587, 0.8071],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0156, 0.0946, -0.124],\n 'r': [0.5609, 0.0092, -0.1498, 0.8142],\n 's': [1, 1, 1]\n },\n {\n 't': [0.019, 0.1163, -0.1339],\n 'r': [0.5609, 0.0092, -0.1498, 0.8142],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0096, -0.0411, -0.08],\n 'r': [0.5291, -0.0092, -0.0837, 0.8443],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0165, 0.0173, -0.1087],\n 'r': [0.2191, 0.1389, -0.1874, 0.9474],\n 's': [1, 1, 1]\n },\n {\n 't': [0.009, 0.0353, -0.1427],\n 'r': [-0.3548, 0.2386, -0.0503, 0.9026],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0055, 0.0162, -0.1628],\n 'r': [-0.5898, 0.2546, 0.0402, 0.7653],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0126, -0.0042, -0.1657],\n 'r': [-0.5898, 0.2546, 0.0402, 0.7653],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0184, -0.0469, -0.0826],\n 'r': [0.4806, -0.0996, -0.0936, 0.8662],\n 's': [1, 1, 1]\n },\n {\n 't': [0.034, 0.0014, -0.1134],\n 'r': [0.079, 0.2891, -0.1225, 0.9461],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0152, 0.0077, -0.141],\n 'r': [-0.2784, 0.3171, 0.0012, 0.9066],\n 's': [1, 1, 1]\n },\n {\n 't': [0.0023, -0.0029, -0.1556],\n 'r': [-0.458, 0.3482, 0.1094, 0.8106],\n 's': [1, 1, 1]\n },\n {\n 't': [-0.0053, -0.0187, -0.1623],\n 'r': [-0.458, 0.3482, 0.1094, 0.8106],\n 's': [1, 1, 1]\n }\n] as const;\n","\nexport class SimulatorXRHand {}","import * as THREE from 'three';\nimport {GLTFLoader} from 'three/addons/loaders/GLTFLoader.js';\n\nimport {HAND_JOINT_NAMES} from '../input/components/HandJointNames';\nimport {Input} from '../input/Input';\nimport type {DeepReadonly} from '../utils/Types';\n\nimport {SimulatorHandPoseChangeRequestEvent} from './events/SimulatorHandEvents';\nimport {SimulatorHandPoseJoints} from './handPoses/HandPoseJoints';\nimport {SIMULATOR_HAND_POSE_TO_JOINTS_LEFT, SIMULATOR_HAND_POSE_TO_JOINTS_RIGHT, SimulatorHandPose} from './handPoses/HandPoses';\nimport {SimulatorControllerState} from './SimulatorControllerState';\nimport {SimulatorXRHand} from './SimulatorXRHand';\n\nconst DEFAULT_HAND_PROFILE_PATH =\n 'https://cdn.jsdelivr.net/npm/@webxr-input-profiles/assets@1.0/dist/profiles/generic-hand/';\n\nconst vector3 = new THREE.Vector3();\nconst quaternion = new THREE.Quaternion();\n\nexport type SimulatorHandPoseHTMLElement = HTMLElement&{\n visible: boolean;\n handPose?: SimulatorHandPose;\n}\n\nexport class SimulatorHands {\n leftController = new THREE.Object3D();\n rightController = new THREE.Object3D();\n leftHand?: THREE.Group;\n rightHand?: THREE.Group;\n leftHandBones: THREE.Object3D[] = [];\n rightHandBones: THREE.Object3D[] = [];\n leftHandPose? = SimulatorHandPose.RELAXED;\n rightHandPose? = SimulatorHandPose.RELAXED;\n leftHandTargetJoints: DeepReadonly<SimulatorHandPoseJoints> =\n SIMULATOR_HAND_POSE_TO_JOINTS_LEFT[SimulatorHandPose.RELAXED];\n rightHandTargetJoints: DeepReadonly<SimulatorHandPoseJoints> =\n SIMULATOR_HAND_POSE_TO_JOINTS_RIGHT[SimulatorHandPose.RELAXED];\n lerpSpeed = 0.1;\n handPosePanelElement?: SimulatorHandPoseHTMLElement;\n onHandPoseChangeRequestBound = this.onHandPoseChangeRequest.bind(this);\n input!: Input;\n loader!: GLTFLoader;\n\n private leftXRHand = new SimulatorXRHand();\n private rightXRHand = new SimulatorXRHand();\n\n constructor(\n private simulatorControllerState: SimulatorControllerState,\n private simulatorScene: THREE.Scene) {}\n\n /**\n * Initialize Simulator Hands.\n */\n init({input}: {input: Input}) {\n this.input = input;\n this.loadMeshes();\n this.simulatorScene.add(this.leftController);\n this.simulatorScene.add(this.rightController);\n }\n\n loadMeshes() {\n this.loader = new GLTFLoader();\n this.loader.setPath(DEFAULT_HAND_PROFILE_PATH);\n this.loader.load('left.glb', gltf => {\n this.leftHand = gltf.scene;\n this.leftController.add(this.leftHand);\n HAND_JOINT_NAMES.forEach(jointName => {\n const bone = gltf.scene.getObjectByName(jointName);\n if (bone) {\n this.leftHandBones.push(bone);\n } else {\n console.warn(`Couldn't find ${jointName} in left hand mesh`);\n }\n });\n this.setLeftHandJoints(this.leftHandTargetJoints);\n this.input.hands[0]?.dispatchEvent?.({\n type: 'connected',\n data: {hand: this.leftXRHand, handedness: 'left'} as XRInputSource\n });\n });\n this.loader.load('right.glb', gltf => {\n this.rightHand = gltf.scene;\n this.rightController.add(this.rightHand);\n HAND_JOINT_NAMES.forEach(jointName => {\n const bone = gltf.scene.getObjectByName(jointName);\n if (bone) {\n this.rightHandBones.push(bone);\n } else {\n console.warn(`Couldn't find ${jointName} in right hand mesh`);\n }\n });\n this.setRightHandJoints(this.rightHandTargetJoints);\n this.input.hands[1]?.dispatchEvent?.({\n type: 'connected',\n data: {hand: this.rightXRHand, handedness: 'right'} as XRInputSource\n });\n });\n }\n\n setLeftHandLerpPose(pose: SimulatorHandPose) {\n if (this.leftHandPose === pose) return;\n\n if (pose === SimulatorHandPose.PINCHING) {\n this.input.dispatchEvent({\n type: 'selectstart',\n target: this.input.controllers[0],\n data: {\n handedness: 'left',\n }\n });\n } else if (this.leftHandPose === SimulatorHandPose.PINCHING) {\n this.input.dispatchEvent({\n type: 'selectend',\n target: this.input.controllers[0],\n data: {\n handedness: 'left',\n }\n });\n }\n\n this.leftHandPose = pose;\n this.leftHandTargetJoints = SIMULATOR_HAND_POSE_TO_JOINTS_LEFT[pose];\n this.updateHandPosePanel();\n }\n\n setRightHandLerpPose(pose: SimulatorHandPose) {\n if (this.rightHandPose === pose) return;\n\n if (pose === SimulatorHandPose.PINCHING) {\n this.input.dispatchEvent({\n type: 'selectstart',\n target: this.input.controllers[1],\n data: {\n handedness: 'right',\n }\n });\n } else if (this.rightHandPose === SimulatorHandPose.PINCHING) {\n this.input.dispatchEvent({\n type: 'selectend',\n target: this.input.controllers[1],\n data: {\n handedness: 'right',\n }\n });\n }\n\n this.rightHandPose = pose;\n this.rightHandTargetJoints = SIMULATOR_HAND_POSE_TO_JOINTS_RIGHT[pose];\n this.updateHandPosePanel();\n }\n\n setLeftHandJoints(joints: DeepReadonly<SimulatorHandPoseJoints>) {\n // Unset the pose if the joints are manually defined.\n if (this.leftHandPose === SimulatorHandPose.PINCHING) {\n this.input.dispatchEvent({\n type: 'selectend',\n target: this.input.controllers[1],\n data: {\n handedness: 'left',\n }\n });\n }\n if (joints != this.leftHandTargetJoints) {\n this.leftHandPose = undefined;\n this.leftHandTargetJoints = joints;\n }\n for (let i = 0; i < this.leftHandBones.length; i++) {\n const bone = this.leftHandBones[i];\n const jointData = joints[i];\n if (bone && jointData) {\n bone.position.fromArray(jointData.t)\n bone.quaternion.fromArray(jointData.r);\n bone.scale.fromArray([1, 1, 1]);\n }\n }\n }\n\n setRightHandJoints(joints: DeepReadonly<SimulatorHandPoseJoints>) {\n // Unset the pose if the joints are manually defined.\n if (this.rightHandPose === SimulatorHandPose.PINCHING) {\n this.input.dispatchEvent({\n type: 'selectend',\n target: this.input.controllers[1],\n data: {\n handedness: 'right',\n }\n });\n }\n if (joints != this.rightHandTargetJoints) {\n this.rightHandPose = undefined;\n this.rightHandTargetJoints = joints;\n }\n for (let i = 0; i < this.rightHandBones.length; i++) {\n const bone = this.rightHandBones[i];\n const jointData = joints[i];\n if (bone && jointData) {\n bone.position.fromArray(jointData.t)\n bone.quaternion.fromArray(jointData.r);\n bone.scale.fromArray([1, 1, 1]);\n }\n }\n }\n\n update() {\n this.lerpLeftHandPose();\n this.lerpRightHandPose();\n this.syncHandJoints();\n }\n\n lerpLeftHandPose() {\n for (let i = 0; i < this.leftHandBones.length; i++) {\n const bone = this.leftHandBones[i];\n const targetJoint = this.leftHandTargetJoints[i];\n if (bone && targetJoint) {\n vector3.fromArray(targetJoint.t)\n quaternion.fromArray(targetJoint.r);\n\n bone.position.lerp(vector3, this.lerpSpeed);\n bone.quaternion.slerp(quaternion, this.lerpSpeed);\n }\n }\n }\n\n lerpRightHandPose() {\n for (let i = 0; i < this.rightHandBones.length; i++) {\n const bone = this.rightHandBones[i];\n const targetJoint = this.rightHandTargetJoints[i];\n if (bone && targetJoint) {\n vector3.fromArray(targetJoint.t)\n quaternion.fromArray(targetJoint.r);\n\n bone.position.lerp(vector3, this.lerpSpeed);\n bone.quaternion.slerp(quaternion, this.lerpSpeed);\n }\n }\n }\n\n syncHandJoints() {\n const hands = this.input.hands;\n const leftHand = hands[0];\n if (leftHand) {\n this.leftController.updateWorldMatrix(true, false);\n leftHand.position.setFromMatrixPosition(this.leftController.matrixWorld);\n leftHand.setRotationFromMatrix(this.leftController.matrixWorld);\n leftHand.updateMatrix();\n for (let i = 0; i < this.leftHandBones.length; i++) {\n const joint = HAND_JOINT_NAMES[i];\n if (!(joint in leftHand.joints)) {\n leftHand.joints[joint] = new THREE.Group() as THREE.XRJointSpace;\n leftHand.add(leftHand.joints[joint]);\n }\n leftHand.joints[joint]!.position.copy(this.leftHandBones[i].position);\n leftHand.joints[joint]!.quaternion.copy(\n this.leftHandBones[i].quaternion);\n leftHand.updateWorldMatrix(false, true);\n }\n }\n const rightHand = hands[1];\n if (rightHand) {\n this.rightController.updateWorldMatrix(true, false);\n rightHand.position.setFromMatrixPosition(\n this.rightController.matrixWorld);\n rightHand.setRotationFromMatrix(this.rightController.matrixWorld);\n rightHand.updateMatrix();\n for (let i = 0; i < this.rightHandBones.length; i++) {\n const joint = HAND_JOINT_NAMES[i];\n if (!(joint in rightHand.joints)) {\n rightHand.joints[joint] = new THREE.Group() as THREE.XRJointSpace;\n rightHand.add(rightHand.joints[joint]);\n }\n rightHand.joints[joint]!.position.copy(this.rightHandBones[i].position);\n rightHand.joints[joint]!.quaternion.copy(\n this.rightHandBones[i].quaternion);\n rightHand.updateWorldMatrix(false, true);\n }\n }\n }\n\n setLeftHandPinching(pinching = true) {\n this.setLeftHandLerpPose(\n pinching ? SimulatorHandPose.PINCHING : SimulatorHandPose.RELAXED);\n }\n\n setRightHandPinching(pinching = true) {\n this.setRightHandLerpPose(\n pinching ? SimulatorHandPose.PINCHING : SimulatorHandPose.RELAXED);\n }\n\n showHands() {\n this.leftController.visible = true;\n this.rightController.visible = true;\n for (let i = 0; i < this.input.hands.length; i++) {\n this.input.hands[i].visible = true;\n }\n this.updateHandPosePanel();\n }\n\n hideHands() {\n this.leftController.visible = false;\n this.rightController.visible = false;\n for (let i = 0; i < this.input.hands.length; i++) {\n this.input.hands[i].visible = false;\n }\n this.updateHandPosePanel();\n }\n\n updateHandPosePanel() {\n if (!this.handPosePanelElement) return;\n if (this.simulatorControllerState.currentControllerIndex === 0) {\n this.handPosePanelElement.visible = this.leftController.visible;\n this.handPosePanelElement.handPose = this.leftHandPose;\n } else {\n this.handPosePanelElement.visible = this.rightController.visible;\n this.handPosePanelElement.handPose = this.rightHandPose;\n }\n }\n\n setHandPosePanelElement(element: HTMLElement) {\n if (this.handPosePanelElement) {\n this.handPosePanelElement.removeEventListener(\n SimulatorHandPoseChangeRequestEvent.type,\n this.onHandPoseChangeRequestBound);\n }\n element.addEventListener(\n SimulatorHandPoseChangeRequestEvent.type,\n this.onHandPoseChangeRequestBound);\n this.handPosePanelElement = element as SimulatorHandPoseHTMLElement;\n this.updateHandPosePanel();\n }\n\n onHandPoseChangeRequest(event: Event) {\n if (event.type != SimulatorHandPoseChangeRequestEvent.type) return;\n const handPoseChangeEvent = event as SimulatorHandPoseChangeRequestEvent;\n if (this.simulatorControllerState.currentControllerIndex === 0) {\n this.setLeftHandLerpPose(handPoseChangeEvent.pose);\n } else {\n this.setRightHandLerpPose(handPoseChangeEvent.pose);\n }\n }\n\n toggleHandedness() {\n this.simulatorControllerState.currentControllerIndex =\n (this.simulatorControllerState.currentControllerIndex + 1) % 2;\n this.updateHandPosePanel();\n }\n}\n","import {SimulatorControls, SimulatorModeIndicatorElement} from './SimulatorControls.js';\nimport {SimulatorHands} from './SimulatorHands.js';\nimport {SimulatorCustomInstruction, SimulatorOptions} from './SimulatorOptions.js';\n\ntype SimulatorInstructionsHTMLElement = HTMLElement&{\n customInstructions: SimulatorCustomInstruction[];\n}\n\nexport class SimulatorInterface {\n private elements: HTMLElement[] = [];\n private interfaceVisible = true;\n\n /**\n * Initialize the simulator interface.\n */\n init(\n simulatorOptions: SimulatorOptions, simulatorControls: SimulatorControls,\n simulatorHands: SimulatorHands) {\n this.createModeIndicator(simulatorOptions, simulatorControls);\n this.showGeminiLivePanel(simulatorOptions);\n this.createHandPosePanel(simulatorOptions, simulatorHands);\n this.showInstructions(simulatorOptions);\n }\n\n createModeIndicator(\n simulatorOptions: SimulatorOptions,\n simulatorControls: SimulatorControls) {\n if (simulatorOptions.modeIndicator.enabled) {\n const modeIndicatorElement =\n document.createElement(simulatorOptions.modeIndicator.element) as\n SimulatorModeIndicatorElement;\n document.body.appendChild(modeIndicatorElement);\n simulatorControls.setModeIndicatorElement(modeIndicatorElement);\n this.elements.push(modeIndicatorElement);\n }\n }\n\n showInstructions(simulatorOptions: SimulatorOptions) {\n if (simulatorOptions.instructions.enabled) {\n const element =\n document.createElement(simulatorOptions.instructions.element) as\n SimulatorInstructionsHTMLElement;\n element.customInstructions =\n simulatorOptions.instructions.customInstructions;\n document.body.appendChild(element);\n this.elements.push(element);\n }\n }\n\n showGeminiLivePanel(simulatorOptions: SimulatorOptions) {\n if (simulatorOptions.geminilive) {\n const element = document.createElement('xrblocks-simulator-geminilive');\n document.body.appendChild(element);\n this.elements.push(element);\n }\n }\n\n createHandPosePanel(\n simulatorOptions: SimulatorOptions, simulatorHands: SimulatorHands) {\n if (simulatorOptions.handPosePanel.enabled) {\n const handsPanelElement =\n document.createElement(simulatorOptions.handPosePanel.element);\n document.body.appendChild(handsPanelElement);\n simulatorHands.setHandPosePanelElement(handsPanelElement);\n this.elements.push(handsPanelElement);\n }\n }\n\n hideUiElements() {\n for (const element of this.elements) {\n element.style.display = 'none';\n }\n this.interfaceVisible = false;\n }\n\n showUiElements() {\n for (const element of this.elements) {\n element.style.display = '';\n }\n this.interfaceVisible = true;\n }\n\n getInterfaceVisible() {\n return !this.interfaceVisible;\n }\n\n toggleInterfaceVisible() {\n if (this.interfaceVisible) {\n this.hideUiElements();\n } else {\n this.showUiElements();\n }\n }\n}","import * as THREE from 'three';\nimport {GLTFLoader} from 'three/addons/loaders/GLTFLoader.js';\nimport type {GLTF} from 'three/addons/loaders/GLTFLoader.js';\n\nimport {SimulatorOptions} from './SimulatorOptions';\n\nexport class SimulatorScene extends THREE.Scene {\n gltf?: GLTF;\n\n constructor() {\n super();\n }\n\n async init(simulatorOptions: SimulatorOptions) {\n this.addLights();\n if (simulatorOptions.scenePath) {\n await this.loadGLTF(\n simulatorOptions.scenePath,\n new THREE.Vector3(\n simulatorOptions.initialScenePosition.x,\n simulatorOptions.initialScenePosition.y,\n simulatorOptions.initialScenePosition.z));\n }\n }\n\n addLights() {\n this.add(new THREE.HemisphereLight(0xbbbbbb, 0x888888, 3));\n }\n\n async loadGLTF(path: string, initialPosition: THREE.Vector3) {\n const loader = new GLTFLoader();\n return new Promise((resolve, reject) => {\n loader.load(\n path,\n (gltf) => {\n gltf.scene.position.copy(initialPosition);\n this.add(gltf.scene);\n this.gltf = gltf;\n resolve(gltf);\n },\n () => {},\n (error) => {\n reject(error);\n });\n });\n }\n}\n","import {Registry} from '../core/components/Registry';\nimport type {Constructor} from '../utils/Types';\n\n// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\nexport type InjectableConstructor = Function&{\n // Static property for dependencies.\n dependencies?: Record<string, Constructor>;\n}\n\nexport interface Injectable {\n init(...args: unknown[]): Promise<void>|void; // The init method.\n constructor: InjectableConstructor; // A reference to its own constructor.\n}\n\n/**\n * Call init on a script or subsystem with dependency injection.\n */\nexport async function callInitWithDependencyInjection(\n script: Injectable, registry: Registry, fallback: unknown) {\n const dependencies = script.constructor.dependencies;\n if (dependencies == null) {\n await script.init(fallback);\n return;\n }\n await script.init(\n Object.fromEntries(Object.entries(dependencies).map(([key, value]) => {\n const dependency = registry.get(value);\n if (!dependency) {\n throw new Error(`Dependency not found for key: ${value.name}`);\n }\n return [key, dependency];\n })));\n}\n","import {Registry} from '../core/components/Registry.js';\nimport {WaitFrame} from '../core/components/WaitFrame.js';\nimport {Script} from '../core/Script.js';\nimport {callInitWithDependencyInjection} from '../utils/DependencyInjection';\n\nimport {SimulatorUserAction} from './userActions/SimulatorUserAction.js';\n\nexport class SimulatorUser extends Script {\n static dependencies = {waitFrame: WaitFrame, registry: Registry};\n journeyId = 0;\n waitFrame!: WaitFrame;\n registry!: Registry;\n\n constructor() {\n super();\n }\n\n init({waitFrame, registry}: {waitFrame: WaitFrame, registry: Registry}) {\n this.waitFrame = waitFrame;\n this.registry = registry;\n }\n\n stopJourney() {\n ++this.journeyId;\n }\n\n isOnJourneyId(id: number) {\n return id == this.journeyId;\n }\n\n async loadJourney(actions: SimulatorUserAction[]) {\n console.log('Load journey');\n const currentJourneyId = ++this.journeyId;\n for (let i = 0; this.isOnJourneyId(currentJourneyId) && i < actions.length;\n ++i) {\n callInitWithDependencyInjection(actions[i], this.registry, undefined);\n await actions[i].play({\n simulatorUser: this,\n journeyId: currentJourneyId,\n waitFrame: this.waitFrame\n });\n }\n console.log('Journey finished');\n }\n}","import * as THREE from 'three';\nimport {FullScreenQuad} from 'three/addons/postprocessing/Pass.js';\n\nimport {XRDeviceCamera} from '../camera/XRDeviceCamera.js';\nimport {Registry} from '../core/components/Registry';\nimport {XREffects} from '../core/components/XREffects';\nimport {Options} from '../core/Options';\nimport {Script} from '../core/Script';\nimport {Depth} from '../depth/Depth';\nimport {DepthMesh} from '../depth/DepthMesh';\nimport {Input} from '../input/Input';\n\nimport {SimulatorCamera} from './SimulatorCamera';\nimport {AVERAGE_IPD_METERS, SimulatorRenderMode} from './SimulatorConstants';\nimport {SimulatorControllerState} from './SimulatorControllerState';\nimport {SimulatorControls} from './SimulatorControls';\nimport {SimulatorDepth} from './SimulatorDepth';\nimport {SimulatorHands} from './SimulatorHands';\nimport {SimulatorInterface} from './SimulatorInterface';\nimport {SimulatorOptions} from './SimulatorOptions';\nimport {SimulatorScene} from './SimulatorScene';\nimport {SimulatorUser} from './SimulatorUser';\n\nexport class Simulator extends Script {\n static dependencies = {\n simulatorOptions: SimulatorOptions,\n input: Input,\n timer: THREE.Timer,\n camera: THREE.Camera,\n renderer: THREE.WebGLRenderer,\n scene: THREE.Scene,\n registry: Registry,\n options: Options,\n depth: Depth,\n };\n\n simulatorScene = new SimulatorScene();\n depth = new SimulatorDepth(this.simulatorScene);\n // Controller poses relative to the camera.\n simulatorControllerState = new SimulatorControllerState();\n hands =\n new SimulatorHands(this.simulatorControllerState, this.simulatorScene);\n simulatorUser = new SimulatorUser();\n userInterface = new SimulatorInterface();\n controls = new SimulatorControls(\n this.simulatorControllerState, this.hands,\n this.setStereoRenderMode.bind(this), this.userInterface);\n renderDepthPass = false;\n renderMode = SimulatorRenderMode.DEFAULT;\n stereoCameras: THREE.Camera[] = [];\n effects?: XREffects;\n\n // Render target for the virtual scene.\n virtualSceneRenderTarget?: THREE.WebGLRenderTarget;\n virtualSceneFullScreenQuad?: FullScreenQuad;\n\n camera?: SimulatorCamera;\n options!: SimulatorOptions;\n renderer!: THREE.WebGLRenderer;\n mainCamera!: THREE.Camera;\n mainScene!: THREE.Scene;\n\n private initialized = false;\n private renderSimulatorSceneToCanvasBound =\n this.renderSimulatorSceneToCanvas.bind(this);\n\n constructor(\n private renderMainScene: (cameraOverride?: THREE.Camera) => void) {\n super();\n this.add(this.simulatorUser);\n }\n\n async init({\n simulatorOptions,\n input,\n timer,\n camera,\n renderer,\n scene,\n registry,\n options,\n depth,\n }: {\n simulatorOptions: SimulatorOptions,\n input: Input,\n timer: THREE.Timer,\n camera: THREE.Camera,\n renderer: THREE.WebGLRenderer,\n scene: THREE.Scene,\n registry: Registry,\n options: Options,\n depth: Depth,\n }) {\n if (this.initialized) return;\n // Get optional dependencies from the registry.\n const deviceCamera = registry.get(XRDeviceCamera);\n const depthMesh = registry.get(DepthMesh);\n this.options = simulatorOptions;\n camera.position.copy(this.options.initialCameraPosition);\n this.userInterface.init(simulatorOptions, this.controls, this.hands);\n renderer.autoClearColor = false;\n await this.simulatorScene.init(simulatorOptions);\n this.hands.init({input});\n this.controls.init({camera, input, timer, renderer, simulatorOptions});\n if (deviceCamera && !this.camera) {\n this.camera = new SimulatorCamera(renderer);\n this.camera.init();\n deviceCamera.registerSimulatorCamera(this.camera);\n }\n\n if (options.depth.enabled) {\n this.renderDepthPass = true;\n this.depth.init(renderer, camera, depth);\n if (options.depth.depthMesh.enabled && depthMesh) {\n camera.add(depthMesh);\n }\n }\n scene.add(camera);\n\n if (this.options.stereo.enabled) {\n this.setupStereoCameras(camera);\n }\n\n this.virtualSceneRenderTarget = new THREE.WebGLRenderTarget(\n renderer.domElement.width, renderer.domElement.height,\n {stencilBuffer: options.stencil});\n const virtualSceneMaterial = new THREE.MeshBasicMaterial(\n {map: this.virtualSceneRenderTarget.texture, transparent: true});\n if (this.options.blendingMode === 'screen') {\n virtualSceneMaterial.blending = THREE.CustomBlending;\n virtualSceneMaterial.blendSrc = THREE.OneFactor;\n virtualSceneMaterial.blendDst =\n THREE.OneMinusSrcColorFactor;\n virtualSceneMaterial.blendEquation =\n THREE.AddEquation;\n }\n this.virtualSceneFullScreenQuad =\n new FullScreenQuad(virtualSceneMaterial);\n\n this.renderer = renderer;\n this.mainCamera = camera;\n this.mainScene = scene;\n this.initialized = true;\n }\n\n\n simulatorUpdate() {\n this.controls.update();\n this.hands.update();\n\n if (this.renderDepthPass) {\n this.depth.update();\n }\n }\n\n setStereoRenderMode(mode: SimulatorRenderMode) {\n if (!this.options.stereo.enabled) return;\n this.renderMode = mode;\n }\n\n setupStereoCameras(camera: THREE.Camera) {\n const leftCamera = camera.clone();\n const rightCamera = camera.clone();\n leftCamera.layers.disableAll();\n leftCamera.layers.enable(0);\n leftCamera.layers.enable(1);\n rightCamera.layers.disableAll();\n rightCamera.layers.enable(0);\n rightCamera.layers.enable(2);\n leftCamera.position.set(-AVERAGE_IPD_METERS / 2, 0, 0);\n rightCamera.position.set(AVERAGE_IPD_METERS / 2, 0, 0);\n leftCamera.updateWorldMatrix(true, false);\n rightCamera.updateWorldMatrix(true, false);\n this.stereoCameras.length = 0;\n this.stereoCameras.push(leftCamera, rightCamera);\n camera.add(leftCamera, rightCamera);\n this.setStereoRenderMode(SimulatorRenderMode.STEREO_LEFT);\n }\n\n onBeforeSimulatorSceneRender() {\n if (this.camera) {\n this.camera.onBeforeSimulatorSceneRender(\n this.mainCamera, this.renderSimulatorSceneToCanvasBound);\n }\n }\n\n onSimulatorSceneRendered() {\n if (this.camera) {\n this.camera.onSimulatorSceneRendered();\n }\n }\n\n getRenderCamera() {\n return {\n [SimulatorRenderMode.DEFAULT]: this.mainCamera,\n [SimulatorRenderMode.STEREO_LEFT]: this.stereoCameras[0],\n [SimulatorRenderMode.STEREO_RIGHT]: this.stereoCameras[1]\n }[this.renderMode];\n }\n\n // Called by core when the simulator is running.\n renderScene() {\n if (!this.renderer) return;\n if (!this.options.renderToRenderTexture) return;\n // Allocate a new render target if the resolution changes.\n if (this.virtualSceneRenderTarget!.width !=\n this.renderer.domElement.width ||\n this.virtualSceneRenderTarget!.height !=\n this.renderer.domElement.height) {\n const stencilEnabled = !!this.virtualSceneRenderTarget?.stencilBuffer;\n this.virtualSceneRenderTarget!.dispose();\n this.virtualSceneRenderTarget = new THREE.WebGLRenderTarget(\n this.renderer.domElement.width, this.renderer.domElement.height,\n {stencilBuffer: stencilEnabled});\n (this.virtualSceneFullScreenQuad!.material as THREE.MeshBasicMaterial)\n .map = this.virtualSceneRenderTarget.texture;\n }\n this.renderer.setRenderTarget(this.virtualSceneRenderTarget!);\n this.renderer.clear();\n this.renderMainScene(this.getRenderCamera());\n }\n\n // Renders the simulator scene onto the main canvas.\n // Then composites the virtual render with the simulator render.\n // Called by core after renderScene.\n renderSimulatorScene() {\n this.onBeforeSimulatorSceneRender();\n this.renderSimulatorSceneToCanvas(this.getRenderCamera());\n this.onSimulatorSceneRendered();\n if (this.options.renderToRenderTexture) {\n this.virtualSceneFullScreenQuad!.render(this.renderer);\n } else {\n // Temporary workaround since splats look faded when rendered to a render\n // texture.\n this.renderMainScene(this.getRenderCamera());\n }\n }\n\n private renderSimulatorSceneToCanvas(camera: THREE.Camera) {\n this.renderer.setRenderTarget(null);\n this.renderer.render(this.simulatorScene, camera);\n this.renderer.clearDepth();\n }\n}\n","import {AI} from '../ai/AI';\nimport {Registry} from '../core/components/Registry';\nimport {Script} from '../core/Script.js';\n\nexport interface AudioListenerOptions {\n sampleRate?: number;\n channelCount?: number;\n echoCancellation?: boolean;\n noiseSuppression?: boolean;\n autoGainControl?: boolean;\n}\n\nfunction arrayBufferToBase64(buffer: ArrayBuffer) {\n const bytes = new Uint8Array(buffer);\n let binary = '';\n for (let i = 0; i < bytes.length; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n return btoa(binary);\n}\n\nexport class AudioListener extends Script {\n static dependencies = {registry: Registry};\n private options: AudioListenerOptions;\n private audioStream?: MediaStream;\n audioContext?: AudioContext;\n private sourceNode?: MediaStreamAudioSourceNode;\n private processorNode?: AudioWorkletNode;\n private isCapturing = false;\n private latestAudioBuffer: ArrayBuffer|null = null;\n private accumulatedChunks: ArrayBuffer[] = [];\n private isAccumulating = false;\n private registry!: Registry;\n aiService?: AI;\n private onAudioData?: ((audioBuffer: ArrayBuffer) => void);\n private onError?: ((error: Error) => void);\n\n constructor(options: AudioListenerOptions = {}) {\n super();\n this.options = {\n sampleRate: 16000,\n channelCount: 1,\n echoCancellation: true,\n noiseSuppression: true,\n autoGainControl: true,\n ...options\n };\n }\n\n /**\n * Init the AudioListener.\n */\n init({registry}: {registry: Registry;}) {\n this.registry = registry;\n }\n\n async startCapture(callbacks: {\n onAudioData?: (audioBuffer: ArrayBuffer) => void;\n onError?: (error: Error) => void;\n accumulate?: boolean;\n } = {}) {\n if (this.isCapturing) return;\n this.onAudioData = callbacks.onAudioData;\n this.onError = callbacks.onError;\n this.isAccumulating = callbacks.accumulate || false;\n \n if (this.isAccumulating) {\n this.accumulatedChunks = [];\n }\n \n try {\n await this.setupAudioCapture();\n this.isCapturing = true;\n } catch (error) {\n console.error('Failed to start audio capture:', error);\n this.onError?.(error as Error);\n this.cleanup();\n }\n }\n\n stopCapture() {\n if (!this.isCapturing) return;\n this.cleanup();\n this.isCapturing = false;\n }\n\n async setupAudioCapture() {\n this.audioStream =\n await navigator.mediaDevices.getUserMedia({audio: true, video: false});\n\n const actualSampleRate =\n this.audioStream.getAudioTracks()[0].getSettings().sampleRate;\n this.audioContext = new AudioContext({sampleRate: actualSampleRate});\n await this.setupAudioWorklet();\n\n this.sourceNode =\n this.audioContext.createMediaStreamSource(this.audioStream);\n this.processorNode =\n new AudioWorkletNode(this.audioContext, 'audio-capture-processor');\n\n this.processorNode.port.onmessage = (event) => {\n if (event.data.type === 'audioData') {\n this.latestAudioBuffer = event.data.data;\n \n // Accumulate chunks if requested\n if (this.isAccumulating) {\n this.accumulatedChunks.push(event.data.data);\n }\n \n this.onAudioData?.(event.data.data);\n this.streamToAI(event.data.data);\n }\n };\n\n // Check if the AudioContext is running, resume if necessary\n if (this.audioContext.state === 'suspended') {\n await this.audioContext.resume();\n }\n\n this.sourceNode.connect(this.processorNode);\n }\n\n private async setupAudioWorklet() {\n const processorCode = `\n class AudioCaptureProcessor extends AudioWorkletProcessor {\n process(inputs, outputs, parameters) {\n const input = inputs[0];\n if (input && input[0]) {\n const inputData = input[0];\n const pcmData = new Int16Array(inputData.length);\n for (let i = 0; i < inputData.length; i++) {\n pcmData[i] = Math.max(-32768, Math.min(32767, inputData[i] * 32768));\n }\n this.port.postMessage({type: 'audioData', data: pcmData.buffer});\n }\n return true;\n }\n }\n registerProcessor('audio-capture-processor', AudioCaptureProcessor);\n `;\n\n const blob = new Blob([processorCode], {type: 'application/javascript'});\n const processorURL = URL.createObjectURL(blob);\n await this.audioContext!.audioWorklet.addModule(processorURL);\n URL.revokeObjectURL(processorURL);\n }\n\n streamToAI(audioBuffer: ArrayBuffer) {\n if (!this.aiService?.sendRealtimeInput) return;\n const base64Audio = arrayBufferToBase64(audioBuffer);\n const actualSampleRate =\n this.audioContext?.sampleRate || this.options.sampleRate;\n this.aiService.sendRealtimeInput({\n audio: {data: base64Audio, mimeType: `audio/pcm;rate=${actualSampleRate}`}\n });\n }\n\n setAIStreaming(enabled: boolean) {\n this.aiService = enabled ? this.registry.get(AI) : undefined;\n }\n\n cleanup() {\n this.processorNode?.disconnect();\n this.sourceNode?.disconnect();\n if (this.audioContext && this.audioContext.state !== 'closed') {\n this.audioContext.close();\n }\n this.audioStream?.getTracks().forEach(track => track.stop());\n this.processorNode = undefined;\n this.sourceNode = undefined;\n this.audioContext = undefined;\n this.audioStream = undefined;\n this.onAudioData = undefined;\n this.onError = undefined;\n this.latestAudioBuffer = null;\n this.accumulatedChunks = [];\n this.isAccumulating = false;\n this.aiService = undefined;\n }\n\n static isSupported() {\n return !!(navigator.mediaDevices && navigator.mediaDevices.getUserMedia);\n }\n\n getIsCapturing() {\n return this.isCapturing;\n }\n\n getLatestAudioBuffer() {\n return this.latestAudioBuffer;\n }\n\n clearLatestAudioBuffer() {\n this.latestAudioBuffer = null;\n }\n\n /**\n * Gets all accumulated audio chunks as a single combined buffer\n */\n getAccumulatedBuffer(): ArrayBuffer|null {\n if (this.accumulatedChunks.length === 0) return null;\n \n const totalLength = this.accumulatedChunks.reduce(\n (sum, chunk) => sum + chunk.byteLength, 0);\n const combined = new ArrayBuffer(totalLength);\n const combinedArray = new Uint8Array(combined);\n \n let offset = 0;\n for (const chunk of this.accumulatedChunks) {\n combinedArray.set(new Uint8Array(chunk), offset);\n offset += chunk.byteLength;\n }\n \n return combined;\n }\n\n /**\n * Clears accumulated chunks\n */\n clearAccumulatedBuffer() {\n this.accumulatedChunks = [];\n }\n\n /**\n * Gets the number of accumulated chunks\n */\n getAccumulatedChunkCount(): number {\n return this.accumulatedChunks.length;\n }\n\n dispose() {\n this.stopCapture();\n super.dispose();\n }\n}\n","import {Script} from '../core/Script.js';\n\nimport {CategoryVolumes} from './CategoryVolumes';\n\nexport interface AudioPlayerOptions {\n sampleRate?: number;\n channelCount?: number;\n category?: string;\n}\n\nexport class AudioPlayer extends Script {\n private options: AudioPlayerOptions = {};\n private audioContext?: AudioContext;\n private audioQueue: AudioBuffer[] = [];\n private nextStartTime = 0;\n private gainNode?: GainNode;\n private categoryVolumes?: CategoryVolumes;\n private volume = 1.0;\n private category = 'speech';\n\n constructor(options: AudioPlayerOptions = {}) {\n super();\n this.options = {sampleRate: 24000, channelCount: 1, ...options};\n if (options.category) {\n this.category = options.category;\n }\n }\n\n /**\n * Sets the CategoryVolumes instance for this player to respect\n * master/category volumes\n */\n setCategoryVolumes(categoryVolumes: CategoryVolumes) {\n this.categoryVolumes = categoryVolumes;\n this.updateGainNodeVolume();\n }\n\n /**\n * Sets the specific volume for this player (0.0 to 1.0)\n */\n setVolume(level: number) {\n this.volume = Math.max(0, Math.min(1, level));\n this.updateGainNodeVolume();\n }\n\n /**\n * Updates the gain node volume based on category volumes\n * Public so CoreSound can update it when master volume changes\n */\n updateGainNodeVolume() {\n if (this.gainNode && this.categoryVolumes) {\n const effectiveVolume =\n this.categoryVolumes.getEffectiveVolume(this.category, this.volume);\n this.gainNode.gain.value = effectiveVolume;\n } else if (this.gainNode) {\n this.gainNode.gain.value = this.volume;\n }\n }\n\n async initializeAudioContext() {\n if (!this.audioContext) {\n this.audioContext =\n new AudioContext({sampleRate: this.options.sampleRate});\n this.nextStartTime = this.audioContext.currentTime;\n\n // Create gain node for volume control\n this.gainNode = this.audioContext.createGain();\n this.gainNode.connect(this.audioContext.destination);\n this.updateGainNodeVolume();\n }\n\n // Ensure audio context is running (not suspended)\n if (this.audioContext.state === 'suspended') {\n await this.audioContext.resume();\n }\n }\n\n async playAudioChunk(base64AudioData: string) {\n if (!base64AudioData) return;\n\n await this.initializeAudioContext();\n const arrayBuffer = this.base64ToArrayBuffer(base64AudioData);\n const audioBuffer = this.audioContext!.createBuffer(\n this.options.channelCount!, arrayBuffer.byteLength / 2,\n this.options.sampleRate!);\n\n const channelData = audioBuffer.getChannelData(0);\n const int16View = new Int16Array(arrayBuffer);\n\n for (let i = 0; i < int16View.length; i++) {\n channelData[i] = int16View[i] / 32768.0;\n }\n\n this.audioQueue.push(audioBuffer);\n this.scheduleAudioBuffers();\n }\n\n private scheduleAudioBuffers() {\n const SCHEDULE_AHEAD_TIME = 0.2;\n while (this.audioQueue.length > 0 &&\n this.nextStartTime <=\n this.audioContext!.currentTime + SCHEDULE_AHEAD_TIME) {\n const audioBuffer = this.audioQueue.shift()!;\n const currentTime = this.audioContext!.currentTime;\n const startTime = Math.max(this.nextStartTime, currentTime);\n\n const source = this.audioContext!.createBufferSource();\n source.buffer = audioBuffer;\n\n // Connect through gain node for volume control\n source.connect(this.gainNode || this.audioContext!.destination);\n source.onended = () => this.scheduleAudioBuffers();\n\n // Start playback\n source.start(startTime);\n\n this.nextStartTime = startTime + audioBuffer.duration;\n }\n }\n\n clearQueue() {\n this.audioQueue = [];\n }\n\n getIsPlaying() {\n return this.nextStartTime > this.audioContext!.currentTime;\n }\n\n getQueueLength() {\n return this.audioQueue.length;\n }\n\n base64ToArrayBuffer(base64: string) {\n const binaryString = atob(base64);\n const bytes = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n return bytes.buffer;\n }\n\n stop() {\n this.clearQueue();\n if (this.audioContext) {\n this.audioContext.close();\n this.audioContext = undefined;\n this.gainNode = undefined;\n this.nextStartTime = 0; // Reset timing\n }\n }\n\n static isSupported() {\n return !!('AudioContext' in window);\n }\n\n dispose() {\n this.stop();\n super.dispose();\n }\n}\n","import * as THREE from 'three';\n\nimport {XR_BLOCKS_ASSETS_PATH} from '../constants';\nimport {Script} from '../core/Script';\n\nimport {CategoryVolumes} from './CategoryVolumes';\n\nconst MUSIC_LIBRARY_PATH = XR_BLOCKS_ASSETS_PATH + 'musicLibrary/';\n\nconst musicLibrary = {\n 'ambient': MUSIC_LIBRARY_PATH + 'AmbientLoop.opus',\n 'background': MUSIC_LIBRARY_PATH + 'BackgroundMusic4.mp3',\n 'buttonHover': MUSIC_LIBRARY_PATH + 'ButtonHover.opus',\n 'buttonPress': MUSIC_LIBRARY_PATH + 'ButtonPress.opus',\n 'menuDismiss': MUSIC_LIBRARY_PATH + 'MenuDismiss.opus'\n} as const;\n\nclass BackgroundMusic extends Script {\n private audioLoader = new THREE.AudioLoader();\n\n private currentAudio: THREE.Audio|null = null;\n private isPlaying = false;\n private musicLibrary = musicLibrary;\n\n private specificVolume = 0.5;\n private musicCategory = 'music';\n\n constructor(\n private listener: THREE.AudioListener,\n private categoryVolumes: CategoryVolumes) {\n super();\n }\n\n // Set the volume for this instance of BackgroundMusic\n setVolume(level: number) {\n this.specificVolume = THREE.MathUtils.clamp(level, 0.0, 1.0);\n if (this.currentAudio && this.isPlaying && this.categoryVolumes) {\n const effectiveVolume = this.categoryVolumes.getEffectiveVolume(\n this.musicCategory, this.specificVolume);\n this.currentAudio.setVolume(effectiveVolume);\n console.log(`BackgroundMusic volume updated to: ${\n effectiveVolume} (specific: ${this.specificVolume})`);\n }\n }\n\n playMusic(musicKey: keyof typeof musicLibrary, category = 'music') {\n if (!this.categoryVolumes || !this.listener || !this.audioLoader) {\n console.error('BackgroundMusic not properly initialized.');\n return;\n }\n const soundPath = this.musicLibrary[musicKey];\n\n if (!soundPath) {\n console.error(`BackgroundMusic: Music key \"${musicKey}\" not found.`);\n return;\n }\n\n this.stopMusic();\n console.log(`BackgroundMusic: Loading sound: ${soundPath}`);\n this.musicCategory = category;\n\n const listener = this.listener;\n\n this.audioLoader.load(\n soundPath,\n (buffer) => {\n console.log(`BackgroundMusic: Successfully loaded ${soundPath}`);\n const audio = new THREE.Audio(listener);\n audio.setBuffer(buffer);\n audio.setLoop(\n this.musicCategory === 'music' ||\n this.musicCategory === 'ambient');\n\n const effectiveVolume = this.categoryVolumes.getEffectiveVolume(\n this.musicCategory, this.specificVolume);\n audio.setVolume(effectiveVolume);\n console.log(`BackgroundMusic: Setting volume for \"${musicKey}\" to ${\n effectiveVolume}`);\n\n audio.play();\n this.currentAudio = audio;\n this.isPlaying = true;\n console.log(`BackgroundMusic: Playing \"${musicKey}\" in category \"${\n this.musicCategory}\"`);\n },\n (xhr) => {\n console.log(`BackgroundMusic: Loading ${soundPath} - ${\n (xhr.loaded / xhr.total * 100).toFixed(0)}% loaded`);\n },\n (error) => {\n console.error(\n `BackgroundMusic: Error loading sound ${soundPath}:`, error);\n this.currentAudio = null;\n this.isPlaying = false;\n });\n }\n\n stopMusic() {\n if (this.currentAudio && this.isPlaying) {\n console.log('BackgroundMusic: Stopping current audio.');\n this.currentAudio.stop();\n }\n this.currentAudio = null;\n this.isPlaying = false;\n }\n\n destroy() {\n console.log('BackgroundMusic Destroying...');\n this.stopMusic();\n }\n}\n\nexport {BackgroundMusic};\n","import * as THREE from 'three';\n\nexport enum VolumeCategory {\n music = 'music',\n sfx = 'sfx',\n speech = 'speech',\n ui = 'ui'\n}\n\nexport class CategoryVolumes {\n isMuted = false;\n masterVolume = 1.0;\n\n volumes: Record<VolumeCategory, number> =\n Object.fromEntries(\n Object.values(VolumeCategory).map(cat => [cat, 1.0])) as\n Record<VolumeCategory, number>;\n\n getCategoryVolume(category: string): number {\n return this.volumes[category as VolumeCategory] ?? 1.0;\n }\n\n getEffectiveVolume(category: string, specificVolume = 1.0): number {\n if (this.isMuted) return 0.0;\n const categoryVol = this.getCategoryVolume(category);\n const clampedSpecificVolume =\n THREE.MathUtils.clamp(specificVolume, 0.0, 1.0);\n return this.masterVolume * categoryVol * clampedSpecificVolume;\n }\n}\n","import {Script} from '../core/Script.js';\n\ninterface SoundPresetTone {\n frequency: number;\n duration: number;\n waveformType: OscillatorType;\n delay?: number;\n}\n\n/**\n * Defines common UI sound presets with their default parameters.\n * Each preset specifies frequency, duration, and waveform type.\n */\nexport const SOUND_PRESETS = {\n BEEP: {frequency: 1000, duration: 0.07, waveformType: 'sine'},\n CLICK: [\n {frequency: 1500, duration: 0.02, waveformType: 'triangle', delay: 0},\n ],\n ACTIVATE: [\n {frequency: 800, duration: 0.05, waveformType: 'sine', delay: 0},\n {frequency: 1200, duration: 0.07, waveformType: 'sine', delay: 50}\n ],\n DEACTIVATE: [\n {frequency: 1200, duration: 0.05, waveformType: 'sine', delay: 0},\n {frequency: 800, duration: 0.07, waveformType: 'sine', delay: 50}\n ]\n} as const;\n\nexport class SoundSynthesizer extends Script {\n audioContext?: AudioContext;\n isInitialized = false;\n debug = false;\n\n /**\n * Initializes the AudioContext.\n */\n private _initAudioContext() {\n if (!this.isInitialized) {\n this.audioContext = new AudioContext();\n this.isInitialized = true;\n if (this.debug) {\n console.log('SoundSynthesizer: AudioContext initialized.');\n }\n }\n }\n\n /**\n * Plays a single tone with specified parameters.\n * @param frequency - The frequency of the tone in Hz.\n * @param duration - The duration of the tone in seconds.\n * @param volume - The volume of the tone (0.0 to 1.0).\n * @param waveformType - The type of waveform ('sine', 'square', 'sawtooth',\n * 'triangle').\n */\n playTone(\n frequency: number, duration: number, volume: number,\n waveformType: OscillatorType) {\n this._initAudioContext(); // Initialize context on first interaction\n\n if (!this.audioContext) {\n console.error(\n 'SoundSynthesizer: AudioContext not available. Cannot play tone.');\n return;\n }\n\n const oscillator = this.audioContext.createOscillator();\n oscillator.type = waveformType;\n oscillator.frequency.setValueAtTime(\n frequency, this.audioContext.currentTime);\n const gainNode = this.audioContext.createGain();\n gainNode.gain.setValueAtTime(volume, this.audioContext.currentTime);\n oscillator.connect(gainNode);\n gainNode.connect(this.audioContext.destination);\n oscillator.start();\n\n // Stop the sound after the specified duration with a slight fade out to\n // prevent clicks\n const stopTime = this.audioContext.currentTime + duration;\n const fadeOutTime = Math.max(\n 0.01, duration * 0.1); // Fade out over 10% of duration, min 0.01s\n\n gainNode.gain.exponentialRampToValueAtTime(0.00001, stopTime - fadeOutTime);\n oscillator.stop(stopTime);\n }\n\n /**\n * Plays a predefined sound preset.\n * @param presetName - The name of the preset (e.g., 'BEEP', 'CLICK',\n * 'ACTIVATE', 'DEACTIVATE').\n * @param volume - The volume for the preset (overrides default\n * if present, otherwise uses this).\n */\n playPresetTone(presetName: keyof typeof SOUND_PRESETS, volume = 0.5) {\n const preset = SOUND_PRESETS[presetName];\n\n if (!preset) {\n console.warn(`SoundSynthesizer: Preset '${presetName}' not found.`);\n return;\n }\n\n // Handle single tone presets\n if (!Array.isArray(preset)) {\n const tone = preset as SoundPresetTone;\n this.playTone(tone.frequency, tone.duration, volume, tone.waveformType);\n } else {\n // Handle multi-tone sequences\n preset.forEach(toneConfig => {\n setTimeout(() => {\n this.playTone(\n toneConfig.frequency, toneConfig.duration, volume,\n toneConfig.waveformType);\n }, toneConfig.delay || 0);\n });\n }\n }\n}\n","import * as THREE from 'three';\n\nimport {Script} from '../core/Script.js';\n\nimport {CategoryVolumes} from './CategoryVolumes.js';\n\nconst spatialSoundLibrary = {\n 'ambient': 'musicLibrary/AmbientLoop.opus',\n 'buttonHover': 'musicLibrary/ButtonHover.opus',\n 'paintOneShot1': 'musicLibrary/PaintOneShot1.opus',\n} as const;\n\nlet soundIdCounter = 0;\n\nexport interface PlaySoundOptions {\n loop?: boolean;\n volume?: number;\n refDistance?: number;\n rolloffFactor?: number;\n onEnded?: () => void;\n}\n\ninterface ActiveSound {\n audio: THREE.PositionalAudio;\n target: THREE.Object3D;\n options: PlaySoundOptions;\n}\n\nexport class SpatialAudio extends Script {\n private audioLoader = new THREE.AudioLoader();\n private soundLibrary = spatialSoundLibrary;\n // Stores { audio: PositionalAudio, target: Object3D } by id\n private activeSounds = new Map<number, ActiveSound>();\n\n private specificVolume = 1.0;\n private category = 'sfx' as const;\n private defaultRefDistance = 1;\n private defaultRolloffFactor = 1;\n\n constructor(\n private listener: THREE.AudioListener,\n private categoryVolumes: CategoryVolumes) {\n super();\n }\n\n /**\n * Plays a sound attached to a specific 3D object.\n * @param soundKey - Key from the soundLibrary.\n * @param targetObject - The object the sound should emanate\n * from.\n * @param options - Optional settings \\{ loop: boolean, volume:\n * number, refDistance: number, rolloffFactor: number, onEnded: function\n * \\}.\n * @returns A unique ID for the playing sound instance, or null\n * if failed.\n */\n playSoundAtObject(\n soundKey: keyof typeof spatialSoundLibrary, targetObject: THREE.Object3D,\n options: PlaySoundOptions = {}) {\n if (!this.listener || !this.audioLoader || !targetObject) {\n console.error(\n 'SpatialAudio not properly initialized or targetObject missing.');\n return null;\n }\n\n const soundPath = this.soundLibrary[soundKey];\n if (!soundPath) {\n console.error(`SpatialAudio: Sound key \"${soundKey}\" not found.`);\n return null;\n }\n\n const soundId = ++soundIdCounter;\n const specificVolume =\n options.volume !== undefined ? options.volume : this.specificVolume;\n const loop = options.loop || false;\n const refDistance = options.refDistance !== undefined ?\n options.refDistance :\n this.defaultRefDistance;\n const rolloffFactor = options.rolloffFactor !== undefined ?\n options.rolloffFactor :\n this.defaultRolloffFactor;\n\n console.log(`SpatialAudio: Loading sound \"${soundKey}\" (${soundPath})`);\n\n this.audioLoader.load(\n soundPath,\n (buffer) => {\n console.log(`SpatialAudio: Successfully loaded \"${soundKey}\"`);\n if (!this.listener) {\n console.error('SpatialAudio: Listener lost during load.');\n return;\n }\n const audio = new THREE.PositionalAudio(this.listener);\n audio.setBuffer(buffer);\n audio.setLoop(loop);\n audio.setRefDistance(refDistance);\n audio.setRolloffFactor(rolloffFactor);\n\n const effectiveVolume = this.categoryVolumes.getEffectiveVolume(\n this.category, specificVolume);\n audio.setVolume(effectiveVolume);\n\n targetObject.add(audio);\n this.activeSounds.set(\n soundId, {audio: audio, target: targetObject, options: options});\n\n // Set up cleanup for non-looping sounds\n if (!loop) {\n audio.onEnded = () => {\n console.log(\n `SpatialAudio: Sound \"${soundKey}\" (ID: ${soundId}) ended.`);\n this._cleanupSound(soundId);\n if (options.onEnded && typeof options.onEnded === 'function') {\n options.onEnded();\n }\n // Important: Clear the onEnded handler after it runs once\n // to prevent issues if the object is reused.\n audio.onEnded = () => {};\n };\n }\n\n audio.play();\n console.log(\n `SpatialAudio: Playing \"${soundKey}\" (ID: ${soundId}) at object ${\n targetObject.name ||\n targetObject.uuid}, Volume: ${effectiveVolume}`);\n },\n (xhr) => {\n console.log(`SpatialAudio: Loading \"${soundKey}\" - ${\n (xhr.loaded / xhr.total * 100).toFixed(0)}% loaded`);\n },\n (error) => {\n console.error(\n `SpatialAudio: Error loading sound \"${soundKey}\":`, error);\n this.activeSounds.delete(soundId); // Clean up if loading failed\n });\n\n return soundId;\n }\n\n /**\n * Stops a specific sound instance by its ID.\n * @param soundId - The ID returned by playSoundAtObject.\n */\n stopSound(soundId: number) {\n const soundData = this.activeSounds.get(soundId);\n if (soundData) {\n console.log(`SpatialAudio: Stopping sound ID: ${soundId}`);\n if (soundData.audio.isPlaying) {\n soundData.audio.stop();\n }\n this._cleanupSound(soundId);\n } else {\n console.warn(`SpatialAudio: Sound ID ${soundId} not found for stopping.`);\n }\n }\n\n /**\n * Internal method to remove sound from object and map.\n * @param soundId - id\n */\n private _cleanupSound(soundId: number) {\n const soundData = this.activeSounds.get(soundId);\n if (soundData) {\n if (soundData.audio.isPlaying) {\n try {\n soundData.audio.stop();\n } catch {\n // continue regardless of error\n }\n }\n if (soundData.target && soundData.audio.parent === soundData.target) {\n soundData.target.remove(soundData.audio);\n }\n this.activeSounds.delete(soundId);\n console.log(`SpatialAudio: Cleaned up sound ID: ${soundId}`);\n }\n }\n\n /**\n * Sets the base specific volume for subsequently played spatial sounds.\n * Does NOT affect currently playing sounds (use updateAllVolumes for that).\n * @param level - Volume level (0.0 to 1.0).\n */\n setVolume(level: number) {\n this.specificVolume = THREE.MathUtils.clamp(level, 0.0, 1.0);\n console.log(\n `SpatialAudio default specific volume set to: ${this.specificVolume}`);\n }\n\n /**\n * Updates the volume of all currently playing spatial sounds managed by this\n * instance.\n */\n updateAllVolumes() {\n if (!this.categoryVolumes) return;\n console.log(`SpatialAudio: Updating volumes for ${\n this.activeSounds.size} active sounds.`);\n this.activeSounds.forEach((soundData) => {\n const specificVolume = soundData.options.volume !== undefined ?\n soundData.options.volume :\n this.specificVolume;\n const effectiveVolume = this.categoryVolumes.getEffectiveVolume(\n this.category, specificVolume);\n soundData.audio.setVolume(effectiveVolume);\n });\n }\n\n destroy() {\n console.log('SpatialAudio Destroying...');\n const idsToStop = Array.from(this.activeSounds.keys());\n idsToStop.forEach(id => this.stopSound(id));\n\n this.activeSounds.clear();\n console.log('SpatialAudio Destroyed.');\n }\n}\n","import * as THREE from 'three';\n\nimport {Script} from '../core/Script.js';\n\nimport {SoundOptions, SpeechRecognizerOptions} from './SoundOptions.js';\nimport {SoundSynthesizer} from './SoundSynthesizer.js';\n\ntype WindowWithSpeechRecognition = Window&typeof globalThis&{\n SpeechRecognition?: SpeechRecognition;\n webkitSpeechRecognition?: SpeechRecognition;\n};\n\ninterface SpeechRecognizerEventMap extends THREE.Object3DEventMap {\n start: object;\n error: {error: string};\n end: object;\n result: {\n originalEvent: SpeechRecognitionEvent; transcript: string;\n confidence: number;\n command?: string; isFinal: boolean;\n };\n}\n\nexport class SpeechRecognizer extends Script<SpeechRecognizerEventMap> {\n static dependencies = {soundOptions: SoundOptions};\n\n options!: SpeechRecognizerOptions;\n recognition?: SpeechRecognition;\n isListening = false;\n lastTranscript = '';\n lastCommand?: string;\n lastConfidence = 0;\n error?: string;\n playActivationSounds = false;\n\n private handleStartBound = this._handleStart.bind(this);\n private handleResultBound = this._handleResult.bind(this);\n private handleEndBound = this._handleEnd.bind(this);\n private handleErrorBound = this._handleError.bind(this);\n\n constructor(private soundSynthesizer: SoundSynthesizer) {\n super();\n }\n\n override init({soundOptions}: {soundOptions: SoundOptions}) {\n this.options = soundOptions.speechRecognizer;\n const SpeechRecognitionAPI =\n (window as WindowWithSpeechRecognition).SpeechRecognition ||\n (window as WindowWithSpeechRecognition).webkitSpeechRecognition;\n if (!SpeechRecognitionAPI) {\n console.warn(\n 'SpeechRecognizer: Speech Recognition API not supported in this browser.');\n this.error = 'API not supported';\n return;\n }\n\n this.recognition = new SpeechRecognitionAPI();\n this.recognition.lang = this.options.lang;\n this.recognition.continuous = this.options.continuous;\n this.recognition.interimResults = this.options.interimResults;\n\n // Setup native event listeners\n this.recognition.onstart = this.handleStartBound;\n this.recognition.onresult = this.handleResultBound;\n this.recognition.onend = this.handleEndBound;\n this.recognition.onerror = this.handleErrorBound;\n }\n\n onSimulatorStarted() {\n this.playActivationSounds = this.options.playSimulatorActivationSounds;\n }\n\n start() {\n if (!this.recognition) {\n console.error('SpeechRecognizer: Not initialized.');\n return;\n }\n if (this.isListening) {\n console.warn('SpeechRecognizer: Already listening.');\n return;\n }\n try {\n this.lastTranscript = '';\n this.lastCommand = undefined;\n this.lastConfidence = 0;\n this.error = undefined;\n this.recognition.start();\n this.isListening = true;\n console.debug('SpeechRecognizer: Listening started.');\n } catch (e: unknown) {\n console.error('SpeechRecognizer: Error starting recognition:', e);\n this.error = (e as Partial<Error>).message || 'Start failed';\n this.isListening = false;\n this.dispatchEvent({type: 'error', error: this.error!});\n }\n }\n\n stop() {\n if (!this.recognition || !this.isListening) {\n return;\n }\n try {\n this.recognition.stop();\n console.debug('SpeechRecognizer: Stop requested.');\n } catch (e) {\n console.error('SpeechRecognizer: Error stopping recognition:', e);\n this.error = (e as Partial<Error>).message || 'Stop failed';\n this.isListening = false;\n }\n }\n\n getLastTranscript() {\n return this.lastTranscript;\n }\n\n getLastCommand() {\n return this.lastCommand;\n }\n\n getLastConfidence() {\n return this.lastConfidence;\n }\n\n // Private handler for the 'start' event\n private _handleStart() {\n console.debug('SpeechRecognizer: Listening started.');\n this.dispatchEvent({type: 'start'});\n if (this.playActivationSounds) {\n this.soundSynthesizer.playPresetTone('ACTIVATE');\n }\n }\n\n // Private handler for the 'result' event\n private _handleResult(event: SpeechRecognitionEvent) {\n let interimTranscript = '';\n let finalTranscript = '';\n let currentConfidence = 0;\n\n for (let i = event.resultIndex; i < event.results.length; ++i) {\n const result = event.results[i];\n const transcript = result[0].transcript;\n if (result.isFinal) {\n finalTranscript += transcript;\n currentConfidence = result[0].confidence;\n } else {\n interimTranscript += transcript;\n }\n }\n\n this.lastTranscript = finalTranscript.trim() || interimTranscript.trim();\n this.lastConfidence = currentConfidence;\n this.lastCommand = undefined;\n\n if (finalTranscript && this.options.commands.length > 0) {\n const upperTranscript = finalTranscript.trim().toUpperCase();\n for (const command of this.options.commands) {\n if (upperTranscript.includes(command.toUpperCase()) &&\n this.lastConfidence >= this.options.commandConfidenceThreshold) {\n this.lastCommand = command;\n console.debug(\n `SpeechRecognizer Detected Command: ${this.lastCommand}`);\n break;\n }\n }\n }\n\n // Dispatch a 'result' event with all the relevant data\n this.dispatchEvent({\n type: 'result',\n originalEvent: event,\n transcript: this.lastTranscript,\n confidence: this.lastConfidence,\n command: this.lastCommand,\n isFinal: !!finalTranscript\n });\n }\n\n // Private handler for the 'end' event (e.g., when silence is detected)\n _handleEnd() {\n this.isListening = false;\n this.dispatchEvent({type: 'end'});\n\n if (this.options.continuous && this.error !== 'aborted' &&\n this.error !== 'no-speech') {\n console.debug('SpeechRecognizer: Restarting continuous listening...');\n setTimeout(() => this.start(), 100);\n } else if (this.playActivationSounds) {\n this.soundSynthesizer.playPresetTone('DEACTIVATE');\n }\n }\n\n // Private handler for the 'error' event\n _handleError(event: SpeechRecognitionErrorEvent) {\n console.error('SpeechRecognizer: Error:', event.error);\n this.error = event.error;\n this.isListening = false;\n this.dispatchEvent({type: 'error', error: event.error});\n }\n\n destroy() {\n this.stop();\n if (this.recognition) {\n this.recognition.onstart = null;\n this.recognition.onresult = null;\n this.recognition.onend = null;\n this.recognition.onerror = null;\n this.recognition = undefined;\n }\n }\n}\n","import * as THREE from 'three';\n\nimport {Script} from '../core/Script.js';\n\nimport {CategoryVolumes} from './CategoryVolumes.js';\nimport {SoundOptions, SpeechSynthesizerOptions} from './SoundOptions.js';\n\nexport class SpeechSynthesizer extends Script {\n static dependencies = {soundOptions: SoundOptions};\n\n private synth = window.speechSynthesis;\n private voices: SpeechSynthesisVoice[] = [];\n private selectedVoice?: SpeechSynthesisVoice;\n private isSpeaking = false;\n private debug = false;\n private specificVolume = 1.0;\n private speechCategory = 'speech';\n private options!: SpeechSynthesizerOptions;\n\n constructor(\n private categoryVolumes: CategoryVolumes,\n private onStartCallback = () => {}, private onEndCallback = () => {},\n private onErrorCallback = (_: Error) => {}) {\n super();\n\n if (!this.synth) {\n console.error('SpeechSynthesizer: Speech Synthesis API not supported.');\n } else {\n this.loadVoices();\n if (this.synth.onvoiceschanged !== undefined) {\n this.synth.onvoiceschanged = this.loadVoices.bind(this);\n }\n }\n if (!this.categoryVolumes && this.synth) {\n console.warn(\n 'SpeechSynthesizer: CategoryVolumes not found. Volume control will use specificVolume only.');\n }\n }\n\n init({soundOptions}: {soundOptions: SoundOptions}) {\n this.options = soundOptions.speechSynthesizer;\n if (this.debug) {\n console.log('SpeechSynthesizer initialized.');\n }\n }\n\n loadVoices() {\n if (!this.synth) return;\n this.voices = this.synth.getVoices();\n if (this.debug) {\n console.log('SpeechSynthesizer: Voices loaded:', this.voices.length);\n }\n this.selectedVoice = this.voices.find(\n voice => voice.name.includes('Google') &&\n voice.lang.startsWith('en')) ||\n this.voices.find(voice => voice.lang.startsWith('en'));\n if (this.selectedVoice) {\n if (this.debug) {\n console.log(\n 'SpeechSynthesizer: Selected voice:', this.selectedVoice.name);\n }\n } else {\n console.warn('SpeechSynthesizer: No suitable default voice found.');\n }\n }\n\n setVolume(level: number) {\n this.specificVolume = THREE.MathUtils.clamp(level, 0.0, 1.0);\n console.log(\n `SpeechSynthesizer specific volume set to: ${this.specificVolume}`);\n }\n\n speak(text: string, lang = 'en-US', pitch = 1.0, rate = 1.0) {\n return new Promise<void>((resolve, reject) => {\n if (!this.synth) {\n console.warn('SpeechSynthesizer: Cannot speak. API not supported.');\n return reject(new Error('Speech Synthesis API not supported.'));\n }\n\n if (this.isSpeaking) {\n if (this.options.allowInterruptions) {\n console.warn(\n 'SpeechSynthesizer: Already speaking. Interrupting current speech.');\n this.cancel();\n } else {\n const errorMsg =\n 'Already speaking and interruptions are not allowed.';\n console.warn(`SpeechSynthesizer: ${errorMsg}`);\n return reject(new Error(errorMsg));\n }\n }\n\n const utterance = new SpeechSynthesisUtterance(text);\n\n utterance.onstart = () => {\n this.isSpeaking = true;\n console.log('SpeechSynthesizer: Speaking started.');\n if (this.onStartCallback) this.onStartCallback();\n };\n\n utterance.onend = () => {\n this.isSpeaking = false;\n console.log('SpeechSynthesizer: Speaking ended.');\n if (this.onEndCallback) this.onEndCallback();\n resolve();\n };\n\n utterance.onerror = (event) => {\n if (this.options.allowInterruptions &&\n (event.error === 'interrupted' || event.error === 'canceled')) {\n console.warn(`SpeechSynthesizer: Speech utterance interrupted: ${\n event.error}`);\n return;\n }\n\n // For all other errors, reject the promise.\n console.error('SpeechSynthesizer: Error occurred:', event.error);\n this.isSpeaking = false;\n this.onErrorCallback(\n new Error(`Speech synthesis error code ${event.error}`));\n reject(event.error);\n };\n\n // Find a suitable voice if not already selected or if lang changed\n let voice = this.selectedVoice;\n if (!voice || !voice.lang.startsWith(lang.substring(0, 2))) {\n voice = this.voices.find(\n v => v.lang === lang && v.name.includes('Google')) ||\n this.voices.find(\n v => v.lang.startsWith(lang.substring(0, 2)) &&\n v.name.includes('Google')) ||\n this.voices.find(v => v.lang === lang) ||\n this.voices.find(v => v.lang.startsWith(lang.substring(0, 2)));\n }\n\n if (voice) {\n utterance.voice = voice;\n console.log(\n `SpeechSynthesizer: Using voice: ${voice.name} for lang ${lang}`);\n } else {\n utterance.lang = lang;\n console.warn(`SpeechSynthesizer: No specific voice found for lang ${\n lang}. Using browser default.`);\n }\n\n utterance.pitch = THREE.MathUtils.clamp(pitch, 0, 2);\n utterance.rate = THREE.MathUtils.clamp(rate, 0.1, 10);\n\n let effectiveVolume = this.specificVolume;\n if (this.categoryVolumes) {\n effectiveVolume = this.categoryVolumes.getEffectiveVolume(\n this.speechCategory, this.specificVolume);\n } else {\n effectiveVolume = THREE.MathUtils.clamp(this.specificVolume, 0.0, 1.0);\n }\n utterance.volume = effectiveVolume;\n console.log(\n `SpeechSynthesizer: Setting utterance volume to ${effectiveVolume}`);\n\n this.synth.speak(utterance);\n });\n }\n\n tts(text: string, lang?: string, pitch?: number, rate?: number) {\n this.speak(text, lang, pitch, rate);\n }\n\n cancel() {\n if (this.synth && this.synth.speaking) {\n this.synth.cancel();\n this.isSpeaking = false;\n console.log('SpeechSynthesizer: Speech cancelled.');\n }\n }\n\n destroy() {\n this.cancel();\n if (this.synth && this.synth.onvoiceschanged !== undefined) {\n this.synth.onvoiceschanged = null;\n }\n this.voices = [];\n console.log('SpeechSynthesizer destroyed.');\n }\n}\n","import * as THREE from 'three';\n\nimport {Script} from '../core/Script';\n\nimport {AudioListener} from './AudioListener';\nimport {AudioPlayer} from './AudioPlayer';\nimport {BackgroundMusic} from './BackgroundMusic';\nimport {CategoryVolumes, VolumeCategory} from './CategoryVolumes';\nimport {SoundOptions} from './SoundOptions';\nimport {SoundSynthesizer} from './SoundSynthesizer';\nimport {SpatialAudio} from './SpatialAudio';\nimport {SpeechRecognizer} from './SpeechRecognizer';\nimport {SpeechSynthesizer} from './SpeechSynthesizer';\n\nexport class CoreSound extends Script {\n static dependencies = {camera: THREE.Camera, soundOptions: SoundOptions}\n\n categoryVolumes = new CategoryVolumes();\n soundSynthesizer = new SoundSynthesizer();\n listener = new THREE.AudioListener();\n backgroundMusic!: BackgroundMusic;\n spatialAudio!: SpatialAudio\n speechRecognizer?: SpeechRecognizer\n speechSynthesizer?: SpeechSynthesizer\n audioListener!: AudioListener;\n audioPlayer!: AudioPlayer;\n options!: SoundOptions;\n\n init({camera, soundOptions}:\n {camera: THREE.Camera; soundOptions: SoundOptions;}) {\n this.options = soundOptions;\n\n this.backgroundMusic =\n new BackgroundMusic(this.listener, this.categoryVolumes);\n this.spatialAudio = new SpatialAudio(this.listener, this.categoryVolumes);\n this.audioListener = new AudioListener();\n // Initialize with 48kHz for general audio playback\n // Gemini Live uses 24kHz but that gets handled automatically via playAIAudio\n this.audioPlayer = new AudioPlayer({sampleRate: 48000});\n this.audioPlayer.setCategoryVolumes(this.categoryVolumes);\n\n camera.add(this.listener);\n this.add(this.backgroundMusic);\n this.add(this.spatialAudio);\n this.add(this.audioListener);\n this.add(this.audioPlayer);\n this.add(this.soundSynthesizer);\n\n if (this.options.speechRecognizer.enabled) {\n this.speechRecognizer = new SpeechRecognizer(this.soundSynthesizer);\n this.add(this.speechRecognizer);\n }\n\n if (this.options.speechSynthesizer.enabled) {\n this.speechSynthesizer = new SpeechSynthesizer(this.categoryVolumes);\n this.add(this.speechSynthesizer);\n }\n }\n\n getAudioListener() {\n return this.listener;\n }\n\n setMasterVolume(level: number) {\n this.categoryVolumes.masterVolume = THREE.MathUtils.clamp(level, 0.0, 1.0);\n this.audioPlayer?.updateGainNodeVolume();\n }\n\n getMasterVolume() {\n return this.categoryVolumes.isMuted ? 0.0 :\n this.categoryVolumes.masterVolume;\n }\n\n setCategoryVolume(category: VolumeCategory, level: number) {\n if (category in this.categoryVolumes.volumes) {\n this.categoryVolumes.volumes[category] =\n THREE.MathUtils.clamp(level, 0.0, 1.0);\n }\n }\n\n getCategoryVolume(category: VolumeCategory) {\n return category in this.categoryVolumes.volumes ?\n this.categoryVolumes.volumes[category] :\n 1.0;\n }\n\n async enableAudio(options: {streamToAI?: boolean; accumulate?: boolean} = {}) {\n const {streamToAI = true, accumulate = false} = options;\n if (streamToAI && this.speechRecognizer?.isListening) {\n console.log('Disabling SpeechRecognizer while streaming audio.');\n this.speechRecognizer.stop();\n }\n this.audioListener.setAIStreaming(streamToAI);\n await this.audioListener.startCapture({accumulate});\n }\n\n disableAudio() {\n this.audioListener?.stopCapture();\n }\n\n /**\n * Starts recording audio with chunk accumulation\n */\n async startRecording() {\n await this.audioListener.startCapture({accumulate: true});\n }\n\n /**\n * Stops recording and returns the accumulated audio buffer\n */\n stopRecording(): ArrayBuffer|null {\n const buffer = this.audioListener.getAccumulatedBuffer();\n this.audioListener.stopCapture();\n return buffer;\n }\n\n /**\n * Gets the accumulated recording buffer without stopping\n */\n getRecordedBuffer(): ArrayBuffer|null {\n return this.audioListener.getAccumulatedBuffer();\n }\n\n /**\n * Clears the accumulated recording buffer\n */\n clearRecordedBuffer() {\n this.audioListener.clearAccumulatedBuffer();\n }\n\n /**\n * Gets the sample rate being used for recording\n */\n getRecordingSampleRate(): number {\n return this.audioListener.audioContext?.sampleRate || 48000;\n }\n\n setAIStreaming(enabled: boolean) {\n this.audioListener?.setAIStreaming(enabled);\n }\n\n isAIStreamingEnabled() {\n return this.audioListener?.aiService !== null;\n }\n\n async playAIAudio(base64AudioData: string) {\n // Gemini Live API outputs audio at 24kHz\n // Only recreate AudioContext if sample rate needs to change\n const currentRate = this.audioPlayer['options'].sampleRate;\n if (currentRate !== 24000) {\n this.audioPlayer['options'].sampleRate = 24000;\n // Only stop if context exists and is different sample rate\n if (this.audioPlayer['audioContext']) {\n this.audioPlayer.stop(); // Reset context with new sample rate\n }\n }\n await this.audioPlayer.playAudioChunk(base64AudioData);\n }\n\n stopAIAudio() {\n this.audioPlayer?.clearQueue();\n }\n\n isAIAudioPlaying() {\n return this.audioPlayer?.getIsPlaying();\n }\n\n /**\n * Plays a raw audio buffer (Int16 PCM data) with proper sample rate\n */\n async playRecordedAudio(audioBuffer: ArrayBuffer, sampleRate?: number) {\n if (!audioBuffer) return;\n \n // Update sample rate if needed\n if (sampleRate && sampleRate !== this.audioPlayer['options'].sampleRate) {\n this.audioPlayer['options'].sampleRate = sampleRate;\n this.audioPlayer.stop(); // Reset context with new sample rate\n }\n \n // Convert ArrayBuffer to base64\n const bytes = new Uint8Array(audioBuffer);\n let binary = '';\n for (let i = 0; i < bytes.length; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n const base64Audio = btoa(binary);\n \n await this.audioPlayer.playAudioChunk(base64Audio);\n }\n\n isAudioEnabled() {\n return this.audioListener?.getIsCapturing();\n }\n\n getLatestAudioBuffer() {\n return this.audioListener?.getLatestAudioBuffer();\n }\n\n clearLatestAudioBuffer() {\n this.audioListener?.clearLatestAudioBuffer();\n }\n\n getEffectiveVolume(category: VolumeCategory, specificVolume = 1.0) {\n return this.categoryVolumes.getEffectiveVolume(category, specificVolume);\n }\n\n muteAll() {\n this.categoryVolumes.isMuted = true;\n }\n\n unmuteAll() {\n this.categoryVolumes.isMuted = false;\n }\n\n destroy() {\n this.backgroundMusic?.destroy();\n this.spatialAudio?.destroy();\n this.speechRecognizer?.destroy();\n this.speechSynthesizer?.destroy();\n this.audioListener?.dispose();\n this.audioPlayer?.dispose();\n this.listener?.parent?.remove(this.listener);\n }\n}\n","/**\n * Conversion factor from Density-Independent Pixels (DP) to\n * distance-independent millimeters (DMM).\n */\nexport const DP_TO_DMM = 0.868;\n","import * as THREE from 'three';\n\nimport {VIEW_DEPTH_GAP} from '../../constants';\nimport {Script} from '../../core/Script';\nimport {DP_TO_DMM} from '../constants';\n\nimport type {ViewOptions} from './ViewOptions';\n\n// Temporary variables.\nconst worldScale = new THREE.Vector3();\n\n/**\n * A fundamental UI component for creating interactive user\n * interfaces. It serves as a base class for other UI elements like Panels,\n * Rows, and Columns, providing core layout logic, visibility control, and\n * interaction hooks.\n *\n * Each `View` is a `THREE.Object3D` and inherits lifecycle methods from\n * `Script`.\n */\nexport class View<TEventMap extends THREE.Object3DEventMap =\n THREE.Object3DEventMap> extends\n Script<TEventMap> {\n /** Text description of the view */\n name = 'View';\n /** Flag indicating View behaves as a 2D quad in layout calculations. */\n isQuad = true;\n /** Flag indicating if this is the root view of a layout. */\n isRoot = false;\n /** Type identifier for easy checking with `instanceof`. */\n isView = true;\n /** Determines if this view can be targeted by user input. */\n selectable = true;\n\n // --- Layout Properties ---\n\n /** Proportional size used in layouts like `Row` or `Col`. */\n weight = 0.5;\n /** The width of the view, as a 0-1 ratio of its parent's available space. */\n width = 1;\n /** The height of the view, as a 0-1 ratio of its parent's available space. */\n height = 1;\n /**\n * The local x-coordinate within the parent's layout, from -0.5 to 0.5.\n * For root view (Panel), this will be addition to the global positioning.\n */\n x = 0;\n /**\n * The local y-coordinate within the parent's layout, from -0.5 to 0.5.\n * For root view (Panel), this will be addition to the global positioning.\n */\n y = 0;\n /**\n * The local z-coordinate within the parent's layout.\n * For root view (Panel), this will be addition to the global positioning.\n */\n z = 0;\n /** Horizontal padding, as a 0-1 ratio of the parent's width. */\n paddingX = 0;\n /** Vertical padding, as a 0-1 ratio of the parent's height. */\n paddingY = 0;\n /** Depth padding, for z-axis adjustment to prevent z-fighting. */\n paddingZ = 0;\n\n // --- Visual Properties ---\n\n /** The overall opacity of the view and its children. */\n opacity = 1.0;\n /** The underlying THREE.Mesh if the view has a visible geometry. */\n mesh?: THREE.Mesh;\n /** The calculated aspect ratio (width / height) of this view. */\n aspectRatio = 1.0;\n\n /**\n * Gets the effective horizontal range for child elements, normalized to 1.0\n * for the smaller dimension.\n * @returns The horizontal layout range.\n */\n get rangeX(): number {\n return Math.max(this.aspectRatio, 1.0);\n }\n\n /**\n * Gets the effective vertical range for child elements, normalized to 1.0 for\n * the smaller dimension.\n * @returns The vertical layout range.\n */\n get rangeY(): number {\n return Math.max(1.0 / this.aspectRatio, 1.0);\n }\n\n /**\n * Creates an instance of View.\n * @param options - Configuration options to apply to the view.\n * @param geometry - The geometry for the view's mesh.\n * @param material - The material for the view's mesh.\n */\n constructor(\n options: ViewOptions = {}, geometry?: THREE.BufferGeometry,\n material?: THREE.Material) {\n super();\n if (geometry && material) {\n this.mesh = new THREE.Mesh(geometry, material);\n this.add(this.mesh);\n }\n Object.assign(this, options);\n }\n\n /**\n * Converts a value from Density-Independent Pixels (DP) to meters.\n * @param dp - The value in density-independent pixels.\n * @returns The equivalent value in meters.\n */\n static dpToMeters(dp: number): number {\n return dp * DP_TO_DMM * 0.001;\n }\n\n /**\n * Converts a value from Density-Independent Pixels (DP) to local units.\n * @param dp - The value in density-independent pixels.\n * @returns The equivalent value in local units.\n */\n dpToLocalUnits(dp: number): number {\n this.getWorldScale(worldScale);\n return View.dpToMeters(dp) / worldScale.x;\n }\n\n /** Makes the view and all its descendants visible. */\n show() {\n this.visible = true;\n this.traverse((child) => {\n child.visible = true;\n });\n }\n\n /** Makes the view and all its descendants invisible. */\n hide() {\n this.visible = false;\n this.traverse((child) => {\n child.visible = false;\n });\n }\n\n /**\n * Calculates and applies the position and scale for this single view based on\n * its layout properties and its parent's dimensions.\n */\n updateLayout() {\n if (this.isRoot || this.parent == null) {\n // Root views are centered and scaled directly by their width and height.\n this.aspectRatio = this.width / this.height;\n this.scale.setScalar(Math.min(this.width, this.height));\n } else if (this.parent instanceof View) {\n // Child views are positioned relative to their parent with padding.\n // A small depth gap is added to prevent z-fighting between UI layers.\n this.position.set(\n (this.x + this.paddingX) * this.parent.rangeX,\n (this.y - this.paddingY) * this.parent.rangeY,\n this.paddingZ + VIEW_DEPTH_GAP);\n this.aspectRatio = (this.width / this.height) * this.parent.aspectRatio;\n this.scale.setScalar(Math.min(\n this.parent.rangeX * this.width, this.parent.rangeY * this.height));\n\n // Increment renderOrder to ensure children render on top of parents,\n // which is crucial for transparency.\n this.renderOrder = this.parent.renderOrder + 1;\n }\n }\n\n /** Triggers a layout update for this view and all its descendants. */\n updateLayouts() {\n this.updateLayoutsBFS();\n }\n\n /**\n * Performs a Breadth-First Search (BFS) traversal to update the layout tree,\n * ensuring parent layouts are calculated before their children.\n */\n updateLayoutsBFS() {\n const queue: THREE.Object3D[] = [this];\n while (queue.length > 0) {\n const currentView = queue.shift();\n if (currentView instanceof View) {\n currentView.updateLayout();\n currentView.children.forEach((childView) => {\n queue.push(childView);\n });\n }\n }\n }\n\n /**\n * Resets the layout state of this view. Intended for override by subclasses.\n */\n resetLayout() {}\n\n /** Resets the layout state for this view and all its descendants. */\n resetLayouts() {\n const queue: THREE.Object3D[] = [this];\n while (queue.length > 0) {\n const currentView = queue.shift();\n if (currentView instanceof View) {\n currentView.resetLayout();\n currentView.children.forEach((childView) => {\n queue.push(childView);\n });\n }\n }\n }\n\n /**\n * Overrides `THREE.Object3D.add` to automatically trigger a layout update\n * when a new `View` is added as a child.\n */\n add(...children: THREE.Object3D[]) {\n super.add(...children);\n for (const child of children) {\n if (child instanceof View) {\n child.updateLayoutsBFS();\n }\n }\n return this;\n }\n\n /**\n * Hook called on a complete select action (e.g., a click) when this view is\n * the target. Intended for override by subclasses.\n * @param _id - The ID of the controller that triggered the action.\n */\n onTriggered(_id: number) {}\n}\n","export const FONT_FAMILIES = {\n Roboto: 'https://fonts.gstatic.com/s/roboto/v18/KFOmCnqEu92Fr1Mu4mxM.woff',\n 'Noto Sans':\n 'https://fonts.gstatic.com/s/notosans/v7/o-0IIpQlx3QUlC5A4PNr5TRG.woff',\n Comfortaa:\n 'https://fonts.gstatic.com/s/comfortaa/v12/1Ptsg8LJRfWJmhDAuUs4TYFs.woff',\n Cookie: 'https://fonts.gstatic.com/s/cookie/v8/syky-y18lb0tSbf9kgqU.woff',\n Philosopher:\n 'https://fonts.gstatic.com/s/philosopher/v9/vEFV2_5QCwIS4_Dhez5jcWBuT0s.woff',\n Quicksand:\n 'https://fonts.gstatic.com/s/quicksand/v7/6xKtdSZaM9iE8KbpRA_hK1QL.woff',\n Trirong: 'https://fonts.gstatic.com/s/trirong/v3/7r3GqXNgp8wxdOdOn4so3g.woff',\n Trocchi: 'https://fonts.gstatic.com/s/trocchi/v6/qWcqB6WkuIDxDZLcPrxeuw.woff',\n 'Advent Pro':\n 'https://fonts.gstatic.com/s/adventpro/v7/V8mAoQfxVT4Dvddr_yOwhTqtLg.woff',\n 'Henny Penny':\n 'https://fonts.gstatic.com/s/hennypenny/v5/wXKvE3UZookzsxz_kjGSfPQtvXQ.woff',\n Orbitron:\n 'https://fonts.gstatic.com/s/orbitron/v9/yMJRMIlzdpvBhQQL_Qq7dys.woff',\n Sacramento:\n 'https://fonts.gstatic.com/s/sacramento/v5/buEzpo6gcdjy0EiZMBUG4C0f-w.woff',\n 'Snowburst One':\n 'https://fonts.gstatic.com/s/snowburstone/v5/MQpS-WezKdujBsXY3B7I-UT7SZieOA.woff',\n Syncopate:\n 'https://fonts.gstatic.com/s/syncopate/v9/pe0sMIuPIYBCpEV5eFdCBfe5.woff',\n Wallpoet:\n 'https://fonts.gstatic.com/s/wallpoet/v9/f0X10em2_8RnXVVdUObp58I.woff',\n 'Sirin Stencil':\n 'https://fonts.gstatic.com/s/sirinstencil/v6/mem4YaWwznmLx-lzGfN7MdRyRc9MAQ.woff',\n 'Roboto Slab':\n 'https://cdn.jsdelivr.net/gh/google/fonts@3b179b729ac3306ab2a249d848d94ff08b90a0af/apache/robotoslab/static/RobotoSlab-Black.ttf'\n};\n\nexport const MATERIAL_ICONS_FONT_FILE =\n 'https://cdn.jsdelivr.net/gh/marella/material-icons@v1.13.14/iconfont/material-icons.woff';","import * as THREE from 'three';\nimport type TroikaThreeText from 'troika-three-text';\n\nimport {getColorHex} from '../../utils/utils';\nimport {View} from '../core/View';\nimport {ViewOptions} from '../core/ViewOptions';\n\nimport {FONT_FAMILIES} from './utils/FontFamilies';\n\n\n// --- Dynamic Import of Troika Three Text and its dependencies ---\n\n/** Enum for the status of the Troika dynamic import. */\nenum TroikaImportStatus {\n PENDING = 0,\n SUCCESS = 1,\n FAILED = 2,\n}\n\n// --- Troika Dependency Management ---\nlet Text: typeof TroikaThreeText.Text;\nlet troikaImportStatus = TroikaImportStatus.PENDING;\nlet troikaImportError: Error|undefined;\n\nasync function importTroika() {\n if (Text) return true;\n try {\n const troikaModule = await import('troika-three-text');\n Text = troikaModule.Text;\n troikaImportStatus = TroikaImportStatus.SUCCESS;\n return true;\n } catch (error: unknown) {\n if (error instanceof Error) {\n troikaImportError = error;\n }\n troikaImportStatus = TroikaImportStatus.FAILED;\n return false;\n }\n};\n\ninterface TextViewEventMap extends THREE.Object3DEventMap {\n synccomplete: object;\n}\n\nexport type TextViewOptions = ViewOptions&{\n useSDFText?: boolean;\n font?: string;\n fontSize?: number;\n /**\n * Font size in dp. This will be scale up so it's a consistent size in world\n * coordinates.\n */\n fontSizeDp?: number;\n fontColor?: string|number;\n maxWidth?: number;\n mode?: 'fitWidth'|'center';\n anchorX?: number|'left'|'center'|'right'|`${number}%`;\n anchorY?: number|'top'|'top-baseline'|'top-cap'|'top-ex'|'middle'|\n 'bottom-baseline'|'bottom'|`${number}%`;\n textAlign?: 'left'|'center'|'right';\n imageOverlay?: string;\n imageOffsetX?: number;\n imageOffsetY?: number;\n text?: string;\n};\n\n/**\n * A view for displaying text in 3D. It features a dual-rendering\n * system:\n * 1. **SDF Text (Default):** Uses `troika-three-text` to render crisp,\n * high-quality text using Signed Distance Fields. This is ideal for most\n * use cases. The library is loaded dynamically on demand.\n * 2. **HTML Canvas Fallback:** If `troika-three-text` fails to load or is\n * disabled via `useSDFText: false`, it renders text to an HTML canvas and\n * applies it as a texture to a plane.\n */\nexport class TextView extends View<TextViewEventMap> {\n /** Determines which rendering backend to use. Defaults to SDF text. */\n useSDFText = true;\n /** TextView resides in a panel by default. */\n isRoot = false;\n /** Default description of this view in Three.js DevTools. */\n name = 'TextView';\n\n /** The underlying renderable object (either a Troika Text or a Plane. */\n textObj?: TroikaThreeText.Text|THREE.Mesh;\n /** The font file to use. Defaults to Roboto. */\n font = FONT_FAMILIES.Roboto;\n /** The size of the font in world units. */\n fontSize?: number;\n fontSizeDp?: number;\n /** The color of the font. */\n fontColor: string|number = 0xFFFFFF;\n /**\n * The maximum width the text can occupy before wrapping.\n * To fit a long TextView within a container, this value should be its\n * container's height / width to avoid it getting rendered outside.\n */\n maxWidth = 1.0;\n /** Layout mode. 'fitWidth' scales text to fit the view's width. */\n mode = 'fitWidth';\n /** Horizontal anchor point ('left', 'center', 'right'). */\n anchorX: number|'left'|'center'|'right'|`${number}%` = 'center';\n /** Vertical anchor point ('top', 'middle', 'bottom'). */\n anchorY: number|'top'|'top-baseline'|'top-cap'|'top-ex'|'middle'|\n 'bottom-baseline'|'bottom'|`${number}%` = 'middle';\n /** Horizontal alignment ('left', 'center', 'right'). */\n textAlign = 'center';\n /** An optional image URL to use as an overlay texture on the text. */\n imageOverlay?: string;\n /** The horizontal offset for the `imageOverlay` texture. */\n imageOffsetX = 0;\n /** The vertical offset for the `imageOverlay` texture. */\n imageOffsetY = 0;\n\n /** Relative local offset in X. */\n x = 0;\n /** Relative local offset in Y. */\n y = 0;\n /** Relative local width. */\n width = 1;\n /** Relative local height. */\n height = 1;\n\n /** Fallback HTML canvas to render legacy text. */\n canvas?: HTMLCanvasElement;\n /** Fallback HTML canvas context to render legacy text. */\n ctx?: CanvasRenderingContext2D;\n /** The calculated height of a single line of text. */\n lineHeight = 0;\n /** The total number of lines after text wrapping. */\n lineCount = 0;\n\n private _initializeTextCalled = false;\n private _text = 'TextView';\n set text(text) {\n this._text = text;\n if (this.useSDFText && Text && this.textObj instanceof Text) {\n this.textObj.text = text;\n this.textObj.sync();\n } else {\n this.updateHTMLText();\n }\n }\n\n get text() {\n return this._text;\n }\n\n /**\n * TextView can render text using either Troika SDF text or HTML canvas.\n * @param options - Configuration options for the TextView.\n * @param geometry - Optional geometry for the view's background mesh.\n * @param material - Optional material for the view's background mesh.\n */\n constructor(\n options: TextViewOptions = {}, geometry?: THREE.BufferGeometry,\n material?: THREE.Material) {\n super(options, geometry, material);\n\n this.useSDFText = options.useSDFText ?? this.useSDFText;\n this.font = options.font ?? this.font;\n this.fontSize = options.fontSize ?? this.fontSize;\n this.fontSizeDp = options.fontSizeDp ?? this.fontSizeDp;\n this.fontColor = options.fontColor ?? this.fontColor;\n this.maxWidth = options.maxWidth ?? this.maxWidth;\n\n this.mode = options.mode ?? this.mode;\n this.anchorX = options.anchorX ?? this.anchorX;\n this.anchorY = options.anchorY ?? this.anchorY;\n this.textAlign = options.textAlign ?? this.textAlign;\n this.imageOverlay = options.imageOverlay ?? this.imageOverlay;\n this.imageOffsetX = options.imageOffsetX ?? this.imageOffsetX;\n this.imageOffsetY = options.imageOffsetY ?? this.imageOffsetY;\n this.text = options.text ?? this._text;\n }\n\n /**\n * Initializes the TextView. It waits for the Troika module to be imported\n * and then creates the text object, sets up aspect ratio, and loads overlays.\n */\n override async init(_?: object) {\n this.useSDFText = this.useSDFText && await importTroika();\n this._initializeText();\n }\n\n /**\n * Sets the text content of the view.\n * @param text - The text to be displayed.\n */\n setText(text: string) {\n this.text = text;\n }\n\n /**\n * Updates the layout of the text object, such as its render order.\n */\n override updateLayout() {\n super.updateLayout();\n if (this.textObj) {\n this.textObj.renderOrder = this.renderOrder;\n if (this.fontSizeDp === undefined) {\n switch (this.mode) {\n case 'fitWidth':\n this.textObj.scale.setScalar(this.rangeX);\n break;\n }\n }\n }\n if (this.fontSizeDp && this.textObj) {\n this.createTextSDF();\n }\n }\n\n /**\n * Creates the text object using Troika Three Text for SDF rendering.\n * This method should only be called from _initializeText() when `useSDFText`\n * is true and the `troika-three-text` module has been successfully imported.\n */\n protected createTextSDF() {\n const obj =\n Text && this.textObj instanceof Text ? this.textObj : new Text();\n obj.text = this.text;\n obj.color = getColorHex(this.fontColor);\n obj.font = this.font;\n obj.anchorX = this.anchorX;\n obj.anchorY = this.anchorY;\n if (this.fontSizeDp !== undefined) {\n obj.fontSize = this.dpToLocalUnits(this.fontSizeDp);\n } else if (this.fontSize !== undefined) {\n obj.fontSize = this.fontSize;\n } else {\n obj.fontSize = 0.06;\n }\n obj.maxWidth = this.maxWidth;\n obj.textAlign = this.textAlign;\n // Transparent objects should not write to depth.\n if (obj.material) {\n obj.material.depthWrite = !obj.material.transparent;\n }\n obj.sync();\n\n this.textObj = obj;\n this.textObj.layers.mask = this.layers.mask;\n this.add(this.textObj);\n }\n\n /**\n * Creates a text object using an HTML canvas as a texture on a THREE.Plane.\n * This serves as a fallback when Troika is not available or `useSDFText` is\n * false. This method should only be called from _initializeText().\n */\n private createTextHTML() {\n this.canvas = document.createElement('canvas');\n this.ctx = this.canvas.getContext('2d')!;\n const planeGeometry = new THREE.PlaneGeometry(this.width, this.height);\n const texture = new THREE.CanvasTexture(this.canvas);\n const planeMaterial = new THREE.MeshBasicMaterial({\n map: texture,\n transparent: true,\n });\n\n this.textObj = new THREE.Mesh(planeGeometry, planeMaterial);\n this.updateHTMLText();\n this.add(this.textObj);\n }\n\n /**\n * Updates the content of the HTML canvas when not using SDF text.\n * It clears the canvas and redraws the text with the current properties.\n */\n private updateHTMLText() {\n if (!this.ctx) return;\n const {canvas, ctx} = this;\n // A higher resolution gives sharper text.\n const resolution = 256;\n canvas!.width = this.width * resolution;\n canvas!.height = this.height * resolution;\n\n ctx.clearRect(0, 0, canvas!.width, canvas!.height);\n const fontSize = this.fontSizeDp !== undefined ?\n this.dpToLocalUnits(this.fontSizeDp) :\n this.fontSize ?? 0.06;\n ctx.font = `${fontSize * resolution}px ${this.font}`;\n ctx.fillStyle =\n `#${getColorHex(this.fontColor).toString(16).padStart(6, '0')}`;\n ctx.textAlign = 'center';\n ctx.textBaseline = 'middle';\n // TODO: add line-break for canvas-based text.\n ctx.fillText(this.text, canvas!.width / 2, canvas!.height / 2);\n\n if (this.textObj?.material.map) {\n this.textObj.material.map.needsUpdate = true;\n }\n }\n\n /**\n * Callback executed when Troika's text sync is complete.\n * It captures layout data like total height and line count.\n */\n onSyncComplete() {\n if (!this.useSDFText || !(this.textObj instanceof Text) ||\n !this.textObj.textRenderInfo) {\n return;\n }\n const caretPositions = this.textObj.textRenderInfo.caretPositions;\n const numberOfChars = caretPositions.length / 4;\n let lineCount = 0;\n const firstBottom = numberOfChars > 0 ? caretPositions[0] : 0;\n let lastBottom = 999999;\n for (let i = 0; i < numberOfChars; i++) {\n const bottom = caretPositions[i * 4 + 2];\n const top = caretPositions[i * 4 + 3];\n const lineHeight = top - bottom;\n if (bottom < lastBottom - lineHeight / 2) {\n lineCount++;\n lastBottom = bottom;\n }\n }\n this.lineHeight =\n numberOfChars > 0 ? (firstBottom - lastBottom) / lineCount : 0;\n this.lineCount = lineCount;\n this.dispatchEvent({type: 'synccomplete'});\n }\n\n /**\n * Private method to perform the actual initialization after the async\n * import has resolved.\n */\n protected _initializeText() {\n if (this._initializeTextCalled) return;\n this._initializeTextCalled = true;\n // Decide whether to use SDF text or fallback to HTML canvas.\n if (this.useSDFText && troikaImportStatus === TroikaImportStatus.SUCCESS) {\n this.createTextSDF();\n } else {\n // If the import failed, log a warning.\n if (troikaImportStatus === TroikaImportStatus.FAILED) {\n console.warn(\n 'Failed to import `troika-three-text`. For 3D text rendering, please ensure `troika-three-text`, `troika-three-utils`, `troika-worker-utils`, `bidi-js`, and `webgl-sdf-generator` are included in your importmap or installed via npm. Refer to templates/1_ui for an example. Falling back to HTML-based text rendering.',\n 'Error details:', troikaImportError?.message);\n // Clear the error so we don't log it repeatedly.\n troikaImportError = undefined;\n }\n this.createTextHTML();\n }\n\n // Applies settings that require the textObj to exist.\n if (this.useSDFText && Text && this.textObj instanceof Text) {\n this.textObj.addEventListener(\n // @ts-expect-error Missing type in Troika\n 'synccomplete', this.onSyncComplete.bind(this));\n\n if (this.imageOverlay) {\n (new THREE.TextureLoader()).load(this.imageOverlay, (texture) => {\n texture.colorSpace = THREE.SRGBColorSpace;\n texture.offset.x = this.imageOffsetX;\n const textObj = this.textObj as unknown as TroikaThreeText.Text;\n textObj.material.map = texture;\n textObj.sync();\n });\n }\n }\n this.updateLayout();\n }\n\n protected syncTextObj() {\n if (Text && this.textObj instanceof Text) {\n this.textObj.sync();\n }\n }\n\n protected setTextColor(color: number) {\n if (Text && this.textObj instanceof Text) {\n this.textObj.color = color;\n }\n }\n\n /**\n * Disposes of resources used by the TextView, such as event listeners.\n */\n override dispose() {\n if (this.useSDFText && this.textObj && Text &&\n this.textObj instanceof Text) {\n this.textObj.removeEventListener(\n // @ts-expect-error Missing type in Troika\n 'synccomplete', this.onSyncComplete.bind(this));\n }\n super.dispose();\n }\n}\n","import * as THREE from 'three';\n\nimport {VIEW_DEPTH_GAP} from '../../constants';\nimport {TextView, TextViewOptions} from '../components/TextView';\n\nimport {MATERIAL_ICONS_FONT_FILE} from './utils/FontFamilies';\n\n/**\n * An interactive circular button that displays a single character\n * icon from the Material Icons font library. It provides visual feedback for\n * hover and selection states by changing its background opacity.\n */\nexport type IconButtonOptions = TextViewOptions&{\n backgroundColor?: THREE.ColorRepresentation;\n defaultOpacity?: number;\n hoverColor?: number;\n hoverOpacity?: number;\n selectedOpacity?: number;\n opacity?: number;\n};\n\nexport class IconButton extends TextView {\n /** The overall opacity when the button is not being interacted with. */\n opacity = 1.0;\n /** The background opacity when the button is not being interacted with. */\n defaultOpacity = 0.0;\n /** The background color when a reticle hovers over the button. */\n hoverColor = 0xaaaaaa;\n /** The background opacity when a reticle hovers over the button. */\n hoverOpacity = 0.2;\n /** The background opacity when the button is actively being pressed. */\n selectedOpacity = 0.4;\n\n /** The icon font file to use. Defaults to Material Icons. */\n font = MATERIAL_ICONS_FONT_FILE;\n /** The underlying mesh for the button's background. */\n mesh!: THREE.Mesh<THREE.PlaneGeometry, THREE.MeshBasicMaterial>;\n\n /**\n * Overrides the parent `rangeX` to ensure the circular shape is not affected\n * by panel aspect ratio.\n */\n get rangeX() {\n return 1;\n }\n\n /**\n * Overrides the parent `rangeY` to ensure the circular shape is not affected\n * by panel aspect ratio.\n */\n get rangeY() {\n return 1;\n }\n\n /**\n * An interactive button that displays a single character icon from a font\n * file. Inherits from TextView to handle text rendering.\n * @param options - The options for the IconButton.\n */\n constructor(options: IconButtonOptions = {}) {\n const {backgroundColor = 0xaaaaaa} = options;\n\n const radius = 0.5;\n const segments = 32;\n const geometry = new THREE.CircleGeometry(radius, segments);\n const material = new THREE.MeshBasicMaterial({\n color: backgroundColor,\n transparent: true,\n depthWrite: false,\n opacity: 0, // Start with zero opacity, will be controlled by interaction\n // logic\n side: THREE.FrontSide\n });\n\n // Pass geometry and material to the TextView -> View chain.\n super(options, geometry, material);\n\n // Applies all provided options to this instance.\n Object.assign(this, options);\n }\n\n /**\n * Initializes the component and sets the render order.\n */\n override async init(_?: object) {\n await super.init();\n\n if (this.mesh) {\n this.mesh.renderOrder = this.renderOrder;\n }\n\n if (this.textObj) {\n this.textObj.renderOrder = this.renderOrder + 1;\n }\n }\n\n /**\n\n /**\n * Handles behavior when the cursor hovers over the button.\n */\n onHoverOver() {\n if (!this.ux) return;\n this.update(); // Consolidate logic in update()\n }\n\n /**\n * Handles behavior when the cursor moves off the button.\n */\n onHoverOut() {\n if (!this.ux) return;\n this.update(); // Consolidate logic in update()\n }\n\n /**\n * Updates the button's visual state based on hover and selection status.\n */\n update() {\n if (!this.ux) return;\n if (this.ux.isHovered() || this.ux.isSelected()) {\n this.mesh!.material.opacity = this.ux.isSelected() ?\n this.selectedOpacity * this.opacity :\n this.hoverOpacity * this.opacity;\n } else {\n this.mesh!.material.opacity = this.defaultOpacity * this.opacity;\n }\n }\n\n /**\n * Overrides the parent's private initialization method. This is called by the\n * parent's `init()` method after the Troika module is confirmed to be loaded.\n */\n protected override _initializeText() {\n // First, run the parent's initialization to ensure this.textObj is created.\n super._initializeText();\n\n // Now that this.textObj is guaranteed to exist, run IconButton-specific\n // logic.\n if (this.textObj) {\n this.textObj.position.set(0, 0, VIEW_DEPTH_GAP);\n\n // Disable raycasting on the text part of the object so it doesn't\n // interfere with the main button geometry's interaction.\n this.textObj.raycast = () => {};\n\n // Run initial state update\n this.update();\n\n switch (this.mode) {\n case 'center':\n this.textObj.scale.setScalar(this.rangeX);\n break;\n }\n this.textObj.scale.set(1, 1, 1);\n }\n\n this.syncTextObj();\n\n // The parent _initializeText already calls updateLayout, so this is not\n // strictly necessary, but kept for clarity.\n this.updateLayout();\n }\n}\n","import {TextView, TextViewOptions} from '../components/TextView.js';\n\nimport {MATERIAL_ICONS_FONT_FILE} from './utils/FontFamilies';\n\n/**\n * A specialized `TextView` component designed for conveniently\n * displaying icons from the Google Material Icons font library.\n *\n * This class simplifies the process of creating an icon by pre-configuring the\n * `font` property. To use it, you provide the codepoint or ligature for the\n * desired icon in the `text` option.\n *\n * @example\n * ```typescript\n * // Creates a 'home' icon.\n * const homeIcon = new IconView({ text: 'home', fontSize: 0.1 });\n * ```\n */\nexport type IconViewOptions = TextViewOptions;\n\nexport class IconView extends TextView {\n constructor(options: IconViewOptions = {}) {\n super({font: MATERIAL_ICONS_FONT_FILE, ...options});\n }\n};\n","import * as THREE from 'three';\n\nimport {View} from '../core/View';\nimport {ViewOptions} from '../core/ViewOptions';\n\n/**\n * A UI component for displaying a 2D image on a panel in XR.\n * It automatically handles loading the image and scaling it to fit within its\n * layout bounds while preserving the original aspect ratio.\n */\nexport type ImageViewOptions = ViewOptions&{\n src?: string;\n};\n\nexport class ImageView extends View {\n /** The URL of the image file to be displayed. */\n src?: string;\n /** The material applied to the image plane. */\n material: THREE.MeshBasicMaterial;\n /** The mesh that renders the image. */\n mesh: THREE.Mesh<THREE.PlaneGeometry, THREE.MeshBasicMaterial>;\n\n private texture?: THREE.Texture;\n private initCalled = false;\n private textureLoader = new THREE.TextureLoader();\n\n /**\n * @param options - Configuration options. Can include properties like\n * `src`, `width`, `height`, and other properties from the base `View` class.\n */\n constructor(options: ImageViewOptions = {}) {\n super(options);\n\n const material = new THREE.MeshBasicMaterial({\n map: null, // Texture will be loaded and assigned in reload()\n transparent: true,\n depthWrite: false,\n side: THREE.DoubleSide,\n });\n\n const geometry = new THREE.PlaneGeometry(1, 1);\n this.mesh = new THREE.Mesh(geometry, material);\n this.material = material;\n this.add(this.mesh);\n }\n\n /**\n * Initializes the component. Called once by the XR Blocks lifecycle.\n */\n init() {\n if (this.initCalled) return;\n this.initCalled = true;\n this.reload();\n }\n\n /**\n * Reloads the image from the `src` URL. If a texture already exists, it is\n * properly disposed of before loading the new one.\n */\n reload() {\n if (!this.src) {\n // If no source, ensure no texture is displayed.\n if (this.material.map) {\n this.material.map = null;\n }\n this.texture?.dispose();\n this.texture = undefined;\n return;\n }\n\n this.texture?.dispose();\n this.texture = this.textureLoader.load(this.src, (loadedTexture) => {\n loadedTexture.colorSpace = THREE.SRGBColorSpace;\n this.material.map = loadedTexture;\n // Updates layout after the image has loaded to get correct dimensions.\n this.updateLayout();\n });\n }\n\n /**\n * Updates the layout of the view and then adjusts the mesh scale to maintain\n * the image's aspect ratio.\n * @override\n */\n updateLayout() {\n super.updateLayout();\n if (this.mesh) {\n this.mesh.renderOrder = this.renderOrder;\n }\n this.scaleImageToCorrectAspectRatio();\n }\n\n /**\n * Calculates the correct scale for the image plane to fit within the view's\n * bounds without distortion.\n */\n scaleImageToCorrectAspectRatio() {\n if (this.texture?.image) {\n const {image} = this.texture;\n const textureWidth = image.width;\n const textureHeight = image.height;\n\n // Determines the scaling factor to fit the image within the view's range.\n const widthScaleFactor = this.rangeX / textureWidth;\n const heightScaleFactor = this.rangeY / textureHeight;\n const minScaleFactor = Math.min(widthScaleFactor, heightScaleFactor);\n\n // Applies the calculated scale to the mesh.\n this.mesh.scale.set(\n textureWidth * minScaleFactor, textureHeight * minScaleFactor, 1);\n }\n }\n\n /**\n * Sets a new image source and reloads it.\n * @param src - The URL of the new image to load.\n */\n load(src: string) {\n this.src = src;\n this.reload();\n }\n}\n","import {UI_OVERLAY_LAYER} from '../../constants';\n\nimport {TextView, TextViewOptions} from './TextView';\n\n/**\n * Identical to text view except sets this.layer to UI_OVERLAY_LAYER.\n */\nexport type LabelViewOptions = TextViewOptions;\n\nexport class LabelView extends TextView {\n constructor(options: LabelViewOptions = {}) {\n super(options);\n this.layers.set(UI_OVERLAY_LAYER);\n }\n\n protected override createTextSDF() {\n super.createTextSDF();\n this.textObj!.material.depthText = false;\n this.textObj!.material.depthWrite = false;\n }\n}\n","import * as THREE from 'three';\n\n/**\n * Shader for the non-interactive Panel background.\n *\n * This shader renders a simple, anti-aliased rounded rectangle (squircle). It\n * can display either a solid background color or a texture map. It is more\n * performant than the SpatialPanelShader as it omits all interactive highlight\n * calculations.\n */\nexport const SquircleShader = {\n uniforms: {\n 'uMainTex': {value: null},\n 'uUseImage': {value: 0.0},\n 'uBackgroundColor': {\n value: new THREE.Vector4(0.4, 0.8, 1.0, 1.0),\n },\n 'uBoxSize': {value: new THREE.Vector2(0.5, 0.5)},\n 'uRadius': {value: 0.05},\n 'uOpacity': {value: 1.0}\n },\n\n vertexShader: /* glsl */ `\n #define USE_UV\n #include <common>\n #include <batching_pars_vertex>\n #include <uv_pars_vertex>\n #include <envmap_pars_vertex>\n #include <color_pars_vertex>\n #include <fog_pars_vertex>\n #include <morphtarget_pars_vertex>\n #include <skinning_pars_vertex>\n #include <logdepthbuf_pars_vertex>\n #include <clipping_planes_pars_vertex>\n\n void main() {\n #include <uv_vertex>\n #include <color_vertex>\n #include <morphinstance_vertex>\n #include <morphcolor_vertex>\n #include <batching_vertex>\n\n #if defined ( USE_ENVMAP ) || defined ( USE_SKINNING )\n\n #include <beginnormal_vertex>\n #include <morphnormal_vertex>\n #include <skinbase_vertex>\n #include <skinnormal_vertex>\n #include <defaultnormal_vertex>\n\n #endif\n\n #include <begin_vertex>\n #include <morphtarget_vertex>\n #include <skinning_vertex>\n #include <project_vertex>\n #include <logdepthbuf_vertex>\n #include <clipping_planes_vertex>\n\n #include <worldpos_vertex>\n #include <envmap_vertex>\n #include <fog_vertex>\n }\n `,\n\n fragmentShader: /* glsl */ `\n precision mediump float;\n\n uniform sampler2D uMainTex;\n uniform vec4 uBackgroundColor;\n uniform vec2 uBoxSize;\n uniform float uRadius;\n uniform float uUseImage;\n uniform float uOpacity;\n\n #define USE_UV\n #include <common>\n #include <dithering_pars_fragment>\n #include <color_pars_fragment>\n #include <uv_pars_fragment>\n #include <map_pars_fragment>\n #include <alphamap_pars_fragment>\n #include <alphatest_pars_fragment>\n #include <alphahash_pars_fragment>\n #include <aomap_pars_fragment>\n #include <lightmap_pars_fragment>\n #include <envmap_common_pars_fragment>\n #include <envmap_pars_fragment>\n #include <fog_pars_fragment>\n #include <specularmap_pars_fragment>\n #include <logdepthbuf_pars_fragment>\n #include <clipping_planes_pars_fragment>\n\n // Distance function for rounded box.\n float distRoundBox(vec2 p, vec2 b, float r) {\n return length(max(abs(p) - b + r, 0.0)) - r;\n }\n\n void main(void) {\n #include <clipping_planes_fragment>\n\n #include <logdepthbuf_fragment>\n #include <map_fragment>\n #include <color_fragment>\n #include <alphamap_fragment>\n #include <alphatest_fragment>\n #include <alphahash_fragment>\n #include <specularmap_fragment>\n vec2 size = uBoxSize * 1000.0;\n\n // Calculates the adjusted radius based on box size.\n float radius = min(size.x, size.y) * (0.05 + uRadius);\n vec2 half_size = 0.5 * size;\n\n // Compute the distance from the rounded box edge.\n float dist = distRoundBox(vUv * size - half_size, half_size, radius);\n\n // Use lerp for smooth color transition based on distance.\n vec4 colorInside = uBackgroundColor;\n\n if (uUseImage > 0.5) {\n colorInside = texture2D(uMainTex, vUv);\n colorInside.a = 1.0;\n }\n\n // Transparent black for outside.\n vec4 colorOutside = vec4(0.0, 0.0, 0.0, 0.0);\n\n vec4 finalColor = mix(colorInside, colorOutside, smoothstep(0.0, 1.0, dist));\n\n // Return premultiplied alpha.\n gl_FragColor = uOpacity * finalColor.a * vec4(finalColor.rgb, 1.0);\n }\n `\n};\n","import * as THREE from 'three';\n\nimport {VIEW_DEPTH_GAP} from '../../constants';\nimport {getVec4ByColorString} from '../../utils/utils';\nimport {TextView, TextViewOptions} from '../components/TextView';\nimport {SquircleShader} from '../shaders/SquircleShader';\n\n/**\n * An interactive button with a rounded rectangle background and a\n * text label. It provides visual feedback for hover and selection states.\n */\nexport type TextButtonOptions = TextViewOptions&{\n backgroundColor?: string,\n opacity?: number,\n maxWidth?: number,\n radius?: number,\n boxSize?: number,\n};\n\nexport class TextButton extends TextView {\n /** Default description of this view in Three.js DevTools. */\n name = 'TextButton';\n /** The font size of the text label. */\n fontSize = 0.05;\n /** The color of the text in its default state. */\n fontColor: string|number = 0xFFFFFF;\n /** The opacity multiplier of the button. */\n opacity = 1.0;\n /** The intrinsic opacity of the button. */\n defaultOpacity = 1.0;\n\n /** The color of the text when the button is hovered. */\n hoverColor: string|number = 0xaaaaaa;\n /** The opacity multiplier of the text when the button is hovered. */\n hoverOpacity = 0.2;\n\n /** The color of the text when the button is pressed. */\n selectedFontColor: string|number = 0x999999;\n /** The opacity multiplier of the text when the button is pressed. */\n selectedOpacity = 0.4;\n\n /** Relative local width. */\n width = 0.9;\n /** Relative local height. */\n height = 0.9;\n\n /** Layout mode. */\n mode = 'center';\n\n /** The horizontal offset for the `imageOverlay` texture. */\n imageOffsetX = 0;\n /** The vertical offset for the `imageOverlay` texture. */\n imageOffsetY = 0;\n\n private uniforms;\n\n /**\n * @param options - Configuration options for the TextButton.\n */\n constructor(options: TextButtonOptions = {}) {\n const geometry = new THREE.PlaneGeometry(1, 1);\n const colorVec4 =\n getVec4ByColorString(options.backgroundColor ?? '#00000000');\n\n const {\n opacity = 0.0,\n radius = SquircleShader.uniforms.uRadius.value,\n boxSize = SquircleShader.uniforms.uBoxSize.value\n } = options;\n\n const uniforms = {\n ...SquircleShader.uniforms,\n uBackgroundColor: {value: colorVec4},\n uOpacity: {value: opacity},\n uAspect: {value: 1.0},\n uRadius: {value: radius},\n uBoxSize: {value: boxSize}\n };\n\n const material = new THREE.ShaderMaterial({\n ...SquircleShader,\n transparent: true,\n uniforms: uniforms,\n depthWrite: false\n });\n\n super(options, geometry, material);\n\n this.uniforms = uniforms;\n this.opacity = opacity;\n\n // Applies our own overrides to the default values.\n this.fontSize = options.fontSize ?? this.fontSize;\n this.fontColor = options.fontColor ?? this.fontColor;\n this.width = options.width ?? this.width;\n this.height = options.height ?? this.height;\n }\n\n /**\n * Initializes the text object after async dependencies are loaded.\n */\n override async init() {\n await super.init();\n this.textObj!.position.set(0, 0, VIEW_DEPTH_GAP);\n\n if (this.mesh) {\n this.mesh.renderOrder = this.renderOrder;\n }\n this.textObj!.renderOrder = this.renderOrder + 1;\n\n // Disable raycasting on the text part so it doesn't interfere\n // with the main button geometry's interaction.\n this.textObj!.raycast = () => {};\n };\n\n // TODO: Implement onHoverOver() and onHoverOut().\n update() {\n if (!this.textObj) {\n return;\n }\n if (this.textObj) {\n this.textObj.renderOrder = this.renderOrder + 1;\n }\n const ux = this.ux;\n if (ux.isHovered()) {\n if (ux.isSelected()) {\n this.setTextColor(0x666666);\n } else {\n this.setTextColor(0xaaaaaa);\n }\n } else {\n this.setTextColor(0xffffff);\n this.uniforms.uOpacity.value = this.defaultOpacity * this.opacity;\n }\n }\n};\n","import * as THREE from 'three';\n\nimport {VideoStream, VideoStreamDetails} from '../../video/VideoStream';\nimport {View} from '../core/View';\nimport {ViewOptions} from '../core/ViewOptions';\n\n/**\n * A UI component for displaying video content on a 3D plane. It\n * supports various sources, including URLs, HTMLVideoElement,\n * THREE.VideoTexture, and the XR Blocks `VideoStream` class. It automatically\n * handles aspect ratio correction to prevent distortion.\n */\nexport type VideoViewOptions = ViewOptions&{\n src?: string;\n muted?: boolean;\n loop?: boolean;\n autoplay?: boolean;\n playsInline?: boolean;\n crossOrigin?: string;\n mode?: 'center'|'stretch';\n};\n\nexport class VideoView extends View {\n /** Default description of this view in Three.js DevTools. */\n name: string = 'VideoView';\n /** The display mode for the video ('center' preserves aspect ratio). */\n mode: 'center'|'stretch' = 'center';\n /** The underlying HTMLVideoElement being used for playback. */\n video?: HTMLVideoElement;\n /** The URL source of the video, if loaded from a URL. */\n src?: string\n /** VideoView resides in a panel by default. */\n isRoot = false;\n\n /** If true, the video will be muted. Default is true. */\n muted = true;\n /** If true, the video will loop. Default is true. */\n loop = true;\n /** If true, the video will attempt to play automatically. Default is true. */\n autoplay = true;\n /** If true, the video will play inline on mobile devices. Default is true. */\n playsInline = true;\n /** The cross-origin setting for the video element. Default is 'anonymous'. */\n crossOrigin = 'anonymous';\n\n /** The material applied to the video plane. */\n material: THREE.MeshBasicMaterial;\n /** The mesh that renders the video texture. */\n mesh: THREE.Mesh<THREE.PlaneGeometry, THREE.MeshBasicMaterial>;\n\n private stream_?: VideoStream;\n private streamReadyCallback_?: (event: {\n details?:\n VideoStreamDetails&{\n aspectRatio?: number\n }\n }) => void;\n\n private texture?: THREE.Texture;\n private videoAspectRatio: number = 0.0;\n\n /**\n * @param options - Configuration options for the VideoView.\n */\n constructor(options: VideoViewOptions = {}) {\n super(options);\n const videoGeometry = new THREE.PlaneGeometry(1, 1);\n const videoMaterial = new THREE.MeshBasicMaterial({\n transparent: true,\n depthWrite: false,\n side: THREE.DoubleSide,\n // `map` will be set based on options.texture or during load\n });\n this.mesh = new THREE.Mesh<THREE.PlaneGeometry, THREE.MeshBasicMaterial>(\n videoGeometry, videoMaterial);\n this.material = videoMaterial;\n this.add(this.mesh);\n\n if (this.texture instanceof THREE.Texture) {\n this.material.map = this.texture;\n } else {\n this.texture = new THREE.Texture();\n this.material.map = this.texture;\n }\n }\n\n /**\n * Initializes the component, loading from `src` if provided in options.\n */\n init() {\n super.init(); // Calls View's init method.\n\n if (this.material.map instanceof THREE.VideoTexture &&\n this.material.map.image) {\n this.loadFromVideoTexture(this.material.map);\n } else if (this.src) {\n this.load(this.src);\n }\n }\n\n /**\n * Loads a video from various source types. This is the main method for\n * setting the video content.\n * @param source - The video source (URL, HTMLVideoElement, VideoTexture, or\n * VideoStream).\n */\n load(source: string|HTMLVideoElement|THREE.VideoTexture|VideoStream) {\n if (source instanceof HTMLVideoElement) {\n this.loadFromVideoElement(source);\n } else if (source instanceof THREE.VideoTexture) {\n this.loadFromVideoTexture(source);\n } else if (typeof source === 'string') {\n this.loadFromURL(source);\n } else if (source instanceof VideoStream) {\n this.loadFromStream(source);\n } else {\n console.error('VideoView: Invalid video source provided.', source);\n }\n }\n\n /**\n * Loads video content from an VideoStream, handling the 'ready' event\n * to correctly display the stream and set the aspect ratio.\n * @param stream - The VideoStream instance.\n */\n loadFromStream(stream: VideoStream) {\n this.disposeStreamListener_();\n this.stream_ = stream;\n\n this.streamReadyCallback_ = (event: {details?: {aspectRatio?: number}}) => {\n if (!this.stream_?.texture) {\n console.warn('Stream is ready, but its texture is not available.');\n return;\n }\n this.loadFromVideoTexture(this.stream_.texture);\n // The event from VideoStream provides the definitive aspect ratio\n if (event.details?.aspectRatio !== undefined) {\n this.videoAspectRatio = event.details?.aspectRatio;\n }\n this.updateLayout();\n };\n\n if (this.stream_.loaded) {\n // If the stream is already loaded, manually trigger the handler\n this.streamReadyCallback_(\n {details: {aspectRatio: this.stream_.aspectRatio!}});\n } else {\n // Otherwise, wait for the 'ready' event\n this.stream_.addEventListener('statechange', this.streamReadyCallback_);\n }\n }\n\n /**\n * Creates a video element and loads content from a URL.\n * @param url - The URL of the video file.\n */\n loadFromURL(url: string) {\n this.src = url;\n const videoElement = document.createElement('video');\n videoElement.muted = this.muted;\n videoElement.loop = this.loop;\n videoElement.playsInline = this.playsInline;\n videoElement.autoplay = this.autoplay;\n videoElement.crossOrigin = this.crossOrigin;\n videoElement.src = url;\n this.loadFromVideoElement(videoElement);\n }\n\n /**\n * Configures the view to use an existing `HTMLVideoElement`.\n * @param videoElement - The video element to use as the source.\n */\n loadFromVideoElement(videoElement: HTMLVideoElement) {\n this.video = videoElement;\n\n if (this.video.autoplay && this.video.paused) {\n this.video.play().catch(error => {\n console.warn('VideoView: Autoplay prevented for video element.', error);\n });\n }\n\n const videoTextureInstance = new THREE.VideoTexture(this.video);\n videoTextureInstance.colorSpace = THREE.SRGBColorSpace;\n\n this.texture = videoTextureInstance; // Update internal texture reference\n this.material.map = this.texture;\n\n const onLoadedMetadata = () => {\n if (this.video!.videoWidth && this.video!.videoHeight) {\n this.videoAspectRatio =\n this.video!.videoWidth / this.video!.videoHeight;\n } else {\n console.warn('VideoView: Video metadata loaded but dimensions are 0.');\n this.videoAspectRatio = 0; // Invalid aspect ratio\n }\n this.updateLayout(); // Update layout now that aspect ratio is known\n };\n\n if (this.video.readyState >= this.video.HAVE_METADATA) {\n onLoadedMetadata();\n } else {\n this.video.addEventListener(\n 'loadedmetadata', onLoadedMetadata, {once: true});\n }\n }\n\n /**\n * Configures the view to use an existing `THREE.VideoTexture`.\n * @param videoTextureInstance - The texture to display.\n */\n loadFromVideoTexture(videoTextureInstance: THREE.VideoTexture) {\n this.texture = videoTextureInstance;\n this.material.map = this.texture;\n this.video = this.texture.image; // Underlying HTMLVideoElement\n\n if (this.video && this.video.videoWidth && this.video.videoHeight) {\n this.videoAspectRatio = this.video.videoWidth / this.video.videoHeight;\n this.updateLayout();\n } else if (this.video) {\n this.video.addEventListener('loadedmetadata', () => {\n if (this.video!.videoWidth && this.video!.videoHeight) {\n this.videoAspectRatio =\n this.video!.videoWidth / this.video!.videoHeight;\n } else {\n this.videoAspectRatio = 0;\n }\n this.updateLayout();\n }, {once: true});\n } else {\n console.warn(\n 'VideoView: VideoTexture does not have a valid underlying video element.');\n this.videoAspectRatio = 0;\n this.updateLayout();\n }\n }\n\n /** Starts video playback. */\n play() {\n if (this.video && this.video.paused) {\n this.video.play().catch(\n e => console.warn('VideoView: Error playing video:', e));\n }\n }\n\n /** Pauses video playback. */\n pause() {\n if (this.video && !this.video.paused) {\n this.video.pause();\n }\n }\n\n private disposeStreamListener_() {\n if (this.stream_ && this.streamReadyCallback_) {\n this.stream_.removeEventListener(\n 'statechange', this.streamReadyCallback_);\n this.stream_ = undefined;\n this.streamReadyCallback_ = undefined;\n }\n }\n\n /**\n * Cleans up resources, particularly the underlying video element and texture,\n * to prevent memory leaks.\n */\n dispose() {\n this.disposeStreamListener_();\n\n if (this.video) {\n this.video.pause();\n this.video.removeAttribute('src');\n this.video.load();\n this.video = undefined;\n }\n if (this.texture) {\n this.texture.dispose();\n this.texture = undefined;\n }\n super.dispose();\n }\n\n /**\n * Updates the layout and scales the video plane to match its aspect ratio.\n * @override\n */\n updateLayout() {\n super.updateLayout();\n if (this.mode === 'stretch' || this.videoAspectRatio <= 0 ||\n !this.material.map) {\n return;\n }\n this.mesh.scale.set(\n Math.min(this.rangeX, this.videoAspectRatio * this.rangeY),\n Math.min(this.rangeY, this.rangeX / this.videoAspectRatio), 1);\n }\n}\n","import * as THREE from 'three';\n\n/**\n * Checks if a given object is a descendant of another object in the scene\n * graph. This function is useful for determining if an interaction (like a\n * raycast hit) has occurred on a component that is part of a larger, complex\n * entity.\n *\n * It uses an iterative approach to traverse up the hierarchy from the child.\n *\n * @param child - The potential descendant object.\n * @param parent - The potential ancestor object.\n * @returns True if `child` is the same as `parent` or is a descendant of\n * `parent`.\n */\nexport function objectIsDescendantOf(\n child?: Readonly<THREE.Object3D>|null,\n parent?: Readonly<THREE.Object3D>|null) {\n // Starts the search from the child object.\n let currentNode: Readonly<THREE.Object3D>|undefined|null = child;\n\n // Traverses up the scene graph hierarchy until we reach the top (null parent)\n // or find the target parent.\n while (currentNode) {\n // If the current node is the parent we're looking for, we've found a match.\n if (currentNode === parent) {\n return true;\n }\n // Moves up to the next level in the hierarchy.\n currentNode = currentNode.parent;\n }\n\n // If we reach the top of the hierarchy without finding the parent,\n // it is not an ancestor.\n return false;\n}\n\n/**\n * Traverses the scene graph from a given node, calling a callback function for\n * each node. The traversal stops if the callback returns true.\n *\n * This function is similar to THREE.Object3D.traverse, but allows for early\n * exit from the traversal based on the callback's return value.\n *\n * @param node - The starting node for the traversal.\n * @param callback - The function to call for each node. It receives the current\n * node as an argument. If the callback returns `true`, the traversal will\n * stop.\n * @returns Whether the callback returned true for any node.\n */\nexport function traverseUtil(\n node: THREE.Object3D, callback: (node: THREE.Object3D) => boolean) {\n if (callback(node)) {\n return true;\n }\n for (const child of node.children) {\n if (traverseUtil(child, callback)) {\n return true;\n }\n }\n return false;\n}\n","import * as THREE from 'three';\n\nimport {Controller} from '../input/Controller';\nimport {Hands} from '../input/Hands';\nimport {Input} from '../input/Input';\nimport {View} from '../ui/core/View';\nimport {objectIsDescendantOf} from '../utils/SceneGraphUtils';\n\nimport {ObjectGrabEvent, ObjectTouchEvent, Script, SelectEvent} from './Script';\n\ntype MaybeXRScript = THREE.Object3D&{isXRScript?: boolean};\ntype MaybeView = THREE.Object3D&{isView?: boolean};\ntype MaybeHasIgnoreReticleRaycast = {\n ignoreReticleRaycast?: boolean;\n};\n\n/**\n * User is an embodied instance to manage hands, controllers, speech, and\n * avatars. It extends Script to update human-world interaction.\n *\n * In the long run, User is to manages avatars, hands, and everything of Human\n * I/O. In third-person view simulation, it should come with an low-poly avatar.\n * To support multi-user social XR planned for future iterations.\n */\nexport class User extends Script {\n static dependencies = {\n input: Input,\n scene: THREE.Scene,\n };\n\n /**\n * Whether to represent a local user, or another user in a multi-user session.\n */\n local = true;\n\n /**\n * The number of hands associated with the XR user.\n */\n numHands = 2;\n\n /**\n * The height of the user in meters.\n */\n height = 1.6;\n\n /**\n * The default distance of a UI panel from the user in meters.\n */\n panelDistance = 1.75;\n\n /**\n * The handedness (primary hand) of the user (0 for left, 1 for right, 2 for\n * both).\n */\n handedness = 1;\n\n /**\n * The radius of the safe space around the user in meters.\n */\n safeSpaceRadius = 0.2;\n\n /**\n * The distance of a newly spawned object from the user in meters.\n */\n objectDistance = 1.5;\n\n /**\n * The angle of a newly spawned object from the user in radians.\n */\n objectAngle = -18.0 / 180.0 * Math.PI;\n\n /**\n * An array of pivot objects. Pivot are sphere at the **starting** tip of\n * user's hand / controller / mouse rays for debugging / drawing applications.\n */\n pivots: THREE.Object3D[] = [];\n\n /**\n * Public data for user interactions, typically holding references to XRHand.\n */\n hands?: Hands;\n\n /**\n * Maps a controller to the object it is currently hovering over.\n */\n hoveredObjectsForController = new Map<Controller, THREE.Object3D|null>();\n\n /**\n * Maps a controller to the object it has currently selected.\n */\n selectedObjectsForController = new Map<Controller, THREE.Object3D>();\n\n /**\n * Maps a hand index (0 or 1) to a set of meshes it is currently touching.\n */\n touchedObjects = new Map<number, Set<THREE.Mesh>>();\n\n /**\n * Maps a hand index to another map that associates a grabbed mesh with its\n * initial grab event data.\n */\n grabbedObjects = new Map<number, Map<THREE.Mesh, ObjectGrabEvent>>();\n\n input!: Input;\n scene!: THREE.Scene;\n controllers!: Controller[];\n\n /**\n * Constructs a new User.\n */\n constructor() {\n super();\n }\n\n /**\n * Initializes the User.\n */\n init({input, scene}: {input: Input, scene: THREE.Scene}) {\n this.input = input;\n this.controllers = input.controllers;\n this.scene = scene;\n }\n\n /**\n * Sets the user's height on the first frame.\n * @param camera -\n */\n setHeight(camera: THREE.Camera) {\n this.height = camera.position.y;\n }\n\n /**\n * Adds pivots at the starting tip of user's hand / controller / mouse rays.\n */\n enablePivots() {\n this.input.enablePivots();\n }\n\n /**\n * Gets the pivot object for a given controller id.\n * @param id - The controller id.\n * @returns The pivot object.\n */\n getPivot(id: number) {\n return this.controllers[id].getObjectByName('pivot');\n }\n\n /**\n * Gets the world position of the pivot for a given controller id.\n * @param id - The controller id.\n * @returns The world position of the pivot.\n */\n getPivotPosition(id: number) {\n return this.getPivot(id)?.getWorldPosition(new THREE.Vector3());\n }\n\n /**\n * Gets reticle's direction in THREE.Vector3.\n * Requires reticle enabled to be called.\n * @param controllerId -\n */\n getReticleDirection(controllerId: number) {\n return this.controllers[controllerId].reticle?.direction;\n }\n\n /**\n * Gets the object targeted by the reticle.\n * Requires `options.reticle.enabled`.\n * @param id - The controller id.\n * @returns The targeted object, or null.\n */\n getReticleTarget(id: number) {\n return this.controllers[id].reticle?.targetObject;\n }\n\n /**\n * Gets the intersection details from the reticle's raycast.\n * Requires `options.reticle.enabled`.\n * @param id - The controller id.\n * @returns The intersection object, or null if no intersection.\n */\n getReticleIntersection(id: number) {\n return this.controllers[id].reticle?.intersection;\n }\n\n /**\n * Checks if any controller is pointing at the given object or its children.\n * @param obj - The object to check against.\n * @returns True if a controller is pointing at the object.\n */\n isPointingAt(obj: THREE.Object3D) {\n for (const selected of this.hoveredObjectsForController.values()) {\n if (objectIsDescendantOf(selected, obj)) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Checks if any controller is selecting the given object or its children.\n * @param obj - The object to check against.\n * @returns True if a controller is selecting the object.\n */\n isSelectingAt(obj: THREE.Object3D) {\n for (const selected of this.selectedObjectsForController.values()) {\n if (objectIsDescendantOf(selected, obj)) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Gets the intersection point on a specific object.\n * Not recommended for general use, since a View / ModelView's\n * ux.positions contains the intersected points.\n * @param obj - The object to check for intersection.\n * @param id - The controller ID, or -1 for any controller.\n * @returns The intersection details, or null if no intersection.\n */\n getIntersectionAt(obj: THREE.Object3D, id = -1) {\n if (id == -1) {\n for (let i = 0; i < 2; ++i) {\n if (this.getReticleTarget(i) === obj) {\n return this.getReticleIntersection(i);\n }\n }\n } else {\n if (this.getReticleTarget(id) === obj) {\n return this.getReticleIntersection(id);\n }\n }\n return null;\n }\n\n /**\n * Gets the world position of a controller.\n * @param id - The controller id.\n * @param target - The target vector to\n * store the result.\n * @returns The world position of the controller.\n */\n getControllerPosition(id: number, target = new THREE.Vector3()) {\n this.controllers[id].getWorldPosition(target);\n return target;\n }\n\n /**\n * Calculates the distance between a controller and an object.\n * @param id - The controller id.\n * @param object - The object to measure the distance to.\n * @returns The distance between the controller and the object.\n */\n getControllerObjectDistance(id: number, object: THREE.Object3D) {\n const controllerPos = this.getControllerPosition(id);\n const objPos = new THREE.Vector3();\n object.getWorldPosition(objPos);\n return controllerPos.distanceTo(objPos);\n }\n\n /**\n * Checks if either controller is selecting.\n * @param id - The controller id. If -1, check both controllers.\n * @returns True if selecting, false otherwise.\n */\n isSelecting(id = -1) {\n if (id == -1) {\n return this.input.controllers.some((controller) => {\n return controller.userData.selected;\n });\n }\n return this.input.controllers[id].userData.selected;\n }\n\n /**\n * Checks if either controller is squeezing.\n * @param id - The controller id. If -1, check both controllers.\n * @returns True if squeezing, false otherwise.\n */\n isSqueezing(id = -1) {\n if (id == -1) {\n return this.input.controllers.some((controller) => {\n return controller.userData.squeezing;\n });\n }\n return this.input.controllers[id].userData.squeezing;\n }\n\n /**\n * Handles the select start event for a controller.\n * @param event - The event object.\n */\n onSelectStart(event: SelectEvent) {\n const controller = event.target;\n const intersections =\n this.input.intersectionsForController.get(controller)!.filter(\n intersection => {\n let target: THREE.Object3D|null = intersection.object;\n while (target) {\n if ((target as MaybeHasIgnoreReticleRaycast)\n .ignoreReticleRaycast === true) {\n return false;\n }\n target = target.parent;\n }\n return true;\n });\n if (intersections && intersections.length > 0) {\n this.selectedObjectsForController.set(\n controller, intersections[0].object);\n this.callObjectSelectStart(event, intersections[0].object);\n }\n }\n\n /**\n * Handles the select end event for a controller.\n * @param event - The event object.\n */\n onSelectEnd(event: SelectEvent) {\n const controller = event.target;\n const intersections = this.input.intersectionsForController.get(controller);\n if (intersections && intersections.length > 0) {\n const selectedObject = this.selectedObjectsForController.get(controller);\n this.callObjectSelectEnd(event, selectedObject || null);\n this.selectedObjectsForController.delete(controller);\n let ancestor: THREE.Object3D|null = selectedObject || null;\n while (ancestor) {\n if ((ancestor as MaybeView).isView && ancestor.visible) {\n (ancestor as View).onTriggered(controller.userData.id);\n break;\n }\n ancestor = ancestor.parent;\n }\n }\n }\n\n /**\n * Handles the squeeze start event for a controller.\n * @param _event - The event object.\n */\n onSqueezeStart(_event: SelectEvent) {}\n\n /**\n * Handles the squeeze end event for a controller.\n * @param _event - The event object.\n */\n onSqueezeEnd(_event: SelectEvent) {}\n\n /**\n * The main update loop called each frame. Updates hover state for all\n * controllers.\n */\n update() {\n if (this.input.controllersEnabled) {\n for (const controller of this.input.controllers) {\n this.updateForController(controller);\n }\n }\n // Direct touch detection.\n this.updateTouchState();\n // Direct grab detection.\n this.updateGrabState();\n }\n\n /**\n * Checks for and handles grab events (touching + pinching).\n */\n updateGrabState() {\n if (!this.hands) {\n return;\n }\n\n for (let i = 0; i < this.numHands; i++) {\n const isPinching = this.isSelecting(i);\n const touchedMeshes = this.touchedObjects.get(i) || new Set<THREE.Mesh>();\n\n const currentlyGrabbedMeshes =\n isPinching ? touchedMeshes : new Set<THREE.Mesh>();\n const previouslyGrabbedMeshesMap =\n this.grabbedObjects.get(i) || new Map();\n\n const newlyGrabbedMeshes = [...currentlyGrabbedMeshes].filter(\n mesh => !previouslyGrabbedMeshesMap.has(mesh));\n\n const releasedMeshes = [...previouslyGrabbedMeshesMap.keys()].filter(\n mesh => !currentlyGrabbedMeshes.has(mesh));\n\n for (const mesh of newlyGrabbedMeshes) {\n const hand = this.hands.getWrist(i);\n if (!hand) continue;\n\n const grabEvent = {handIndex: i, hand: hand};\n\n if (!this.grabbedObjects.has(i)) {\n this.grabbedObjects.set(i, new Map());\n }\n this.grabbedObjects.get(i)!.set(mesh, grabEvent);\n this.callObjectGrabStart(grabEvent, mesh);\n }\n\n for (const mesh of releasedMeshes) {\n const grabEvent = previouslyGrabbedMeshesMap.get(mesh);\n this.callObjectGrabEnd(grabEvent, mesh);\n previouslyGrabbedMeshesMap.delete(mesh);\n }\n\n for (const mesh of currentlyGrabbedMeshes) {\n if (previouslyGrabbedMeshesMap.has(mesh)) {\n const grabEvent = previouslyGrabbedMeshesMap.get(mesh);\n this.callObjectGrabbing(grabEvent, mesh);\n }\n }\n }\n }\n\n /**\n * Checks for and handles touch events for the hands' index fingers.\n */\n updateTouchState() {\n if (!this.hands) {\n return;\n }\n for (let i = 0; i < this.numHands; i++) {\n const indexTip = this.hands.getIndexTip(i);\n if (!indexTip) {\n continue;\n }\n\n const indexTipPosition = new THREE.Vector3();\n indexTip.getWorldPosition(indexTipPosition);\n\n const currentlyTouchedMeshes: THREE.Mesh[] = [];\n this.scene.traverse((object) => {\n if ((object as Partial<THREE.Mesh>).isMesh && object.visible) {\n const boundingBox = new THREE.Box3().setFromObject(object);\n if (boundingBox.containsPoint(indexTipPosition)) {\n currentlyTouchedMeshes.push(object as THREE.Mesh);\n }\n }\n });\n\n const previouslyTouchedMeshes = this.touchedObjects.get(i) || new Set();\n const currentMeshesSet = new Set(currentlyTouchedMeshes);\n\n const newlyTouchedMeshes = currentlyTouchedMeshes.filter(\n mesh => !previouslyTouchedMeshes.has(mesh));\n const removedMeshes = [...previouslyTouchedMeshes].filter(\n mesh => !currentMeshesSet.has(mesh));\n\n const touchingEvent = {handIndex: i, touchPosition: indexTipPosition};\n\n if (newlyTouchedMeshes.length > 0) {\n for (const mesh of newlyTouchedMeshes) {\n this.callObjectTouchStart(touchingEvent, mesh);\n }\n }\n\n if (removedMeshes.length > 0) {\n for (const mesh of removedMeshes) {\n this.callObjectTouchEnd(touchingEvent, mesh);\n }\n }\n\n for (const mesh of currentMeshesSet) {\n this.callObjectTouching(touchingEvent, mesh);\n }\n\n if (currentMeshesSet.size > 0) {\n this.touchedObjects.set(i, currentMeshesSet);\n } else {\n this.touchedObjects.delete(i);\n }\n }\n }\n\n /**\n * Updates the hover state for a single controller.\n * @param controller - The controller to update.\n */\n updateForController(controller: Controller) {\n const intersections =\n this.input.intersectionsForController.get(controller)!;\n const currentHoverTarget =\n intersections.length > 0 ? intersections[0].object : null;\n const previousHoverTarget =\n this.hoveredObjectsForController.get(controller);\n if (previousHoverTarget !== currentHoverTarget) {\n this.callHoverExit(controller, previousHoverTarget || null);\n this.hoveredObjectsForController.set(controller, currentHoverTarget);\n this.callHoverEnter(controller, currentHoverTarget);\n } else if (previousHoverTarget) {\n this.callOnHovering(controller, previousHoverTarget);\n }\n }\n\n /**\n * Recursively calls onHoverExit on a target and its ancestors.\n * @param controller - The controller exiting hover.\n * @param target - The object being exited.\n */\n callHoverExit(controller: Controller, target: THREE.Object3D|null) {\n if (target == null) return;\n if ((target as MaybeXRScript).isXRScript) {\n (target as Script).onHoverExit(controller);\n }\n this.callHoverExit(controller, target.parent);\n }\n\n /**\n * Recursively calls onHoverEnter on a target and its ancestors.\n * @param controller - The controller entering hover.\n * @param target - The object being entered.\n */\n callHoverEnter(controller: Controller, target: THREE.Object3D|null) {\n if (target == null) return;\n if ((target as MaybeXRScript).isXRScript) {\n (target as Script).onHoverEnter(controller);\n }\n this.callHoverEnter(controller, target.parent);\n }\n\n /**\n * Recursively calls onHovering on a target and its ancestors.\n * @param controller - The controller hovering.\n * @param target - The object being entered.\n */\n callOnHovering(controller: Controller, target: THREE.Object3D|null) {\n if (target == null) return;\n if ((target as MaybeXRScript).isXRScript) {\n (target as Script).onHovering(controller);\n }\n this.callOnHovering(controller, target.parent);\n }\n\n /**\n * Recursively calls onObjectSelectStart on a target and its ancestors until\n * the event is handled.\n * @param event - The original select start event.\n * @param target - The object being selected.\n */\n callObjectSelectStart(event: SelectEvent, target: THREE.Object3D|null) {\n if (target == null) return;\n if ((target as MaybeXRScript).isXRScript &&\n (target as Script).onObjectSelectStart(event)) {\n // The event was handled already so do not propagate up.\n return;\n }\n this.callObjectSelectStart(event, target.parent);\n }\n\n /**\n * Recursively calls onObjectSelectEnd on a target and its ancestors until\n * the event is handled.\n * @param event - The original select end event.\n * @param target - The object being un-selected.\n */\n callObjectSelectEnd(event: SelectEvent, target: THREE.Object3D|null) {\n if (target == null) return;\n if ((target as MaybeXRScript).isXRScript &&\n (target as Script).onObjectSelectEnd(event)) {\n // The event was handled already so do not propagate up.\n return;\n }\n this.callObjectSelectEnd(event, target.parent);\n }\n\n /**\n * Recursively calls onObjectTouchStart on a target and its ancestors.\n * @param event - The original touch start event.\n * @param target - The object being touched.\n */\n callObjectTouchStart(event: ObjectTouchEvent, target: THREE.Object3D|null) {\n if (target == null) return;\n if ((target as MaybeXRScript).isXRScript) {\n (target as Script).onObjectTouchStart(event);\n }\n this.callObjectTouchStart(event, target.parent);\n }\n\n /**\n * Recursively calls onObjectTouching on a target and its ancestors.\n * @param event - The original touch event.\n * @param target - The object being touched.\n */\n callObjectTouching(event: ObjectTouchEvent, target: THREE.Object3D|null) {\n if (target == null) return;\n if ((target as MaybeXRScript).isXRScript) {\n (target as Script).onObjectTouching(event);\n }\n this.callObjectTouching(event, target.parent);\n }\n\n /**\n * Recursively calls onObjectTouchEnd on a target and its ancestors.\n * @param event - The original touch end event.\n * @param target - The object being un-touched.\n */\n callObjectTouchEnd(event: ObjectTouchEvent, target: THREE.Object3D|null) {\n if (target == null) return;\n if ((target as MaybeXRScript).isXRScript) {\n (target as Script).onObjectTouchEnd(event);\n }\n this.callObjectTouchEnd(event, target.parent);\n }\n\n /**\n * Recursively calls onObjectGrabStart on a target and its ancestors.\n * @param event - The original grab start event.\n * @param target - The object being grabbed.\n */\n callObjectGrabStart(event: ObjectGrabEvent, target: THREE.Object3D|null) {\n if (target == null) return;\n if ((target as MaybeXRScript).isXRScript) {\n (target as Script).onObjectGrabStart(event);\n }\n this.callObjectGrabStart(event, target.parent);\n }\n\n /**\n * Recursively calls onObjectGrabbing on a target and its ancestors.\n * @param event - The original grabbing event.\n * @param target - The object being grabbed.\n */\n callObjectGrabbing(event: ObjectGrabEvent, target: THREE.Object3D|null) {\n if (target == null) return;\n if ((target as MaybeXRScript).isXRScript) {\n (target as Script).onObjectGrabbing(event);\n }\n this.callObjectGrabbing(event, target.parent);\n }\n\n /**\n * Recursively calls onObjectGrabEnd on a target and its ancestors.\n * @param event - The original grab end event.\n * @param target - The object being released.\n */\n callObjectGrabEnd(event: ObjectGrabEvent, target: THREE.Object3D|null) {\n if (target == null) return;\n if ((target as MaybeXRScript).isXRScript) {\n (target as Script).onObjectGrabEnd(event);\n }\n this.callObjectGrabEnd(event, target.parent);\n }\n\n /**\n * Checks if a controller is selecting a specific object. Returns the\n * intersection details if true.\n * @param obj - The object to check for selection.\n * @param controller - The controller performing the select.\n * @returns The intersection object if a match is found, else null.\n */\n select(obj: THREE.Object3D, controller: THREE.Object3D) {\n const intersections = this.input.intersectionsForController.get(controller);\n return intersections && intersections.length > 0 &&\n objectIsDescendantOf(intersections[0].object, obj) ?\n intersections[0] :\n null;\n }\n};\n","import * as THREE from 'three';\n\nexport const DOWN = Object.freeze(new THREE.Vector3(0, -1, 0));\nexport const UP = Object.freeze(new THREE.Vector3(0, 1, 0));\nexport const FORWARD = Object.freeze(new THREE.Vector3(0, 0, -1));\nexport const BACK = Object.freeze(new THREE.Vector3(0, 0, 1));\nexport const LEFT = Object.freeze(new THREE.Vector3(-1, 0, 0));\nexport const RIGHT = Object.freeze(new THREE.Vector3(1, 0, 0));\nexport const ZERO_VECTOR3 = Object.freeze(new THREE.Vector3(0, 0, 0));\n","import * as THREE from 'three';\n\nimport {Script, SelectEvent} from '../core/Script';\nimport {Input} from '../input/Input';\nimport {MouseController} from '../input/MouseController';\nimport {UP} from '../utils/HelperConstants';\n\n// Temporary variables.\nconst _quaternion = new THREE.Quaternion();\nconst _euler = new THREE.Euler();\nconst _vector3 = new THREE.Vector3();\n\nexport interface Draggable extends THREE.Object3D {\n draggable: boolean;\n // Whether to continuously face the camera as the user drags.\n // If unspecified, defaults to false.\n dragFacingCamera?: boolean;\n}\n\nexport enum DragMode {\n TRANSLATING = 'TRANSLATING',\n ROTATING = 'ROTATING',\n SCALING = 'SCALING',\n DO_NOT_DRAG = 'DO_NOT_DRAG',\n}\n\nexport interface HasDraggingMode {\n draggingMode: DragMode;\n}\n\nexport class DragManager extends Script {\n static readonly dependencies = {input: Input, camera: THREE.Camera};\n static readonly IDLE = 'IDLE';\n static readonly TRANSLATING = DragMode.TRANSLATING;\n static readonly ROTATING = DragMode.ROTATING;\n static readonly SCALING = DragMode.SCALING;\n static readonly DO_NOT_DRAG = DragMode.DO_NOT_DRAG;\n private mode = DragManager.IDLE;\n private controller1?: THREE.Object3D;\n private controller2?: THREE.Object3D;\n private originalObjectPosition = new THREE.Vector3();\n private originalObjectRotation = new THREE.Quaternion();\n private originalObjectScale = new THREE.Vector3();\n private originalController1Position = new THREE.Vector3();\n private originalController1RotationInverse = new THREE.Quaternion();\n private originalController1MatrixInverse = new THREE.Matrix4();\n private originalScalingControllerDistance = 0.0;\n private originalScalingObjectScale = new THREE.Vector3();\n private intersection?: THREE.Intersection;\n private draggableObject?: Draggable;\n private input!: Input;\n private camera!: THREE.Camera;\n\n init({input, camera}: {input: Input, camera: THREE.Camera}) {\n this.input = input;\n this.camera = camera;\n }\n\n onSelectStart(event: SelectEvent) {\n const controller = event.target;\n const intersections = this.input.intersectionsForController.get(controller);\n if (intersections && intersections.length > 0) {\n this.beginDragging(intersections[0], controller);\n }\n }\n\n onSelectEnd() {\n this.mode = DragManager.IDLE;\n this.intersection = undefined;\n this.draggableObject = undefined;\n }\n\n update() {\n for (const controller of this.input.controllers) {\n this.updateDragging(controller);\n }\n }\n\n beginDragging(intersection: THREE.Intersection, controller: THREE.Object3D) {\n const [draggableObject, draggingMode] =\n this.findDraggableObjectAndDraggingMode(intersection.object);\n if (draggableObject == null || draggingMode == null ||\n draggingMode == DragManager.DO_NOT_DRAG) {\n return false;\n }\n if (this.mode != DragManager.IDLE) {\n // Already dragging, switch to scaling.\n return this.beginScaling(controller);\n }\n this.draggableObject = draggableObject;\n this.mode = draggingMode == DragManager.ROTATING ? DragManager.ROTATING :\n DragManager.TRANSLATING;\n this.originalController1Position.copy(controller.position);\n this.originalController1MatrixInverse\n .compose(controller.position, controller.quaternion, controller.scale)\n .invert();\n this.originalController1RotationInverse.copy(controller.quaternion)\n .invert();\n this.intersection = intersection;\n this.controller1 = controller;\n this.originalObjectRotation.copy(draggableObject.quaternion);\n this.originalObjectPosition.copy(draggableObject.position);\n this.originalObjectScale.copy(draggableObject.scale);\n return true;\n }\n\n // Scaling is a two-handed gesture, based on the distance between the two\n // hands.\n beginScaling(controller: THREE.Object3D) {\n this.controller2 = controller;\n this.originalScalingControllerDistance =\n _vector3\n .subVectors(this.controller1!.position, this.controller2.position)\n .length();\n this.originalScalingObjectScale.copy(this.intersection!.object.scale);\n this.mode = DragManager.SCALING;\n return true;\n }\n\n updateDragging(controller: THREE.Object3D) {\n if (this.mode == DragManager.TRANSLATING) {\n return this.updateTranslating();\n } else if (this.mode == DragManager.ROTATING) {\n return this.updateRotating(controller);\n } else if (this.mode == DragManager.SCALING) {\n return this.updateScaling();\n }\n // Continue handle controller.\n return false;\n }\n\n updateTranslating() {\n const model = this.draggableObject!;\n model.position.copy(this.originalObjectPosition);\n model.quaternion.copy(this.originalObjectRotation);\n model.scale.copy(this.originalObjectScale)\n model.updateMatrix();\n this.controller1!.updateMatrix();\n model.matrix.premultiply(this.originalController1MatrixInverse)\n .premultiply(this.controller1!.matrix);\n model.position.setFromMatrixPosition(model.matrix);\n if (model.dragFacingCamera) {\n this.turnPanelToFaceTheCamera();\n }\n return true;\n }\n\n updateRotating(controller: THREE.Object3D) {\n if (controller != this.controller1) {\n return;\n }\n if (controller instanceof MouseController) {\n return this.updateRotatingFromMouseController(controller);\n }\n const model = this.draggableObject!;\n const deltaPosition = new THREE.Vector3().subVectors(\n controller.position, this.originalController1Position);\n deltaPosition.applyQuaternion(this.originalController1RotationInverse);\n const offsetRotation =\n _quaternion.setFromAxisAngle(UP, 10.0 * deltaPosition.x);\n model.quaternion.multiplyQuaternions(\n offsetRotation, this.originalObjectRotation);\n return true;\n }\n\n updateRotatingFromMouseController(controller: THREE.Object3D) {\n const model = this.draggableObject!;\n const deltaRotation = _quaternion.multiplyQuaternions(\n controller.quaternion, this.originalController1RotationInverse);\n const rotationYawAngle = _euler.setFromQuaternion(deltaRotation, 'YXZ');\n const offsetRotation =\n _quaternion.setFromAxisAngle(UP, -10.0 * rotationYawAngle.y);\n model.quaternion.multiplyQuaternions(\n offsetRotation, this.originalObjectRotation);\n return true;\n }\n\n updateScaling() {\n const newControllerDistance =\n _vector3\n .subVectors(this.controller1!.position, this.controller2!.position)\n .length();\n const distanceRatio =\n newControllerDistance / this.originalScalingControllerDistance;\n const model = this.draggableObject!;\n model.scale.copy(this.originalScalingObjectScale)\n .multiplyScalar(distanceRatio);\n return true;\n }\n\n turnPanelToFaceTheCamera() {\n const model = this.draggableObject!;\n _vector3.subVectors(model.position, this.camera.position);\n model.quaternion.setFromAxisAngle(\n UP, (3 * Math.PI / 2) - Math.atan2(_vector3.z, _vector3.x));\n }\n\n /**\n * Seach up the scene graph to find the first draggable object and the first\n * drag mode at or below the draggable object.\n * @param target - Child object to search.\n * @returns Array containing the first draggable object and the first drag\n * mode.\n */\n private findDraggableObjectAndDraggingMode(\n target: THREE.Object3D|null|\n undefined): [Draggable|undefined, DragMode|undefined] {\n let currentTarget = target;\n let draggableObject: Draggable|undefined;\n let draggingMode: DragMode|undefined;\n while (currentTarget && !draggableObject) {\n draggableObject = (currentTarget as Partial<Draggable>).draggable ?\n (currentTarget as Draggable) :\n undefined;\n draggingMode = draggingMode ??\n (currentTarget as Partial<HasDraggingMode>).draggingMode;\n currentTarget = currentTarget.parent;\n }\n return [draggableObject, draggingMode];\n }\n}\n","import * as THREE from 'three';\n\nimport {IconButton, IconButtonOptions} from './IconButton';\n\n/**\n *A specialized `IconButton` that provides a simple, single-click\n * way for users to end the current WebXR session.\n *\n * It inherits the visual and interactive properties of `IconButton` and adds\n * the specific logic for session termination.\n */\nexport class ExitButton extends IconButton {\n /**\n * Declares the dependencies required by this script, which will be injected\n * by the core engine during initialization.\n */\n static dependencies = {\n renderer: THREE.WebGLRenderer,\n };\n\n /** The size of the 'close' icon font. */\n fontSize = 0.8;\n /** The base opacity when the button is not being interacted with. */\n defaultOpacity = 0.2;\n /** The opacity when a controller's reticle hovers over the button. */\n hoverOpacity = 0.8;\n /** The background color of the button's circular shape. */\n backgroundColor = 0xffffff;\n\n /** A private reference to the injected THREE.WebGLRenderer instance. */\n private renderer!: THREE.WebGLRenderer;\n\n /**\n * @param options - Configuration options to override the button's default\n * appearance.\n */\n constructor(options: IconButtonOptions = {}) {\n // Passes a default icon ('close') and any user-provided options to the\n // parent IconButton constructor.\n super({text: 'close', ...options});\n }\n\n /**\n * Initializes the component and stores the injected renderer dependency.\n * @param dependencies - The injected dependencies.\n */\n override async init({renderer}: {renderer: THREE.WebGLRenderer;}) {\n await super.init();\n this.renderer = renderer;\n }\n\n /**\n * This method is triggered when the button is successfully selected (e.g.,\n * clicked). It finds the active WebXR session and requests to end it.\n * @override\n */\n onTriggered() {\n console.log('ExitButton triggered: Shutting down XR session.');\n const session = this.renderer.xr.getSession();\n if (session) {\n // Asynchronously end the session. No need to await.\n session.end();\n }\n }\n}\n","import {ExitButton} from '../components/ExitButton';\nimport {IconButton, IconButtonOptions} from '../components/IconButton';\nimport {IconView} from '../components/IconView';\nimport {ImageView, ImageViewOptions} from '../components/ImageView';\nimport {LabelView} from '../components/LabelView';\nimport {TextButton, TextButtonOptions} from '../components/TextButton';\nimport {TextView, TextViewOptions} from '../components/TextView';\nimport {VideoView, VideoViewOptions} from '../components/VideoView';\nimport type {Panel} from '../core/Panel';\nimport type {PanelOptions} from '../core/PanelOptions';\nimport {View} from '../core/View';\nimport {ViewOptions} from '../core/ViewOptions';\n\nimport type {Col, ColOptions} from './Col';\nimport type {Orbiter, OrbiterOptions} from './Orbiter';\nimport type {Row, RowOptions} from './Row';\n\n/**\n * A layout container that arranges child views in a grid-like\n * structure. It provides helper methods like `addRow()` and `addCol()` to\n * declaratively build complex layouts. Children are positioned based on the\n * order they are added and their respective `weight` properties.\n */\nexport type GridOptions = ViewOptions&{\n weight?: number;\n};\n\nexport class Grid extends View {\n static RowClass: typeof Row;\n static ColClass: typeof Col;\n static PanelClass: typeof Panel;\n static OrbiterClass: typeof Orbiter;\n\n /**\n * The weight of the current rows in the grid.\n */\n rowWeight = 0;\n\n /**\n * The weight of the current columns in the grid.\n */\n colWeight = 0;\n\n /**\n * The summed weight to the left of the grid.\n */\n leftWeight = 0;\n\n /**\n * The summed weight to the top of the grid.\n */\n topWeight = 0;\n\n cols = 0;\n rows = 0;\n\n /**\n * Initializes the Grid class with the provided Row, Col, and Panel\n * classes.\n * @param RowClass - The class for rows.\n * @param ColClass - The class for columns.\n * @param PanelClass - The class for panels.\n * @param OrbiterClass - The class for panels.\n */\n static init(\n RowClass: typeof Row, ColClass: typeof Col, PanelClass: typeof Panel,\n OrbiterClass: typeof Orbiter) {\n Grid.RowClass = RowClass;\n Grid.ColClass = ColClass;\n Grid.PanelClass = PanelClass;\n Grid.OrbiterClass = OrbiterClass;\n }\n\n /**\n * Adds an image to the grid.\n * @param options - The options for the image.\n * @returns The added image view.\n */\n addImage(options: ImageViewOptions) {\n const image = new ImageView(options);\n this.add(image);\n return image;\n }\n\n addVideo(options: VideoViewOptions) {\n const video = new VideoView(options);\n this.add(video);\n return video;\n }\n\n addIconButton(options: IconButtonOptions = {}) {\n const iconButton = new IconButton(options);\n this.add(iconButton);\n return iconButton;\n }\n\n addTextButton(options: TextButtonOptions = {}) {\n const iconButton = new TextButton(options);\n this.add(iconButton);\n return iconButton;\n }\n\n addIcon(options: IconButtonOptions = {}) {\n const iconView = new IconView(options);\n this.add(iconView);\n return iconView;\n }\n\n addText(options: TextViewOptions = {}) {\n const textView = new TextView(options);\n this.add(textView);\n return textView;\n }\n\n addLabel(options: object) {\n const labelView = new LabelView(options);\n this.add(labelView);\n return labelView;\n }\n\n addOrbiter(options: OrbiterOptions = {}) {\n const ui = new Grid.OrbiterClass(options);\n this.add(ui);\n return ui;\n }\n\n addExitButton(options: IconButtonOptions = {}) {\n const ui = new ExitButton(options);\n this.add(ui);\n return ui;\n }\n\n /**\n * Adds a panel to the grid.\n * @param options - The options for the panel.\n * @returns The added panel.\n */\n addPanel(options: PanelOptions = {}) {\n options.isRoot = false;\n const panel = new Grid.PanelClass(options);\n this.add(panel);\n return panel;\n }\n\n /**\n * Adds a row to the grid.\n * @param options - The options for the row.\n * @returns The added row.\n */\n addRow(options: RowOptions = {}) {\n const row = new Grid.RowClass(options);\n row.topWeight = this.rowWeight;\n row.height = row.weight;\n\n this.rowWeight += row.weight;\n this.add(row);\n this.rows++;\n return row;\n }\n\n /**\n * Adds a column to the grid.\n * @param options - The options for the column.\n * @returns The added column.\n */\n addCol(options: ColOptions = {}) {\n const col = new Grid.ColClass(options);\n col.leftWeight = this.colWeight;\n col.width = col.weight;\n\n this.colWeight += col.weight;\n this.add(col);\n this.cols++;\n return col;\n }\n\n /**\n * Updates the layout of the grid.\n */\n updateLayout() {\n this.x = -0.5 + (this.leftWeight + this.width / 2);\n this.y = 0.5 - (this.topWeight + this.height / 2);\n super.updateLayout();\n }\n\n /**\n * Initializes the layout of the grid with compose().\n */\n resetLayout() {\n this.rows = 0;\n this.cols = 0;\n this.colWeight = 0;\n this.rowWeight = 0;\n\n for (const child of this.children) {\n if (child instanceof Grid.RowClass) {\n child.topWeight = this.rowWeight;\n child.height = child.weight;\n this.rowWeight += child.weight;\n this.rows++;\n } else if (child instanceof Grid.ColClass) {\n child.leftWeight = this.colWeight;\n child.width = child.weight;\n this.colWeight += child.weight;\n this.cols++;\n }\n }\n }\n}\n","import * as THREE from 'three';\n\n/**\n * Shader for the interactive SpatialPanel UI component.\n *\n * This shader renders a rounded rectangle (squircle) that can display a\n * background color or texture. Its key feature is the ability to render\n * dynamic, radial \"glow\" highlights at the location of up to two controller\n * reticles. The highlight is constrained to the panel's border, providing clear\n * visual feedback for dragging and interaction.\n */\nexport const SpatialPanelShader = {\n uniforms: {\n 'uMainTex': {value: null},\n 'uUseImage': {value: 0.0},\n 'uBackgroundColor': {\n value: new THREE.Vector4(0.4, 0.8, 1.0, 1.0),\n },\n 'uBoxSize': {value: new THREE.Vector2(0.5, 0.5)},\n 'uRadius': {value: 0.05},\n 'uReticleUVs': {value: new THREE.Vector4(0.5, 0.5, 0.5, 0.5)},\n 'uSelected': {value: new THREE.Vector2(0.0, 0.0)},\n 'uBorderWidth': {value: 0.1},\n 'uHighlightRadius': {value: 0.2},\n 'uOutlineWidth': {value: 0.01},\n 'uOpacity': {value: 1.0}\n },\n\n vertexShader: /* glsl */ `\n varying vec2 vTexCoord;\n\n void main() {\n vTexCoord = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n }\n `,\n\n fragmentShader: /* glsl */ `\n precision mediump float;\n\n uniform sampler2D uMainTex;\n uniform vec4 uBackgroundColor;\n uniform vec2 uBoxSize;\n uniform float uRadius;\n uniform float uUseImage;\n\n uniform vec4 uReticleUVs;\n uniform vec2 uSelected;\n uniform float uBorderWidth;\n uniform float uHighlightRadius;\n uniform float uOutlineWidth;\n uniform float uOpacity;\n\n varying vec2 vTexCoord;\n\n // Distance function for rounded box.\n float distRoundBox(vec2 p, vec2 b, highp float r) {\n return length(max(abs(p) - b + r, 0.0)) - r;\n }\n\n vec4 highlight(in vec4 baseColor, in vec4 colorOutside,\n in float distOuterUV, in float aa, in vec2 mouse, in float selected) {\n\n vec4 highlightColor = vec4(0.0);\n float normDist = 1.0; // Initialize outside the highlight range\n bool mousePressed = selected > 0.0;\n bool mouseHovering = selected <= 0.0 && length(uReticleUVs.xy) > 0.0;\n bool mouseNearBorder = (mouseHovering || mousePressed);\n vec4 finalColor = baseColor;\n\n if (mouseNearBorder) {\n // Scale mouse and fragment coordinates by the inverse of uBoxSize\n\n vec2 fragAspect = vTexCoord;\n fragAspect.x *= uBoxSize.x / uBoxSize.y;\n vec2 mouseAspect = mouse;\n mouseAspect.x *= uBoxSize.x / uBoxSize.y;\n\n // Calculate vector from mouse to fragment in aspect-corrected space\n vec2 diffAspect = fragAspect - mouseAspect;\n\n // Calculate the distance in the aspect-corrected space\n float distToMouseAspect = length(diffAspect);\n\n // Normalized distance from mouse within the highlight radius\n normDist = distToMouseAspect / uHighlightRadius;\n\n // Define highlight color\n float innerWhite = mousePressed ? 0.9 : 0.8;\n\n // Radial gradient calculation\n float radialFactor = smoothstep(1.0, 0.0, normDist); // 1 at center, 0 at edge\n highlightColor = vec4(vec3(innerWhite), 1.0) * vec4(vec3(1.0), radialFactor);\n\n // Calculate distance to the inner edge of the border in UV space\n float distInnerUV = distRoundBox(\n (vTexCoord - 0.5) * uBoxSize,\n (uBoxSize - uBorderWidth) * 0.5, 0.5 * uRadius);\n\n float highlightEdgeSharpness = 200.0;\n float innerHighlightAmount = clamp(highlightEdgeSharpness * -distOuterUV, 0.0, 1.0);\n float outerHighlightAmount = clamp(highlightEdgeSharpness * distInnerUV, 0.0, 1.0);\n float highlightAmount = min(innerHighlightAmount, outerHighlightAmount);\n vec4 highlightColor = mix(finalColor, finalColor + highlightColor, highlightColor.a);\n finalColor = mix(finalColor, highlightColor, highlightAmount);\n }\n return finalColor;\n }\n\n void main(void) {\n vec2 size = uBoxSize * 1000.0;\n float radius = min(size.x, size.y) * (0.05 + uRadius);\n vec2 half_size = 0.5 * size;\n\n // Distance to the outer edge of the round box in UV space (0-1)\n float distOuterUV = distRoundBox(vTexCoord * uBoxSize - uBoxSize * 0.5, uBoxSize * 0.5, uRadius);\n\n // Antialiasing delta\n float aa = fwidth(distOuterUV) * 0.8;\n\n // Base color: opaque inside, transparent outside\n vec4 colorInside = uBackgroundColor;\n if (uUseImage > 0.5) {\n colorInside = texture2D(uMainTex, vTexCoord);\n colorInside.a = 1.0;\n }\n vec4 colorOutside = vec4(0.0, 0.0, 0.0, 0.0);\n vec4 baseColor = mix(colorInside, colorOutside, smoothstep(0.0, aa, distOuterUV));\n\n vec4 finalColor1 = highlight(baseColor, colorOutside, distOuterUV, aa, uReticleUVs.xy, uSelected.x);\n vec4 finalColor2 = highlight(baseColor, colorOutside, distOuterUV, aa, uReticleUVs.zw, uSelected.y);\n\n gl_FragColor = uOpacity * max(finalColor1, finalColor2);\n }\n `\n};\n","import * as THREE from 'three';\n\nimport type {Shader} from '../../utils/Types';\nimport {getVec4ByColorString} from '../../utils/utils';\n\n\n/**\n * A specialized `THREE.Mesh` designed for rendering UI panel\n * backgrounds. It utilizes a custom shader to draw rounded rectangles\n * (squircles) and provides methods to dynamically update its appearance,\n * such as aspect ratio and size. This class is a core building block for\n * `Panel` components.\n */\nexport class PanelMesh extends\n THREE.Mesh<THREE.PlaneGeometry, THREE.ShaderMaterial> {\n /** Text description of the PanelMesh */\n name = 'PanelMesh';\n\n /**\n * Provides convenient access to the material's shader uniforms.\n * @returns The uniforms object of the shader material.\n */\n get uniforms() {\n return this.material.uniforms;\n }\n\n /**\n * Creates an instance of PanelMesh.\n * @param shader - Shader for the panel mesh.\n * @param backgroundColor - The background color as a CSS string.\n * @param panelScale - The initial scale of the plane\n */\n constructor(shader: Shader, backgroundColor?: string, panelScale = 1.0) {\n // Each mesh needs its own unique set of uniforms.\n const uniforms = THREE.UniformsUtils.clone(shader.uniforms);\n\n const material = new THREE.ShaderMaterial({\n uniforms: uniforms,\n vertexShader: shader.vertexShader,\n fragmentShader: shader.fragmentShader,\n transparent: true,\n depthWrite: false,\n side: THREE.DoubleSide,\n });\n\n const geometry = new THREE.PlaneGeometry(panelScale, panelScale);\n\n super(geometry, material);\n\n if (backgroundColor) {\n uniforms.uBackgroundColor.value = getVec4ByColorString(backgroundColor);\n }\n }\n\n /**\n * Sets the panel's absolute dimensions (width and height) in the shader.\n * This is used by the shader to correctly calculate properties like rounded\n * corner radii.\n * @param width - The width of the panel.\n * @param height - The height of the panel.\n */\n setWidthHeight(width: number, height: number) {\n this.uniforms.uBoxSize.value.set(width, height);\n }\n\n /**\n * Adjusts the mesh's scale to match a given aspect ratio, preventing the\n * panel from appearing stretched.\n * @param aspectRatio - The desired width-to-height ratio.\n */\n setAspectRatio(aspectRatio: number) {\n this.scale.set(\n Math.max(aspectRatio, 1.0), Math.max(1.0 / aspectRatio, 1.0), 1.0);\n }\n}\n","import * as THREE from 'three';\n\nimport {User} from '../../core/User';\nimport {Draggable, DragMode, HasDraggingMode} from '../../ux/DragManager';\nimport {DP_TO_DMM} from '../constants';\nimport {Grid} from '../layouts/Grid';\nimport {SpatialPanelShader} from '../shaders/SpatialPanelShader';\nimport {SquircleShader} from '../shaders/SquircleShader';\n\nimport {PanelMesh} from './PanelMesh';\nimport {PanelOptions} from './PanelOptions';\nimport {View} from './View.js';\n\n// Default panel width in density-independent pixels (DP).\nconst DEFAULT_WIDTH_DP = 1024;\n\n// Default panel height in density-independent pixels (DP).\nconst DEFAULT_HEIGHT_DP = 720;\n\n// Default panel width in meters, calculated from DP for root panels.\nconst DEFAULT_WIDTH_M = DEFAULT_WIDTH_DP * DP_TO_DMM * 0.001;\n\n// Default panel height in meters, calculated from DP for root panels.\nconst DEFAULT_HEIGHT_M = DEFAULT_HEIGHT_DP * DP_TO_DMM * 0.001;\n\nexport type PanelFadeState = 'idle'|'fading-in'|'fading-out';\n\n/**\n * A fundamental UI container that displays content on a 2D quad in\n * 3D space. It supports background colors, rounded corners (squircles), and can\n * be made interactive and draggable. It serves as a base for building complex\n * user interfaces.\n *\n * The panel intelligently selects a shader:\n * - `SpatialPanelShader`: For interactive, draggable panels with hover/select\n * highlights.\n * - `SquircleShader`: For static, non-interactive panels with a clean, rounded\n * look.\n */\nexport class Panel extends View implements Draggable, Partial<HasDraggingMode> {\n static dependencies = {user: User, timer: THREE.Timer};\n\n keepFacingCamera = true;\n\n /** Text description of the view */\n name = 'Panel';\n\n /** Type identifier for easy checking with `instanceof`. */\n isPanel = true;\n\n /** The underlying mesh that renders the panel's background. */\n mesh: PanelMesh;\n\n /** Determines if the panel can be dragged by the user. */\n draggable = false;\n\n /** Dragging mode, defaults to true if draggable else undefined. */\n draggingMode?: DragMode;\n\n /** Determines if the panel can be touched by the user's hands. */\n touchable = false;\n\n /**\n * If true, a root panel will automatically spawn in front of the user.\n */\n useDefaultPosition = true;\n\n /**\n * Panel by default uses borderless shader.\n * This flag indicates whether to use borderless shader for Spatial Panels.\n */\n useBorderlessShader = false;\n\n /**\n * Whether to show highlights for the spatial panel.\n */\n showHighlights = false;\n\n /** The background color of the panel, expressed as a CSS color string. */\n backgroundColor = '#c2c2c255';\n\n // --- Private Fading Animation Properties ---\n /**\n * The current state of the fading animation.\n */\n private _fadeState: PanelFadeState = 'idle';\n\n /**\n * Default duration for fade animations in seconds.\n */\n private _fadeDuration = 0.2;\n\n /**\n * Timer for the current fade animation, driven by the core clock.\n */\n private _fadeTimer = 0;\n\n /**\n * The current opacity value, used during animations.\n */\n private _currentOpacity = 1.0;\n\n /**\n * The start opacity value for the current animation.\n */\n private _startOpacity = 1.0;\n\n /**\n * The target opacity value for the current animation.\n */\n private _targetOpacity = 1.0;\n\n /**\n * An optional callback function to execute when a fade animation completes.\n */\n onFadeComplete?: () => void;\n\n private timer!: THREE.Timer;\n\n constructor(options: PanelOptions = {}) {\n super(options);\n\n const isDraggable = options.draggable ?? this.draggable;\n\n const useBorderlessShader = options.useBorderlessShader ?? (!isDraggable);\n // Draggable panels have a larger geometry for interaction padding.\n const panelScale = useBorderlessShader ? 1.0 : 1.3;\n // Use SpatialPanelShader for SpatialPanel, while developers can choose\n // useBorderlessShader=false to disable the interactive border.\n const shader = useBorderlessShader ? SquircleShader : SpatialPanelShader;\n options.useBorderlessShader = useBorderlessShader;\n this.showHighlights = !useBorderlessShader;\n\n // Applies user-provided options or default options.\n this.backgroundColor = options.backgroundColor ?? this.backgroundColor;\n this.draggable = isDraggable;\n this.draggingMode = options.draggingMode ?? this.draggable ?\n DragMode.TRANSLATING :\n DragMode.DO_NOT_DRAG;\n this.touchable = options.touchable ?? this.touchable;\n this.isRoot = options.isRoot ?? true;\n this.width = options.width ?? (this.isRoot ? DEFAULT_WIDTH_M : 1);\n this.height = options.height ?? (this.isRoot ? DEFAULT_HEIGHT_M : 1);\n this.showHighlights = options.showHighlights ?? this.showHighlights;\n this.useDefaultPosition =\n options.useDefaultPosition ?? this.useDefaultPosition;\n this.useBorderlessShader =\n options.useBorderlessShader ?? this.useBorderlessShader;\n\n this.mesh = new PanelMesh(shader, this.backgroundColor, panelScale);\n this.add(this.mesh);\n\n this.updateLayout();\n }\n\n /**\n * Initializes the panel, setting its default position if applicable.\n */\n init({user, timer}: {user: User; timer: THREE.Timer;}) {\n super.init();\n this.selectable = true;\n this.timer = timer;\n\n // A manual position set in .position.set() will override the\n // default position to create the SpatialPanel.\n if (this.position.x !== 0 || this.position.y !== 0 ||\n this.position.z !== 0) {\n this.useDefaultPosition = false;\n }\n\n if (this.isRoot && this.useDefaultPosition) {\n this.position.set(\n this.x, user.height + this.y, -user.panelDistance + this.z);\n } else {\n this.position.set(\n this.position.x + this.x, this.position.y + this.y,\n this.position.z + this.z);\n }\n }\n\n /**\n * Starts fading the panel and its children in.\n * @param duration - Optional fade duration in seconds.\n * @param onComplete - Optional callback when fade completes.\n */\n fadeIn(duration?: number, onComplete?: () => void) {\n if (this._fadeState === 'fading-in') return;\n this._startFade(1.0, duration, onComplete);\n this._fadeState = 'fading-in';\n }\n\n /**\n * Starts fading the panel and its children out.\n * @param duration - Optional fade duration in seconds.\n * @param onComplete - Optional callback when fade completes.\n */\n fadeOut(duration?: number, onComplete?: () => void) {\n if (this._fadeState === 'fading-out') return;\n this._startFade(0.0, duration, onComplete);\n this._fadeState = 'fading-out';\n }\n\n /**\n * Initiates a fade animation.\n */\n private _startFade(\n targetOpacity: number, duration?: number, onComplete?: () => void) {\n this._fadeDuration = duration ?? 0.2;\n this.onFadeComplete = onComplete;\n this._fadeTimer = 0;\n this._startOpacity = this._currentOpacity;\n this._targetOpacity = targetOpacity;\n\n if (this._fadeDuration <= 0) {\n this._completeFade();\n } else {\n this._prepareMaterialsForFade();\n }\n }\n\n /**\n * Ensures all child materials are configured for transparency.\n */\n private _prepareMaterialsForFade() {\n this.traverse((child) => {\n if (child instanceof THREE.Mesh && child.material) {\n const materials: THREE.Material[] =\n Array.isArray(child.material) ? child.material : [child.material];\n materials.forEach(material => {\n material.transparent = true;\n });\n }\n });\n }\n\n /**\n * Applies the given opacity to all materials in the hierarchy.\n */\n private _applyOpacity(opacityValue: number) {\n this.traverse((child) => {\n if (child instanceof View) child.opacity = opacityValue;\n if (child instanceof THREE.Mesh && child.material) {\n const materials: THREE.Material[] =\n Array.isArray(child.material) ? child.material : [child.material];\n materials.forEach(material => {\n if (material instanceof THREE.ShaderMaterial) {\n material.uniforms.uOpacity.value = opacityValue;\n } else {\n material.opacity = opacityValue;\n }\n });\n }\n });\n }\n\n /**\n * Finalizes the fade animation, sets final visibility, and triggers callback.\n */\n private _completeFade() {\n this._currentOpacity = this._targetOpacity;\n this._applyOpacity(this._currentOpacity);\n this._fadeState = 'idle';\n if (this._currentOpacity === 0)\n this.hide();\n else\n this.show();\n this.onFadeComplete?.();\n }\n\n /**\n * Updates the fade animation progress each frame.\n */\n update() {\n if (this._fadeState !== 'idle') {\n this._fadeTimer += this.timer.getDelta();\n const progress = Math.min(this._fadeTimer / this._fadeDuration, 1.0);\n this._currentOpacity = THREE.MathUtils.lerp(\n this._startOpacity, this._targetOpacity, progress);\n this._applyOpacity(this._currentOpacity);\n if (progress >= 1.0) {\n this._completeFade();\n }\n }\n }\n\n /**\n * Adds a Grid layout as a direct child of this panel.\n * @returns The newly created Grid instance.\n */\n addGrid() {\n const grid = new Grid();\n this.add(grid);\n return grid;\n }\n\n /**\n * Updates the panel's visual dimensions based on its layout properties.\n */\n updateLayout() {\n super.updateLayout();\n this.mesh.setAspectRatio(this.aspectRatio);\n const parentAspectRatio =\n this.isRoot || !this.parent ? 1.0 : (this.parent as View).aspectRatio;\n this.mesh.setWidthHeight(\n this.width * Math.max(parentAspectRatio, 1.0),\n this.height * Math.max(1.0 / parentAspectRatio, 1.0));\n }\n\n /**\n * Gets the panel's width in meters.\n * @returns The width in meters.\n */\n getWidth() {\n return this.width;\n }\n\n /**\n * Gets the panel's height in meters.\n * @returns The height in meters.\n */\n getHeight() {\n return this.height;\n }\n}\n","import {Grid, GridOptions} from './Grid.js';\n\n/**\n * A layout component used within a `Grid` to arrange child elements\n * horizontally. The width of each column is determined by its `weight` property\n * relative to the total weight of all columns in the same row.\n */\nexport type ColOptions = GridOptions&{\n weight?: number;\n};\n\nexport class Col extends Grid {\n constructor(options: ColOptions = {}) {\n if (options.weight === undefined) {\n options.weight = 0.5;\n }\n super(options);\n }\n}\n","import {Grid, GridOptions} from './Grid.js';\n\n/**\n * A layout container designed to hold secondary UI elements, such\n * as an exit button or settings icon. It typically \"orbits\" or remains\n * attached to a corner of its parent panel, outside the main content area.\n */\nexport type OrbiterOptions = GridOptions;\n\nexport class Orbiter extends Grid {\n init() {\n super.init();\n\n this.position.set(-0.45 * this.rangeX, 0.7 * this.rangeY, this.position.z);\n this.scale.set(0.2, 0.2, 1.0);\n }\n}\n","import {Grid, GridOptions} from './Grid.js';\n\n/**\n * A layout component used within a `Grid` to arrange child elements\n * vertically. The height of each row is determined by its `weight` property\n * relative to the total weight of all rows in the grid.\n */\nexport type RowOptions = GridOptions&{\n weight?: number;\n};\n\nexport class Row extends Grid {\n constructor(options: RowOptions = {}) {\n if (options.weight === undefined) {\n options.weight = 0.5;\n }\n super(options);\n }\n}\n","import {Panel} from '../core/Panel';\nimport {PanelOptions} from '../core/PanelOptions';\n\n/**\n * A fundamental UI container that lets you display app content in a\n * 3D space. It can be thought of as a \"window\" or \"surface\" in XR. It provides\n * visual feedback for user interactions like hovering and selecting, driven by\n * a custom shader, and can be made draggable.\n */\nexport type SpatialPanelOptions = PanelOptions&{\n showEdge?: boolean;\n dragFacingCamera?: boolean;\n};\n\nexport class SpatialPanel extends Panel {\n /**\n * Keeps the panel facing the camera as it is dragged.\n */\n dragFacingCamera = true;\n\n /**\n * Creates an instance of SpatialPanel.\n */\n constructor(options: SpatialPanelOptions = {}) {\n options.draggable = options.draggable ?? true;\n options.dragFacingCamera = options.dragFacingCamera ?? true;\n super(options);\n // Reset the following fields with our own defaults.\n this.draggable = options.draggable ?? this.draggable;\n this.dragFacingCamera = options.dragFacingCamera ?? this.dragFacingCamera;\n this.mesh.material.visible = options.showEdge !== false;\n }\n\n update() {\n super.update();\n this._updateInteractionFeedback();\n }\n\n /**\n * Updates shader uniforms to provide visual feedback for controller\n * interactions, such as hover and selection highlights. This method is\n * optimized to only update uniforms when the state changes.\n */\n private _updateInteractionFeedback() {\n if (this.useBorderlessShader || !this.showHighlights) {\n return;\n }\n const [id1, id2] = this.ux.getPrimaryTwoControllerIds();\n\n // --- Update Selection Uniform ---\n const isSelected1 = (id1 !== null) ? this.ux.selected[id1] : false;\n const isSelected2 = (id2 !== null) ? this.ux.selected[id2] : false;\n\n this.mesh.material.uniforms.uSelected.value.set(\n isSelected1 ? 1.0 : 0.0, isSelected2 ? 1.0 : 0.0);\n\n // --- Update Reticle UVs Uniform ---\n const u1 = (id1 !== null) ? this.ux.uvs[id1].x : -1;\n const v1 = (id1 !== null) ? this.ux.uvs[id1].y : -1;\n const u2 = (id2 !== null) ? this.ux.uvs[id2].x : -1;\n const v2 = (id2 !== null) ? this.ux.uvs[id2].y : -1;\n\n this.mesh.material.uniforms.uReticleUVs.value.set(u1, v1, u2, v2);\n }\n}\n","/**\n * UI is a declarative 3D UI composition engine for WebXR,\n * inspired by modern frameworks like Jetpack Compose. It builds a three.js\n * scene graph from a JSON configuration, allowing for a clean separation of UI\n * structure and application logic.\n */\n\nimport {Script} from '../core/Script';\nimport type {Constructor} from '../utils/Types';\n\nimport {IconButton, IconButtonOptions} from './components/IconButton';\nimport {IconView, IconViewOptions} from './components/IconView';\nimport {ImageView, ImageViewOptions} from './components/ImageView';\nimport {LabelView, LabelViewOptions} from './components/LabelView';\nimport {TextButton, TextButtonOptions} from './components/TextButton';\nimport {TextView, TextViewOptions} from './components/TextView';\nimport {VideoView, VideoViewOptions} from './components/VideoView';\nimport {Panel} from './core/Panel';\nimport type {PanelOptions} from './core/PanelOptions';\nimport {View} from './core/View';\nimport {Col, ColOptions} from './layouts/Col';\nimport {Grid, GridOptions} from './layouts/Grid';\nimport {Orbiter, OrbiterOptions} from './layouts/Orbiter';\nimport {Row, RowOptions} from './layouts/Row';\nimport {SpatialPanel, SpatialPanelOptions} from './layouts/SpatialPanel';\n\n// Initializes the Grid class with its dependencies for declarative building.\nGrid.init(Row, Col, Panel, Orbiter);\n\nexport type UIJsonNodeOptions =\n |PanelOptions|TextViewOptions|IconViewOptions|ImageViewOptions|\n LabelViewOptions|TextButtonOptions|VideoViewOptions|ColOptions|GridOptions|\n RowOptions|OrbiterOptions|SpatialPanelOptions|IconButtonOptions;\n\nexport type UIJsonNode = {\n type: string,\n options?: UIJsonNodeOptions,\n position?: {x: number, y: number, z: number},\n rotation?: {x: number, y: number, z: number},\n children?: Array<UIJsonNode>\n};\n\n/**\n * Manages the construction and lifecycle of a declarative UI defined by a JSON\n * object. It translates the JSON structure into a hierarchy of UI objects.\n * See samples/ui for a complete example of composing UI with JSON.\n */\nexport class UI extends Script {\n views: View[] = [];\n\n /**\n * A static registry mapping string identifiers to UI component classes.\n * This allows for an extensible and declarative UI system.\n */\n static ComponentRegistry = new Map<string, Constructor<View>>();\n\n /**\n * Registers a component class with a string key, making it available to the\n * `compose` function.\n * @param typeName - The key to use in the JSON configuration.\n * @param componentClass - The class constructor of the UI component.\n */\n static registerComponent(\n typeName: string, componentClass: Constructor<View>) {\n if (UI.ComponentRegistry.has(typeName)) {\n console.warn(`UI: Component type \"${typeName}\" is being overwritten.`);\n }\n UI.ComponentRegistry.set(typeName, componentClass);\n }\n\n /**\n * Composes a UI hierarchy from a JSON object and attaches it to this UI\n * instance. This is the primary method for building a declarative UI.\n *\n * @param json - The JSON object defining the UI structure.\n * @returns The root view of the composed UI, or null if composition fails.\n */\n compose(json: UIJsonNode): View|null {\n const rootComponent = this._composeNode(json);\n if (rootComponent) {\n this.add(rootComponent);\n rootComponent.traverse((node) => {\n if (node instanceof View) {\n this.views.push(node);\n }\n });\n }\n return rootComponent;\n }\n\n /**\n * Recursively processes a single node from the UI JSON configuration.\n * @param nodeJson - The JSON node for a single UI element.\n * @returns The composed UI object for this node, or null on error.\n */\n private _composeNode(nodeJson: UIJsonNode): View|null {\n const {\n type,\n options = {},\n position = {x: 0, y: 0, z: 0},\n rotation = {x: 0, y: 0, z: 0},\n children = []\n } = nodeJson;\n const ComponentClass = UI.ComponentRegistry.get(type);\n\n if (!ComponentClass) {\n console.error(`UI Error: Unknown component type \"${\n type}\". Make sure it's registered.`);\n return null;\n }\n\n const componentInstance = new ComponentClass(options);\n componentInstance.position.set(position.x, position.y, position.z);\n componentInstance.rotation.set(rotation.x, rotation.y, rotation.z);\n\n children.forEach((childJson: UIJsonNode) => {\n const childComponent = this._composeNode(childJson);\n if (childComponent) {\n componentInstance.add(childComponent);\n }\n });\n\n // For layouts, ensure they update their children's positions.\n if (componentInstance instanceof Grid) {\n componentInstance.resetLayouts();\n }\n\n return componentInstance;\n }\n}\n\n// Pre-register the standard set of UI components.\nUI.registerComponent('Panel', Panel);\nUI.registerComponent('Grid', Grid);\nUI.registerComponent('Row', Row);\nUI.registerComponent('Col', Col);\nUI.registerComponent('Orbiter', Orbiter);\nUI.registerComponent('Text', TextView);\nUI.registerComponent('TextView', TextView);\nUI.registerComponent('Label', LabelView);\nUI.registerComponent('LabelView', LabelView);\nUI.registerComponent('VideoView', VideoView);\nUI.registerComponent('TextButton', TextButton);\nUI.registerComponent('IconButton', IconButton);\nUI.registerComponent('IconView', IconView);\nUI.registerComponent('Image', ImageView);\nUI.registerComponent('ImageView', ImageView);\nUI.registerComponent('SpatialPanel', SpatialPanel);\n","class LoadingSpinner extends HTMLElement {\n private static style = `\n /* Styles for the wrapper that covers the screen */\n .wrapper {\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background-color: rgba(0, 0, 0, 0.1);\n display: flex;\n justify-content: center;\n align-items: center;\n z-index: 9999;\n transition: visibility 0s, opacity 0.2s linear;\n }\n\n /* The spinning circle */\n .spinner {\n border: 8px solid rgba(255, 255, 255, 0.3);\n border-left-color: #ffffff;\n border-radius: 50%;\n width: 60px;\n height: 60px;\n animation: spin 1s linear infinite;\n }\n\n /* The animation is safely scoped inside the shadow DOM */\n @keyframes spin {\n to {\n transform: rotate(360deg);\n }\n }`;\n private static innerHTML = `\n <style>\n ${LoadingSpinner.style}\n </style>\n <div class=\"wrapper\">\n <div class=\"spinner\"></div>\n </div>\n `;\n\n connectedCallback() {\n const shadowRoot = this.attachShadow({mode: 'open'});\n shadowRoot.innerHTML = LoadingSpinner.innerHTML;\n }\n}\ncustomElements.define('xb-blocks-loading-spinner', LoadingSpinner);\n\n// Creates a new Loading spinner and attaches it to document.body.\nexport function createLoadingSpinner() {\n return document.body.appendChild(\n document.createElement('xb-blocks-loading-spinner'));\n}\n","import * as THREE from 'three';\n\nimport {createLoadingSpinner} from './CreateLoadingSpinner';\n\n/**\n * Manages the global THREE.DefaultLoadingManager instance for\n * XRBlocks and handles communication of loading progress to the parent iframe.\n * This module controls the visibility of a loading spinner\n * in the DOM based on loading events.\n *\n * Import the single instance\n * `loadingSpinnerManager` to use it throughout the application.\n */\nexport class LoadingSpinnerManager {\n /**\n * DOM element of the loading spinner, created\n * when showSpinner() is called and removed on `onLoad` or `onError`.\n */\n private spinnerElement?: HTMLElement;\n\n /**\n * Tracks if the manager is currently loading assets.\n */\n isLoading = false;\n\n constructor() {\n this.setupCallbacks();\n }\n\n showSpinner() {\n if (!this.spinnerElement) {\n this.spinnerElement = createLoadingSpinner();\n }\n }\n\n hideSpinner() {\n if (this.spinnerElement) {\n this.spinnerElement.remove();\n this.spinnerElement = undefined;\n }\n }\n\n private setupCallbacks() {\n /**\n * Callback function for when the first loading item starts.\n * It sends an initial 'XR_LOADING_PROGRESS' message to the parent window.\n * Note: The spinner is now shown via a manual call to showSpinner()\n * @param _url - The URL of the item being loaded.\n * @param itemsLoaded - The number of items loaded so far.\n * @param itemsTotal - The total number of items to load.\n */\n THREE.DefaultLoadingManager.onStart = (_url, itemsLoaded, itemsTotal) => {\n this.isLoading = true;\n window.parent.postMessage(\n {\n type: 'XR_LOADING_PROGRESS',\n payload: {\n progress: itemsLoaded / itemsTotal,\n message: 'Loading assets...'\n }\n },\n '*');\n };\n\n /**\n * Callback function for when a loading item progresses.\n * It sends a 'XR_LOADING_PROGRESS' message to the parent window with\n * updated progress.\n * @param _url - The URL of the item currently in progress.\n * @param itemsLoaded - The number of items loaded so far.\n * @param itemsTotal - The total number of items to load.\n */\n THREE.DefaultLoadingManager.onProgress = (_url, itemsLoaded, itemsTotal) => {\n window.parent.postMessage(\n {\n type: 'XR_LOADING_PROGRESS',\n payload: {\n progress: itemsLoaded / itemsTotal,\n message:\n `Loading ${Math.round((itemsLoaded / itemsTotal) * 100)}%`\n }\n },\n '*');\n };\n\n /**\n * Callback function for when all loading items are complete.\n * It removes the loading spinner from the DOM and sends an\n * 'XR_LOADING_COMPLETE' message to the parent window.\n */\n THREE.DefaultLoadingManager.onLoad = () => {\n this.isLoading = false;\n this.hideSpinner();\n window.parent.postMessage({type: 'XR_LOADING_COMPLETE'}, '*');\n };\n\n /**\n * Callback function for when a loading item encounters an error.\n * It removes the loading spinner from the DOM and sends an\n * 'XR_LOADING_ERROR' message to the parent window.\n * @param url - The URL of the item that failed to load.\n */\n THREE.DefaultLoadingManager.onError = (url) => {\n this.isLoading = false;\n console.warn('XRBlocks: Error loading: ' + url);\n this.hideSpinner();\n window.parent.postMessage(\n {\n type: 'XR_LOADING_ERROR',\n payload: {url, message: 'Failed to load assets.'}\n },\n '*');\n };\n }\n}\n\nexport const loadingSpinnerManager = new LoadingSpinnerManager();\n","/**\n * Utility functions for positioning and orienting objects in 3D\n * space.\n */\nimport * as THREE from 'three';\n\n// Reusable instances to avoid creating new objects in the render loop.\nconst vector3 = new THREE.Vector3();\nconst vector3a = new THREE.Vector3();\nconst vector3b = new THREE.Vector3();\nconst matrix4 = new THREE.Matrix4();\n\n/**\n * Places and orients an object at a specific intersection point on another\n * object's surface. The placed object's 'up' direction will align with the\n * surface normal at the intersection, and its 'forward' direction will point\n * towards a specified target object (e.g., the camera), but constrained to the\n * surface plane.\n *\n * This is useful for placing objects on walls or floors so they sit flat\n * against the surface but still turn to face the user.\n *\n * @param obj - The object to be placed and oriented.\n * @param intersection - The intersection data from a\n * raycast,\n * containing the point and normal of the surface. The normal is assumed to be\n * in local space.\n * @param target - The object that `obj` should face (e.g., the\n * camera).\n * @returns The modified `obj`.\n */\nexport function placeObjectAtIntersectionFacingTarget(\n obj: THREE.Object3D, intersection: THREE.Intersection,\n target: THREE.Object3D) {\n // 1. Position the object at the intersection point.\n obj.position.copy(intersection.point);\n\n // 2. Determine the world-space normal of the surface at the intersection\n // point. We must ensure the matrix of the intersected object is up-to-date.\n intersection.object.updateWorldMatrix(true, false);\n\n // 3. Determine the desired forward direction.\n // This is the vector from the object to the target, projected onto the\n // surface plane.\n const worldNormal = vector3b.copy(intersection.normal!)\n .transformDirection(intersection.object.matrixWorld);\n const forwardVector = target.getWorldPosition(vector3)\n .sub(obj.position)\n .cross(worldNormal)\n .cross(worldNormal)\n .multiplyScalar(-1)\n .normalize();\n\n // 4. Create an orthonormal basis (a new coordinate system).\n // The 'up' vector is the surface normal.\n // The 'forward' vector is the direction towards the target on the plane.\n // The 'right' vector is perpendicular to both.\n const rightVector = vector3a.crossVectors(worldNormal, forwardVector);\n matrix4.makeBasis(rightVector, worldNormal, forwardVector);\n\n // 5. Apply the rotation from the new basis to the object.\n // This aligns the object's local axes with the new basis vectors.\n // Note: Three.js objects' 'forward' is conventionally the -Z axis.\n // makeBasis sets the +Z axis to forwardVector, so models may need to be\n // authored with +Z forward, or a rotation offset can be applied here.\n obj.quaternion.setFromRotationMatrix(matrix4);\n return obj;\n}\n","import * as THREE from 'three';\n\n/**\n * Represents a single detected object in the XR environment and holds metadata\n * about the object's properties. Note: 3D object position is stored in the\n * position property of `Three.Object3D`.\n */\nexport class DetectedObject extends THREE.Object3D {\n /**\n * A semantic label for the object (e.g., 'chair', 'table').\n */\n label: string;\n\n /**\n * The cropped part of the image that contains the object, as a base64 Data\n * URL.\n */\n image: string|null;\n\n /**\n * The 2D bounding box of the detected object in normalized screen\n * coordinates. Values are between 0 and 1. Centerpoint of this bounding is\n * used for backproject to obtain 3D object position (i.e., this.position).\n */\n detection2DBoundingBox: THREE.Box2;\n\n /**\n * Allows for additional, dynamic properties to be added to the object, as\n * defined in the schema in `ObjectsOptions`.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n [key: string]: any;\n\n /**\n * @param label - The semantic label of the object.\n * @param image - The base64 encoded cropped image of the object.\n * @param boundingBox - The 2D bounding box.\n * @param additionalData - A key-value map of additional properties from the\n * detector. This includes any object proparties that is requested through the\n * schema but is not assigned a class property by default (e.g., color, size).\n */\n constructor(\n label: string, image: string|null, boundingBox: THREE.Box2,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n additionalData: {[key: string]: any} = {}) {\n super();\n this.label = label;\n this.image = image;\n this.detection2DBoundingBox = boundingBox;\n\n // Assign any additional properties to this object.\n Object.assign(this, additionalData);\n }\n}\n","import * as THREE from 'three';\n\nimport {AI} from '../../ai/AI';\nimport {AIOptions} from '../../ai/AIOptions';\nimport {Gemini} from '../../ai/Gemini';\nimport {cropImage, transformRgbUvToWorld} from '../../camera/CameraUtils';\nimport {XRDeviceCamera} from '../../camera/XRDeviceCamera';\nimport {Script} from '../../core/Script';\nimport {Depth} from '../../depth/Depth';\nimport {parseBase64DataURL} from '../../utils/utils';\nimport {WorldOptions} from '../WorldOptions';\n\nimport {DetectedObject} from './DetectedObject';\n\n/**\n * Detects objects in the user's environment using a specified backend.\n * It queries an AI model with the device camera feed and returns located\n * objects with 2D and 3D positioning data.\n */\nexport class ObjectDetector extends Script {\n static dependencies = {\n options: WorldOptions,\n ai: AI,\n aiOptions: AIOptions,\n deviceCamera: XRDeviceCamera,\n depth: Depth,\n camera: THREE.Camera,\n };\n\n /**\n * A map from the object's UUID to our custom `DetectedObject` instance.\n */\n private _detectedObjects = new Map<string, DetectedObject>();\n\n private _debugVisualsGroup?: THREE.Group;\n\n /**\n * The configuration for the Gemini backend.\n */\n private _geminiConfig!: object;\n\n // Injected dependencies\n private options!: WorldOptions;\n private ai!: AI;\n private aiOptions!: AIOptions;\n private deviceCamera!: XRDeviceCamera;\n private depth!: Depth;\n private camera!: THREE.Camera;\n\n /**\n * Initializes the ObjectDetector.\n * @override\n */\n init({options, ai, aiOptions, deviceCamera, depth, camera}: {\n options: WorldOptions,\n ai: AI,\n aiOptions: AIOptions,\n deviceCamera: XRDeviceCamera,\n depth: Depth,\n camera: THREE.Camera,\n }) {\n this.options = options;\n this.ai = ai;\n this.aiOptions = aiOptions;\n this.deviceCamera = deviceCamera;\n this.depth = depth;\n this.camera = camera;\n this._geminiConfig = this._buildGeminiConfig();\n\n if (this.options.objects.showDebugVisualizations) {\n this._debugVisualsGroup = new THREE.Group();\n // Disable raycasting for the debug group to prevent interaction errors.\n this._debugVisualsGroup.raycast = () => {};\n this.add(this._debugVisualsGroup);\n }\n }\n\n /**\n * Runs the object detection process based on the configured backend.\n * @returns A promise that resolves with an\n * array of detected `DetectedObject` instances.\n */\n async runDetection() {\n this.clear(); // Clear previous results before starting a new detection.\n\n switch (this.options.objects.backendConfig.activeBackend) {\n case 'gemini':\n return this._runGeminiDetection();\n // Future backends like 'mediapipe' will be handled here.\n // case 'mediapipe':\n // return this._runMediaPipeDetection();\n default:\n console.warn(`ObjectDetector backend '${\n this.options.objects.backendConfig\n .activeBackend}' is not supported.`);\n return [];\n }\n }\n\n /**\n * Runs object detection using the Gemini backend.\n */\n private async _runGeminiDetection() {\n if (!this.ai.isAvailable()) {\n console.error('Gemini is unavailable for object detection.');\n return [];\n }\n\n const base64Image =\n this.deviceCamera.getSnapshot({outputFormat: 'base64'}) as string |\n null;\n if (!base64Image) {\n console.warn('Could not get device camera snapshot.');\n return [];\n }\n\n const {mimeType, strippedBase64} = parseBase64DataURL(base64Image);\n\n // Cache depth and camera data to align with the captured image frame.\n const cachedDepthArray = this.depth.depthArray[0].slice(0);\n const cachedMatrixWorld = this.camera.matrixWorld.clone();\n\n // Temporarily set the Gemini config for this specific query type.\n const originalGeminiConfig = this.aiOptions.gemini.config;\n this.aiOptions.gemini.config = this._geminiConfig;\n const textPrompt = 'What do you see in this image?';\n\n try {\n const rawResponse = await (this.ai.model as Gemini).query({\n type: 'multiPart',\n parts: [\n {inlineData: {mimeType: mimeType || undefined, data: strippedBase64}},\n {text: textPrompt}\n ]\n });\n\n let parsedResponse;\n try {\n if (rawResponse && rawResponse.text) {\n parsedResponse = JSON.parse(rawResponse.text);\n } else {\n console.error(\n 'AI response is missing text field:', rawResponse,\n 'Raw response was:', rawResponse);\n return [];\n }\n } catch (e) {\n console.error(\n 'Failed to parse AI response JSON:', e,\n 'Raw response was:', rawResponse);\n return [];\n }\n\n if (!Array.isArray(parsedResponse)) {\n console.error('Parsed AI response is not an array:', parsedResponse);\n return [];\n }\n\n if (this.options.objects.showDebugVisualizations) {\n this._visualizeBoundingBoxesOnImage(base64Image, parsedResponse);\n }\n\n const detectionPromises = parsedResponse.map(async (item) => {\n const {ymin, xmin, ymax, xmax, objectName, ...additionalData} =\n item || {};\n if ([ymin, xmin, ymax, xmax].some(coord => typeof coord !== 'number')) {\n return null;\n }\n\n // Bounding box from AI is 0-1000, convert to normalized 0-1.\n const boundingBox = new THREE.Box2(\n new THREE.Vector2(xmin / 1000, ymin / 1000),\n new THREE.Vector2(xmax / 1000, ymax / 1000));\n\n const center = new THREE.Vector2();\n boundingBox.getCenter(center);\n\n const uvInput = {u: center.x, v: center.y};\n const projectionMatrix = this.deviceCamera.simulatorCamera ?\n this.camera.projectionMatrix :\n new THREE.Matrix4().fromArray(this.depth.view[0].projectionMatrix);\n const worldPosition = transformRgbUvToWorld(\n uvInput, cachedDepthArray, projectionMatrix, cachedMatrixWorld,\n this.deviceCamera, this.depth);\n\n if (worldPosition) {\n const margin = this.options.objects.objectImageMargin;\n\n // Create a new bounding box for cropping that includes the margin.\n const cropBox = boundingBox.clone();\n cropBox.min.subScalar(margin);\n cropBox.max.addScalar(margin);\n const objectImage = await cropImage(base64Image, cropBox);\n\n const object = new DetectedObject(\n objectName, objectImage, boundingBox, additionalData);\n object.position.copy(worldPosition);\n\n this.add(object);\n this._detectedObjects.set(object.uuid, object);\n\n if (this._debugVisualsGroup) {\n this._createDebugVisual(object);\n }\n return object;\n }\n });\n\n const detectedObjects =\n (await Promise.all(detectionPromises)).filter(Boolean);\n return detectedObjects;\n\n } catch (error) {\n console.error('AI query for object detection failed:', error);\n return [];\n } finally {\n // Restore the original config after the query.\n this.aiOptions.gemini.config = originalGeminiConfig;\n }\n }\n\n /**\n * Retrieves a list of currently detected objects.\n *\n * @param label - The semantic label to filter by (e.g., 'chair'). If null,\n * all objects are returned.\n * @returns An array of `Object` instances.\n */\n get(label = null) {\n const allObjects = Array.from(this._detectedObjects.values());\n if (!label) {\n return allObjects;\n }\n return allObjects.filter(obj => obj.label === label);\n }\n\n /**\n * Removes all currently detected objects from the scene and internal\n * tracking.\n */\n clear() {\n for (const obj of this._detectedObjects.values()) {\n this.remove(obj);\n }\n this._detectedObjects.clear();\n if (this._debugVisualsGroup) {\n this._debugVisualsGroup.clear();\n }\n return this;\n }\n\n /**\n * Toggles the visibility of all debug visualizations for detected objects.\n * @param visible - Whether the visualizations should be visible.\n */\n showDebugVisualizations(visible = true) {\n if (this._debugVisualsGroup) {\n this._debugVisualsGroup.visible = visible;\n }\n }\n\n /**\n * Draws the detected bounding boxes on the input image and triggers a\n * download for debugging.\n * @param base64Image - The base64 encoded input image.\n * @param detections - The array of detected objects from the\n * AI response.\n */\n private _visualizeBoundingBoxesOnImage(\n base64Image: string, detections: object[]) {\n const img = new Image();\n img.onload = () => {\n const canvas = document.createElement('canvas');\n canvas.width = img.naturalWidth;\n canvas.height = img.naturalHeight;\n const ctx = canvas.getContext('2d')!;\n\n ctx.drawImage(img, 0, 0);\n\n detections.forEach((item) => {\n const {ymin, xmin, ymax, xmax, objectName} = (item || {}) as {\n ymin?: number,\n xmin?: number,\n ymax?: number,\n xmax?: number,\n objectName?: string,\n };\n if ([ymin, xmin, ymax, xmax].some(\n (coord) => typeof coord !== 'number')) {\n return;\n }\n\n // Bounding box from AI is 0-1000, scale it to image dimensions.\n const rectX = xmin! / 1000 * canvas.width;\n const rectY = ymin! / 1000 * canvas.height;\n const rectWidth = (xmax! - xmin!) / 1000 * canvas.width;\n const rectHeight = (ymax! - ymin!) / 1000 * canvas.height;\n\n ctx.strokeStyle = '#FF0000';\n ctx.lineWidth = Math.max(2, canvas.width / 400);\n ctx.strokeRect(rectX, rectY, rectWidth, rectHeight);\n\n // Draw label.\n const text = objectName || 'unknown';\n const fontSize = Math.max(16, canvas.width / 80);\n ctx.font = `bold ${fontSize}px sans-serif`;\n ctx.textBaseline = 'bottom';\n const textMetrics = ctx.measureText(text);\n\n // Draw a background for the text for better readability.\n ctx.fillStyle = 'rgba(0, 0, 0, 0.6)';\n ctx.fillRect(\n rectX, rectY - fontSize, textMetrics.width + 8, fontSize + 4);\n\n // Draw the text itself.\n ctx.fillStyle = '#FFFFFF'; // White text\n ctx.fillText(text, rectX + 4, rectY + 2);\n });\n\n // Create a link and trigger the download.\n const timestamp =\n new Date().toISOString().slice(0, 19).replace('T', '_').replace(\n /:/g, '-');\n const link = document.createElement('a');\n link.download = `detection_debug_${timestamp}.png`;\n link.href = canvas.toDataURL('image/png');\n link.click();\n };\n img.src = base64Image;\n }\n\n /**\n * Creates a simple debug visualization for an object based on its position\n * (center of its 2D detection bounding box).\n * @param object - The detected object to visualize.\n */\n private async _createDebugVisual(object: DetectedObject) {\n // Create sphere.\n const sphere = new THREE.Mesh(\n new THREE.SphereGeometry(0.03, 16, 16),\n new THREE.MeshBasicMaterial({color: 0xff4285F4}));\n sphere.position.copy(object.position);\n\n // Create and configure the text label using Troika.\n const {Text} = await import('troika-three-text');\n const textLabel = new Text();\n textLabel.text = object.label;\n textLabel.fontSize = 0.07;\n textLabel.color = 0xffffff;\n textLabel.anchorX = 'center';\n textLabel.anchorY = 'bottom';\n\n // Position the label above the sphere\n textLabel.position.copy(sphere.position);\n textLabel.position.y += 0.04; // Offset above the sphere.\n\n this._debugVisualsGroup!.add(sphere, textLabel);\n textLabel.sync(); // Required for Troika text to appear.\n }\n\n /**\n * Builds the Gemini configuration object from the world options.\n */\n private _buildGeminiConfig() {\n const geminiOptions = this.options.objects.backendConfig.gemini;\n return {\n thinkingConfig: {\n thinkingBudget: 0,\n },\n responseMimeType: 'application/json',\n responseSchema: geminiOptions.responseSchema,\n systemInstruction: [{text: geminiOptions.systemInstruction}],\n };\n }\n}\n","import * as THREE from 'three';\n\n/**\n * Represents a single detected plane in the XR environment. It's a THREE.Mesh\n * that also holds metadata about the plane's properties.\n * Note: This requires experimental flag for Chrome.\n */\nexport class DetectedPlane extends THREE.Mesh {\n /**\n * The underlying XRPlane object from the WebXR API.\n * @see https://immersive-web.github.io/real-world-geometry/plane-detection.html#xrplane\n */\n xrPlane: XRPlane;\n\n /**\n * A semantic label for the plane (e.g., 'floor', 'wall', 'ceiling', 'table').\n * Since xrPlane.semanticLabel is readonly, this allows user authoring.\n */\n label: string;\n\n /**\n * The orientation of the plane ('Horizontal' or 'Vertical').\n */\n orientation: XRPlaneOrientation;\n\n /**\n * @param xrPlane - The plane object from the WebXR API.\n * @param material - The material for the mesh.\n */\n constructor(xrPlane: XRPlane, material: THREE.Material) {\n // Create geometry from the plane's polygon points.\n const planePolygon = xrPlane.polygon;\n const vertices = [];\n for (const point of planePolygon) {\n vertices.push(new THREE.Vector2(point.x, point.z));\n }\n const shape = new THREE.Shape(vertices);\n const geometry = new THREE.ShapeGeometry(shape);\n\n // ShapeGeometry creates a mesh in the XY plane by default.\n // We must rotate it to lie flat in the XZ plane to correctly represent\n // horizontal surfaces before applying the world pose provided by the API.\n geometry.rotateX(Math.PI / 2);\n\n super(geometry, material);\n\n this.xrPlane = xrPlane;\n this.label = xrPlane.semanticLabel || 'unknown';\n this.orientation = xrPlane.orientation;\n }\n};\n","import * as THREE from 'three';\n\nimport {Script} from '../../core/Script';\nimport {WorldOptions} from '../WorldOptions';\n\nimport {DetectedPlane} from './DetectedPlane';\n\n/**\n * Detects and manages real-world planes provided by the WebXR Plane Detection\n * API. It creates, updates, and removes `Plane` mesh objects in the scene.\n */\nexport class PlaneDetector extends Script {\n static dependencies = {options: WorldOptions, renderer: THREE.WebGLRenderer};\n\n /**\n * A map from the WebXR `XRPlane` object to our custom `DetectedPlane` mesh.\n */\n private _detectedPlanes = new Map<XRPlane, DetectedPlane>();\n\n /**\n * The material used for visualizing planes when debugging.\n */\n private _debugMaterial!: THREE.Material;\n\n /**\n * The reference space used for poses.\n */\n private _xrRefSpace?: XRReferenceSpace;\n private renderer!: THREE.WebGLRenderer;\n\n /**\n * Initializes the PlaneDetector.\n */\n override init({options, renderer}:\n {options: WorldOptions, renderer: THREE.WebGLRenderer}) {\n this.renderer = renderer;\n if (options.planes.showDebugVisualizations) {\n this._debugMaterial = new THREE.MeshBasicMaterial(\n {color: 0xffff00, wireframe: true, side: THREE.DoubleSide});\n }\n }\n\n /**\n * Processes the XRFrame to update plane information.\n */\n override update(_: number, frame: XRFrame) {\n if (!frame || !frame.detectedPlanes) return;\n\n this._xrRefSpace =\n this._xrRefSpace || this.renderer.xr.getReferenceSpace() || undefined;\n\n if (!this._xrRefSpace) return;\n\n const detectedPlanesInFrame = frame.detectedPlanes;\n const planesToRemove = new Set(this._detectedPlanes.keys());\n\n for (const xrPlane of detectedPlanesInFrame) {\n planesToRemove.delete(xrPlane); // This plane is still active.\n\n const existingPlaneMesh = this._detectedPlanes.get(xrPlane);\n\n if (existingPlaneMesh) {\n // Plane already exists, check if it needs an update.\n if (xrPlane.lastChangedTime >\n (existingPlaneMesh.xrPlane.lastChangedTime || 0)) {\n this._updatePlaneMesh(frame, existingPlaneMesh, xrPlane);\n }\n } else {\n // This is a newly detected plane.\n this._addPlaneMesh(frame, xrPlane);\n }\n }\n\n // Remove planes that are no longer detected.\n for (const xrPlane of planesToRemove) {\n this._removePlaneMesh(xrPlane);\n }\n }\n\n /**\n * Creates and adds a new `Plane` mesh to the scene.\n * @param frame - WebXR frame.\n * @param xrPlane - The new WebXR plane object.\n */\n private _addPlaneMesh(frame: XRFrame, xrPlane: XRPlane) {\n const material =\n this._debugMaterial || new THREE.MeshBasicMaterial({visible: false});\n const planeMesh = new DetectedPlane(xrPlane, material);\n\n this._updatePlanePose(frame, planeMesh, xrPlane);\n\n this._detectedPlanes.set(xrPlane, planeMesh);\n this.add(planeMesh);\n }\n\n /**\n * Updates an existing `DetectedPlane` mesh's geometry and pose.\n * @param frame - WebXR frame.\n * @param planeMesh - The mesh to update.\n * @param xrPlane - The updated plane data.\n */\n private _updatePlaneMesh(\n frame: XRFrame, planeMesh: DetectedPlane, xrPlane: XRPlane) {\n // Recreate geometry from the new polygon.\n const newVertices = xrPlane.polygon.map(p => new THREE.Vector2(p.x, p.z));\n const newShape = new THREE.Shape(newVertices);\n const newGeometry = new THREE.ShapeGeometry(newShape);\n\n planeMesh.geometry.dispose();\n planeMesh.geometry = newGeometry;\n planeMesh.xrPlane = xrPlane; // Update the reference.\n\n this._updatePlanePose(frame, planeMesh, xrPlane);\n }\n\n /**\n * Removes a `Plane` mesh from the scene and disposes of its resources.\n * @param xrPlane - The WebXR plane object to remove.\n */\n private _removePlaneMesh(xrPlane: XRPlane) {\n const planeMesh = this._detectedPlanes.get(xrPlane);\n if (planeMesh) {\n planeMesh.geometry.dispose();\n this.remove(planeMesh);\n this._detectedPlanes.delete(xrPlane);\n }\n }\n\n /**\n * Updates the position and orientation of a `DetectedPlane` mesh from its XR\n * pose.\n * @param frame - The current XRFrame.\n * @param planeMesh - The mesh to update.\n * @param xrPlane - The plane data with the pose.\n */\n private _updatePlanePose(\n frame: XRFrame, planeMesh: DetectedPlane, xrPlane: XRPlane) {\n const pose = frame.getPose(xrPlane.planeSpace, this._xrRefSpace!);\n if (pose) {\n planeMesh.position.copy(pose.transform.position);\n planeMesh.quaternion.copy(pose.transform.orientation);\n }\n }\n\n /**\n * Retrieves a list of detected planes, optionally filtered by a semantic\n * label.\n *\n * @param label - The semantic label to filter by (e.g.,\n * 'floor', 'wall').\n * If null or undefined, all detected planes are returned.\n * @returns An array of `DetectedPlane` objects\n * matching the criteria.\n */\n get(label?: string) {\n const allPlanes = Array.from(this._detectedPlanes.values());\n if (!label) {\n return allPlanes;\n }\n return allPlanes.filter(plane => plane.label === label);\n }\n\n /**\n * Toggles the visibility of the debug meshes for all planes.\n * Requires `showDebugVisualizations` to be true in the options.\n * @param visible - Whether to show or hide the planes.\n */\n showDebugVisualizations(visible = true) {\n if (this._debugMaterial) {\n this.visible = visible;\n }\n }\n}\n","import * as THREE from 'three';\n\nimport {Script} from '../core/Script';\nimport {placeObjectAtIntersectionFacingTarget} from '../utils/ObjectPlacement';\n\nimport {ObjectDetector} from './objects/ObjectDetector';\nimport {PlaneDetector} from './planes/PlaneDetector';\nimport {WorldOptions} from './WorldOptions';\n// Import other modules as they are implemented in future.\n// import { SceneMesh } from '/depth/SceneMesh.js';\n// import { LightEstimation } from '/lighting/LightEstimation.js';\n// import { HumanRecognizer } from '/human/HumanRecognizer.js';\n\n/**\n * Manages all interactions with the real-world environment perceived by the XR\n * device. This class abstracts the complexity of various perception APIs\n * (Depth, Planes, Meshes, etc.) and provides a simple, event-driven interface\n * for developers to use `this.world.depth.mesh`, `this.world.planes`.\n */\nexport class World extends Script {\n static dependencies = {\n options: WorldOptions,\n camera: THREE.Camera,\n };\n\n /**\n * Configuration options for all world-sensing features.\n */\n options!: WorldOptions;\n\n /**\n * The depth module instance. Null if not enabled.\n */\n // depth = null;\n\n /**\n * The light estimation module instance. Null if not enabled.\n */\n // lighting = null;\n\n /**\n * The plane detection module instance. Null if not enabled.\n * Not recommended for anchoring.\n */\n planes?: PlaneDetector;\n\n /**\n * The scene mesh module instance. Null if not enabled.\n * TODO: Not yet supported in Chrome.\n */\n // meshes = null;\n\n /**\n * The object recognition module instance. Null if not enabled.\n */\n objects?: ObjectDetector;\n\n /**\n * A Three.js Raycaster for performing intersection tests.\n */\n private raycaster = new THREE.Raycaster();\n\n private camera!: THREE.Camera;\n\n /**\n * Initializes the world-sensing modules based on the provided configuration.\n * This method is called automatically by the XRCore.\n */\n override async init({options, camera}:\n {options: WorldOptions, camera: THREE.Camera}) {\n this.options = options;\n this.camera = camera;\n\n if (!this.options || !this.options.enabled) {\n return;\n }\n\n // Conditionally initialize each perception module based on options.\n if (this.options.planes.enabled) {\n this.planes = new PlaneDetector();\n this.add(this.planes);\n }\n\n if (this.options.objects.enabled) {\n this.objects = new ObjectDetector();\n this.add(this.objects);\n }\n\n\n // TODO: Initialize other modules as they are available & implemented.\n /*\n if (this.options.sceneMesh.enabled) {\n this.meshes = new SceneMesh();\n }\n\n if (this.options.lighting.enabled) {\n this.lighting = new LightEstimation();\n }\n\n if (this.options.humans.enabled) {\n this.humans = new HumanRecognizer();\n }\n */\n }\n\n /**\n * Places an object at the reticle.\n */\n anchorObjectAtReticle(_object: THREE.Object3D, _reticle: THREE.Object3D) {\n throw new Error('Method not implemented');\n }\n\n /**\n * Updates all active world-sensing modules with the latest XRFrame data.\n * This method is called automatically by the XRCore on each frame.\n * @param _timestamp - The timestamp for the current frame.\n * @param frame - The current XRFrame, containing environmental\n * data.\n * @override\n */\n update(_timestamp: number, frame?: XRFrame) {\n if (!this.options?.enabled || !frame) {\n return;\n }\n\n // Note: Object detection is not run per-frame by default as it's a\n // costly operation. It should be triggered manually via\n // `this.world.objects.runDetection()`.\n\n // TODO: Update other modules as they are available & implemented.\n // this.meshes?.update(frame);\n // this.lighting?.update(frame);\n // this.humans?.update(frame);\n }\n\n /**\n * Performs a raycast from a controller against detected real-world surfaces\n * (currently planes) and places a 3D object at the intersection point,\n * oriented to face the user.\n *\n * We recommend using /templates/3_depth/ to anchor objects based on\n * depth mesh for mixed reality experience for accuracy. This function is\n * design for demonstration purposes.\n *\n * @param objectToPlace - The object to position in the\n * world.\n * @param controller - The controller to use for raycasting.\n * @returns True if the object was successfully placed, false\n * otherwise.\n */\n placeOnSurface(objectToPlace: THREE.Object3D, controller: THREE.Object3D) {\n if (!this.planes) {\n console.warn('Cannot placeOnSurface: PlaneDetector is not enabled.');\n return false;\n }\n\n const allPlanes = this.planes.get();\n if (allPlanes.length === 0) {\n return false; // No surfaces to cast against.\n }\n\n this.raycaster.setFromXRController(controller as THREE.XRTargetRaySpace);\n\n const intersections = this.raycaster.intersectObjects(allPlanes);\n\n if (intersections.length > 0) {\n const intersection = intersections[0];\n placeObjectAtIntersectionFacingTarget(\n objectToPlace, intersection, this.camera);\n return true;\n }\n\n return false;\n }\n\n /**\n * Toggles the visibility of all debug visualizations for world features.\n * @param visible - Whether the visualizations should be visible.\n */\n showDebugVisualizations(visible = true) {\n this.planes?.showDebugVisualizations(visible);\n this.objects?.showDebugVisualizations(visible);\n // this.meshes?.showDebugVisualizations(visible);\n }\n}\n","import * as THREE from 'three';\n\nimport {Options} from '../Options';\nimport {MeshScript} from '../Script';\n\n/**\n * Defines the possible XR modes.\n */\nexport type XRMode = 'AR'|'VR';\n\nexport type XRTransitionToVROptions = {\n /** The target opacity. */\n targetAlpha?: number;\n /** The target color. Defaults to `defaultBackgroundColor`. */\n color?: THREE.Color | number;\n}\n\n/**\n * Manages smooth transitions between AR (transparent) and VR (colored)\n * backgrounds within an active XR session.\n */\nexport class XRTransition extends\n MeshScript<THREE.SphereGeometry, THREE.MeshBasicMaterial> {\n ignoreReticleRaycast = true;\n static dependencies = {\n renderer: THREE.WebGLRenderer,\n camera: THREE.Camera,\n timer: THREE.Timer,\n scene: THREE.Scene,\n options: Options,\n };\n\n /** Current XR mode, either 'AR' or 'VR'. Defaults to 'AR'. */\n public currentMode: XRMode = 'AR';\n\n /** The duration in seconds for the fade-in and fade-out transitions. */\n private transitionTime = 1.5;\n private renderer!: THREE.WebGLRenderer;\n private scene!: THREE.Scene;\n private sceneCamera!: THREE.Camera;\n private timer!: THREE.Timer;\n private targetAlpha = 0;\n private defaultBackgroundColor = new THREE.Color(0xffffff);\n\n constructor() {\n const geometry = new THREE.SphereGeometry(1, 64, 32);\n const material = new THREE.MeshBasicMaterial({\n color: 0xffffff,\n transparent: true,\n opacity: 0,\n depthTest: false,\n side: THREE.BackSide, // Render on the inside of the sphere.\n });\n super(geometry, material);\n this.ignoreReticleRaycast = true;\n this.renderOrder = -Infinity;\n }\n\n init({renderer, camera, timer, scene, options}: {\n renderer: THREE.WebGLRenderer,\n camera: THREE.Camera,\n timer: THREE.Timer,\n scene: THREE.Scene,\n options: Options\n }) {\n this.renderer = renderer;\n this.sceneCamera = camera;\n this.timer = timer;\n this.scene = scene;\n this.transitionTime = options.transition.transitionTime;\n this.defaultBackgroundColor.set(options.transition.defaultBackgroundColor);\n this.material.color.copy(this.defaultBackgroundColor);\n this.scene.add(this);\n }\n\n /**\n * Starts the transition to a VR background.\n * @param options - Optional parameters.\n */\n toVR({targetAlpha = 1.0, color}: XRTransitionToVROptions = {}) {\n this.targetAlpha = THREE.MathUtils.clamp(targetAlpha, 0, 1);\n this.material.color.set(color ?? this.defaultBackgroundColor);\n this.currentMode = 'VR';\n }\n\n /**\n * Starts the transition to a transparent AR background.\n */\n toAR() {\n this.targetAlpha = 0.0;\n this.currentMode = 'AR';\n }\n\n update() {\n // Always keep the fade mesh centered on the active camera.\n if (this.renderer.xr.isPresenting) {\n this.renderer.xr.getCamera().getWorldPosition(this.position);\n } else {\n this.sceneCamera.getWorldPosition(this.position);\n }\n\n const currentOpacity = this.material.opacity;\n if (currentOpacity !== this.targetAlpha) {\n const lerpFactor = this.timer.getDelta() / this.transitionTime;\n this.material.opacity =\n THREE.MathUtils.lerp(currentOpacity, this.targetAlpha, lerpFactor);\n if (Math.abs(this.material.opacity - this.targetAlpha) < 0.01) {\n this.material.opacity = this.targetAlpha;\n }\n }\n }\n\n dispose() {\n if (this.parent) {\n this.parent.remove(this);\n }\n this.material.dispose();\n this.geometry.dispose();\n }\n}\n","import * as THREE from 'three';\n\nimport {AI} from '../ai/AI';\nimport {AIOptions} from '../ai/AIOptions';\nimport {XRDeviceCamera} from '../camera/XRDeviceCamera';\nimport {UI_OVERLAY_LAYER} from '../constants';\nimport {Depth} from '../depth/Depth';\nimport {DepthOptions} from '../depth/DepthOptions';\nimport {Hands} from '../input/Hands';\nimport {Input} from '../input/Input';\nimport {Lighting} from '../lighting/Lighting';\nimport {Physics} from '../physics/Physics';\nimport {Simulator} from '../simulator/Simulator';\nimport {SimulatorOptions} from '../simulator/SimulatorOptions';\nimport {CoreSound} from '../sound/CoreSound';\nimport {SoundOptions} from '../sound/SoundOptions';\nimport {UI} from '../ui/UI';\nimport {onDesktopUserAgent} from '../utils/BrowserUtils';\nimport {callInitWithDependencyInjection} from '../utils/DependencyInjection';\nimport {loadingSpinnerManager} from '../utils/LoadingSpinnerManager';\nimport {traverseUtil} from '../utils/SceneGraphUtils';\nimport {DragManager} from '../ux/DragManager';\nimport {World} from '../world/World';\nimport {WorldOptions} from '../world/WorldOptions';\n\nimport {Registry} from './components/Registry';\nimport {ScreenshotSynthesizer} from './components/ScreenshotSynthesizer';\nimport {ScriptsManager} from './components/ScriptsManager';\nimport {WaitFrame} from './components/WaitFrame';\nimport {IMMERSIVE_AR, WebXRSessionEventType, WebXRSessionManager} from './components/WebXRSessionManager';\nimport {XRButton} from './components/XRButton';\nimport {XREffects} from './components/XREffects';\nimport {XRTransition} from './components/XRTransition';\nimport {Options} from './Options';\nimport {Script} from './Script';\nimport {User} from './User';\n\n/**\n * Core is the central engine of the XR Blocks framework, acting as a\n * singleton manager for all XR subsystems. Its primary goal is to abstract\n * low-level WebXR and THREE.js details, providing a simplified and powerful API\n * for developers and AI agents to build interactive XR applications.\n */\nexport class Core {\n static instance?: Core;\n /**\n * Component responsible for capturing screenshots of the XR scene for AI.\n */\n screenshotSynthesizer = new ScreenshotSynthesizer();\n /**\n * Component responsible for waiting for the next frame.\n */\n waitFrame = new WaitFrame();\n /**\n * Registry used for dependency injection on existing subsystems.\n */\n registry = new Registry();\n\n /**\n * A clock for tracking time deltas. Call clock.getDeltaTime().\n */\n timer = new THREE.Timer();\n\n /** Manages hand, mouse, gaze inputs. */\n input = new Input();\n\n /** The main camera for rendering. */\n camera!: THREE.PerspectiveCamera;\n\n /** The root scene graph for all objects. */\n scene = new THREE.Scene();\n\n /** Represents the user in the XR scene. */\n user = new User();\n\n /** Manages all UI elements. */\n ui = new UI();\n\n /** Manages all (spatial) audio playback. */\n sound = new CoreSound();\n\n private renderSceneBound = this.renderScene.bind(this);\n\n /** Manages the desktop XR simulator. */\n simulator = new Simulator(this.renderSceneBound);\n\n /** Manages drag-and-drop interactions. */\n dragManager = new DragManager();\n\n /** Manages drag-and-drop interactions. */\n world = new World();\n\n /** A shared texture loader. */\n textureLoader = new THREE.TextureLoader();\n\n private webXRSettings: XRSessionInit = {};\n\n /** Whether the XR simulator is currently active. */\n simulatorRunning = false;\n\n renderer!: THREE.WebGLRenderer;\n options!: Options;\n deviceCamera?: XRDeviceCamera;\n depth = new Depth();\n lighting?: Lighting;\n physics?: Physics;\n xrButton?: XRButton;\n effects?: XREffects;\n ai = new AI();\n transition?: XRTransition;\n currentFrame?: XRFrame;\n scriptsManager = new ScriptsManager(async (script: Script) => {\n await callInitWithDependencyInjection(script, this.registry, this);\n if (this.physics) {\n await script.initPhysics(this.physics);\n }\n });\n renderSceneOverride?:\n (renderer: THREE.WebGLRenderer, scene: THREE.Scene,\n camera: THREE.Camera) => void;\n webXRSessionManager?: WebXRSessionManager;\n\n /**\n * Core is a singleton manager that manages all XR \"blocks\".\n * It initializes core components and abstractions like the scene, camera,\n * user, UI, AI, and input managers.\n */\n constructor() {\n if (Core.instance) {\n return Core.instance;\n }\n Core.instance = this;\n\n this.scene.name = 'XR Blocks Scene';\n\n // Separate calls because spark hijacks THREE.Scene.add and only supports\n // adding objects one at a time. See\n // https://github.com/sparkjsdev/spark/blob/0edfc8d9232b8f6eb036d27af57dc40daf94e1f3/src/SparkRenderer.ts#L63\n this.scene.add(this.user);\n this.scene.add(this.dragManager);\n this.scene.add(this.ui);\n this.scene.add(this.sound);\n this.scene.add(this.world);\n\n this.registry.register(this.registry);\n this.registry.register(this.waitFrame);\n this.registry.register(this.scene);\n this.registry.register(this.timer);\n this.registry.register(this.input);\n this.registry.register(this.user);\n this.registry.register(this.ui);\n this.registry.register(this.sound);\n this.registry.register(this.dragManager);\n this.registry.register(this.user);\n this.registry.register(this.simulator);\n this.registry.register(this.scriptsManager);\n this.registry.register(this.depth);\n }\n\n /**\n * Initializes the Core system with a given set of options. This includes\n * setting up the renderer, enabling features like controllers, depth\n * sensing, and physics, and starting the render loop.\n * @param options - Configuration options for the\n * session.\n */\n async init(options = new Options()) {\n loadingSpinnerManager.showSpinner();\n\n this.registry.register(options, Options);\n this.registry.register(options.depth, DepthOptions);\n this.registry.register(options.simulator, SimulatorOptions);\n this.registry.register(options.world, WorldOptions);\n this.registry.register(options.ai, AIOptions);\n this.registry.register(options.sound, SoundOptions);\n\n if (options.transition.enabled) {\n this.transition = new XRTransition();\n this.user.add(this.transition);\n this.registry.register(this.transition);\n }\n\n this.camera = new THREE.PerspectiveCamera(\n /*fov=*/ 90, window.innerWidth / window.innerHeight,\n /*near=*/ options.camera.near, /*far=*/ options.camera.far);\n this.registry.register(this.camera, THREE.Camera);\n this.registry.register(this.camera, THREE.PerspectiveCamera);\n this.renderer = new THREE.WebGLRenderer({\n canvas: options.canvas,\n antialias: options.antialias,\n stencil: options.stencil,\n alpha: true,\n logarithmicDepthBuffer: options.logarithmicDepthBuffer\n });\n this.renderer.setPixelRatio(window.devicePixelRatio);\n this.renderer.setSize(window.innerWidth, window.innerHeight);\n this.renderer.xr.enabled = true;\n // disable built-in occlusion\n this.renderer.xr.getDepthSensingMesh = function(){ return null; }\n this.registry.register(this.renderer);\n\n this.renderer.xr.setReferenceSpaceType(options.referenceSpaceType);\n\n if (!options.canvas) {\n const xrContainer = document.createElement('div');\n document.body.appendChild(xrContainer);\n xrContainer.appendChild(this.renderer.domElement);\n }\n\n this.options = options;\n\n // Sets up controllers.\n if (options.controllers.enabled) {\n this.input.init(\n {scene: this.scene, options: options, renderer: this.renderer});\n this.input.bindSelectStart(this.scriptsManager.callSelectStartBound);\n this.input.bindSelectEnd(this.scriptsManager.callSelectEndBound);\n this.input.bindSelect(this.scriptsManager.callSelectBound);\n this.input.bindSqueezeStart(this.scriptsManager.callSqueezeStartBound);\n this.input.bindSqueezeEnd(this.scriptsManager.callSqueezeEndBound);\n this.input.bindSqueeze(this.scriptsManager.callSqueezeBound);\n this.input.bindKeyDown(this.scriptsManager.callKeyDownBound);\n this.input.bindKeyUp(this.scriptsManager.callKeyUpBound);\n }\n\n // Sets up device camera.\n if (options.deviceCamera?.enabled) {\n this.deviceCamera = new XRDeviceCamera(options.deviceCamera);\n this.registry.register(this.deviceCamera);\n }\n\n const webXRRequiredFeatures: string[] = options.webxrRequiredFeatures;\n this.webXRSettings.requiredFeatures = webXRRequiredFeatures;\n // Sets up depth.\n if (options.depth.enabled) {\n webXRRequiredFeatures.push('depth-sensing');\n webXRRequiredFeatures.push('local-floor');\n this.webXRSettings.depthSensing = {\n usagePreference: [],\n dataFormatPreference:\n [this.options.depth.useFloat32 ? 'float32' : 'luminance-alpha'],\n };\n this.depth.init(\n this.camera, options.depth, this.renderer, this.registry, this.scene);\n }\n if (options.hands.enabled) {\n webXRRequiredFeatures.push('hand-tracking');\n this.user.hands = new Hands(this.input.hands);\n }\n if (options.world.planes.enabled) {\n webXRRequiredFeatures.push('plane-detection');\n }\n\n // Sets up lighting.\n if (options.lighting.enabled) {\n webXRRequiredFeatures.push('light-estimation');\n this.lighting = new Lighting();\n this.lighting.init(\n options.lighting, this.renderer, this.scene, this.depth);\n }\n\n // Sets up physics.\n if (options.physics && options.physics.RAPIER) {\n this.physics = new Physics();\n this.registry.register(this.physics);\n await this.physics.init({physicsOptions: options.physics});\n\n if (options.depth.enabled) {\n this.depth.depthMesh?.initRapierPhysics(\n this.physics.RAPIER, this.physics.blendedWorld);\n }\n }\n\n this.webXRSessionManager = new WebXRSessionManager(\n this.renderer,\n this.webXRSettings,\n IMMERSIVE_AR,\n );\n this.webXRSessionManager.addEventListener(\n WebXRSessionEventType.SESSION_START,\n (event) => this.onXRSessionStarted(event.session),\n );\n this.webXRSessionManager.addEventListener(\n WebXRSessionEventType.SESSION_END,\n this.onXRSessionEnded.bind(this),\n );\n\n // Sets up xrButton.\n const shouldAutostartSimulator = this.options.xrButton.autostartSimulator ||\n this.options.xrButton.autostartSimulatorOnDesktop &&\n this.options.xrButton.enableSimulator && onDesktopUserAgent();\n if (!shouldAutostartSimulator && options.xrButton.enabled) {\n this.xrButton = new XRButton(\n this.webXRSessionManager,\n options.xrButton?.startText,\n options.xrButton?.endText,\n options.xrButton?.invalidText,\n options.xrButton?.startSimulatorText,\n options.xrButton?.enableSimulator,\n options.xrButton?.showSimulatorButtonOnMobile,\n this.startSimulator.bind(this),\n );\n document.body.appendChild(this.xrButton.domElement);\n }\n\n await this.webXRSessionManager.initialize();\n\n // Sets up postprocessing effects.\n if (options.usePostprocessing) {\n this.effects = new XREffects(this.renderer, this.scene, this.timer);\n this.simulator.effects = this.effects;\n }\n\n // Sets up AI services.\n if (options.ai.enabled) {\n this.registry.register(this.ai);\n this.scene.add(this.ai);\n // Manually init the script in case other scripts rely on it.\n await this.scriptsManager.initScript(this.ai);\n }\n\n await this.scriptsManager.syncScriptsWithScene(this.scene);\n\n // For desktop only:\n window.addEventListener('resize', this.onWindowResize.bind(this));\n\n this.renderer.setAnimationLoop(this.update.bind(this));\n\n if (this.physics) {\n setInterval(this.physicsStep.bind(this), 1000 * this.physics.timestep);\n }\n\n if (this.options.reticles.enabled) {\n this.input.addReticles();\n }\n\n if (shouldAutostartSimulator) {\n this.startSimulator();\n }\n\n if (!loadingSpinnerManager.isLoading) {\n loadingSpinnerManager.hideSpinner();\n }\n }\n\n /**\n * The main update loop, called every frame by the renderer. It orchestrates\n * all per-frame updates for subsystems and scripts.\n *\n * Order:\n * 1. Depth\n * 2. World Perception\n * 3. Input / Reticles / UIs\n * 4. Scripts\n * @param time - The current time in milliseconds.\n * @param frame - The WebXR frame object, if in an XR session.\n */\n private update(time: number, frame: XRFrame) {\n this.currentFrame = frame;\n this.timer.update(time);\n if (this.simulatorRunning) {\n this.simulator.simulatorUpdate();\n }\n this.depth.update(frame);\n\n if (this.lighting) {\n this.lighting.update();\n }\n\n // Traverse the scene to find all scripts.\n this.scriptsManager.syncScriptsWithScene(this.scene);\n\n // Updates reticles and UIs.\n for (const script of this.scriptsManager.scripts) {\n script.ux.reset();\n }\n this.input.update();\n\n // Updates scripts with user interactions.\n for (const controller of this.input.controllers) {\n if (controller.userData.selected) {\n for (const script of this.scriptsManager.scripts) {\n script.onSelecting({target: controller});\n }\n }\n }\n\n for (const controller of this.input.controllers) {\n if (controller.userData.squeezing) {\n for (const script of this.scriptsManager.scripts) {\n script.onSqueezing({target: controller});\n }\n }\n }\n\n // Run callbacks that use wait frame.\n this.waitFrame.onFrame();\n\n // Updates renderings.\n for (const script of this.scriptsManager.scripts) {\n script.update(time, frame);\n }\n\n this.renderSimulatorAndScene();\n this.screenshotSynthesizer.onAfterRender(\n this.renderer, this.renderSceneBound, this.deviceCamera);\n if (this.simulatorRunning) {\n this.simulator.renderSimulatorScene();\n }\n }\n\n /**\n * Advances the physics simulation by a fixed timestep and calls the\n * corresponding physics update on all active scripts.\n */\n private physicsStep() {\n this.physics!.physicsStep();\n for (const script of this.scriptsManager.scripts) {\n script.physicsStep();\n }\n }\n\n /**\n * Lifecycle callback executed when an XR session starts. Notifies all active\n * scripts.\n * @param session - The newly started WebXR session.\n */\n private async onXRSessionStarted(session: XRSession) {\n if (this.options.deviceCamera?.enabled) {\n await this.deviceCamera!.init();\n }\n this.scriptsManager.onXRSessionStarted(session);\n }\n\n private async startSimulator() {\n this.xrButton?.domElement.remove();\n this.scene.add(this.simulator);\n await this.scriptsManager.initScript(this.simulator);\n this.onSimulatorStarted();\n }\n\n /**\n * Lifecycle callback executed when an XR session ends. Notifies all active\n * scripts.\n */\n private onXRSessionEnded() {\n this.startSimulator();\n this.scriptsManager.onXRSessionEnded();\n }\n\n /**\n * Lifecycle callback executed when the desktop simulator starts. Notifies\n * all active scripts.\n */\n private onSimulatorStarted() {\n this.simulatorRunning = true;\n this.scriptsManager.onSimulatorStarted();\n if (this.lighting) {\n this.lighting.simulatorRunning = true;\n }\n }\n\n /**\n * Handles browser window resize events to keep the camera and renderer\n * synchronized.\n */\n private onWindowResize() {\n this.camera.aspect = window.innerWidth / window.innerHeight;\n this.camera.updateProjectionMatrix();\n this.renderer.setSize(window.innerWidth, window.innerHeight);\n }\n\n private renderSimulatorAndScene() {\n if (this.simulatorRunning) {\n this.simulator.renderScene();\n } else {\n this.renderScene();\n }\n }\n\n private renderScene(cameraOverride?: THREE.Camera) {\n if (this.renderSceneOverride) {\n this.renderSceneOverride(\n this.renderer, this.scene, cameraOverride ?? this.camera);\n } else if (this.effects) {\n this.effects.render();\n } else {\n this.renderer.render(this.scene, cameraOverride ?? this.camera);\n if (traverseUtil(\n this.scene,\n (node: THREE.Object3D) =>\n node.layers.isEnabled(UI_OVERLAY_LAYER))) {\n const originalLayers = this.camera.layers.mask;\n this.camera.layers.set(UI_OVERLAY_LAYER);\n this.renderer.render(this.scene, this.camera);\n this.camera.layers.mask = originalLayers;\n }\n }\n }\n};\n","import * as THREE from 'three';\nimport type {Shader} from '../../utils/Types';\n\nexport class OcclusionUtils {\n /**\n * Creates a simple material used for rendering objects into the occlusion\n * map. This material is intended to be used with `renderer.overrideMaterial`.\n * @returns A new instance of THREE.MeshBasicMaterial.\n */\n static createOcclusionMapOverrideMaterial() {\n return new THREE.MeshBasicMaterial();\n }\n\n /**\n * Modifies a material's shader in-place to incorporate distance-based\n * alpha occlusion. This is designed to be used with a material's\n * `onBeforeCompile` property. This only works with built-in three.js\n * materials.\n * @param shader - The shader object provided by onBeforeCompile.\n */\n static addOcclusionToShader(shader: Shader) {\n shader.uniforms.occlusionEnabled = {value: true};\n shader.uniforms.tOcclusionMap = {value: null};\n shader.uniforms.uOcclusionClipFromWorld = {value: new THREE.Matrix4()};\n shader.defines = {USE_UV: true, DISTANCE: true};\n shader.vertexShader =\n shader.vertexShader\n .replace(\n '#include <common>',\n [\n 'uniform mat4 uOcclusionClipFromWorld;',\n 'varying vec4 vOcclusionScreenCoord;', '#include <common>'\n ].join('\\n'))\n .replace('#include <fog_vertex>', [\n '#include <fog_vertex>',\n 'vOcclusionScreenCoord = uOcclusionClipFromWorld * worldPosition;',\n ].join('\\n'));\n shader.fragmentShader =\n shader.fragmentShader\n .replace(\n 'uniform vec3 diffuse;',\n [\n 'uniform vec3 diffuse;',\n 'uniform bool occlusionEnabled;',\n 'uniform sampler2D tOcclusionMap;',\n 'varying vec4 vOcclusionScreenCoord;',\n ].join('\\n'))\n .replace('vec4 diffuseColor = vec4( diffuse, opacity );', [\n 'vec4 diffuseColor = vec4( diffuse, opacity );',\n 'vec2 occlusion_coordinates = 0.5 + 0.5 * vOcclusionScreenCoord.xy / vOcclusionScreenCoord.w;',\n 'vec2 occlusion_sample = texture2D(tOcclusionMap, occlusion_coordinates.xy).rg;',\n 'occlusion_sample = occlusion_sample / max(0.0001, occlusion_sample.g);',\n 'float occlusion_value = clamp(occlusion_sample.r, 0.0, 1.0);',\n 'diffuseColor.a *= occlusionEnabled ? occlusion_value : 1.0;',\n ].join('\\n'));\n }\n}","import * as THREE from 'three';\n\nimport {UP, ZERO_VECTOR3} from './HelperConstants';\n\n// Reusable instances to avoid creating new objects in the render loop.\nconst euler = new THREE.Euler();\nconst matrix4 = new THREE.Matrix4();\nconst v1 = new THREE.Vector3();\n\n/**\n * Extracts only the yaw (Y-axis rotation) from a quaternion.\n * This is useful for making an object face a certain direction horizontally\n * without tilting up or down.\n *\n * @param rotation - The source quaternion from which to\n * extract the yaw.\n * @param target - The target\n * quaternion to store the result.\n * If not provided, a new quaternion will be created.\n * @returns The resulting quaternion containing only the yaw\n * rotation.\n */\nexport function extractYaw(\n rotation: Readonly<THREE.Quaternion>, target = new THREE.Quaternion()) {\n // Ensures the Y-axis rotation (yaw) is calculated first and is independent of\n // the X (pitch) and Z (roll) rotations. This prevents gimbal lock from\n // affecting the yaw value.\n euler.setFromQuaternion(rotation, 'YXZ');\n\n // Creates a new quaternion from only the yaw component (the rotation around\n // the 'up' vector).\n return target.setFromAxisAngle(UP, euler.y);\n}\n\n/**\n * Creates a rotation such that forward (0, 0, -1) points towards the forward\n * vector and the up direction is the normalized projection of the provided up\n * vector onto the plane orthogonal to the target.\n * @param forward - Forward vector\n * @param up - Up vector\n * @param target - Output\n * @returns\n */\nexport function lookAtRotation(\n forward: Readonly<THREE.Vector3>, up = UP,\n target = new THREE.Quaternion()) {\n matrix4.lookAt(ZERO_VECTOR3, forward, up);\n return target.setFromRotationMatrix(matrix4);\n}\n\n/**\n * Clamps the provided rotation's angle.\n * The rotation is modified in place.\n * @param rotation - The quaternion to clamp.\n * @param angle - The maximum allowed angle in radians.\n */\nexport function clampRotationToAngle(\n rotation: THREE.Quaternion, angle: number) {\n let currentAngle = 2 * Math.acos(rotation.w);\n currentAngle = (currentAngle + Math.PI) % (2 * Math.PI) - Math.PI;\n if (Math.abs(currentAngle) <= angle) {\n return;\n }\n const axis = v1.set(rotation.x, rotation.y, rotation.z)\n .multiplyScalar(1 / Math.sqrt(1 - rotation.w * rotation.w));\n axis.normalize();\n rotation.setFromAxisAngle(axis, angle * Math.sign(currentAngle));\n}\n","import {Injectable} from '../../utils/DependencyInjection';\n\nexport class SimulatorUserAction implements Injectable {\n static dependencies = {};\n async init(_options: object = {}) {}\n async play(_options: object = {}) {}\n}\n","import * as THREE from 'three';\n\nimport {WaitFrame} from '../../core/components/WaitFrame';\nimport {Input} from '../../input/Input';\nimport {UP} from '../../utils/HelperConstants';\nimport {clampRotationToAngle, lookAtRotation} from '../../utils/RotationUtils';\nimport {Simulator} from '../Simulator';\nimport {SimulatorControls} from '../SimulatorControls';\nimport {SimulatorUser} from '../SimulatorUser.js';\n\nimport {SimulatorUserAction} from './SimulatorUserAction';\n\nconst LOOK_AT_ANGLE_THRESHOLD = 3 * Math.PI / 180;\nconst ROTATION_SPEED_RADIANS_PER_SECOND = 1;\n\nconst controllerToTargetVector = new THREE.Vector3();\nconst targetWorldPosition = new THREE.Vector3();\nconst targetPositionRelativeToCamera = new THREE.Vector3();\nconst inverseControllerRotation = new THREE.Quaternion();\nconst finalRotation = new THREE.Quaternion();\nconst deltaRotation = new THREE.Quaternion();\n\nexport class PinchOnButtonAction extends SimulatorUserAction {\n static dependencies = {\n simulator: Simulator,\n camera: THREE.Camera,\n timer: THREE.Timer,\n input: Input,\n };\n private simulator!: Simulator;\n private camera!: THREE.Camera;\n private timer!: THREE.Timer;\n private input!: Input;\n\n constructor(private target: THREE.Object3D) {\n super();\n }\n\n async init({simulator, camera, timer, input}: {\n simulator: Simulator,\n camera: THREE.Camera,\n timer: THREE.Timer,\n input: Input\n }) {\n this.simulator = simulator;\n this.camera = camera;\n this.timer = timer;\n this.input = input\n }\n\n controllerIsPointingAtButton(\n controls: SimulatorControls, camera: THREE.Camera) {\n const controllerState = controls.simulatorControllerState;\n const controllerIndex = controllerState.currentControllerIndex;\n const localControllerPosition =\n controllerState.localControllerPositions[controllerIndex];\n const localControllerRotation =\n controllerState.localControllerOrientations[controllerIndex];\n this.target.getWorldPosition(targetWorldPosition);\n targetPositionRelativeToCamera.copy(targetWorldPosition)\n .applyMatrix4(camera.matrixWorldInverse);\n\n inverseControllerRotation.copy(localControllerRotation).invert();\n controllerToTargetVector.copy(targetPositionRelativeToCamera)\n .sub(localControllerPosition);\n lookAtRotation(controllerToTargetVector, UP, finalRotation);\n const angle = (finalRotation.angleTo(localControllerRotation) + Math.PI) %\n (2 * Math.PI) -\n Math.PI;\n return angle < LOOK_AT_ANGLE_THRESHOLD;\n }\n\n rotateControllerTowardsButton(\n controls: SimulatorControls, camera: THREE.Camera, deltaTime: number) {\n const controllerState = controls.simulatorControllerState;\n const controllerIndex = controllerState.currentControllerIndex;\n const localControllerPosition =\n controllerState.localControllerPositions[controllerIndex];\n const localControllerRotation =\n controllerState.localControllerOrientations[controllerIndex];\n this.target.getWorldPosition(targetWorldPosition);\n targetPositionRelativeToCamera.copy(targetWorldPosition)\n .applyMatrix4(camera.matrixWorldInverse);\n\n inverseControllerRotation.copy(localControllerRotation).invert();\n controllerToTargetVector.copy(targetPositionRelativeToCamera)\n .sub(localControllerPosition);\n lookAtRotation(controllerToTargetVector, UP, finalRotation);\n deltaRotation.copy(finalRotation).multiply(inverseControllerRotation);\n clampRotationToAngle(\n deltaRotation, ROTATION_SPEED_RADIANS_PER_SECOND * deltaTime);\n localControllerRotation.premultiply(deltaRotation);\n }\n\n pinchController() {\n const simulator = this.simulator;\n const controllerState = simulator.controls.simulatorControllerState;\n const newSelectingState = true;\n this.input.dispatchEvent({\n type: newSelectingState ? 'selectstart' : 'selectend',\n target: this.input.controllers[controllerState.currentControllerIndex]\n });\n if (controllerState.currentControllerIndex == 0) {\n simulator.hands.setLeftHandPinching(newSelectingState);\n } else {\n simulator.hands.setRightHandPinching(newSelectingState);\n }\n }\n\n async play({simulatorUser, journeyId, waitFrame}: {\n simulatorUser: SimulatorUser,\n journeyId: number,\n waitFrame: WaitFrame\n }) {\n let pinchedOnButton = false;\n\n while (simulatorUser.isOnJourneyId(journeyId) && (!pinchedOnButton)) {\n const deltaTime = this.timer.getDelta();\n if (!this.controllerIsPointingAtButton(\n this.simulator.controls, this.camera)) {\n this.rotateControllerTowardsButton(\n this.simulator.controls, this.camera, deltaTime);\n } else {\n this.pinchController();\n pinchedOnButton = true;\n }\n await waitFrame.waitFrame();\n }\n }\n}\n","import {Simulator} from '../Simulator';\n\nimport {SimulatorUserAction} from './SimulatorUserAction';\n\nexport class ShowHandsAction extends SimulatorUserAction {\n static dependencies = {simulator: Simulator};\n simulator!: Simulator;\n\n async init({simulator}: {simulator: Simulator}) {\n this.simulator = simulator;\n }\n\n async play() {\n if (this.simulator.hands) {\n this.simulator.hands.showHands();\n }\n }\n}\n","import * as THREE from 'three';\n\nimport {WaitFrame} from '../../core/components/WaitFrame';\nimport {UP} from '../../utils/HelperConstants';\nimport {clampRotationToAngle, lookAtRotation} from '../../utils/RotationUtils';\nimport {clamp} from '../../utils/utils';\nimport {SimulatorUser} from '../SimulatorUser';\n\nimport {SimulatorUserAction} from './SimulatorUserAction';\n\nconst NEAR_TARGET_DISTANCE = 0.5;\nconst NEAR_TARGET_THRESHOLD = 0.1;\nconst LOOK_AT_ANGLE_THRESHOLD = 3 * Math.PI / 180;\nconst MOVEMENT_SPEED_METERS_PER_SECOND = 1;\nconst ROTATION_SPEED_RADIANS_PER_SECOND = 1;\n\n// Temporary variables.\nconst targetWorldPosition = new THREE.Vector3();\nconst cameraToTargetVector = new THREE.Vector3();\n// A position close to the target to move to.\nconst closeToTargetPosition = new THREE.Vector3();\nconst deltaRotation = new THREE.Quaternion();\nconst finalRotation = new THREE.Quaternion();\nconst inverseCameraRotation = new THREE.Quaternion();\n\n/**\n * Represents a action to walk towards a panel or object.\n */\nexport class WalkTowardsPanelAction extends SimulatorUserAction {\n static dependencies = {camera: THREE.Camera, timer: THREE.Timer};\n camera!: THREE.Camera;\n timer!: THREE.Timer;\n\n constructor(private target: THREE.Object3D) {\n super();\n }\n\n async init({camera, timer}: {camera: THREE.Camera, timer: THREE.Timer}) {\n this.camera = camera;\n this.timer = timer;\n }\n\n isLookingAtTarget() {\n const camera = this.camera;\n this.target.getWorldPosition(targetWorldPosition);\n cameraToTargetVector.copy(targetWorldPosition).sub(camera.position);\n lookAtRotation(cameraToTargetVector, UP, finalRotation);\n const angle =\n (finalRotation.angleTo(camera.quaternion) + Math.PI) % (2 * Math.PI) -\n Math.PI;\n return angle < LOOK_AT_ANGLE_THRESHOLD;\n }\n\n isNearTarget() {\n const camera = this.camera;\n this.target.getWorldPosition(targetWorldPosition);\n cameraToTargetVector.copy(targetWorldPosition).sub(camera.position);\n return Math.abs(cameraToTargetVector.length() - NEAR_TARGET_DISTANCE) <\n NEAR_TARGET_THRESHOLD;\n }\n\n lookAtTarget() {\n const camera = this.camera;\n inverseCameraRotation.copy(camera.quaternion).invert();\n this.target.getWorldPosition(targetWorldPosition);\n cameraToTargetVector.copy(targetWorldPosition).sub(camera.position);\n lookAtRotation(cameraToTargetVector, UP, finalRotation);\n camera.quaternion.copy(finalRotation);\n }\n\n lookTowardsTarget() {\n const camera = this.camera;\n inverseCameraRotation.copy(camera.quaternion).invert();\n const deltaTime = this.timer.getDelta();\n this.target.getWorldPosition(targetWorldPosition);\n cameraToTargetVector.copy(targetWorldPosition).sub(camera.position);\n lookAtRotation(cameraToTargetVector, UP, finalRotation);\n deltaRotation.copy(finalRotation).multiply(inverseCameraRotation);\n clampRotationToAngle(\n deltaRotation, ROTATION_SPEED_RADIANS_PER_SECOND * deltaTime);\n camera.quaternion.premultiply(deltaRotation);\n }\n\n moveTowardsTarget() {\n const camera = this.camera;\n const deltaTime = this.timer.getDelta();\n this.target.getWorldPosition(targetWorldPosition);\n cameraToTargetVector.copy(targetWorldPosition).sub(camera.position);\n closeToTargetPosition.copy(targetWorldPosition)\n .addScaledVector(cameraToTargetVector, -NEAR_TARGET_THRESHOLD);\n const cameraToCloseToTarget = closeToTargetPosition.sub(camera.position);\n const movementDistance = clamp(\n cameraToCloseToTarget.length(), 0,\n MOVEMENT_SPEED_METERS_PER_SECOND * deltaTime);\n camera.position.addScaledVector(\n cameraToCloseToTarget,\n movementDistance / cameraToCloseToTarget.length());\n }\n\n async play({simulatorUser, journeyId, waitFrame}: {\n simulatorUser: SimulatorUser,\n journeyId: number,\n waitFrame: WaitFrame\n }) {\n let isLookingAtTarget = this.isLookingAtTarget();\n let isNearTarget = this.isNearTarget();\n let shouldContinueJourney = simulatorUser.isOnJourneyId(journeyId);\n\n while (shouldContinueJourney && (!isLookingAtTarget || !isNearTarget)) {\n if (!isLookingAtTarget) {\n this.lookTowardsTarget();\n } else {\n this.lookAtTarget();\n this.moveTowardsTarget();\n }\n await waitFrame.waitFrame();\n isLookingAtTarget = this.isLookingAtTarget();\n isNearTarget = this.isNearTarget();\n shouldContinueJourney = simulatorUser.isOnJourneyId(journeyId);\n }\n }\n}\n","import * as THREE from 'three';\n\nimport {Core} from './core/Core';\nimport {Options} from './core/Options';\nimport {Script} from './core/Script';\n\n/**\n * The global singleton instance of Core, serving as the main entry point\n * for the entire XR system.\n */\nexport const core = new Core();\n\n/**\n * A direct alias to the main `THREE.Scene` instance managed by the core.\n * Use this to add or remove objects from your XR experience.\n * @example\n * ```\n * const myObject = new THREE.Mesh();\n * scene.add(myObject);\n * ```\n */\nexport const scene = core.scene;\n\n/**\n * A direct alias to the `User` instance, which represents the user in the XR\n * scene and manages inputs like controllers and hands.\n * @example\n * ```\n * if (user.isSelecting()) {\n * console.log('User is pinching or clicking (globally)!');\n * }\n * ```\n */\nexport const user = core.user;\n\n/**\n * A direct alias to the `World` instance, which manages real-world\n * understanding features like plane detection and object detection.\n */\nexport const world = core.world;\n\n/**\n * A direct alias to the `AI` instance for integrating generative AI features,\n * including multi-modal understanding, image generation, and live conversation.\n */\nexport const ai = core.ai;\n\n// --- Function Aliases ---\n// These are bound shortcuts to frequently used methods for convenience.\n\n/**\n * A shortcut for `core.scene.add()`. Adds one or more objects to the scene.\n * @param object - The object(s) to add.\n * @see {@link three#Object3D.add}\n */\nexport function add(...object: THREE.Object3D[]) {\n return scene.add(...object);\n}\n\n/**\n * A shortcut for `core.init()`. Initializes the XR Blocks system and starts\n * the render loop. This is the main entry point for any application.\n * @param options - Configuration options for the session.\n * @see {@link Core.init}\n */\nexport function init(options: Options = new Options()) {\n return core.init(options);\n}\n\n/**\n * A shortcut for `core.scriptsManager.initScript()`. Manually initializes a\n * script and its dependencies.\n * @param script - The script to initialize.\n * @see {@link ScriptsManager.initScript}\n */\nexport function initScript(script: Script) {\n return core.scriptsManager.initScript(script);\n}\n\n/**\n * A shortcut for `core.scriptsManager.uninitScript()`. Disposes of a script\n * and removes it from the update loop.\n * @param script - The script to uninitialize.\n * @see {@link ScriptsManager.uninitScript}\n */\nexport function uninitScript(script: Script) {\n return core.scriptsManager.uninitScript(script);\n}\n\n/**\n * A shortcut for `core.clock.getDeltaTime()`. Gets the time in seconds since\n * the last frame, useful for animations.\n * @returns The delta time in seconds.\n * @see {@link Clock.getDeltaTime}\n */\nexport function getDeltaTime() {\n return core.timer.getDelta();\n}\n\n/**\n * Toggles whether the reticle can target the depth-sensing mesh.\n * @param value - True to add the depth mesh as a target, false to\n * remove it.\n */\nexport function showReticleOnDepthMesh(value: boolean) {\n if (core.depth.depthMesh) {\n core.depth.depthMesh.ignoreReticleRaycast = !value;\n }\n}\n\n/**\n * Retrieves the left camera from the stereoscopic XR camera rig.\n * @returns The left eye's camera.\n */\nexport function getXrCameraLeft() {\n return core.renderer.xr.getCamera().cameras[0];\n}\n\n/**\n * Retrieves the right camera from the stereoscopic XR camera rig.\n * @returns The right eye's camera.\n */\nexport function getXrCameraRight() {\n return core.renderer.xr.getCamera().cameras[1];\n}\n","import * as THREE from 'three';\n\nimport {LEFT_VIEW_ONLY_LAYER, RIGHT_VIEW_ONLY_LAYER} from '../constants';\n\n/**\n * Sets the given object and all its children to only be visible in the left\n * eye.\n * @param obj - Object to show only in the left eye.\n * @returns The original object.\n */\nexport function showOnlyInLeftEye<T extends THREE.Object3D>(obj: T) {\n obj.layers.set(LEFT_VIEW_ONLY_LAYER);\n obj.children.forEach((child) => {\n showOnlyInLeftEye(child);\n });\n return obj;\n}\n\n/**\n * Sets the given object and all its children to only be visible in the right\n * eye.\n * @param obj - Object to show only in the right eye.\n * @returns The original object.\n */\nexport function showOnlyInRightEye<T extends THREE.Object3D>(obj: T) {\n obj.layers.set(RIGHT_VIEW_ONLY_LAYER);\n obj.children.forEach((child) => {\n showOnlyInRightEye(child);\n });\n return obj;\n}\n\n/**\n * Loads a stereo image from a URL and returns two THREE.Texture objects, one\n * for the left eye and one for the right eye.\n * @param url - The URL of the stereo image.\n * @returns A promise that resolves to an array containing the left and right\n * eye textures.\n */\nexport async function loadStereoImageAsTextures(url: string) {\n const image = await new Promise(\n (resolve, reject) => {\n new THREE.ImageLoader().load(url, resolve, undefined, reject)});\n const leftTexture = new THREE.Texture();\n leftTexture.image = image;\n leftTexture.repeat.x = 0.5;\n leftTexture.needsUpdate = true;\n const rightTexture = leftTexture.clone();\n rightTexture.offset.x = 0.5;\n rightTexture.needsUpdate = true;\n return [leftTexture, rightTexture];\n}\n","import * as THREE from 'three';\nimport {SVGLoader, SVGResult} from 'three/addons/loaders/SVGLoader.js';\n\nimport {View} from '../core/View.js';\n\nconst SVG_BASE_PATH =\n 'https://cdn.jsdelivr.net/gh/marella/material-symbols@v0.33.0/svg/{{weight}}/{{style}}/{{icon}}.svg'\n\nexport type MaterialSymbolsViewOptions = {\n /** The name of the icon (e.g., 'sunny', 'home'). */\n icon?: string;\n /** The weight of the icon (e.g., 100, 400, 700). */\n iconWeight?: number;\n /** The style of the icon ('outlined', 'filled', or 'round'). */\n iconStyle?: string;\n /** The scale factor for the icon. */\n iconScale?: number;\n /** The color of the icon in hex format (e.g., '#FFFFFF'). */\n iconColor?: string;\n};\n\n/**\n * A View that dynamically loads and displays an icon from the Google\n * Material Symbols library as a 3D object. It constructs the icon from SVG\n * data, allowing for customization of weight, style, color, and scale.\n */\nexport class MaterialSymbolsView extends View {\n #icon = '';\n get icon() {\n return this.#icon;\n }\n set icon(value) {\n if (this.#icon == value) return;\n this.#icon = value;\n this.updateIcon();\n }\n #iconWeight = 400;\n get iconWeight() {\n return this.#iconWeight;\n }\n set iconWeight(value) {\n if (this.#iconWeight == value) return;\n this.#iconWeight = value;\n this.updateIcon();\n }\n #iconStyle = '';\n get iconStyle() {\n return this.#iconStyle;\n }\n set iconStyle(value) {\n if (this.#iconStyle == value) return;\n this.#iconStyle = value;\n this.updateIcon();\n }\n #iconColor = '';\n get iconColor() {\n return this.#iconColor;\n }\n set iconColor(value) {\n if (this.#iconColor == value) return;\n this.#iconColor = value;\n this.group?.traverse?.((child) => {\n if (child instanceof THREE.Mesh) {\n child.material?.color?.set?.(value);\n }\n });\n }\n\n iconScale = 1;\n private loadedSvgPath?: string;\n private loadingSvgPath?: string;\n private group?: THREE.Group;\n\n /**\n * Construct a Material Symbol view.\n * @param options - Options for the icon.\n */\n constructor({\n icon = 'sunny',\n iconWeight = 400,\n iconStyle = 'outlined',\n iconScale = 1,\n iconColor = '#FFFFFF'\n }: MaterialSymbolsViewOptions) {\n super({});\n this.icon = icon;\n this.iconWeight = iconWeight;\n this.iconStyle = iconStyle;\n this.iconScale = iconScale;\n this.iconColor = iconColor;\n }\n\n async init() {\n if (this.group == null) {\n await this.updateIcon();\n }\n }\n\n /**\n * Updates the icon displayed by loading the appropriate SVG from the Material\n * Symbols library based on the current `icon`, `iconWeight`, and `iconStyle`\n * properties.\n * @returns Promise<void>\n */\n async updateIcon() {\n if (!this.icon || !this.iconWeight || !this.iconStyle) {\n return;\n }\n const svgPath = SVG_BASE_PATH.replace('{{style}}', this.iconStyle)\n .replace('{{icon}}', this.icon)\n .replace('{{weight}}', String(this.iconWeight));\n if (svgPath == this.loadedSvgPath || svgPath == this.loadingSvgPath) {\n return;\n }\n this.loadingSvgPath = svgPath;\n const svgData = await new Promise<SVGResult>((resolve, reject) => {\n const loader = new SVGLoader();\n loader.load(svgPath, resolve, undefined, reject);\n });\n this.loadingSvgPath = undefined;\n this.loadedSvgPath = svgPath;\n const [viewMinX, viewMinY, viewWidth, viewHeight] =\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (svgData.xml as any).attributes.viewBox.value.split(' ');\n const paths = svgData.paths;\n const group = new THREE.Group();\n\n const scale = 1 / Math.max(viewWidth, viewHeight);\n\n const material = new THREE.MeshBasicMaterial({\n color: this.iconColor,\n transparent: true,\n side: THREE.DoubleSide,\n depthWrite: false,\n });\n\n for (let i = 0; i < paths.length; i++) {\n const path = paths[i];\n const shapes = SVGLoader.createShapes(path);\n\n for (let j = 0; j < shapes.length; j++) {\n const shape = shapes[j];\n const geometry = new THREE.ShapeGeometry(shape);\n const mesh = new THREE.Mesh(geometry, material);\n // Flip the icon over y.\n mesh.scale.set(scale, -scale, scale);\n // Center the icon\n mesh.position.x = -0.5 - viewMinX * scale;\n mesh.position.y = 0.5 + viewMinY * scale;\n group.add(mesh);\n }\n }\n if (this.group) {\n this.remove(this.group);\n this.group?.traverse?.((child) => {\n if ('dispose' in child && typeof child.dispose === 'function') {\n child.dispose?.();\n }\n if (child instanceof THREE.Mesh) {\n child.geometry?.dispose?.();\n child.material?.dispose?.();\n }\n });\n }\n this.group = group;\n group.scale.setScalar(this.iconScale);\n this.add(group);\n }\n}\n","import * as THREE from 'three';\nimport {Script} from '../../core/Script.js';\nimport {clamp} from '../../utils/utils.js';\n\n/**\n * Manages the state and animation logic for a scrolling text view.\n * It tracks the total number of lines, the current scroll position (as a line\n * number), and the target line, smoothly animating between them over time.\n */\nexport class TextScrollerState extends Script {\n static dependencies = {timer: THREE.Timer};\n scrollSpeedLinesPerSecond = 3;\n lines = 1;\n currentLine = 0;\n targetLine = 0;\n shouldUpdate = true;\n timer!: THREE.Timer;\n lineCount = 0;\n\n init({timer}: {timer: THREE.Timer}) {\n this.timer = timer;\n }\n\n update() {\n super.update();\n if (!this.shouldUpdate) {\n return false;\n }\n // Simple linear speed scrolling.\n const deltaTime = this.timer.getDelta();\n const deltaLines = this.scrollSpeedLinesPerSecond * deltaTime;\n const distanceToTargetLine = this.targetLine - this.currentLine;\n this.currentLine += clamp(distanceToTargetLine, -deltaLines, deltaLines);\n }\n}\n","import * as THREE from 'three';\n\nimport {View} from '../core/View';\n\nconst vector3 = new THREE.Vector3();\n\n/**\n * A simple container that represents a single, swipeable page\n * within a `Pager` component. It's a fundamental building block for creating\n * carousels or tabbed interfaces.\n */\nexport class Page extends View {\n constructor(options = {}) {\n super(options);\n }\n\n updateLayout() {\n // Do not update the position.\n vector3.copy(this.position);\n super.updateLayout();\n this.position.copy(vector3);\n }\n}\n","import * as THREE from 'three';\n\nimport {Script} from '../../core/Script.js';\nimport {clamp} from '../../utils/utils.js';\n\n/**\n * A state management class for a `Pager` component. It tracks the\n * total number of pages, the current scroll position, and handles the physics\n * and animation logic for smooth, inertia-based scrolling between pages.\n */\nexport class PagerState extends Script {\n static dependencies = {timer: THREE.Timer};\n currentPage = 0;\n shouldUpdate = true;\n pages = 1;\n timer!: THREE.Timer;\n\n constructor({pages = 1}) {\n super();\n this.pages = pages;\n }\n\n init({timer}: {timer: THREE.Timer}) {\n this.timer = timer;\n }\n\n update() {\n super.update();\n if (!this.shouldUpdate) {\n return false;\n }\n const velocity = Math.sin(Math.PI * (this.currentPage % 1));\n const direction = ((this.currentPage % 1) >= 0.5 ? 1 : -1) *\n Number(Math.abs(velocity) > 0.01);\n const targetPage = clamp(this.currentPage + direction, 0, this.pages - 1);\n const remainingDelta = Math.abs(targetPage - this.currentPage);\n this.currentPage +=\n direction * clamp(velocity * this.timer.getDelta(), 0, remainingDelta);\n }\n\n addPage() {\n return this.pages++;\n }\n}\n","import * as THREE from 'three';\n\nimport {SelectEvent} from '../../core/Script';\nimport {Input} from '../../input/Input';\nimport {clamp} from '../../utils/utils';\nimport {View} from '../core/View';\nimport {ViewOptions} from '../core/ViewOptions';\n\nimport {Page} from './Page';\nimport {PagerState} from './PagerState';\n\nconst vector3 = new THREE.Vector3();\nconst matrix4 = new THREE.Matrix4();\n\ntype MaybeDisposable = {\n dispose?: () => void\n};\n\nexport type PagerOptions = ViewOptions&{\n state?: PagerState;\n enableRaycastOnChildren?: boolean;\n continuousScrolling?: boolean;\n}\n\n/**\n * A layout container that manages a collection of `Page` views and\n * allows the user to navigate between them, typically through swiping\n * gestures. It clips the content of its pages to create a sliding window\n * effect.\n */\nexport class Pager extends View {\n static dependencies = {renderer: THREE.WebGLRenderer, input: Input};\n\n localClippingPlanes = [\n new THREE.Plane(new THREE.Vector3(1, 0, 0), 0.5),\n new THREE.Plane(new THREE.Vector3(-1, 0, 0), 0.5),\n ];\n raycastMesh = new THREE.Mesh(\n new THREE.PlaneGeometry(), new THREE.MeshBasicMaterial({visible: false}));\n\n state: PagerState;\n clippingPlanes: THREE.Plane[] = [];\n private selecting = false;\n private selectStartPositionLocal = new THREE.Vector3();\n private selectStartPage = 0;\n private raycastPlane = new THREE.Plane();\n private selectingRay = new THREE.Ray();\n private selectingRayTarget = new THREE.Vector3();\n private selectingController!: THREE.Object3D;\n private enableRaycastOnChildren;\n private continuousScrolling;\n private input!: Input;\n\n constructor(options: PagerOptions = {}) {\n super(options);\n const {\n state = new PagerState({pages: 1}),\n enableRaycastOnChildren = true,\n continuousScrolling = true\n } = options;\n this.state = state;\n this.enableRaycastOnChildren = enableRaycastOnChildren;\n this.continuousScrolling = continuousScrolling;\n for (let i = 0; i < this.state.pages; i++) {\n this.add(new Page());\n }\n for (let i = 0; i < this.localClippingPlanes.length; i++) {\n this.clippingPlanes.push(this.localClippingPlanes[i].clone());\n }\n }\n\n init({renderer, input}: {renderer: THREE.WebGLRenderer, input: Input}) {\n renderer.localClippingEnabled = true;\n this.input = input;\n }\n\n updatePageCount() {\n this.remove(this.raycastMesh);\n for (let i = this.children.length; i < this.state.pages; i++) {\n this.add(new Page());\n }\n for (let i = this.state.pages; i < this.children.length;) {\n (this.children[i] as MaybeDisposable).dispose?.();\n this.remove(this.children[i]);\n }\n this.add(this.raycastMesh);\n }\n\n updatePagePositions() {\n const halfNumberOfPages = Math.floor(this.state.pages / 2);\n for (let i = 0; i < this.state.pages; i++) {\n const deltaFromCurrentPage =\n this.continuousScrolling && this.state.pages > 1 ?\n ((i - this.state.currentPage + halfNumberOfPages + this.state.pages) %\n this.state.pages -\n halfNumberOfPages) :\n i - this.state.currentPage;\n this.children[i].position.x = deltaFromCurrentPage * this.rangeX;\n }\n }\n\n resetClippingPlanesToLocalSpace() {\n for (let i = 0;\n i < this.localClippingPlanes.length && i < this.clippingPlanes.length;\n i++) {\n this.clippingPlanes[i].copy(this.localClippingPlanes[i]);\n }\n }\n\n updateClippingPlanes() {\n // Map the clipping planes back to world space.\n this.resetClippingPlanesToLocalSpace();\n this.updateWorldMatrix(/*updateParents=*/ true, /*updateChildren=*/ false);\n for (const plane of this.clippingPlanes) {\n plane.applyMatrix4(this.matrixWorld);\n }\n this.traverse(child => {\n if (child instanceof THREE.Mesh) {\n child.material.clippingPlanes = this.clippingPlanes;\n }\n });\n }\n\n update() {\n this.updatePageCount();\n this.updatePagePositions();\n this.updateClippingPlanes();\n }\n\n updateLayout() {\n super.updateLayout();\n this.raycastMesh.scale.set(this.rangeX, this.rangeY, 1.0);\n }\n\n onObjectSelectStart(event: SelectEvent) {\n const controller = event.target;\n const intersections =\n this.input.intersectionsForController.get(controller)!;\n const intersectionIndex =\n intersections.findIndex(intersection => intersection.object == this);\n if (intersectionIndex == -1) return false;\n const intersection = intersections[intersectionIndex];\n this.selecting = true;\n this.selectingController = controller;\n this.updateMatrixWorld();\n this.selectStartPositionLocal.copy(intersection.point)\n .applyMatrix4(matrix4.copy(this.matrixWorld).invert());\n this.raycastPlane.normal.set(0, 0, 1.0);\n this.raycastPlane.constant = 0;\n this.raycastPlane.applyMatrix4(this.matrixWorld);\n this.selectStartPage = this.state.currentPage;\n return true;\n }\n\n protected computeSelectingDelta(\n selectingPosition: THREE.Vector3, startSelectPosition: THREE.Vector3) {\n return (selectingPosition.x - startSelectPosition.x) / this.rangeX;\n }\n\n onSelecting() {\n if (this.selecting) {\n // Raycast to the plane;\n this.selectingRay.origin.set(0.0, 0.0, 0.0);\n this.selectingRay.direction.set(0.0, 0.0, -1.0);\n this.selectingController.updateMatrixWorld();\n this.selectingRay.applyMatrix4(this.selectingController.matrixWorld);\n this.selectingRay.intersectPlane(\n this.raycastPlane, this.selectingRayTarget);\n this.updateMatrixWorld();\n this.selectingRayTarget.applyMatrix4(\n matrix4.copy(this.matrixWorld).invert());\n const deltaPage = this.computeSelectingDelta(\n this.selectingRayTarget, this.selectStartPositionLocal);\n this.state.currentPage =\n this.continuousScrolling && this.state.pages > 1 ?\n ((this.selectStartPage - deltaPage + this.state.pages) %\n this.state.pages) :\n clamp(this.selectStartPage - deltaPage, 0, this.state.pages - 1);\n }\n }\n\n onObjectSelectEnd(event: SelectEvent) {\n if (event.target == this.selectingController) {\n this.selecting = false;\n }\n return true;\n }\n\n /**\n * Raycast to the pager's raycastMesh so the user can scroll across pages.\n */\n raycast(raycaster: THREE.Raycaster, intersects: THREE.Intersection[]) {\n const thisIntersections: THREE.Intersection[] = [];\n this.raycastMesh.raycast(raycaster, thisIntersections);\n thisIntersections.forEach(intersection => {\n intersection.object = this;\n intersects.push(intersection);\n });\n // Loop through children.\n if (this.enableRaycastOnChildren) {\n const childIntersections: THREE.Intersection[] = [];\n for (const child of this.children) {\n raycaster.intersectObject(child, true, childIntersections);\n }\n // Create if the intersection is on this page.\n this.updateMatrixWorld();\n matrix4.copy(this.matrixWorld).invert();\n for (const intersection of childIntersections) {\n const pointInLocalCoordinates =\n vector3.copy(intersection.point).applyMatrix4(matrix4);\n if (Math.abs(pointInLocalCoordinates.x) < 0.5) {\n intersects.push(intersection);\n }\n }\n }\n return false;\n }\n}\n","import * as THREE from 'three';\n\nimport {Pager} from './Pager';\n\n/**\n * A specialized `Pager` that arranges its pages vertically and\n * enables vertical swiping gestures. It is commonly used as the foundation for\n * scrollable text views.\n */\nexport class VerticalPager extends Pager {\n localClippingPlanes = [\n new THREE.Plane(new THREE.Vector3(0, 1, 0), 0.5),\n new THREE.Plane(new THREE.Vector3(0, -1, 0), 0.5),\n ];\n\n updateLayout() {\n super.updateLayout();\n this.localClippingPlanes[0].constant = 0.5 * this.rangeY;\n this.localClippingPlanes[1].constant = 0.5 * this.rangeY;\n }\n\n protected computeSelectingDelta(\n selectingPosition: THREE.Vector3, startSelectPosition: THREE.Vector3) {\n return (selectingPosition.y - startSelectPosition.y) / this.rangeY;\n }\n}\n","import {View} from '../core/View';\nimport {ViewOptions} from '../core/ViewOptions';\nimport {TextScrollerState} from '../layouts/TextScrollerState';\nimport {VerticalPager} from '../layouts/VerticalPager';\n\nimport {TextView} from './TextView';\n\n/**\n * A high-quality scrolling text view that uses Troika for SDF text\n * rendering and a `VerticalPager` for clipping and scrolling. This component is\n * ideal for displaying logs, chat histories, or other long-form text content\n * that requires crisp rendering and smooth scrolling.\n *\n * It is built by composing three key components:\n * - A `TextView` to render the actual text content.\n * - A `TextScrollerState` to manage the animation and state of the scroll\n * position.\n * - A `VerticalPager` to clip the `TextView` and create the visible scroll\n * window.\n */\nexport type ScrollingTroikaTextViewOptions = ViewOptions&{\n text?: string;\n textAlign?: 'left'|'right'|'center';\n scrollerState?: TextScrollerState;\n fontSize?: number;\n};\n\nexport class ScrollingTroikaTextView extends View {\n private scrollerState: TextScrollerState;\n private pager: VerticalPager;\n private textViewWrapper: View;\n private textView: TextView;\n private onTextSyncCompleteBound = this.onTextSyncComplete.bind(this);\n private currentText = '';\n\n constructor({\n text = 'ScrollingTroikaTextView',\n textAlign = 'left',\n scrollerState = new TextScrollerState(),\n fontSize = 0.06\n }: ScrollingTroikaTextViewOptions = {}) {\n super();\n this.scrollerState = scrollerState || new TextScrollerState();\n this.pager = new VerticalPager();\n this.textViewWrapper = new View();\n this.pager.children[0].add(this.textViewWrapper);\n this.textView = new TextView({\n text: text,\n textAlign: textAlign,\n fontSize: fontSize,\n anchorX: 0,\n anchorY: 0\n });\n this.textView.x = -0.5;\n this.textView.addEventListener(\n 'synccomplete', this.onTextSyncCompleteBound);\n this.textViewWrapper.add(this.textView);\n\n this.add(this.scrollerState);\n this.add(this.pager);\n }\n\n update() {\n this.textViewWrapper.y = this.textView.lineHeight *\n this.textView.aspectRatio * this.scrollerState.currentLine;\n this.textViewWrapper.updateLayout();\n }\n\n addText(text: string) {\n this.setText(this.currentText + text);\n }\n\n setText(text: string) {\n this.currentText = text;\n this.textView.setText(this.currentText);\n }\n\n onTextSyncComplete() {\n if (this.textView.lineCount > 0) {\n this.textView.y =\n -0.5 + this.textView.lineHeight * this.textView.aspectRatio;\n this.textView.updateLayout();\n this.scrollerState.lineCount = this.textView.lineCount;\n this.scrollerState.targetLine = this.textView.lineCount - 1;\n\n this.clipToLineHeight();\n }\n }\n\n clipToLineHeight() {\n const lineHeight = this.textView.lineHeight * this.textView.aspectRatio;\n const visibleLines = Math.floor(1.0 / lineHeight);\n const newHeight = visibleLines * lineHeight;\n this.pager.localClippingPlanes[1].constant = newHeight - 0.5;\n }\n}\n","import * as THREE from 'three';\n\nimport {MouseController} from '../../input/MouseController';\nimport {clamp} from '../../utils/utils';\n\nconst positionDiff = new THREE.Vector3();\nconst rotationDiff = new THREE.Quaternion();\nconst euler = new THREE.Euler();\n\n/**\n * A non-visual helper class for calculating a slider value based on\n * a controller's movement relative to an initial pose. It can derive the value\n * from either positional (for XR hands/controllers) or rotational (for mouse)\n * input, making it a flexible tool for creating virtual sliders without a\n * visible UI element.\n */\nexport class FreestandingSlider {\n initialPosition = new THREE.Vector3();\n initialRotationInverse = new THREE.Quaternion();\n rotationScale: number;\n\n /**\n * Create a freestanding slider object.\n */\n constructor(\n public startingValue = 0.0, public minValue = 0.0, public maxValue = 1.0,\n public scale = 1.0, rotationScale?: number) {\n this.rotationScale =\n rotationScale != undefined ? rotationScale : -this.scale;\n }\n\n /**\n * Captures the initial position and rotation to serve as the reference point\n * for the gesture.\n * @param position - The starting world position.\n * @param rotation - The starting world rotation.\n */\n setInitialPose(position: THREE.Vector3, rotation: THREE.Quaternion) {\n this.initialPosition.copy(position);\n this.initialRotationInverse.copy(rotation).invert();\n }\n\n /**\n * A convenience method to capture the initial pose from a controller object.\n * @param controller - The controller to use as the reference.\n */\n setInitialPoseFromController(controller: THREE.Object3D) {\n this.setInitialPose(controller.position, controller.quaternion);\n }\n\n /**\n * Calculates the slider value based on a new world position.\n * @param position - The current world position of the input source.\n * @returns The calculated slider value, clamped within the min/max range.\n */\n getValue(position: THREE.Vector3) {\n positionDiff.copy(position)\n .sub(this.initialPosition)\n .applyQuaternion(this.initialRotationInverse);\n return clamp(\n this.startingValue + this.scale * positionDiff.x, this.minValue,\n this.maxValue);\n }\n\n /**\n * Calculates the slider value based on a new world rotation (for mouse\n * input).\n * @param rotation - The current world rotation of the input source.\n * @returns The calculated slider value, clamped within the min/max range.\n */\n getValueFromRotation(rotation: THREE.Quaternion) {\n rotationDiff.copy(rotation).multiply(this.initialRotationInverse);\n euler.setFromQuaternion(rotationDiff, 'YXZ');\n return clamp(\n this.startingValue + this.rotationScale * euler.y, this.minValue,\n this.maxValue);\n }\n\n /**\n * A polymorphic method that automatically chooses the correct calculation\n * (positional or rotational) based on the controller type.\n * @param controller - The controller providing the input.\n * @returns The calculated slider value.\n */\n getValueFromController(controller: THREE.Object3D) {\n return controller instanceof MouseController ?\n this.getValueFromRotation(controller.quaternion) :\n this.getValue(controller.position);\n }\n\n /**\n * Updates the starting value, typically after a gesture has ended.\n * @param value - The new starting value for the next gesture.\n */\n updateValue(value: number) {\n this.startingValue = value\n }\n}\n","import * as THREE from 'three';\nimport {DRACOLoader} from 'three/addons/loaders/DRACOLoader.js';\nimport {GLTF, GLTFLoader} from 'three/addons/loaders/GLTFLoader.js';\nimport {KTX2Loader} from 'three/addons/loaders/KTX2Loader.js';\n\n/**\n * The base URL for Three.js JSM examples, used for DRACO and KTX2 decoders.\n */\nconst jsmUrl =\n `https://cdn.jsdelivr.net/npm/three@0.${THREE.REVISION}.0/examples/jsm/`;\n\n/**\n * The configured GLTFLoader instance.\n */\nlet gltfLoaderInstance: GLTFLoader|undefined;\n\nfunction getGLTFLoader(\n renderer?: THREE.WebGLRenderer, manager?: THREE.LoadingManager) {\n if (gltfLoaderInstance) {\n return gltfLoaderInstance;\n }\n const dracoLoader = new DRACOLoader(manager);\n dracoLoader.setDecoderPath(jsmUrl + 'libs/draco/');\n dracoLoader.setDecoderConfig({type: 'js'});\n const ktx2Loader = new KTX2Loader(manager);\n ktx2Loader.setTranscoderPath(jsmUrl + 'libs/basis/');\n if (renderer) {\n ktx2Loader.detectSupport(renderer);\n }\n\n gltfLoaderInstance = new GLTFLoader(manager);\n gltfLoaderInstance.setDRACOLoader(dracoLoader);\n gltfLoaderInstance.setKTX2Loader(ktx2Loader);\n return gltfLoaderInstance;\n}\n\nexport type ModelLoaderLoadGLTFOptions = {\n /** The base path for the model files. */\n path?: string;\n /** The URL of the model file. */\n url: string;\n /** The renderer. */\n renderer?: THREE.WebGLRenderer;\n};\n\nexport type ModelLoaderLoadOptions = ModelLoaderLoadGLTFOptions&{\n /**\n * Optional callback for loading progress. Note: This will be ignored if a\n * LoadingManager is provided.\n */\n onProgress?: (event: ProgressEvent) => void;\n};\n\n/**\n * Manages the loading of 3D models, automatically handling dependencies\n * like DRACO and KTX2 loaders.\n */\nexport class ModelLoader {\n private manager: THREE.LoadingManager;\n\n /**\n * Creates an instance of ModelLoader.\n * @param manager - The\n * loading manager to use,\n * required for KTX2 texture support.\n */\n constructor(manager = THREE.DefaultLoadingManager) {\n this.manager = manager;\n }\n\n /**\n * Loads a model based on its file extension. Supports .gltf, .glb,\n * .ply, .spz, .splat, and .ksplat.\n * @returns A promise that resolves with the loaded model data (e.g., a glTF\n * scene or a SplatMesh).\n */\n async load({path, url = '', renderer = undefined, onProgress = undefined}:\n ModelLoaderLoadOptions) {\n if (onProgress) {\n console.warn(\n 'ModelLoader: An onProgress callback was provided to load(), ' +\n 'but a LoadingManager is in use. Progress will be reported via the ' +\n 'LoadingManager\\'s onProgress callback. The provided callback will be ignored.');\n }\n const extension = url.split('.').pop()?.toLowerCase() || '';\n const splatExtensions = ['ply', 'spz', 'splat', 'ksplat'];\n const gltfExtensions = ['gltf', 'glb'];\n\n if (gltfExtensions.includes(extension)) {\n return await this.loadGLTF({path, url, renderer});\n } else if (splatExtensions.includes(extension)) {\n return await this.loadSplat({url});\n }\n console.error('Unsupported file type: ' + extension);\n return null;\n }\n\n /**\n * Loads a 3DGS model (.ply, .spz, .splat, .ksplat).\n * @param url - The URL of the model file.\n * @returns A promise that resolves with the loaded\n * SplatMesh object.\n */\n async loadSplat({url = ''}) {\n const {SplatMesh} = await import('@sparkjsdev/spark'); // Dynamic import\n const splatMesh = new SplatMesh({url});\n await splatMesh.initialized;\n return splatMesh;\n }\n\n /**\n * Loads a GLTF or GLB model.\n * @param options - The loading options.\n * @returns A promise that resolves with the loaded glTF object.\n */\n async loadGLTF({\n path,\n url = '',\n renderer = undefined,\n }: ModelLoaderLoadGLTFOptions) {\n const loader = getGLTFLoader(renderer, this.manager);\n if (path) {\n loader.setPath(path);\n }\n return new Promise<GLTF>((resolve, reject) => {\n loader.load(\n url, (gltf) => resolve(gltf), undefined, (error) => reject(error));\n });\n }\n}\n","import * as THREE from 'three';\n\n/**\n * A custom `THREE.BufferGeometry` that creates one rounded corner\n * piece for the `ModelViewerPlatform`. Four of these are instantiated and\n * rotated to form all corners of the platform.\n */\nexport class ModelViewerPlatformCornerGeometry extends THREE.BufferGeometry {\n constructor(\n radius = 1, tube = 0.4, radialSegments = 12, tubularSegments = 48) {\n super();\n\n const indices = [];\n const vertices = [];\n const normals = [];\n const uvs = [];\n\n const center = new THREE.Vector3();\n const vertex = new THREE.Vector3();\n const normal = new THREE.Vector3();\n\n for (let j = 0; j <= radialSegments; j++) {\n for (let i = 0; i <= tubularSegments; i++) {\n const u = i / tubularSegments * Math.PI / 2;\n const v = j / radialSegments * Math.PI + 3 * Math.PI / 2;\n\n vertex.x = (radius + tube * Math.cos(v)) * Math.cos(u);\n vertex.y = (radius + tube * Math.cos(v)) * Math.sin(u);\n vertex.z = tube * Math.sin(v);\n vertices.push(vertex.x, vertex.y, vertex.z);\n\n center.x = radius * Math.cos(u);\n center.y = radius * Math.sin(u);\n normal.subVectors(vertex, center).normalize();\n normals.push(normal.x, normal.y, normal.z);\n\n uvs.push(i / tubularSegments);\n uvs.push(j / radialSegments);\n }\n }\n\n for (let j = 1; j <= radialSegments; j++) {\n for (let i = 1; i <= tubularSegments; i++) {\n const a = (tubularSegments + 1) * j + i - 1;\n const b = (tubularSegments + 1) * (j - 1) + i - 1;\n const c = (tubularSegments + 1) * (j - 1) + i;\n const d = (tubularSegments + 1) * j + i;\n\n indices.push(a, b, d);\n indices.push(b, c, d);\n }\n }\n\n this.setIndex(indices);\n this.setAttribute(\n 'position', new THREE.Float32BufferAttribute(vertices, 3));\n this.setAttribute('normal', new THREE.Float32BufferAttribute(normals, 3));\n this.setAttribute('uv', new THREE.Float32BufferAttribute(uvs, 2));\n }\n}\n","import * as THREE from 'three';\nimport * as BufferGeometryUtils from 'three/addons/utils/BufferGeometryUtils.js';\n\nimport {ModelViewerPlatformCornerGeometry} from './ModelViewerPlatformCornerGeometry.js';\n\n/**\n * A factory function that constructs the complete geometry for a\n * `ModelViewerPlatform`. It combines several sub-geometries: four rounded\n * corners, four straight side tubes, and the flat top and bottom surfaces.\n * @param width - The total width of the platform.\n * @param depth - The total depth of the platform.\n * @param thickness - The thickness of the platform.\n * @param cornerRadius - The radius of the rounded corners.\n * @returns A merged `THREE.BufferGeometry` for the entire platform.\n */\nexport function createPlatformGeometry(\n width = 1, depth = 1, thickness = 0.02, cornerRadius = 0.03,\n cornerWidthSegments = 5, radialSegments = 5) {\n const sideGeometries = createPlatformSideGeometries(\n width, depth, thickness, cornerRadius, cornerWidthSegments,\n radialSegments);\n const sideGeometriesVertexCount = sideGeometries.reduce((acc, val) => {\n return acc + val.index!.count;\n }, 0);\n const flatGeometries = createPlatformFlatGeometries(\n width, depth, thickness, cornerRadius, cornerWidthSegments);\n const flatGeometriesVertexCount = flatGeometries.reduce((acc, val) => {\n return acc + val.index!.count;\n }, 0);\n const allGeometries = [...sideGeometries, ...flatGeometries];\n const mergedGeometry = BufferGeometryUtils.mergeGeometries(allGeometries);\n allGeometries.forEach(geometry => geometry.dispose());\n mergedGeometry.addGroup(0, sideGeometriesVertexCount, 0);\n mergedGeometry.addGroup(\n sideGeometriesVertexCount, flatGeometriesVertexCount, 1);\n mergedGeometry.computeBoundingBox();\n return mergedGeometry;\n}\n\nfunction createPlatformSideGeometries(\n width = 1, depth = 1, thickness = 0.01, cornerRadius = 0.03,\n cornerWidthSegments = 5, radialSegments = 5) {\n const cornerGeometry =\n new ModelViewerPlatformCornerGeometry(\n cornerRadius, thickness / 2, radialSegments, cornerWidthSegments)\n .rotateX(Math.PI / 2);\n const cornerGeometry1 =\n cornerGeometry.clone()\n .rotateY(2 * Math.PI / 2)\n .translate(\n -(width / 2 - cornerRadius), 0, -(depth / 2 - cornerRadius));\n const cornerGeometry2 =\n cornerGeometry.clone()\n .rotateY(3 * Math.PI / 2)\n .translate(\n -(width / 2 - cornerRadius), 0, (depth / 2 - cornerRadius));\n const cornerGeometry3 =\n cornerGeometry.clone()\n .rotateY(4 * Math.PI / 2)\n .translate((width / 2 - cornerRadius), 0, (depth / 2 - cornerRadius));\n const cornerGeometry4 =\n cornerGeometry.rotateY(5 * Math.PI / 2)\n .translate(\n (width / 2 - cornerRadius), 0, -(depth / 2 - cornerRadius));\n const cornerTubes =\n [cornerGeometry1, cornerGeometry2, cornerGeometry3, cornerGeometry4];\n\n const widthTube =\n new THREE\n .CylinderGeometry(\n thickness / 2, thickness / 2, (width - 2 * cornerRadius),\n radialSegments, 1, true, 0, Math.PI)\n .rotateZ(Math.PI / 2);\n const widthTube1 =\n widthTube.clone().rotateX(-Math.PI / 2).translate(0, 0, -depth / 2);\n const widthTube2 = widthTube.rotateX(Math.PI / 2).translate(0, 0, depth / 2);\n\n const depthTube =\n new THREE\n .CylinderGeometry(\n thickness / 2, thickness / 2, (depth - 2 * cornerRadius),\n radialSegments, 1, true, 0, Math.PI)\n .rotateX(-Math.PI / 2);\n const depthTube1 =\n depthTube.clone().rotateY(Math.PI).translate(-width / 2, 0, 0);\n const depthTube2 = depthTube.translate(width / 2, 0, 0);\n const sideTubes = [widthTube1, widthTube2, depthTube1, depthTube2];\n return [...cornerTubes, ...sideTubes];\n}\n\nfunction createPlatformFlatGeometries(\n width = 1, depth = 1, thickness = 0.01, cornerRadius = 0.03,\n cornerWidthSegments = 5) {\n const widthMinusRadius = width - 2 * cornerRadius;\n const depthMinusRadius = depth - 2 * cornerRadius;\n const longQuad =\n new THREE.PlaneGeometry(width, depthMinusRadius).rotateX(-Math.PI / 2);\n const shortQuad = new THREE.PlaneGeometry(widthMinusRadius, cornerRadius)\n .rotateX(-Math.PI / 2);\n const shortQuadTranslationZ = depthMinusRadius / 2 + cornerRadius / 2;\n const shortQuad1 = shortQuad.clone().translate(0, 0, shortQuadTranslationZ);\n const shortQuad2 = shortQuad.translate(0, 0, -shortQuadTranslationZ)\n const quadGeometries = [longQuad, shortQuad1, shortQuad2];\n\n const cornerCircle =\n new THREE\n .CircleGeometry(cornerRadius, cornerWidthSegments, 0, Math.PI / 2)\n .rotateX(-Math.PI / 2);\n const circleTranslationZ = depthMinusRadius / 2;\n const circleTranslationX = widthMinusRadius / 2;\n const cornerCircle1 =\n cornerCircle.clone()\n .rotateY(3 * Math.PI / 2)\n .translate(circleTranslationX, 0, circleTranslationZ);\n const cornerCircle2 =\n cornerCircle.clone()\n .rotateY(0 * Math.PI / 2)\n .translate(circleTranslationX, 0, -circleTranslationZ);\n const cornerCircle3 =\n cornerCircle.clone()\n .rotateY(1 * Math.PI / 2)\n .translate(-circleTranslationX, 0, -circleTranslationZ);\n const cornerCircle4 =\n cornerCircle.clone()\n .rotateY(2 * Math.PI / 2)\n .translate(-circleTranslationX, 0, circleTranslationZ);\n const circleGeometries =\n [cornerCircle1, cornerCircle2, cornerCircle3, cornerCircle4];\n const topGeometries = [...quadGeometries, ...circleGeometries];\n const bottomGeometries = topGeometries.map(geometry => {\n return geometry.clone().rotateX(Math.PI).translate(0, -thickness / 2, 0);\n });\n topGeometries.forEach(geometry => geometry.translate(0, thickness / 2, 0));\n return [...topGeometries, ...bottomGeometries];\n}\n","import * as THREE from 'three';\n\nimport {DragManager} from '../../ux/DragManager.js';\n\nimport {AnimatableNumber} from './AnimatableNumber.js';\nimport {createPlatformGeometry} from './ModelViewerPlatformGeometry.js';\n\n/**\n * A specialized `THREE.Mesh` that serves as the interactive base for\n * a `ModelViewer`. It has a distinct visual appearance and handles the logic\n * for fading in and out on hover. Its `draggingMode` is set to `TRANSLATING` to\n * enable movement.\n */\nexport class ModelViewerPlatform extends\n THREE.Mesh<THREE.BufferGeometry, THREE.Material[]> {\n draggingMode = DragManager.TRANSLATING;\n opacity: AnimatableNumber;\n\n constructor(width: number, depth: number, thickness: number) {\n const geometry = createPlatformGeometry(width, depth, thickness);\n super(geometry, [\n new THREE.MeshLambertMaterial(\n {color: 0xFFFFFF, transparent: true, opacity: 0.0}),\n new THREE.MeshLambertMaterial(\n {color: 0xFFFFFF, transparent: true, opacity: 0.0})\n ]);\n this.opacity = new AnimatableNumber(0, 0, 0.5, 0);\n }\n\n update(deltaTime: number) {\n this.opacity.update(deltaTime);\n this.material[0].opacity = this.opacity.value;\n this.material[1].opacity = 0.5 * this.opacity.value;\n this.visible = this.opacity.value > 0.001;\n }\n}\n","import type {SplatMesh} from '@sparkjsdev/spark';\nimport * as THREE from 'three';\nimport type {GLTF} from 'three/addons/loaders/GLTFLoader.js';\n\nimport {OCCLUDABLE_ITEMS_LAYER} from '../../constants';\nimport {Script} from '../../core/Script';\nimport {Depth} from '../../depth/Depth';\nimport {OcclusionUtils} from '../../depth/occlusion/OcclusionUtils';\nimport {BACK, LEFT} from '../../utils/HelperConstants';\nimport {ModelLoader} from '../../utils/ModelLoader';\nimport {getGroupBoundingBox} from '../../utils/ModelUtils';\nimport type {Shader} from '../../utils/Types';\nimport {Draggable, DragManager, DragMode, HasDraggingMode} from '../../ux/DragManager';\n\nimport {ModelViewerPlatform} from './ModelViewerPlatform';\n\nconst defaultPlatformMargin = new THREE.Vector2(0.2, 0.2);\nconst vector3 = new THREE.Vector3();\nconst quaternion = new THREE.Quaternion();\nconst quaternion2 = new THREE.Quaternion();\n\nexport interface GLTFData {\n model: string;\n path: string;\n scale?: THREE.Vector3Like;\n rotation?: THREE.Vector3Like;\n position?: THREE.Vector3Like;\n verticallyAlignObject?: boolean;\n horizontallyAlignObject?: boolean;\n}\n\nexport interface SplatData {\n model: string;\n scale?: THREE.Vector3Like;\n rotation?: THREE.Vector3Like;\n position?: THREE.Vector3Like;\n verticallyAlignObject?: boolean;\n horizontallyAlignObject?: boolean;\n}\n\nexport class SplatAnchor extends THREE.Object3D implements HasDraggingMode {\n draggingMode = DragMode.ROTATING;\n}\n\nexport class RotationRaycastMesh extends\n THREE.Mesh<THREE.BufferGeometry, THREE.Material> {\n constructor(geometry: THREE.BufferGeometry, material: THREE.Material) {\n super(geometry, material);\n }\n draggingMode = DragMode.ROTATING;\n}\n\n/**\n * A comprehensive UI component for loading, displaying, and\n * interacting with 3D models (GLTF and Splats) in an XR scene. It\n * automatically creates an interactive platform for translation and provides\n * mechanisms for rotation and scaling in both desktop and XR.\n */\nexport class ModelViewer extends Script implements Draggable {\n static dependencies = {\n camera: THREE.Camera,\n depth: Depth,\n scene: THREE.Scene,\n renderer: THREE.WebGLRenderer,\n };\n\n draggable = true;\n rotatable = true;\n scalable = true;\n platformAnimationSpeed = 2;\n platformThickness = 0.02;\n isOneOneScale = false;\n initialScale = new THREE.Vector3().setScalar(1);\n startAnimationOnLoad = true;\n clipActions: THREE.AnimationAction[] = [];\n\n private data?: GLTFData|SplatData;\n private clock = new THREE.Clock();\n private animationMixer?: THREE.AnimationMixer;\n private gltfMesh?: GLTF;\n private splatMesh?: SplatMesh;\n // Anchor to act as a proxy for the splat mesh\n private splatAnchor?: SplatAnchor;\n private hoveringControllers = new Set();\n private raycastToChildren: boolean;\n private occludableShaders = new Set<Shader>();\n private camera?: THREE.Camera;\n private depth?: Depth;\n private scene?: THREE.Scene;\n private renderer?: THREE.WebGLRenderer;\n private bbox = new THREE.Box3();\n private platform?: ModelViewerPlatform;\n private controlBar?: THREE.Mesh;\n private rotationRaycastMesh?: RotationRaycastMesh;\n\n constructor({\n castShadow = true,\n receiveShadow = true,\n raycastToChildren = false,\n }) {\n super();\n this.castShadow = castShadow;\n this.receiveShadow = receiveShadow;\n this.raycastToChildren = raycastToChildren;\n }\n\n async init({camera, depth, scene, renderer}: {\n camera: THREE.Camera,\n depth: Depth,\n scene: THREE.Scene,\n renderer: THREE.WebGLRenderer,\n }) {\n this.camera = camera;\n this.depth = depth;\n this.scene = scene;\n this.renderer = renderer;\n\n for (const shader of this.occludableShaders) {\n this.depth!.occludableShaders.add(shader);\n }\n\n if (this.splatMesh) {\n await this.createSparkRendererIfNeeded();\n this.scene!.add(this.splatMesh);\n }\n }\n\n async loadSplatModel({\n data,\n onSceneLoaded = (_) => {},\n platformMargin = defaultPlatformMargin,\n setupRaycastCylinder = true,\n setupRaycastBox = false,\n setupPlatform = true,\n }: {\n data: SplatData,\n onSceneLoaded?: (scene: THREE.Object3D) => void,\n platformMargin?: THREE.Vector2,\n setupRaycastCylinder?: boolean,\n setupRaycastBox?: boolean,\n setupPlatform?: boolean\n }) {\n this.data = data;\n if (data.scale) {\n this.initialScale.copy(data.scale);\n }\n\n const splatMesh = await new ModelLoader().loadSplat({url: data.model});\n this.splatMesh = splatMesh;\n splatMesh.raycast = () => {};\n this.splatAnchor = new SplatAnchor;\n\n if (data.scale) {\n this.splatAnchor.scale.copy(data.scale);\n }\n if (data.rotation) {\n this.splatAnchor.rotation.set(\n THREE.MathUtils.degToRad(data.rotation.x),\n THREE.MathUtils.degToRad(data.rotation.y),\n THREE.MathUtils.degToRad(data.rotation.z));\n }\n if (data.position) {\n this.splatAnchor.position.copy(data.position);\n }\n\n this.add(this.splatAnchor);\n\n if (this.scene) {\n await this.createSparkRendererIfNeeded();\n this.scene.add(this.splatMesh);\n }\n\n await this.setupBoundingBox(\n data.verticallyAlignObject !== false,\n data.horizontallyAlignObject !== false);\n\n if (setupRaycastCylinder) {\n this.setupRaycastCylinder();\n } else if (setupRaycastBox) {\n this.setupRaycastBox();\n }\n if (setupPlatform) {\n this.setupPlatform(platformMargin);\n }\n\n this.setCastShadow(this.castShadow);\n this.setReceiveShadow(this.receiveShadow);\n\n // Return the anchor, as it's the interactive object in the scene graph\n return onSceneLoaded ? onSceneLoaded(this.splatAnchor) : this.splatAnchor;\n }\n\n async loadGLTFModel({\n data,\n onSceneLoaded = () => {},\n platformMargin = defaultPlatformMargin,\n setupRaycastCylinder = true,\n setupRaycastBox = false,\n setupPlatform = true,\n renderer = undefined,\n addOcclusionToShader = false\n }: {\n data: GLTFData,\n onSceneLoaded?: (scene: THREE.Object3D) => void,\n platformMargin?: THREE.Vector2,\n setupRaycastCylinder?: boolean,\n setupRaycastBox?: boolean,\n setupPlatform?: boolean,\n renderer?: THREE.WebGLRenderer,\n addOcclusionToShader?: boolean,\n }) {\n this.data = data;\n if (data.scale) {\n this.initialScale.copy(data.scale);\n }\n const gltf = await new ModelLoader().loadGLTF(\n {path: data.path, url: data.model, renderer: renderer});\n const animationMixer = new THREE.AnimationMixer(gltf.scene);\n gltf.animations.forEach((clip) => {\n if (this.startAnimationOnLoad) {\n animationMixer.clipAction(clip).play();\n } else {\n this.clipActions.push(animationMixer.clipAction(clip));\n }\n });\n (gltf.scene as unknown as HasDraggingMode).draggingMode =\n DragManager.ROTATING;\n this.gltfMesh = gltf;\n this.animationMixer = animationMixer;\n // Set the initial scale\n if (data.scale) {\n this.gltfMesh.scene.scale.copy(data.scale);\n }\n if (data.rotation) {\n gltf.scene.rotation.set(\n THREE.MathUtils.degToRad(data.rotation.x),\n THREE.MathUtils.degToRad(data.rotation.y),\n THREE.MathUtils.degToRad(data.rotation.z));\n }\n if (data.position) {\n gltf.scene.position.copy(data.position);\n }\n (gltf.scene as unknown as HasDraggingMode).draggingMode =\n DragManager.ROTATING;\n this.add(gltf.scene);\n await this.setupBoundingBox(\n data.verticallyAlignObject !== false,\n data.horizontallyAlignObject !== false);\n if (setupRaycastCylinder) {\n this.setupRaycastCylinder();\n } else if (setupRaycastBox) {\n this.setupRaycastBox();\n }\n if (setupPlatform) {\n this.setupPlatform(platformMargin);\n }\n this.setCastShadow(this.castShadow);\n this.setReceiveShadow(this.receiveShadow);\n if (addOcclusionToShader) {\n for (const material of this.platform?.material || []) {\n material.onBeforeCompile = (shader: Shader) => {\n OcclusionUtils.addOcclusionToShader(shader);\n shader.uniforms.occlusionEnabled.value = true;\n material.userData.shader = shader;\n this.occludableShaders.add(shader);\n this.depth?.occludableShaders.add(shader);\n }\n }\n this.platform?.layers.enable(OCCLUDABLE_ITEMS_LAYER);\n gltf.scene.traverse((child) => {\n if ((child as Partial<THREE.Mesh>).isMesh) {\n const mesh = child as THREE.Mesh;\n (mesh.material instanceof Array ? mesh.material : [\n mesh.material\n ]).forEach((material) => {\n material.transparent = true;\n material.onBeforeCompile = (shader) => {\n OcclusionUtils.addOcclusionToShader(shader);\n shader.uniforms.occlusionEnabled.value = true;\n this.occludableShaders.add(shader);\n this.depth?.occludableShaders.add(shader);\n };\n });\n child.layers.enable(OCCLUDABLE_ITEMS_LAYER);\n }\n });\n }\n return onSceneLoaded ? onSceneLoaded(gltf.scene) : gltf.scene;\n }\n\n async setupBoundingBox(\n verticallyAlignObject = true, horizontallyAlignObject = true) {\n if (this.splatMesh) {\n const localBbox = await this.splatMesh.getBoundingBox(false);\n if (localBbox.isEmpty()) {\n this.bbox = localBbox;\n return;\n }\n this.splatAnchor!.updateMatrix();\n const localBboxOfTransformedMesh =\n localBbox.clone().applyMatrix4(this.splatAnchor!.matrix);\n\n const translationAmount = new THREE.Vector3();\n localBboxOfTransformedMesh.getCenter(translationAmount)\n .multiplyScalar(-1);\n if (verticallyAlignObject) {\n translationAmount.y = -localBboxOfTransformedMesh.min.y;\n } else {\n translationAmount.y = 0;\n }\n if (!horizontallyAlignObject) {\n translationAmount.x = 0;\n translationAmount.z = 0;\n }\n this.splatAnchor!.position.add(translationAmount);\n this.bbox = localBboxOfTransformedMesh.translate(translationAmount);\n } else {\n const contentChildren = this.children.filter(\n (c) => c !== this.platform && c !== this.rotationRaycastMesh &&\n c !== this.controlBar);\n this.bbox = getGroupBoundingBox(contentChildren);\n if (this.bbox.isEmpty()) {\n return;\n }\n\n const translationAmount = new THREE.Vector3();\n this.bbox.getCenter(translationAmount).multiplyScalar(-1);\n if (verticallyAlignObject) {\n translationAmount.y = -this.bbox.min.y;\n } else {\n translationAmount.y = 0;\n }\n if (!horizontallyAlignObject) {\n translationAmount.x = 0;\n translationAmount.z = 0;\n }\n for (const child of contentChildren) {\n child.position.add(translationAmount);\n }\n this.bbox.translate(translationAmount);\n }\n }\n\n setupRaycastCylinder() {\n const bboxSize = new THREE.Vector3();\n this.bbox.getSize(bboxSize);\n\n const radius = 0.05 + 0.5 * Math.min(bboxSize.x, bboxSize.z);\n const rotationRaycastMesh = new RotationRaycastMesh(\n new THREE.CylinderGeometry(radius, radius, bboxSize.y),\n new THREE.MeshBasicMaterial({color: 0x990000, wireframe: true}));\n this.bbox.getCenter(rotationRaycastMesh.position);\n this.rotationRaycastMesh = rotationRaycastMesh;\n this.rotationRaycastMesh.visible = false;\n this.add(this.rotationRaycastMesh);\n }\n\n setupRaycastBox() {\n if (this.rotationRaycastMesh) {\n this.rotationRaycastMesh.removeFromParent();\n this.rotationRaycastMesh.geometry.dispose();\n this.rotationRaycastMesh.material.dispose();\n }\n const bboxSize = new THREE.Vector3();\n this.bbox.getSize(bboxSize);\n\n const rotationRaycastMesh = new RotationRaycastMesh(\n new THREE.BoxGeometry(bboxSize.x, bboxSize.y, bboxSize.z),\n new THREE.MeshBasicMaterial({color: 0x990000, wireframe: true}));\n this.bbox.getCenter(rotationRaycastMesh.position);\n this.rotationRaycastMesh = rotationRaycastMesh;\n this.rotationRaycastMesh.visible = false;\n this.add(this.rotationRaycastMesh);\n }\n\n setupPlatform(platformMargin = defaultPlatformMargin) {\n const bboxSize = new THREE.Vector3();\n this.bbox.getSize(bboxSize);\n const width = bboxSize.x + platformMargin.x;\n const depth = bboxSize.z + platformMargin.y;\n this.platform =\n new ModelViewerPlatform(width, depth, this.platformThickness);\n const center = new THREE.Vector3();\n this.bbox.getCenter(center);\n this.platform.position.set(center.x, -this.platformThickness / 2, center.z);\n this.add(this.platform);\n }\n\n update() {\n if (this.splatMesh && this.splatAnchor) {\n // Synchronize the splat mesh's transform with its anchor\n this.updateMatrixWorld(true);\n this.splatAnchor.matrixWorld.decompose(\n this.splatMesh.position, this.splatMesh.quaternion,\n this.splatMesh.scale);\n }\n const delta = this.clock.getDelta();\n if (this.animationMixer) {\n this.animationMixer.update(delta);\n }\n if (this.platform) {\n this.platform.update(delta);\n }\n const camera = this.camera;\n if (this.controlBar != null && this.controlBar.parent == this &&\n camera != null) {\n const directionToCamera =\n vector3.copy(camera.position).sub(this.position);\n const distanceToCamera = directionToCamera.length();\n const pitchAngleRadians = Math.asin(directionToCamera.normalize().y);\n directionToCamera.y = 0;\n directionToCamera.normalize();\n // Make the button face the camera.\n quaternion.copy(this.quaternion).invert();\n this.controlBar.quaternion.setFromAxisAngle(LEFT, pitchAngleRadians)\n .premultiply(quaternion2.setFromUnitVectors(BACK, directionToCamera))\n .premultiply(quaternion);\n this.controlBar.position.setScalar(0)\n .addScaledVector(directionToCamera, 0.5)\n .applyQuaternion(quaternion);\n this.controlBar.position.y = 0.0;\n this.controlBar.scale.set(\n distanceToCamera / this.scale.x, distanceToCamera / this.scale.y,\n distanceToCamera / this.scale.z);\n }\n }\n\n onObjectSelectStart() {\n return this.draggable || this.rotatable || this.scalable;\n }\n\n onObjectSelectEnd() {\n return this.draggable || this.rotatable || this.scalable;\n }\n\n onHoverEnter(controller: THREE.Object3D) {\n this.hoveringControllers.add(controller);\n if (this.platform) {\n this.platform.opacity.speed = this.platformAnimationSpeed;\n }\n }\n\n onHoverExit(controller: THREE.Object3D) {\n this.hoveringControllers.delete(controller);\n if (this.platform && this.hoveringControllers.size == 0) {\n this.platform.opacity.speed = -this.platformAnimationSpeed;\n }\n }\n\n /**\n * {@inheritDoc}\n */\n raycast(raycaster: THREE.Raycaster, intersects: THREE.Intersection[]) {\n const content = this.gltfMesh?.scene ?? this.splatMesh;\n if (this.raycastToChildren && content) {\n const childRaycasts: THREE.Intersection[] = [];\n for (const child of this.children) {\n if (child != this.rotationRaycastMesh && child != this.platform &&\n child != this.controlBar) {\n raycaster.intersectObject(child, true, childRaycasts);\n }\n }\n intersects.push(...childRaycasts);\n }\n\n if (this.rotationRaycastMesh) {\n const rotationIntersects: THREE.Intersection[] = [];\n this.rotationRaycastMesh.raycast(raycaster, rotationIntersects);\n for (const intersect of rotationIntersects) {\n intersects.push(intersect);\n }\n }\n\n if (this.platform) {\n const platformIntersects: THREE.Intersection[] = [];\n this.platform.raycast(raycaster, platformIntersects);\n for (const intersect of platformIntersects) {\n intersects.push(intersect);\n }\n }\n\n if (this.controlBar != null && this.controlBar.parent == this) {\n const controlButtonIntersects: THREE.Intersection[] = [];\n this.controlBar.raycast(raycaster, controlButtonIntersects);\n for (const intersect of controlButtonIntersects) {\n intersects.push(intersect);\n }\n }\n return false;\n }\n\n onScaleButtonClick() {\n this.scale.setScalar(1.0);\n }\n\n setCastShadow(castShadow: boolean) {\n this.castShadow = castShadow;\n if (this.gltfMesh) {\n this.gltfMesh.scene.traverse(function(child) {\n child.castShadow = castShadow;\n });\n }\n if (this.platform) {\n this.platform.castShadow = false;\n }\n }\n\n setReceiveShadow(receiveShadow: boolean) {\n this.receiveShadow = receiveShadow;\n if (this.gltfMesh) {\n this.gltfMesh.scene.traverse(function(child) {\n child.receiveShadow = receiveShadow;\n });\n }\n if (this.platform) {\n this.platform.receiveShadow = receiveShadow;\n }\n }\n\n getOcclusionEnabled() {\n for (const shader of this.occludableShaders) {\n return shader.uniforms.occlusionEnabled.value;\n }\n return false;\n }\n\n setOcclusionEnabled(enabled: boolean) {\n for (const shader of this.occludableShaders) {\n shader.uniforms.occlusionEnabled.value = enabled;\n }\n }\n\n playClipAnimationOnce() {\n if (this.startAnimationOnLoad || this.clipActions.length === 0) {\n return;\n }\n\n this.clipActions.forEach((clip) => {\n clip.reset();\n clip.clampWhenFinished = true;\n clip.loop = THREE.LoopOnce;\n clip.play();\n });\n }\n\n async createSparkRendererIfNeeded() {\n // We insert our own SparkRenderer configured to show Gaussians up to\n // Math.sqrt(5) standard deviations from the center, recommended for XR.\n const {SparkRenderer} = await import('@sparkjsdev/spark');\n let sparkRendererExists = false;\n this.scene!.traverse((child) => {\n sparkRendererExists ||= (child instanceof SparkRenderer);\n });\n if (!sparkRendererExists) {\n this.scene!.add(new SparkRenderer(\n {renderer: this.renderer!, maxStdDev: Math.sqrt(5)}));\n }\n }\n}\n","import * as THREE from 'three';\n\n/**\n * Calculates the bounding box for a group of THREE.Object3D instances.\n *\n * @param objects - An array of THREE.Object3D instances.\n * @returns The computed THREE.Box3.\n */\nexport function getGroupBoundingBox(objects: THREE.Object3D[]) {\n const bbox = new THREE.Box3();\n if (objects.length === 0) {\n return bbox;\n }\n\n const parentReferences = new Map();\n for (const child of objects) {\n if (child.parent) {\n parentReferences.set(child, child.parent);\n child.removeFromParent();\n }\n bbox.expandByObject(child, true);\n }\n\n // Restore parent references\n for (const [child, parent] of parentReferences.entries()) {\n parent.add(child);\n }\n return bbox;\n}\n","// Fork of HTMLMesh.js from three.js.\nimport * as THREE from 'three';\n\nimport {SelectEvent} from '../../core/Script';\nimport {User} from '../../core/User';\nimport {View} from '../core/View';\n\ninterface LinePoint {\n x: number;\n y: number;\n b?: boolean;\n}\n\n/**\n * A `View` that functions as a drawable canvas in 3D space. It uses\n * an HTML canvas as a texture on a plane, allowing users to draw on its surface\n * with their XR controllers. It supports basic drawing, undo, and redo\n * functionality.\n */\nexport class SketchPanel extends View {\n static dependencies = {user: User};\n private canvas: HTMLCanvasElement;\n private ctx: CanvasRenderingContext2D;\n private activeHand = -1;\n private activeLine: LinePoint[] = [];\n private activeLines: LinePoint[][] = [];\n private removedLines: LinePoint[][] = [];\n private isDrawing = false;\n\n private user!: User;\n\n material: THREE.MeshBasicMaterial;\n\n constructor() {\n const canvas = document.createElement('canvas');\n canvas.width = 1024;\n canvas.height = 1024;\n\n // Draw something on the canvas\n const ctx = canvas.getContext('2d')!;\n const texture = new THREE.CanvasTexture(canvas);\n\n const geometry =\n new THREE.PlaneGeometry(canvas.width * 0.001, canvas.height * 0.001);\n\n const material = new THREE.MeshBasicMaterial(\n {map: texture, toneMapped: false, alphaTest: 0.01});\n\n super({}, geometry, material);\n this.canvas = canvas;\n this.ctx = ctx;\n this.material = material;\n\n // view options\n this.width = canvas.width * 0.001;\n this.height = canvas.height * 0.001;\n this.scale.set(this.width, this.height, 1);\n }\n\n /**\n * Init the SketchPanel.\n */\n init({user}: {user: User}) {\n super.init();\n this.user = user;\n\n this.clearCanvas();\n }\n\n getContext() {\n return this.ctx;\n }\n\n triggerUpdate() {\n this.material.map!.needsUpdate = true;\n }\n\n onSelectStart(event: SelectEvent) {\n if (this.activeHand !== -1) {\n // do nothing, drawing is in progress\n return;\n }\n this.activeHand = event?.target?.userData?.id ?? -1;\n\n if (this.activeHand === 0 || this.activeHand === 1) {\n this.activeLine = [];\n this.ctx.beginPath();\n }\n }\n\n onSelectEnd(event: SelectEvent) {\n const id = event?.target?.userData?.id ?? -1;\n // check if user released an active hand\n if (id === this.activeHand) {\n // line could be empty, or contain select start only\n if (this.activeHand >= 0 && this.activeLine.length > 1) {\n this.activeLines.push(this.activeLine);\n // Added a new line, no more option for re-do\n this.removedLines = [];\n }\n this.isDrawing = false;\n this.activeLine = [];\n this.activeHand = -1;\n }\n }\n\n /**\n * Updates the painter's line to the current pivot position during selection.\n */\n onSelecting(event: SelectEvent) {\n const id = event.target.userData.id;\n if (id !== this.activeHand) {\n return;\n }\n\n const data = this.user.getReticleIntersection(id);\n\n if (data) {\n if (data.object instanceof SketchPanel && data.uv) {\n const x = Math.round(data.uv.x * 1024);\n const y = Math.round(1024 - data.uv.y * 1024);\n\n const ctx = this.ctx;\n if (this.isDrawing) {\n ctx.lineTo(x, y);\n ctx.strokeStyle = 'black';\n ctx.lineWidth = 6; // You can adjust the line width here\n ctx.stroke();\n\n this.triggerUpdate();\n this.activeLine.push({x, y});\n } else {\n this.activeLine.push({x, y, b: true});\n ctx.moveTo(x, y);\n this.isDrawing = true;\n }\n } else {\n // pointer exit from the SketchPanel\n this.isDrawing = false;\n }\n } else {\n // no plane at the pointer\n this.isDrawing = false;\n }\n }\n\n clearCanvas(forceUpdate = true) {\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n this.ctx.fillStyle = '#FFFFFF';\n this.ctx.fillRect(\n 0, 0, this.canvas.width, this.canvas.height); // Fill the entire canvas\n if (forceUpdate) {\n this.triggerUpdate();\n }\n }\n\n removeAll() {\n this.activeLines = [];\n this.removedLines = [];\n this.clearCanvas();\n }\n\n undo() {\n if (this.activeLines.length === 0) {\n return;\n }\n\n this.ctx = this.canvas.getContext('2d')!;\n\n const line = this.activeLines.pop()!;\n this.removedLines.push(line);\n\n this.clearCanvas(false);\n this.activeLines.forEach((line) => {\n this.#drawLine(line);\n });\n\n this.triggerUpdate();\n }\n\n redo() {\n if (this.removedLines.length === 0) {\n return;\n }\n const line = this.removedLines.pop()!;\n this.activeLines.push(line);\n this.#drawLine(line);\n this.triggerUpdate();\n }\n\n #drawLine(line: LinePoint[]) {\n // common context options\n this.ctx.beginPath();\n this.ctx.strokeStyle = 'black';\n this.ctx.lineWidth = 6;\n\n line.forEach((point) => {\n if (point.b) {\n this.ctx.moveTo(point.x, point.y);\n } else {\n this.ctx.lineTo(point.x, point.y);\n this.ctx.stroke();\n }\n });\n }\n\n update() {\n // empty\n }\n}\n","import * as THREE from 'three';\n\nimport {Pager} from './Pager';\n\n/**\n * A specialized `Pager` that arranges its pages horizontally and\n * enables horizontal swiping gestures for navigation. It clips content that\n * is outside the viewable area.\n */\nexport class HorizontalPager extends Pager {\n localClippingPlanes = [\n new THREE.Plane(new THREE.Vector3(1, 0, 0), 0.5),\n new THREE.Plane(new THREE.Vector3(-1, 0, 0), 0.5),\n ];\n\n updateLayout() {\n super.updateLayout();\n this.localClippingPlanes[0].constant = 0.5 * this.rangeX;\n this.localClippingPlanes[1].constant = 0.5 * this.rangeX;\n }\n}\n","import {TextView} from '../components/TextView';\n\nimport {PagerState} from './PagerState';\n\n/**\n * A UI component that visually displays the current page and total\n * number of pages for a `Pager`. It typically renders as a series of dots\n * (e.g., \"◦ ● ◦\") to indicate the user's position in a carousel.\n */\nexport class PageIndicator extends TextView {\n emptyPageIndicator = '◦';\n currentPageIndicator = '•';\n numberOfPages = 0;\n pagerState: PagerState;\n previousPage = 0;\n\n constructor({pagerState}: {pagerState: PagerState}) {\n super({\n text: '',\n });\n this.pagerState = pagerState;\n this.previousPage = Math.round(pagerState.currentPage);\n this.numberOfPages = pagerState.pages;\n this.updateText();\n }\n\n update() {\n super.update();\n const currentPage = Math.round(this.pagerState.currentPage);\n if (this.previousPage !== currentPage ||\n this.numberOfPages !== this.pagerState.pages) {\n this.updateText();\n }\n }\n\n updateText() {\n const currentPage =\n Math.round(this.pagerState.currentPage) % this.pagerState.pages;\n const text = new Array(this.pagerState.pages).fill(this.emptyPageIndicator);\n text[currentPage] = this.currentPageIndicator;\n this.setText(text.join(''));\n this.previousPage = currentPage;\n }\n}\n","import {StreamState, VideoStream, VideoStreamDetails, VideoStreamOptions} from './VideoStream';\n\ntype VideoFileStreamDetails = VideoStreamDetails&{\n width?: number;\n height?: number;\n aspectRatio?: number;\n videoFile?: string|File;\n}\n\nexport type VideoFileStreamOptions = VideoStreamOptions&{\n /** The video file path, URL, or File object. */\n videoFile?: string|File;\n};\n\n/**\n * VideoFileStream handles video playback from a file source.\n */\nexport class VideoFileStream extends VideoStream<VideoFileStreamDetails> {\n private videoFile_?: string|File;\n\n /**\n * @param options - Configuration for the file stream.\n */\n constructor({videoFile = undefined, willCaptureFrequently = false} = {}) {\n super({willCaptureFrequently});\n this.videoFile_ = videoFile;\n }\n\n /**\n * Initializes the file stream based on the given video file.\n */\n async init() {\n await super.init();\n if (this.videoFile_) {\n this.setState_(StreamState.INITIALIZING);\n await this.initStream_();\n } else {\n console.warn('VideoFileStream initialized without a video file.');\n this.setState_(StreamState.IDLE);\n }\n }\n\n /**\n * Initializes the video stream from the provided file.\n */\n protected async initStream_() {\n if (!this.videoFile_) {\n throw new Error('No video file has been provided.');\n }\n\n this.stop_();\n\n this.video_.srcObject = null;\n this.video_.src = typeof this.videoFile_ === 'string' ?\n this.videoFile_ :\n URL.createObjectURL(this.videoFile_);\n this.video_.loop = true;\n this.video_.muted = true;\n\n await new Promise<void>((resolve, reject) => {\n this.video_.onloadedmetadata = () => {\n this.handleVideoStreamLoadedMetadata(resolve, reject);\n };\n this.video_.onerror = () => {\n const error = new Error('Error occurred while loading the video file.');\n this.setState_(StreamState.ERROR, {error});\n reject(error);\n };\n this.video_.play();\n });\n\n // After metadata is loaded, set the final STREAMING state\n this.setState_(StreamState.STREAMING, {\n width: this.width,\n height: this.height,\n aspectRatio: this.aspectRatio,\n videoFile: this.videoFile_\n });\n }\n\n /**\n * Sets a new video file source and re-initializes the stream.\n * @param videoFile - The new video file to play.\n */\n async setSource(videoFile: string|File) {\n if (!videoFile) {\n console.warn('setSource called with no file. Stopping stream.');\n this.stop_();\n this.videoFile_ = undefined;\n return;\n }\n this.setState_(StreamState.INITIALIZING);\n this.videoFile_ = videoFile;\n await this.initStream_();\n }\n}\n"],"names":["Context","constructor","instructions","this","instruction","build","memory","tools","formattedHistory","getShortTerm","map","entry","formatEntry","join","toolDescriptions","tool","name","description","role","content","Memory","shortTermMemory","addShortTerm","push","clear","length","Agent","dependencies","ai","callbacks","isSessionActive","contextBuilder","lifecycleCallbacks","start","prompt","isAvailable","init","aiOptions","options","run","context","response","model","query","type","text","JSON","stringify","toolCall","console","log","finalResponse","error","findTool","result","execute","args","errorMsg","find","getSessionState","isActive","toolCount","memorySize","Tool","parameters","onTriggered","success","data","Promise","resolve","metadata","executedAt","Date","now","toolName","Error","message","String","toJSON","GenerateSkyboxTool","scene","super","properties","required","image","generate","background","THREE","TextureLoader","load","mapping","EquirectangularReflectionMapping","timestamp","e","SkyboxAgent","sound","sessionState","messageCount","toolCallCount","startLiveSession","wrappedCallbacks","wrapCallbacks","setLiveCallbacks","functionDeclarations","systemInstruction","parts","startTime","onSessionStart","stopLiveSession","endTime","onSessionEnd","onopen","onmessage","onerror","lastError","onError","onclose","event","sendToolResponse","validateToolResponse","responses","Array","isArray","functionResponses","every","fr","id","undefined","createToolResponse","getLiveSessionState","getSessionDuration","GetWeatherTool","location","unit","enum","latitude","longitude","url","fetch","json","ok","temperature","current","temperature_2m","weathercode","weather_code","UX","parent","draggable","selectable","touchable","selected","hovered","touched","activeDragged","positions","distances","uvs","initialPosition","Vector3","isHovered","includes","isSelected","isDragging","update","controller","intersection","userData","initializeVariablesForId","object","mesh","uv","copy","point","distance","Vector2","reset","i","getPrimaryTwoControllerIds","activeControllerIds","ScriptMixin","base","ux","isXRScript","_","_time","_frame","initPhysics","_physics","physicsStep","onXRSessionStarted","_session","onXRSessionEnded","onSimulatorStarted","onSelectStart","_event","onSelectEnd","onSelect","onSelecting","onKeyDown","onKeyUp","onSqueezeStart","onSqueezeEnd","onSqueezing","onSqueeze","onObjectSelectStart","onObjectSelectEnd","onHoverEnter","_controller","onHoverExit","onHovering","onObjectTouchStart","onObjectTouching","onObjectTouchEnd","onObjectGrabStart","onObjectGrabbing","onObjectGrabEnd","dispose","ScriptMixinObject3D","Object3D","Script","ScriptMixinMeshScript","Mesh","MeshScript","geometry","material","clamp","value","min","max","Math","lerp","x","y","t","print","urlParams","URLSearchParams","window","search","getUrlParameter","get","getUrlParamBool","defaultBool","inputString","toLowerCase","getUrlParamInt","defaultNumber","inputNumber","num","parseInt","isNaN","getUrlParamFloat","parseFloat","getVec4ByColorString","colorString","hex","startsWith","slice","len","alpha","expandedHex","split","char","r","g","b","Vector4","getColorHex","fontColor","vec4","round","z","parseBase64DataURL","dataURL","match","mimeType","strippedBase64","substring","GeminiOptions","apiKey","urlParam","keyValid","enabled","config","live","voiceName","screenshotInterval","audioConfig","sampleRate","channelCount","echoCancellation","noiseSuppression","autoGainControl","OpenAIOptions","AIOptions","gemini","openai","globalUrlParams","key","BaseAIModel","createPartFromUri","createUserContent","GoogleGenAI","EndSensitivity","StartSensitivity","Modality","Gemini","inited","isLiveMode","liveCallbacks","async","genAIModule","import","errorMessage","loadGoogleGenAIModule","isLiveAvailable","params","liveSession","defaultConfig","responseModalities","AUDIO","speechConfig","voiceConfig","prebuiltVoiceConfig","outputAudioTranscription","inputAudioTranscription","reason","warn","connectParams","connect","close","debug","sendRealtimeInput","input","getLiveSessionStatus","hasSession","_tools","models","generateContent","contents","modelParams","inlineData","base64","uri","functionCalls","item","header","candidates","firstCandidate","part","OpenAIApi","OpenAI","openAIModule","default","loadOpenAIModule","dangerouslyAllowBrowser","chat","completions","create","messages","choices","SUPPORTED_MODELS","AI","lock","loadKeysFromFile","keysCache","modelName","ModelClass","modelOptions","initializeModel","resolveApiKey","isValidApiKey","genericKey","modelKey","geminiKey64","atob","keysFromFile","modelNameWithApiKeySuffix","keyFromFile","triggerKeyPopup","createSampleKeysStructure","hasApiKey","NUM_HANDS","HAND_JOINT_COUNT","HAND_JOINT_IDX_CONNECTION_MAP","HAND_BONE_IDX_CONNECTION_MAP","VIEW_DEPTH_GAP","LEFT_VIEW_ONLY_LAYER","RIGHT_VIEW_ONLY_LAYER","OCCLUDABLE_ITEMS_LAYER","UI_OVERLAY_LAYER","DEFAULT_DEVICE_CAMERA_WIDTH","DEFAULT_DEVICE_CAMERA_HEIGHT","XR_BLOCKS_ASSETS_PATH","deepFreeze","obj","Object","freeze","getOwnPropertyNames","forEach","prop","isFrozen","deepMerge","obj1","obj2","merged","prototype","hasOwnProperty","call","val1","val2","DeviceCameraOptions","willCaptureFrequently","baseCaptureOptions","videoConstraints","width","ideal","height","xrDeviceCameraEnvironmentOptions","facingMode","xrDeviceCameraUserOptions","xrDeviceCameraEnvironmentContinuousOptions","xrDeviceCameraUserContinuousOptions","onDesktopUserAgent","test","navigator","userAgent","DepthMeshTexturedShader","vertexShader","fragmentShader","DepthMesh","camera","Camera","renderer","WebGLRenderer","isDepthMesh","depthOptions","depthTextures","depthMesh","PlaneGeometry","uniforms","useDepthTexture","showDebugTexture","uDepthTexture","uDepthTextureArray","uIsTextureArray","uColor","Color","uResolution","uRawValueToMeters","uMinDepth","uMaxDepth","uOpacity","opacity","uDebug","uLightDirection","normalize","uUsingFloatDepth","useFloat32","ShaderMaterial","side","FrontSide","transparent","ShadowMaterial","shadowOpacity","depthWrite","ignoreReticleRaycast","worldPosition","worldQuaternion","Quaternion","updateVertexNormals","minDepth","maxDepth","minDepthPrev","maxDepthPrev","colliders","projectionMatrixInverse","Matrix4","lastColliderUpdateTime","colliderId","visible","renderShadow","performance","colliderUpdateFps","depthTextureMaterialUniforms","receiveShadow","castShadow","useDownsampledGeometry","downsampledGeometry","downsampledMesh","add","updateDepth","depthData","xr","getCamera","cameras","projectionMatrix","invert","updateFullResolutionGeometry","updateGeometry","attributes","position","needsUpdate","depthTextureLeft","isTextureArray","ExternalTexture","rawValueToMeters","computeVertexNormals","updateColliderIfNeeded","updateGPUDepth","convertGPUToGPU","depthTarget","WebGLRenderTarget","format","RedFormat","FloatType","internalFormat","minFilter","NearestFilter","magFilter","depthBuffer","depthTexture","texture","__webglTexture","gpuPixels","Float32Array","depthShader","uTexture","uCameraNear","depthNear","blending","NoBlending","depthTest","DoubleSide","depthScene","Scene","depthCamera","OrthographicCamera","originalRenderTarget","getRenderTarget","setRenderTarget","render","readRenderTargetPixels","buffer","depthArray","Uint16Array","vertexPosition","count","u","array","v","depthX","rawDepth","depth","patchHoles","patchHolesUpper","set","applyMatrix4","multiplyScalar","timeSinceLastUpdate","RAPIER","getWorldPosition","getWorldQuaternion","rigidBody","setTranslation","setRotation","vertices","indices","getIndex","shape","ColliderDesc","trimesh","setDensity","useDualCollider","blendedWorld","removeCollider","createCollider","newCollider","collider","initRapierPhysics","desc","RigidBodyDesc","fixed","createRigidBody","getDepth","raycaster","ndc","ndc2D","setFromCamera","intersects","intersectObject","raycast","intersections","intersect","normal","face","getColliderFromHandle","handle","DepthMeshOptions","DepthOptions","debugging","constantKernel","applyGaussianBlur","applyKawaseBlur","occlusion","xrDepthMeshOptions","xrDepthMeshVisualizationOptions","xrDepthMeshPhysicsOptions","DepthTextures","uint16Arrays","uint8Arrays","dataTextures","nativeTextures","createDataDepthTextures","view_id","typedArray","HalfFloatType","DataTexture","Uint8Array","RGFormat","UnsignedByteType","updateData","float32Data","float16Data","DataUtils","toHalfFloat","updateNativeTexture","sourceTexture","textureProperties","__version","KawaseBlurShader","OcclusionShader","OcclusionMapShader","OcclusionMapMeshMaterial","MeshBasicMaterial","useFloatDepth","uViewId","cameraFar","far","cameraNear","near","uFloatDepth","uDepthNear","onBeforeCompile","shader","assign","replace","KawaseBlurMode","OcclusionPass","Pass","renderToScreen","occludableItemsLayer","occlusionMeshMaterial","occlusionMapUniforms","uUvTransform","uAlpha","tDiffuse","tDepth","occlusionMapQuad","FullScreenQuad","occlusionMapTexture","kawaseBlurTargets","kawaseBlurQuads","setupKawaseBlur","DOWN","UP","occlusionUniforms","tOcclusionMap","occlusionQuad","mode","inputTexture","uBlurSize","uTexelSize","kawase1Material","defines","MODE","setDepthTexture","viewId","writeBuffer","readBuffer","dimensions","renderOcclusionMapFromScene","renderOcclusionMapFromReadBuffer","blurOcclusionMap","applyOcclusionMapToRenderedImage","overrideMaterial","getDrawingBufferSize","setSize","renderTarget","originalCameraLayers","from","keys","filter","element","layers","isEnabled","disableAll","enable","updateOcclusionMapUniforms","uOcclusionClipFromWorld","multiply","matrixWorldInverse","clipSpacePosition","Depth","view","cpuDepthData","gpuDepthData","occludableShaders","Set","depthClientsInitialized","depthClients","instance","registry","register","shadowMap","PCFShadowMap","occlusionPass","depthY","getProjectedDepthViewPositionFromWorldPosition","target","getVertex","updateCPUDepthData","updateGPUDepthData","cpuDepth","getTexture","frame","updateLocalDepth","renderOcclusionPass","leftCamera","session","binding","getBinding","depthActive","needsDepth","size","pauseDepthSensing","resumeDepthSensing","xrRefSpace","requestReferenceSpace","then","refSpace","addEventListener","pose","getViewerPose","views","depthUsage","getDepthInformation","leftDepthTexture","rightDepthTexture","xrIsPresenting","isPresenting","debugLog","arrayBuffer","uint8Array","binaryString","byte","fromCharCode","data_str","btoa","resumeDepth","client","pauseDepth","delete","aspectRatios","RGB","rgbToDepthParams","scale","scaleX","scaleY","translateU","translateV","k1","k2","k3","p1","p2","xc","yc","transformRgbToDepthUv","rgbUv","xrDeviceCamera","simulatorCamera","viewportAspect","innerWidth","innerHeight","cameraAspect","relativeWidth","relativeHeight","relativeScaleX","relativeScaleY","u_norm","v_norm","u_centered","v_centered","r2","radial","transformRgbUvToWorld","viewProjectionMatrix","matrixWorld","xrDepth","depthUV","depthU","depthV","rawDepthValue","depthInMeters","viewSpacePosition","viewProjectionMatrixInverse","clone","cropImage","base64Image","boundingBox","img","Image","reject","onload","err","src","canvas","document","createElement","ctx","getContext","unitBox","Box2","clampedBox","cropSize","getSize","sourceX","sourceY","sourceWidth","sourceHeight","drawImage","toDataURL","StreamState","VideoStream","loaded","state","IDLE","stream_","video_","frozenTexture_","canvas_","context_","willCaptureFrequently_","autoplay","muted","playsInline","VideoTexture","colorSpace","SRGBColorSpace","LinearFilter","setState_","details","force","dispatchEvent","handleVideoStreamLoadedMetadata","allowRetry","videoWidth","videoHeight","aspectRatio","setTimeout","ERROR","getSnapshot","outputFormat","quality","readyState","HAVE_CURRENT_DATA","getImageData","frozenTexture","Texture","stop_","getTracks","track","stop","srcObject","URL","revokeObjectURL","XRDeviceCamera","isInitializing_","availableDevices_","currentDeviceIndex_","videoConstraints_","getAvailableVideoDevices","mediaDevices","enumerateDevices","devices","simulatorDevices","device","kind","INITIALIZING","initStream_","NO_DEVICES_FOUND","currentTrackSettings_","stream","deviceIdConstraint","deviceId","targetDeviceId","exact","d","groupId","getMedia","getUserMedia","video","videoTracks","getVideoTracks","activeTrack","getSettings","findIndex","onloadedmetadata","play","getCurrentDevice","trackSettings","STREAMING","setDeviceId","newIndex","setFacingMode","getAvailableDevices","getCurrentTrackSettings","getCurrentDeviceIndex","registerSimulatorCamera","Registry","instances","Map","registrationType","getOrCreate","factory","unregister","flipBufferVertically","bytesPerRow","tempRow","topRowOffset","bottomRowOffset","subarray","PendingScreenshotRequest","overlayOnCamera","ScreenshotSynthesizer","pendingScreenshotRequests","virtualBuffer","virtualRealBuffer","renderTargetWidth","onAfterRender","renderSceneFn","deviceCamera","request","createVirtualImageDataURL","virtualImageDataUrl","resolveVirtualOnlyRequests","haveVirtualAndRealReqeusts","some","createVirtualRealImageDataURL","virtualRealImageDataUrl","resolveVirtualRealRequests","mainRenderTarget","mainRenderTargetSingleViewWidth","scaledHeight","virtualRenderTarget","clearColor","clearDepth","expectedBufferLength","readRenderTargetPixelsAsync","virtualCanvas","imageData","ImageData","Uint8ClampedArray","putImageData","remainingRequests","virtualRealRenderTarget","quad","getFullScreenQuad","virtualRealCanvas","fullScreenQuad","getScreenshot","ScriptsManager","initScriptFunction","scripts","callSelectStartBound","callSelectStart","bind","callSelectEndBound","callSelectEnd","callSelectBound","callSelect","callSqueezeStartBound","callSqueezeStart","callSqueezeEndBound","callSqueezeEnd","callSqueezeBound","callSqueeze","callKeyDownBound","callKeyDown","callKeyUpBound","callKeyUp","initializingScripts","initScript","script","has","uninitScript","syncScriptsWithScene","seenScripts","promises","traverse","allSettled","WaitFrame","onFrame","callback","waitFrame","WebXRSessionEventType","WebXRSessionManager","EventDispatcher","sessionInit","onSessionEndedBound","onSessionEndedInternal","initialize","xrModeSupported","UNSUPPORTED","modeSupported","isSessionSupported","sessionOptions","optionalFeatures","READY","offerSession","onSessionStartedInternal","catch","startSession","currentSession","requestSession","endSession","end","isXRSupported","setSession","SESSION_START","SESSION_END","removeEventListener","XRBUTTON_CLASS","XRButton","sessionManager","startText","endText","invalidText","startSimulatorText","enableSimulator","showSimulatorButtonOnMobile","startSimulator","domElement","simulatorButtonElement","xrButtonElement","createXRButtonElement","createSimulatorButton","showXRNotSupported","onSessionReady","onSessionStarted","onSessionEnded","classList","innerText","onclick","remove","appendChild","disabled","textContent","button","style","display","innerHTML","XRPass","_renderer","_writeBuffer","_readBuffer","_deltaTime","_maskActive","_viewId","XREffects","timer","passes","renderTargets","addPass","pass","setupRenderTargets","defaultTarget","neededRenderTargets","DepthTexture","cameraAutoUpdate","renderXr","renderSimulator","xrEnabled","viewport","getViewport","deltaTime","getDelta","camIndex","cam","setViewport","autoClearColor","eye","lastRenderTargetIndex","nextRenderTargetIndex","HAND_JOINT_NAMES","Handedness","Hands","hands","dominant","RIGHT","getJoint","jointName","targetHandednessEnum","resolvedHandednessEnum","NONE","hand","joints","getIndexTip","handedness","getThumbTip","getMiddleTip","getRingTip","getPinkyTip","getWrist","toString","s","LEFT","joint","toFixed","toPositionQuaternionArray","orderedHandedness","numJoints","handDataAvailable","quaternion","w","expectedSize","isValid","handIndex","ReticleShader","setHex","uPressed","Reticle","rotationSmoothing","offset","CircleGeometry","makeTranslation","UniformsUtils","direction","renderOrder","originalNormal","newRotation","objectRotation","normalVector","setRotationFromNormalVector","angle","angleTo","cross","setFromAxisAngle","slerp","setPoseFromIntersection","applyQuaternion","setColor","color","getColor","setPressed","pressed","setScalar","setPressedAmount","pressedAmount","ControllerRayVisual","Line","BufferGeometry","setFromPoints","AnimatableNumber","minValue","maxValue","speed","deltaTimeSeconds","GazeController","connected","reticle","activationTimeSeconds","activationAmount","lastReticlePosition","clock","Clock","updateMatrixWorld","delta","distanceTo","updateReticleScale","disconnect","MouseController","Raycaster","forwardVector","updateMousePositionFromEvent","mouse","clientX","clientY","rayDirection","ray","setFromUnitVectors","ActiveControllers","MATRIX4","Input","controllers","controllerGrips","initialized","pivotsEnabled","gazeController","mouseController","controllersEnabled","listeners","intersectionsForController","activeControllers","getController","visualization","controllerModelFactory","XRControllerModelFactory","getControllerGrip","createControllerModel","getHand","visualizeJoints","handModelFactory","XRHandModelFactory","handModel","createHandModel","visualizeMeshes","visualizeRays","bindSelectStart","defaultOnSelectStart","bindSelectEnd","defaultOnSelectEnd","bindSqueezeStart","bindSqueezeEnd","bindListener","defaultOnConnected","defaultOnDisconnected","addObject","group","Group","enablePivots","pivot","IcosahedronGeometry","addReticles","_setRaycasterFromController","performRaycastOnScene","defaultOnSqueezeStart","squeezing","defaultOnSqueezeEnd","gamepad","inputSource","leftController","rightController","listenerName","listener","unbindListener","index","indexOf","splice","bindSelect","bindSqueeze","bindKeyDown","bindKeyUp","unbindKeyDown","unbindKeyUp","intersectObjectByController","setFromXRController","intersectObjectByEvent","updateController","updateReticleFromIntersections","origin","identity","extractRotation","enableGazeController","disableGazeController","disableControllers","targetObject","enableControllers","Lighting","dirLight","DirectionalLight","ambientProbe","LightProbe","ambientLight","lightGroup","simulatorRunning","lightingOptions","xrLight","XREstimatedLight","castDirectionalLightShadow","shadow","mapSize","cameraFrustrumRadius","left","right","top","bottom","blurSamples","radius","bias","CameraHelper","useAmbientSH","useDirectionalLight","directionalLight","intensity","sh","lightProbe","coefficients","fromArray","useDynamicSoftShadow","ambientLightIntensity","ambientMonoIntensity","mainLightIntensity","ambientToMain","Physics","fps","timestep","physicsOptions","World","gravity","useEventQueue","eventQueue","EventQueue","worldStep","step","free","HandsOptions","enableHands","enableHandsVisualization","LightingOptions","PhysicsOptions","SimulatorMode","NEXT_SIMULATOR_MODE","USER","POSE","CONTROLLER","SimulatorOptions","initialCameraPosition","scenePath","initialScenePosition","defaultMode","defaultHand","modeIndicator","customInstructions","handPosePanel","geminilive","stereo","renderToRenderTexture","blendingMode","SpeechSynthesizerOptions","allowInterruptions","SpeechRecognizerOptions","lang","continuous","commands","interimResults","commandConfidenceThreshold","playSimulatorActivationSounds","SoundOptions","speechSynthesizer","speechRecognizer","ObjectsOptions","showDebugVisualizations","objectImageMargin","backendConfig","activeBackend","responseSchema","items","objectName","ymin","xmin","ymax","xmax","mediapipe","PlanesOptions","WorldOptions","planes","objects","enablePlaneDetection","enableObjectDetection","InputOptions","enabledMouse","ReticleOptions","XRTransitionOptions","transitionTime","defaultBackgroundColor","Options","antialias","logarithmicDepthBuffer","stencil","webxrRequiredFeatures","referenceSpaceType","lighting","reticles","simulator","world","physics","transition","usePostprocessing","xrButton","autostartSimulatorOnDesktop","autostartSimulator","enableUI","enableReticles","enableDepth","enableCamera","enableHandRays","enableGeminiLive","enableAI","enableXRTransitions","SimulatorMediaDeviceInfo","label","ConstrainDomStringMatch","SimulatorCamera","cameraCreated","matchRenderingCamera","PerspectiveCamera","createSimulatorCamera","mediaStream","captureStream","videoTrack","cameraInfo","onBeforeSimulatorSceneRender","renderScene","sWidth","sHeight","croppedSourceWidth","croppedSourceHeight","sx","sy","onSimulatorSceneRendered","restartVideoTrack","constraints","constraint","matches","c","ACCEPTABLE","EXACT","UNACCEPTABLE","IDEAL","evaluateConstrainDOMString","AVERAGE_IPD_METERS","SimulatorRenderMode","Keycodes","SimulatorControllerState","localControllerPositions","localControllerOrientations","currentControllerIndex","A_CODE","D_CODE","E_CODE","Q_CODE","S_CODE","W_CODE","vector3","euler","Euler","SimulatorControlMode","simulatorControllerState","downKeys","setStereoRenderMode","toggleUserInterface","onPointerDown","onPointerUp","onPointerMove","code","DIGIT_1","STEREO_LEFT","DIGIT_2","STEREO_RIGHT","BACKQUOTE","onModeActivated","onModeDeactivated","updateCameraPosition","updateControllerPositions","cameraRotation","cameraPosition","Number","premultiply","updateMatrix","rotateOnPointerMove","objectQuaternion","multiplier","setFromQuaternion","movementX","movementY","PI_2","PI","setFromEuler","enableSimulatorHands","showHands","disableSimulatorHands","hideHands","SPACE_CODE","T_CODE","SimulatorControllerMode","buttons","controllerOrientation","toggleControllerIndex","toggleHandedness","controllerSelecting","newSelectingState","setLeftHandPinching","setRightHandPinching","SimulatorPoseMode","SimulatorUserMode","SetSimulatorModeEvent","Event","simulatorMode","bubbles","composed","preventDefault","SimulatorControls","userInterface","pointerDown","_onPointerDown","_onPointerUp","_onKeyDown","_onKeyUp","_onPointerMove","toggleInterfaceVisible","simulatorModes","simulatorModeControls","simulatorOptions","setSimulatorMode","LEFT_SHIFT_CODE","modeIndicatorElement","setModeIndicatorElement","SimulatorDepthMaterial","SimulatorDepth","simulatorScene","depthWidth","depthHeight","depthBufferSlice","createRenderTarget","depthMaterial","depthRenderTarget","renderDepthScene","bindBuffer","PIXEL_PACK_BUFFER","j","i_offset","j_offset","copyWithin","SimulatorHandPoseChangeRequestEvent","SimulatorHandPose","SIMULATOR_HAND_POSE_TO_JOINTS_LEFT","RELAXED","PINCHING","FIST","THUMBS_UP","POINTING","ROCK","THUMBS_DOWN","VICTORY","SIMULATOR_HAND_POSE_TO_JOINTS_RIGHT","SIMULATOR_HAND_POSE_NAMES","SimulatorXRHand","SimulatorHands","leftHandBones","rightHandBones","leftHandPose","rightHandPose","leftHandTargetJoints","rightHandTargetJoints","lerpSpeed","onHandPoseChangeRequestBound","onHandPoseChangeRequest","leftXRHand","rightXRHand","loadMeshes","loader","GLTFLoader","setPath","gltf","leftHand","bone","getObjectByName","setLeftHandJoints","rightHand","setRightHandJoints","setLeftHandLerpPose","updateHandPosePanel","setRightHandLerpPose","jointData","lerpLeftHandPose","lerpRightHandPose","syncHandJoints","targetJoint","updateWorldMatrix","setFromMatrixPosition","setRotationFromMatrix","pinching","handPosePanelElement","handPose","setHandPosePanelElement","handPoseChangeEvent","SimulatorInterface","elements","interfaceVisible","simulatorControls","simulatorHands","createModeIndicator","showGeminiLivePanel","createHandPosePanel","showInstructions","body","handsPanelElement","hideUiElements","showUiElements","getInterfaceVisible","SimulatorScene","addLights","loadGLTF","HemisphereLight","path","callInitWithDependencyInjection","fallback","fromEntries","entries","dependency","SimulatorUser","journeyId","stopJourney","isOnJourneyId","loadJourney","actions","currentJourneyId","simulatorUser","Simulator","Timer","renderMainScene","controls","renderDepthPass","renderMode","DEFAULT","stereoCameras","renderSimulatorSceneToCanvasBound","renderSimulatorSceneToCanvas","setupStereoCameras","virtualSceneRenderTarget","stencilBuffer","virtualSceneMaterial","CustomBlending","blendSrc","OneFactor","blendDst","OneMinusSrcColorFactor","blendEquation","AddEquation","virtualSceneFullScreenQuad","mainCamera","mainScene","simulatorUpdate","rightCamera","getRenderCamera","stencilEnabled","renderSimulatorScene","AudioListener","isCapturing","latestAudioBuffer","accumulatedChunks","isAccumulating","startCapture","onAudioData","accumulate","setupAudioCapture","cleanup","stopCapture","audioStream","audio","actualSampleRate","getAudioTracks","audioContext","AudioContext","setupAudioWorklet","sourceNode","createMediaStreamSource","processorNode","AudioWorkletNode","port","streamToAI","resume","blob","Blob","processorURL","createObjectURL","audioWorklet","addModule","audioBuffer","aiService","base64Audio","bytes","binary","arrayBufferToBase64","setAIStreaming","isSupported","getIsCapturing","getLatestAudioBuffer","clearLatestAudioBuffer","getAccumulatedBuffer","totalLength","reduce","sum","chunk","byteLength","combined","ArrayBuffer","combinedArray","clearAccumulatedBuffer","getAccumulatedChunkCount","AudioPlayer","audioQueue","nextStartTime","volume","category","setCategoryVolumes","categoryVolumes","updateGainNodeVolume","setVolume","level","gainNode","effectiveVolume","getEffectiveVolume","gain","initializeAudioContext","currentTime","createGain","destination","playAudioChunk","base64AudioData","base64ToArrayBuffer","createBuffer","channelData","getChannelData","int16View","Int16Array","scheduleAudioBuffers","shift","source","createBufferSource","onended","duration","clearQueue","getIsPlaying","getQueueLength","charCodeAt","MUSIC_LIBRARY_PATH","musicLibrary","ambient","buttonHover","buttonPress","menuDismiss","BackgroundMusic","audioLoader","AudioLoader","currentAudio","isPlaying","specificVolume","musicCategory","MathUtils","playMusic","musicKey","soundPath","stopMusic","Audio","setBuffer","setLoop","xhr","total","destroy","VolumeCategory","CategoryVolumes","isMuted","masterVolume","volumes","values","cat","getCategoryVolume","categoryVol","clampedSpecificVolume","SOUND_PRESETS","BEEP","frequency","waveformType","CLICK","delay","ACTIVATE","DEACTIVATE","SoundSynthesizer","isInitialized","_initAudioContext","playTone","oscillator","createOscillator","setValueAtTime","stopTime","fadeOutTime","exponentialRampToValueAtTime","playPresetTone","presetName","preset","toneConfig","tone","spatialSoundLibrary","paintOneShot1","soundIdCounter","SpatialAudio","soundLibrary","activeSounds","defaultRefDistance","defaultRolloffFactor","playSoundAtObject","soundKey","soundId","loop","refDistance","rolloffFactor","PositionalAudio","setRefDistance","setRolloffFactor","onEnded","_cleanupSound","uuid","stopSound","soundData","updateAllVolumes","SpeechRecognizer","soundOptions","soundSynthesizer","isListening","lastTranscript","lastConfidence","playActivationSounds","handleStartBound","_handleStart","handleResultBound","_handleResult","handleEndBound","_handleEnd","handleErrorBound","_handleError","SpeechRecognitionAPI","SpeechRecognition","webkitSpeechRecognition","recognition","onstart","onresult","onend","lastCommand","getLastTranscript","getLastCommand","getLastConfidence","interimTranscript","finalTranscript","currentConfidence","resultIndex","results","transcript","isFinal","confidence","trim","upperTranscript","toUpperCase","command","originalEvent","SpeechSynthesizer","onStartCallback","onEndCallback","onErrorCallback","synth","speechSynthesis","voices","isSpeaking","speechCategory","loadVoices","onvoiceschanged","getVoices","selectedVoice","voice","speak","pitch","rate","cancel","utterance","SpeechSynthesisUtterance","tts","speaking","CoreSound","backgroundMusic","spatialAudio","audioListener","audioPlayer","getAudioListener","setMasterVolume","getMasterVolume","setCategoryVolume","enableAudio","disableAudio","startRecording","stopRecording","getRecordedBuffer","clearRecordedBuffer","getRecordingSampleRate","isAIStreamingEnabled","playAIAudio","stopAIAudio","isAIAudioPlaying","playRecordedAudio","isAudioEnabled","muteAll","unmuteAll","DP_TO_DMM","worldScale","View","rangeX","rangeY","isQuad","isRoot","isView","weight","paddingX","paddingY","paddingZ","dpToMeters","dp","dpToLocalUnits","getWorldScale","show","child","hide","updateLayout","updateLayouts","updateLayoutsBFS","queue","currentView","children","childView","resetLayout","resetLayouts","_id","FONT_FAMILIES","MATERIAL_ICONS_FONT_FILE","TroikaImportStatus","Text","troikaImportError","troikaImportStatus","PENDING","TextView","_text","useSDFText","textObj","sync","updateHTMLText","font","maxWidth","anchorX","anchorY","textAlign","imageOffsetX","imageOffsetY","lineHeight","lineCount","_initializeTextCalled","fontSize","fontSizeDp","imageOverlay","troikaModule","SUCCESS","FAILED","importTroika","_initializeText","setText","createTextSDF","mask","createTextHTML","planeGeometry","CanvasTexture","planeMaterial","clearRect","fillStyle","padStart","textBaseline","fillText","onSyncComplete","textRenderInfo","caretPositions","numberOfChars","firstBottom","lastBottom","syncTextObj","setTextColor","IconButton","backgroundColor","defaultOpacity","hoverColor","hoverOpacity","selectedOpacity","onHoverOver","onHoverOut","IconView","ImageView","initCalled","textureLoader","reload","loadedTexture","scaleImageToCorrectAspectRatio","textureWidth","textureHeight","widthScaleFactor","heightScaleFactor","minScaleFactor","LabelView","depthText","SquircleShader","uMainTex","uUseImage","uBackgroundColor","uBoxSize","uRadius","TextButton","colorVec4","boxSize","uAspect","selectedFontColor","VideoView","crossOrigin","videoAspectRatio","videoGeometry","videoMaterial","loadFromVideoTexture","HTMLVideoElement","loadFromVideoElement","loadFromURL","loadFromStream","disposeStreamListener_","streamReadyCallback_","videoElement","paused","videoTextureInstance","onLoadedMetadata","HAVE_METADATA","once","pause","removeAttribute","objectIsDescendantOf","currentNode","traverseUtil","node","User","local","numHands","panelDistance","safeSpaceRadius","objectDistance","objectAngle","pivots","hoveredObjectsForController","selectedObjectsForController","touchedObjects","grabbedObjects","setHeight","getPivot","getPivotPosition","getReticleDirection","controllerId","getReticleTarget","getReticleIntersection","isPointingAt","isSelectingAt","getIntersectionAt","getControllerPosition","getControllerObjectDistance","controllerPos","objPos","isSelecting","isSqueezing","callObjectSelectStart","selectedObject","callObjectSelectEnd","ancestor","updateForController","updateTouchState","updateGrabState","isPinching","touchedMeshes","currentlyGrabbedMeshes","previouslyGrabbedMeshesMap","newlyGrabbedMeshes","releasedMeshes","grabEvent","callObjectGrabStart","callObjectGrabEnd","callObjectGrabbing","indexTip","indexTipPosition","currentlyTouchedMeshes","isMesh","Box3","setFromObject","containsPoint","previouslyTouchedMeshes","currentMeshesSet","newlyTouchedMeshes","removedMeshes","touchingEvent","touchPosition","callObjectTouchStart","callObjectTouchEnd","callObjectTouching","currentHoverTarget","previousHoverTarget","callHoverExit","callHoverEnter","callOnHovering","select","FORWARD","BACK","ZERO_VECTOR3","_quaternion","_euler","_vector3","DragMode","DragManager","originalObjectPosition","originalObjectRotation","originalObjectScale","originalController1Position","originalController1RotationInverse","originalController1MatrixInverse","originalScalingControllerDistance","originalScalingObjectScale","TRANSLATING","ROTATING","SCALING","DO_NOT_DRAG","beginDragging","draggableObject","updateDragging","draggingMode","findDraggableObjectAndDraggingMode","beginScaling","compose","controller1","controller2","subVectors","updateTranslating","updateRotating","updateScaling","matrix","dragFacingCamera","turnPanelToFaceTheCamera","updateRotatingFromMouseController","deltaPosition","offsetRotation","multiplyQuaternions","deltaRotation","rotationYawAngle","distanceRatio","atan2","currentTarget","ExitButton","getSession","Grid","rowWeight","colWeight","leftWeight","topWeight","cols","rows","RowClass","ColClass","PanelClass","OrbiterClass","addImage","addVideo","addIconButton","iconButton","addTextButton","addIcon","iconView","addText","textView","addLabel","labelView","addOrbiter","ui","addExitButton","addPanel","panel","addRow","row","addCol","col","SpatialPanelShader","uReticleUVs","uSelected","uBorderWidth","uHighlightRadius","uOutlineWidth","PanelMesh","panelScale","setWidthHeight","setAspectRatio","DEFAULT_WIDTH_M","DEFAULT_WIDTH_DP","DEFAULT_HEIGHT_M","DEFAULT_HEIGHT_DP","Panel","user","keepFacingCamera","isPanel","useDefaultPosition","useBorderlessShader","showHighlights","_fadeState","_fadeDuration","_fadeTimer","_currentOpacity","_startOpacity","_targetOpacity","isDraggable","fadeIn","onComplete","_startFade","fadeOut","targetOpacity","onFadeComplete","_completeFade","_prepareMaterialsForFade","_applyOpacity","opacityValue","progress","addGrid","grid","parentAspectRatio","getWidth","getHeight","Col","Orbiter","Row","SpatialPanel","showEdge","_updateInteractionFeedback","id1","id2","isSelected1","isSelected2","u1","v1","u2","v2","UI","ComponentRegistry","registerComponent","typeName","componentClass","rootComponent","_composeNode","nodeJson","rotation","ComponentClass","componentInstance","childJson","childComponent","LoadingSpinner","HTMLElement","connectedCallback","attachShadow","customElements","define","LoadingSpinnerManager","isLoading","setupCallbacks","showSpinner","spinnerElement","hideSpinner","DefaultLoadingManager","onStart","_url","itemsLoaded","itemsTotal","postMessage","payload","onProgress","onLoad","loadingSpinnerManager","vector3a","vector3b","matrix4","placeObjectAtIntersectionFacingTarget","worldNormal","transformDirection","sub","rightVector","crossVectors","makeBasis","setFromRotationMatrix","DetectedObject","additionalData","detection2DBoundingBox","ObjectDetector","_detectedObjects","_geminiConfig","_buildGeminiConfig","_debugVisualsGroup","runDetection","_runGeminiDetection","cachedDepthArray","cachedMatrixWorld","originalGeminiConfig","rawResponse","parsedResponse","parse","_visualizeBoundingBoxesOnImage","detectionPromises","coord","center","getCenter","uvInput","margin","cropBox","subScalar","addScalar","objectImage","_createDebugVisual","all","Boolean","allObjects","detections","naturalWidth","naturalHeight","rectX","rectY","rectWidth","rectHeight","strokeStyle","lineWidth","strokeRect","textMetrics","measureText","fillRect","toISOString","link","download","href","click","sphere","SphereGeometry","textLabel","geminiOptions","thinkingConfig","thinkingBudget","responseMimeType","DetectedPlane","xrPlane","planePolygon","polygon","Shape","ShapeGeometry","rotateX","semanticLabel","orientation","PlaneDetector","_detectedPlanes","_debugMaterial","wireframe","detectedPlanes","_xrRefSpace","getReferenceSpace","detectedPlanesInFrame","planesToRemove","existingPlaneMesh","lastChangedTime","_updatePlaneMesh","_addPlaneMesh","_removePlaneMesh","planeMesh","_updatePlanePose","newVertices","p","newShape","newGeometry","getPose","planeSpace","transform","allPlanes","plane","anchorObjectAtReticle","_object","_reticle","_timestamp","placeOnSurface","objectToPlace","intersectObjects","XRTransition","BackSide","currentMode","targetAlpha","Infinity","sceneCamera","toVR","toAR","currentOpacity","lerpFactor","abs","Core","screenshotSynthesizer","renderSceneBound","dragManager","webXRSettings","scriptsManager","setPixelRatio","devicePixelRatio","getDepthSensingMesh","setReferenceSpaceType","xrContainer","webXRRequiredFeatures","requiredFeatures","depthSensing","usagePreference","dataFormatPreference","webXRSessionManager","shouldAutostartSimulator","effects","onWindowResize","setAnimationLoop","setInterval","time","currentFrame","renderSimulatorAndScene","aspect","updateProjectionMatrix","cameraOverride","renderSceneOverride","originalLayers","OcclusionUtils","createOcclusionMapOverrideMaterial","addOcclusionToShader","occlusionEnabled","USE_UV","DISTANCE","extractYaw","lookAtRotation","forward","up","lookAt","clampRotationToAngle","currentAngle","acos","axis","sqrt","sign","SimulatorUserAction","_options","LOOK_AT_ANGLE_THRESHOLD","controllerToTargetVector","targetWorldPosition","targetPositionRelativeToCamera","inverseControllerRotation","finalRotation","PinchOnButtonAction","controllerIsPointingAtButton","controllerState","controllerIndex","localControllerPosition","localControllerRotation","rotateControllerTowardsButton","pinchController","pinchedOnButton","ShowHandsAction","cameraToTargetVector","closeToTargetPosition","inverseCameraRotation","WalkTowardsPanelAction","isLookingAtTarget","isNearTarget","lookAtTarget","lookTowardsTarget","moveTowardsTarget","addScaledVector","cameraToCloseToTarget","movementDistance","shouldContinueJourney","core","getDeltaTime","showReticleOnDepthMesh","getXrCameraLeft","getXrCameraRight","showOnlyInLeftEye","showOnlyInRightEye","loadStereoImageAsTextures","ImageLoader","leftTexture","repeat","rightTexture","MaterialSymbolsView","icon","updateIcon","iconWeight","iconStyle","iconColor","iconScale","svgPath","loadedSvgPath","loadingSvgPath","svgData","SVGLoader","viewMinX","viewMinY","viewWidth","viewHeight","xml","viewBox","paths","shapes","createShapes","TextScrollerState","scrollSpeedLinesPerSecond","lines","currentLine","targetLine","shouldUpdate","deltaLines","distanceToTargetLine","Page","PagerState","pages","currentPage","velocity","sin","targetPage","remainingDelta","addPage","Pager","localClippingPlanes","Plane","raycastMesh","clippingPlanes","selecting","selectStartPositionLocal","selectStartPage","raycastPlane","selectingRay","Ray","selectingRayTarget","enableRaycastOnChildren","continuousScrolling","localClippingEnabled","updatePageCount","updatePagePositions","halfNumberOfPages","floor","deltaFromCurrentPage","resetClippingPlanesToLocalSpace","updateClippingPlanes","intersectionIndex","selectingController","constant","computeSelectingDelta","selectingPosition","startSelectPosition","intersectPlane","deltaPage","thisIntersections","childIntersections","pointInLocalCoordinates","VerticalPager","ScrollingTroikaTextView","scrollerState","onTextSyncCompleteBound","onTextSyncComplete","currentText","pager","textViewWrapper","clipToLineHeight","newHeight","positionDiff","rotationDiff","FreestandingSlider","startingValue","rotationScale","initialRotationInverse","setInitialPose","setInitialPoseFromController","getValue","getValueFromRotation","getValueFromController","updateValue","jsmUrl","REVISION","gltfLoaderInstance","ModelLoader","manager","extension","pop","loadSplat","SplatMesh","splatMesh","dracoLoader","DRACOLoader","setDecoderPath","setDecoderConfig","ktx2Loader","KTX2Loader","setTranscoderPath","detectSupport","setDRACOLoader","setKTX2Loader","getGLTFLoader","ModelViewerPlatformCornerGeometry","tube","radialSegments","tubularSegments","normals","vertex","cos","a","setIndex","setAttribute","Float32BufferAttribute","createPlatformGeometry","thickness","cornerRadius","cornerWidthSegments","sideGeometries","cornerGeometry","cornerGeometry1","rotateY","translate","cornerGeometry2","cornerGeometry3","cornerGeometry4","cornerTubes","widthTube","CylinderGeometry","rotateZ","widthTube1","widthTube2","depthTube","depthTube1","depthTube2","createPlatformSideGeometries","sideGeometriesVertexCount","acc","val","flatGeometries","widthMinusRadius","depthMinusRadius","longQuad","shortQuad","shortQuadTranslationZ","shortQuad1","shortQuad2","quadGeometries","cornerCircle","circleTranslationZ","circleTranslationX","cornerCircle1","cornerCircle2","cornerCircle3","cornerCircle4","topGeometries","bottomGeometries","createPlatformFlatGeometries","flatGeometriesVertexCount","allGeometries","mergedGeometry","BufferGeometryUtils","mergeGeometries","addGroup","computeBoundingBox","ModelViewerPlatform","MeshLambertMaterial","defaultPlatformMargin","quaternion2","SplatAnchor","RotationRaycastMesh","ModelViewer","raycastToChildren","rotatable","scalable","platformAnimationSpeed","platformThickness","isOneOneScale","initialScale","startAnimationOnLoad","clipActions","hoveringControllers","bbox","createSparkRendererIfNeeded","loadSplatModel","onSceneLoaded","platformMargin","setupRaycastCylinder","setupRaycastBox","setupPlatform","splatAnchor","degToRad","setupBoundingBox","verticallyAlignObject","horizontallyAlignObject","setCastShadow","setReceiveShadow","loadGLTFModel","animationMixer","AnimationMixer","animations","clip","clipAction","gltfMesh","platform","localBbox","getBoundingBox","isEmpty","localBboxOfTransformedMesh","translationAmount","contentChildren","rotationRaycastMesh","controlBar","parentReferences","removeFromParent","expandByObject","getGroupBoundingBox","bboxSize","BoxGeometry","decompose","directionToCamera","distanceToCamera","pitchAngleRadians","asin","childRaycasts","rotationIntersects","platformIntersects","controlButtonIntersects","onScaleButtonClick","getOcclusionEnabled","setOcclusionEnabled","playClipAnimationOnce","clampWhenFinished","LoopOnce","SparkRenderer","sparkRendererExists","maxStdDev","SketchPanel","toneMapped","alphaTest","activeHand","activeLine","activeLines","removedLines","isDrawing","clearCanvas","triggerUpdate","beginPath","lineTo","stroke","moveTo","forceUpdate","removeAll","undo","line","drawLine","redo","HorizontalPager","PageIndicator","pagerState","emptyPageIndicator","currentPageIndicator","numberOfPages","previousPage","updateText","fill","VideoFileStream","videoFile","videoFile_","setSource"],"mappings":"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"}
|