Hi, I’m working on a WebXR Demo which attempts to show LumaAI 3DGS in visionOS,but I can’t make Natural Input work.
- After “Enter VR”,if I allow all permissions, I can’t see hands in VR. But if I don’t allow hand-tracking permission, I can see my hands but can’t control anything. similar to this post: Reddit - Dive into anything
- Safari Web Inspector currently has a bug so I can’t see log, thus I don’t know if my code work.
import * as THREE from 'three';
import { LumaSplatsThree } from "@lumaai/luma-web";
import { VRButton } from "three/examples/jsm/webxr/VRButton.js";
import { DemoProps } from ".";
export function DemoVR(props: DemoProps) {
let { renderer, camera, scene, controls, gui } = props;
renderer.xr.enabled = true;
let vrButton = VRButton.createButton(renderer);
let canvas = renderer.getContext().canvas as HTMLCanvasElement;
canvas.parentElement!.append(vrButton);
let cameraGroup = new THREE.Group();
scene.add(cameraGroup);
cameraGroup.add(camera);
const onSessionStart = () => {
cameraGroup.position.set(0.9, -0.15, -0.3);
cameraGroup.scale.set(0.1, 0.1, 0.1);
};
let controller1 = renderer.xr.getController(0);
let controller2 = renderer.xr.getController(1);
scene.add(controller1);
scene.add(controller2);
const lineMaterial = new THREE.LineBasicMaterial({ color: 0xff0000 });
const geometry = new THREE.BufferGeometry().setFromPoints([new THREE.Vector3(0, 0, 0), new THREE.Vector3(0, 0, -1)]);
const line = new THREE.Line(geometry, lineMaterial);
line.name = 'line';
line.scale.z = 5;
controller1.add(line.clone());
controller2.add(line.clone());
const movementScale = 0.1;
let isMoving = false;
function updateCameraPosition(controller) {
const direction = new THREE.Vector3(0, 0, -1);
direction.applyQuaternion(controller.quaternion);
const offset = direction.multiplyScalar(-movementScale);
cameraGroup.position.add(offset);
}
function handleSelectStart(event) {
const controller = event.target;
controller.userData.targetRayMode = event.data.targetRayMode;
isMoving = true;
}
function handleSelectEnd() {
isMoving = false;
}
controller1.addEventListener('selectstart', handleSelectStart);
controller1.addEventListener('selectend', handleSelectEnd);
controller2.addEventListener('selectstart', handleSelectStart);
controller2.addEventListener('selectend', handleSelectEnd);
renderer.setAnimationLoop(() => {
if (isMoving) {
updateCameraPosition(controller1);
updateCameraPosition(controller2);
}
});
renderer.xr.addEventListener('sessionstart', onSessionStart);
let splats = new LumaSplatsThree({
// Kind Humanoid @RyanHickman
source: 'https://lumalabs.ai/capture/xxxx',
// disable three.js shader integration for performance
enableThreeShaderIntegration: false,
});
scene.add(splats);
return {
dispose: () => {
splats.dispose();
vrButton.remove();
//renderer.xr.removeEventListener('sessionstart', onSessionStart);
}
}
}