@pmndrs/xr
Version:
VR/AR for threejs
110 lines (109 loc) • 3.96 kB
JavaScript
import { DevUI } from '@iwer/devui';
import { SyntheticEnvironmentModule } from '@iwer/sem';
import { XRDevice, metaQuest3, metaQuest2, metaQuestPro, oculusQuest1 } from 'iwer';
import { Euler, Quaternion } from 'three';
const configurations = { metaQuest3, metaQuest2, metaQuestPro, oculusQuest1 };
const defaultSyntheticEnvironments = [
//default default environment:
'office_small',
'meeting_room',
'living_room',
'music_room',
'office_large',
];
const handednessList = ['left', 'none', 'right'];
export function emulate(options) {
const type = typeof options === 'string' ? options : (options.type ?? 'metaQuest3');
const xrdevice = new XRDevice(configurations[type], typeof options === 'string' ? undefined : options);
if (typeof options != 'string') {
applyEmulatorTransformOptions(xrdevice, options.headset);
applyEmulatorInputSourcesOptions(xrdevice.hands, options.hand);
applyEmulatorInputSourcesOptions(xrdevice.controllers, options.controller);
xrdevice.primaryInputMode = options.primaryInputMode ?? 'controller';
}
xrdevice.ipd = typeof options === 'string' ? 0 : (options.ipd ?? 0);
xrdevice.installRuntime();
xrdevice.installDevUI(DevUI);
const syntheticEnvironment = typeof options === 'string' ? true : options.syntheticEnvironment;
if (syntheticEnvironment === false) {
return xrdevice;
}
xrdevice.installSEM(SyntheticEnvironmentModule);
if (syntheticEnvironment === null) {
//dont preload any environment
return xrdevice;
}
if (typeof syntheticEnvironment === 'string' && defaultSyntheticEnvironments.includes(syntheticEnvironment)) {
//load the selected default environment
xrdevice.sem?.loadDefaultEnvironment(syntheticEnvironment);
return xrdevice;
}
if (syntheticEnvironment === true || syntheticEnvironment === undefined) {
//load the first default environment
xrdevice.sem?.loadDefaultEnvironment(defaultSyntheticEnvironments[0]);
return xrdevice;
}
if (typeof syntheticEnvironment === 'object') {
//load the provided environment
xrdevice.sem?.loadEnvironment(syntheticEnvironment);
return xrdevice;
}
//fetch the environment from the provided link
fetch(syntheticEnvironment)
.then((response) => response.json())
.then((environment) => xrdevice.sem?.loadEnvironment(environment))
.catch(console.error);
return xrdevice;
}
const eulerHelper = new Euler();
const quaternionHelper = new Quaternion();
function applyEmulatorInputSourcesOptions(xrInputSources, options) {
if (options == null) {
return;
}
for (const handedness of handednessList) {
applyEmulatorTransformOptions(xrInputSources[handedness], options[handedness]);
}
}
function applyEmulatorTransformOptions(target, options) {
if (target == null || options == null) {
return;
}
setVector(target.position, options.position);
setVector(eulerHelper, options.rotation);
setQuaternion(target.quaternion, quaternionHelper.setFromEuler(eulerHelper));
setQuaternion(target.quaternion, options.quaternion);
}
function setVector(target, value) {
if (value == null) {
return;
}
if (value instanceof Euler && target instanceof Euler) {
target.copy(value);
}
if (Array.isArray(value)) {
target.x = value[0];
target.y = value[1];
target.z = value[2];
return;
}
target.x = value.x;
target.y = value.y;
target.z = value.z;
}
function setQuaternion(target, value) {
if (value == null) {
return;
}
if (Array.isArray(value)) {
target.x = value[0];
target.y = value[1];
target.z = value[2];
target.w = value[3];
return;
}
target.x = value.x;
target.y = value.y;
target.z = value.z;
target.w = value.w;
}