Spaces:
Running
on
T4
Running
on
T4
import * as THREE from 'three'; | |
import {Button} from '@mui/material'; | |
import {useCallback, useEffect, useState} from 'react'; | |
import {BufferedSpeechPlayer} from '../createBufferedSpeechPlayer'; | |
type Props = { | |
bufferedSpeechPlayer: BufferedSpeechPlayer; | |
renderer: THREE.WebGLRenderer | null; | |
onARVisible?: () => void; | |
onARHidden?: () => void; | |
}; | |
export default function ARButton({ | |
bufferedSpeechPlayer, | |
renderer, | |
onARVisible, | |
onARHidden, | |
}: Props) { | |
const [session, setSession] = useState<XRSession | null>(null); | |
const [supported, setSupported] = useState<boolean>(true); | |
useEffect(() => { | |
if (!navigator.xr) { | |
setSupported(false); | |
return; | |
} | |
navigator.xr.isSessionSupported('immersive-ar').then((supported) => { | |
setSupported(supported); | |
}); | |
}, []); | |
const resetBuffers = useCallback( | |
(event: XRSessionEvent) => { | |
const session = event.target; | |
if (!(session instanceof XRSession)) { | |
return; | |
} | |
switch (session.visibilityState) { | |
case 'visible': | |
console.log('Restarting speech player, device is visible'); | |
bufferedSpeechPlayer.stop(); | |
bufferedSpeechPlayer.start(); | |
onARVisible?.(); | |
break; | |
case 'hidden': | |
console.log('Stopping speech player, device is hidden'); | |
bufferedSpeechPlayer.stop(); | |
bufferedSpeechPlayer.start(); | |
onARHidden?.(); | |
break; | |
} | |
}, | |
[bufferedSpeechPlayer], | |
); | |
async function onSessionStarted(session: XRSession) { | |
setSession(session); | |
session.onvisibilitychange = resetBuffers; | |
session.onend = onSessionEnded; | |
await renderer.xr.setSession(session); | |
} | |
function onSessionEnded() { | |
setSession(null); | |
} | |
const onClick = () => { | |
if (session === null) { | |
navigator.xr!.requestSession('immersive-ar').then(onSessionStarted); | |
} else { | |
session.end(); | |
} | |
}; | |
return ( | |
<Button | |
variant="contained" | |
onClick={onClick} | |
disabled={!supported || renderer == null} | |
sx={{mt: 1}}> | |
{supported | |
? renderer != null | |
? 'Enter AR' | |
: 'Initializing AR...' | |
: 'AR Not Supported'} | |
</Button> | |
); | |
} | |