threlte logo
@threlte/xr

<Headset>

<Headset /> provides the ability to attach objects to the pose of the user’s headset.

<script>
  import { Headset } from '@threlte/xr'
  import { AudioListener } from '@threlte/extras'
</script>

<Headset>
  <AudioListener />
</Headset>

If you need to only read from the current headset pose, the useHeadset hook is available.

Like a Portal, you can place it anywhere in your Threlte application.

<Headset> will sync position and rotation with the current camera when not in an immersive XR session.

<script lang='ts'>
  import { Canvas } from '@threlte/core'
  import { VRButton } from '@threlte/xr'
  import Scene from './Scene.svelte'

  let isPlaying = false
</script>

<Canvas>
  <Scene {isPlaying} />
</Canvas>

<VRButton on:click={() => isPlaying = true} />
<script lang="ts">
  import { T } from '@threlte/core'
  import { Edges } from '@threlte/extras'
</script>

<T.Mesh {...$$restProps}>
  {@const size = 0.005}
  {@const length = size * 14}
  <T.CylinderGeometry args={[size, size, length]} />
  <T.MeshStandardMaterial color='#eedbcb' />

  <Edges color="black" scale={1.001} thresholdAngle={20} />

  <T.Mesh position={[size * 4, -length, 0]} rotation.z={Math.PI / 5}>
    <T.CylinderGeometry args={[size, size, length]} />
    <T.MeshStandardMaterial color='#eedbcb' />

    <Edges color="black" scale={1.001} thresholdAngle={20} />

    <T.Mesh position={[0, -size * 8, 0]} rotation.z={Math.PI / 4}>
      <T.IcosahedronGeometry args={[size * 3, 2]} />
      <T.MeshStandardMaterial color='gray' />

      <Edges color="black" scale={1.001} thresholdAngle={20} />
    </T.Mesh>
  </T.Mesh>
</T.Mesh>
<script lang='ts'>
  import { T } from '@threlte/core'
  import { Headset, XR, useXR } from '@threlte/xr'
  import { AudioListener } from '@threlte/extras'
  import { spring } from 'svelte/motion'
  import { MathUtils } from 'three'
  import Turntable from '../../extras/positional-audio/Turntable.svelte'
  import Speaker from '../../extras/positional-audio/Speaker.svelte'
  import Microphone from './Microphone.svelte'

  export let isPlaying = false

  let toggle: () => void

  const { isPresenting } = useXR()

  const smoothVolume = spring(0)
  $: volume = $isPresenting ? 1 : 0
  $: smoothVolume.set(volume)
  $: if (isPlaying) toggle()
</script>

<XR>
  <Headset>
    <Microphone
      position={[-0.1, -0.05, -0.1]}
      rotation.x={Math.PI / 3}
    />
  </Headset>
</XR>

<Headset>
  <AudioListener />
</Headset>

<T.Group position={[0, 0.6, -0.5]} scale={0.08}>
  <Turntable
    bind:toggle
    bind:volume
  />
  <Speaker
    position.x={6}
    rotation.y={MathUtils.DEG2RAD * -7}
    {volume}
  />
  <Speaker
    position.x={-6}
    rotation.y={MathUtils.DEG2RAD * 7}
    {volume}
  />
</T.Group>

<T.PerspectiveCamera
  makeDefault
  near={0.001}
  position={[0, 1, 2]}
/>

<T.AmbientLight />
<T.DirectionalLight />