import * as THREE from 'https://unpkg.com/three/build/three.module.js'; import { FIGMA_PANEL_HEIGHT_PX, FIGMA_PANEL_WIDTH_PX, SCALE_FACTOR, VR_PANEL_POSITION, WORLD_PANEL_HEIGHT, WORLD_PANEL_WIDTH, WORLD_SEEK_BAR_HIT_AREA_HEIGHT_MULTIPLIER, WORLD_SEEK_BAR_PROGRESS_HEIGHT, WORLD_SEEK_BAR_TRACK_HEIGHT, WORLD_SEEK_BAR_WIDTH, WORLD_SEEK_BAR_Y_OFFSET, type VrPanelButtonLayout } from './vr-panel-layout.js'; import { createPanelBackgroundTexture } from './vr-panel-button-textures.js'; export type ButtonMeshOptions = VrPanelButtonLayout & { texture: any; }; export type SeekBarMeshes = { hitAreaMesh: any; progressMesh: any; trackMesh: any; }; export function createVrPanelGroup(scene: any): any { const group = new THREE.Group(); group.position.set(VR_PANEL_POSITION.x, VR_PANEL_POSITION.y, VR_PANEL_POSITION.z); group.rotation.x = 0; scene.add(group); return group; } export function createPanelBackground(title: string): any { const panelMaterial = new THREE.MeshBasicMaterial({ map: createPanelBackgroundTexture(title), transparent: true, opacity: 0, depthWrite: false }); const panelGeometry = new THREE.PlaneGeometry(WORLD_PANEL_WIDTH, WORLD_PANEL_HEIGHT); const panelMesh = new THREE.Mesh(panelGeometry, panelMaterial); panelMesh.name = 'vrControlPanelBackground'; panelMesh.renderOrder = 0; return panelMesh; } export function createSeekBarMeshes(): SeekBarMeshes { const trackMaterial = new THREE.MeshBasicMaterial({ color: 0x767676, transparent: true, opacity: 0 }); const trackGeometry = new THREE.PlaneGeometry(WORLD_SEEK_BAR_WIDTH, WORLD_SEEK_BAR_TRACK_HEIGHT); const trackMesh = new THREE.Mesh(trackGeometry, trackMaterial); trackMesh.name = 'seekBarTrackVisual'; trackMesh.position.y = WORLD_SEEK_BAR_Y_OFFSET; trackMesh.position.z = 0.01; trackMesh.renderOrder = 1; const progressMaterial = new THREE.MeshBasicMaterial({ color: 0xffffff, transparent: true, opacity: 0 }); const progressGeometry = new THREE.PlaneGeometry(WORLD_SEEK_BAR_WIDTH, WORLD_SEEK_BAR_PROGRESS_HEIGHT); const progressMesh = new THREE.Mesh(progressGeometry, progressMaterial); progressMesh.name = 'seekBarProgressVisual'; progressMesh.position.y = WORLD_SEEK_BAR_Y_OFFSET + SCALE_FACTOR; progressMesh.position.x = -WORLD_SEEK_BAR_WIDTH / 2; progressMesh.position.z = 0.015; progressMesh.scale.x = 0.001; progressMesh.renderOrder = 2; const hitAreaGeometry = new THREE.PlaneGeometry( WORLD_SEEK_BAR_WIDTH, WORLD_SEEK_BAR_TRACK_HEIGHT * WORLD_SEEK_BAR_HIT_AREA_HEIGHT_MULTIPLIER ); const hitAreaMaterial = new THREE.MeshBasicMaterial({ visible: false, transparent: true, opacity: 0 }); const hitAreaMesh = new THREE.Mesh(hitAreaGeometry, hitAreaMaterial); hitAreaMesh.name = 'seekBarHitArea'; hitAreaMesh.position.y = WORLD_SEEK_BAR_Y_OFFSET; hitAreaMesh.position.z = 0.012; hitAreaMesh.renderOrder = 2; return { hitAreaMesh, progressMesh, trackMesh }; } export function createButtonMesh({ centerX, centerY, name, size, texture }: ButtonMeshOptions): any { const buttonWorldSize = size * SCALE_FACTOR; const buttonMaterial = new THREE.MeshBasicMaterial({ map: texture, transparent: true, opacity: 0, depthWrite: false }); const buttonGeometry = new THREE.PlaneGeometry(buttonWorldSize, buttonWorldSize); const buttonMesh = new THREE.Mesh(buttonGeometry, buttonMaterial); buttonMesh.name = name; buttonMesh.renderOrder = 3; const worldButtonOffsetX = (centerX - FIGMA_PANEL_WIDTH_PX / 2) * SCALE_FACTOR; const worldButtonOffsetY = -(centerY - FIGMA_PANEL_HEIGHT_PX / 2) * SCALE_FACTOR; buttonMesh.position.set(worldButtonOffsetX, worldButtonOffsetY, 0.02); return buttonMesh; }