forked from EXT/VR180-Web-Player
110 lines
2.8 KiB
TypeScript
110 lines
2.8 KiB
TypeScript
import * as THREE from 'https://unpkg.com/three/build/three.module.js';
|
|
import {
|
|
getSeekProgressFromIntersection,
|
|
type VrControlPanel
|
|
} from './vr-control-panel.js';
|
|
|
|
type VrControllerSelectionOptions = {
|
|
exitVr: () => void;
|
|
forward: () => void;
|
|
hidePanel: () => void;
|
|
isPanelVisible: () => boolean;
|
|
raycaster: any;
|
|
rewind: () => void;
|
|
seek: (progress: number) => void;
|
|
showPanel: () => void;
|
|
toggleMute: () => void;
|
|
togglePlayPause: () => void;
|
|
uiElements: any[];
|
|
vrPanel: VrControlPanel | undefined;
|
|
};
|
|
|
|
const tempMatrix = new THREE.Matrix4();
|
|
|
|
export function createVrController(scene: any, renderer: any, onSelectStart: (event: any) => void): {
|
|
controller: any;
|
|
raycaster: any;
|
|
} {
|
|
const controller = renderer.xr.getController(0);
|
|
controller.addEventListener('selectstart', onSelectStart);
|
|
|
|
const lineMaterial = new THREE.LineBasicMaterial({ color: 0xffffff, transparent: true, opacity: 0.5 });
|
|
const lineGeometry = new THREE.BufferGeometry().setFromPoints([
|
|
new THREE.Vector3(0, 0, 0),
|
|
new THREE.Vector3(0, 0, -5)
|
|
]);
|
|
controller.add(new THREE.Line(lineGeometry, lineMaterial));
|
|
scene.add(controller);
|
|
|
|
const raycaster = new THREE.Raycaster();
|
|
raycaster.near = 0.1;
|
|
raycaster.far = 5;
|
|
|
|
return { controller, raycaster };
|
|
}
|
|
|
|
export function handleVrControllerSelect(event: any, options: VrControllerSelectionOptions): void {
|
|
const controller = event.target;
|
|
if (!options.raycaster) return;
|
|
|
|
controller.updateMatrixWorld();
|
|
tempMatrix.identity().extractRotation(controller.matrixWorld);
|
|
options.raycaster.ray.origin.setFromMatrixPosition(controller.matrixWorld);
|
|
options.raycaster.ray.direction.set(0, 0, -1).applyMatrix4(tempMatrix);
|
|
|
|
const directIntersects = options.raycaster.intersectObjects(options.uiElements, true);
|
|
if (directIntersects.length === 0) {
|
|
togglePanel(options);
|
|
return;
|
|
}
|
|
|
|
const firstIntersected = directIntersects[0].object;
|
|
const intersectionPoint = directIntersects[0].point;
|
|
|
|
if (firstIntersected.name === 'vrPlayPauseButton') {
|
|
options.togglePlayPause();
|
|
options.showPanel();
|
|
return;
|
|
}
|
|
|
|
if (firstIntersected.name === 'vrRewindButton') {
|
|
options.rewind();
|
|
options.showPanel();
|
|
return;
|
|
}
|
|
|
|
if (firstIntersected.name === 'vrForwardButton') {
|
|
options.forward();
|
|
options.showPanel();
|
|
return;
|
|
}
|
|
|
|
if (firstIntersected.name === 'vrExitButton') {
|
|
options.exitVr();
|
|
options.showPanel();
|
|
return;
|
|
}
|
|
|
|
if (firstIntersected.name === 'vrVolumeButton') {
|
|
options.toggleMute();
|
|
options.showPanel();
|
|
return;
|
|
}
|
|
|
|
if (firstIntersected.name === 'seekBarHitArea') {
|
|
options.showPanel();
|
|
options.seek(getSeekProgressFromIntersection(options.vrPanel, intersectionPoint));
|
|
return;
|
|
}
|
|
|
|
togglePanel(options);
|
|
}
|
|
|
|
function togglePanel(options: VrControllerSelectionOptions): void {
|
|
if (options.isPanelVisible()) {
|
|
options.hidePanel();
|
|
} else {
|
|
options.showPanel();
|
|
}
|
|
}
|