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>

<div>
  <Canvas>
    <Scene {isPlaying} />
  </Canvas>
  <VRButton onclick={() => (isPlaying = true)} />
</div>

<style>
  div {
    height: 100%;
  }
</style>
<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 />