Skip to main content
Documentation

Points in 3D Space

Convert between screen and 3D coordinates with Five SDK in React.

In this chapter you will learn

  • How to use the Five SDK event system (tapGesture, etc.) in React.
  • How to obtain 3D coordinates from tapGesture and project them to screen coordinates.

Event system overview

  • tapGesture: click/touch. The default behavior is moving to a point.
  • panGesture: drag to rotate/pan.
  • pinchGesture: two-finger zoom.
  • mouseWheel: scroll-wheel zoom.
  • You can prevent the default behavior by listening for a wants* event and returning false from the callback, for example wantsTapGesture.

React example: pick a 3D point on click

import { useEffect, useRef, useState } from 'react'
import { Five, Mode, parseWork } from '@realsee/five'

const workURL = 'https://vr-public.realsee-cdn.cn/release/static/image/release/five/work-sample/07bdc58f413bc5494f05c7cbb5cbdce4/work.json'

export default function FivePoints() {
  const containerRef = useRef(null)
  const fiveRef = useRef(null)
  const [enabled, setEnabled] = useState(false)
  const [points, setPoints] = useState([])

  useEffect(() => {
    const five = new Five()
    fiveRef.current = five
    if (containerRef.current) five.appendTo(containerRef.current)
    fetch(workURL).then(r=>r.json()).then(json=>five.load(parseWork(json)))

    const onResize = () => five.refresh()
    window.addEventListener('resize', onResize, false)

    const onWantsTap = (raycaster) => {
      if (!enabled) return true
      const intersection = five.model.intersectRaycaster(raycaster)
      if (intersection) {
        setPoints((prev) => [...prev, ...intersection])
      }
      return false
    }
    five.on('wantsTapGesture', onWantsTap)

    return () => {
      window.removeEventListener('resize', onResize, false)
      five.off('wantsTapGesture', onWantsTap)
      five.dispose()
    }
  }, [enabled])

  return (
    <div style={{ width: '100vw', height: '100vh' }}>
      <div ref={containerRef} style={{ width: '100%', height: '100%', overflow: 'hidden' }} />
      <div style={{ position: 'fixed', top: 16, left: 16, display: 'flex', gap: 8 }}>
        <button className="btn btn-primary" onClick={()=>setEnabled(v=>!v)}>{enabled? 'Disable picking':'Enable picking'}</button>
      </div>
      <div style={{ position: 'fixed', bottom: 16, left: 16, background: '#fff', padding: 8, borderRadius: 4, maxWidth: 320 }}>
        <div>Picked: {points.length}</div>
      </div>
    </div>
  )
}

To map a 3D point to screen coordinates, use five.project2d(vector, testModel); see the next chapter, "Adding Tags".