threlte logo
@threlte/xr

useHitTest

Provides a hit test result on each frame during an immersive-ar session.

<script>
  useHitTest((hitMatrix: THREE.Matrix4, hit: XRHitTestResult) => {

  })
</script>

Hit testing can be useful for placing virtual objects relative to real world objects.

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

<Canvas>
	<Scene />
</Canvas>

<ARButton />
<script lang='ts'>
  import * as THREE from 'three'
  import { T } from '@threlte/core'
  import { XR, Controller, Hand, useHitTest } from '@threlte/xr'
  
  const geometry = new THREE.CylinderGeometry(0.1, 0.1, 0.2, 32).translate(0, 0.1, 0);
  const meshes: THREE.Mesh[] = []
  
  let reticle: THREE.Mesh
  
  const handleSelect = () => {
    if (!reticle.visible) return
  
    const material = new THREE.MeshPhongMaterial({ color: 0xffffff * Math.random() })
    const mesh = new THREE.Mesh(geometry, material)
    reticle.matrix.decompose(mesh.position, mesh.quaternion, mesh.scale)
    mesh.scale.y = Math.random() * 2 + 1
    meshes.push(mesh)
  }
  
  useHitTest((hitMatrix, hit) => {
    if (hit) {
      reticle.visible = true
      reticle.matrix.copy(hitMatrix)
    } else {
      reticle.visible = false
    }
  })
  
  </script>
  
  <XR>
    <Controller left on:select={handleSelect} />
    <Controller right on:select={handleSelect} />
    <Hand left on:pinchend={handleSelect} />
    <Hand right on:pinchend={handleSelect} />
  </XR>
  
  <T.HemisphereLight
    args={[0xffffff, 0xbbbbff, 1]}
    position={[0.5, 1, 0.25]}
  />
  
  <T.Mesh
    bind:ref={reticle}
    matrixAutoUpdate={false}
    visible={false}
  >
    <T.RingGeometry
      args={[0.15, 0.2, 32]}
      on:create={({ ref }) => ref.rotateX(-Math.PI / 2)}
    />
    <T.MeshBasicMaterial />
  </T.Mesh>
  
  {#each meshes as mesh, index (index)}
    <T is={mesh} />
  {/each}