{"version":3,"file":"Autofocus.cjs","sources":["../../src/effects/Autofocus.tsx"],"sourcesContent":["import * as THREE from 'three'\nimport React, {\n  useRef,\n  useContext,\n  useState,\n  useEffect,\n  useCallback,\n  forwardRef,\n  useImperativeHandle,\n  RefObject,\n  useMemo,\n} from 'react'\nimport { useThree, useFrame, createPortal, type Vector3 } from '@react-three/fiber'\nimport { CopyPass, DepthPickingPass, DepthOfFieldEffect } from 'postprocessing'\nimport { easing } from 'maath'\n\nimport { DepthOfField } from './DepthOfField'\nimport { EffectComposerContext } from '../EffectComposer'\n\nexport type AutofocusProps = React.ComponentProps<typeof DepthOfField> & {\n  target?: Vector3\n  /** should the target follow the pointer */\n  mouse?: boolean\n  /** size of the debug green point  */\n  debug?: number\n  /** manual update */\n  manual?: boolean\n  /** approximate time to reach the target */\n  smoothTime?: number\n}\n\nexport type AutofocusApi = {\n  dofRef: RefObject<DepthOfFieldEffect>\n  hitpoint: THREE.Vector3\n  update: (delta: number, updateTarget: boolean) => void\n}\n\nexport const Autofocus = forwardRef<AutofocusApi, AutofocusProps>(\n  (\n    { target = undefined, mouse: followMouse = false, debug = undefined, manual = false, smoothTime = 0.25, ...props },\n    fref\n  ) => {\n    const dofRef = useRef<DepthOfFieldEffect>(null)\n    const hitpointRef = useRef<THREE.Mesh>(null)\n    const targetRef = useRef<THREE.Mesh>(null)\n\n    const scene = useThree(({ scene }) => scene)\n    const pointer = useThree(({ pointer }) => pointer)\n    const { composer, camera } = useContext(EffectComposerContext)\n\n    // see: https://codesandbox.io/s/depthpickingpass-x130hg\n    const [depthPickingPass] = useState(() => new DepthPickingPass())\n    const [copyPass] = useState(() => new CopyPass())\n    useEffect(() => {\n      composer.addPass(depthPickingPass)\n      composer.addPass(copyPass)\n      return () => {\n        composer.removePass(depthPickingPass)\n        composer.removePass(copyPass)\n      }\n    }, [composer, depthPickingPass, copyPass])\n\n    useEffect(() => {\n      return () => {\n        depthPickingPass.dispose()\n        copyPass.dispose()\n      }\n    }, [depthPickingPass, copyPass])\n\n    const [hitpoint] = useState(() => new THREE.Vector3(0, 0, 0))\n\n    const [ndc] = useState(() => new THREE.Vector3(0, 0, 0))\n    const getHit = useCallback(\n      async (x: number, y: number) => {\n        ndc.x = x\n        ndc.y = y\n        ndc.z = await depthPickingPass.readDepth(ndc)\n        ndc.z = ndc.z * 2.0 - 1.0\n        const hit = 1 - ndc.z > 0.0000001 // it is missed if ndc.z is close to 1\n        return hit ? ndc.unproject(camera) : false\n      },\n      [ndc, depthPickingPass, camera]\n    )\n\n    const update = useCallback(\n      async (delta: number, updateTarget = true) => {\n        // Update hitpoint\n        if (target) {\n          hitpoint.set(...(target as [number, number, number]))\n        } else {\n          const { x, y } = followMouse ? pointer : { x: 0, y: 0 }\n          const hit = await getHit(x, y)\n          if (hit) hitpoint.copy(hit)\n        }\n\n        // Update target\n        if (updateTarget && dofRef.current?.target) {\n          if (smoothTime > 0 && delta > 0) {\n            easing.damp3(dofRef.current.target, hitpoint, smoothTime, delta)\n          } else {\n            dofRef.current.target.copy(hitpoint)\n          }\n        }\n      },\n      [target, hitpoint, followMouse, getHit, smoothTime, pointer]\n    )\n\n    useFrame(async (_, delta) => {\n      if (!manual) {\n        update(delta)\n      }\n      if (hitpointRef.current) {\n        hitpointRef.current.position.copy(hitpoint)\n      }\n      if (targetRef.current && dofRef.current?.target) {\n        targetRef.current.position.copy(dofRef.current.target)\n      }\n    })\n\n    // Ref API\n    const api = useMemo<AutofocusApi>(\n      () => ({\n        dofRef,\n        hitpoint,\n        update,\n      }),\n      [hitpoint, update]\n    )\n    useImperativeHandle(fref, () => api, [api])\n\n    return (\n      <>\n        {debug\n          ? createPortal(\n              <>\n                <mesh ref={hitpointRef}>\n                  <sphereGeometry args={[debug, 16, 16]} />\n                  <meshBasicMaterial color=\"#00ff00\" opacity={1} transparent depthWrite={false} />\n                </mesh>\n                <mesh ref={targetRef}>\n                  <sphereGeometry args={[debug / 2, 16, 16]} />\n                  <meshBasicMaterial color=\"#00ff00\" opacity={0.5} transparent depthWrite={false} />\n                </mesh>\n              </>,\n              scene\n            )\n          : null}\n\n        <DepthOfField ref={dofRef} {...props} target={hitpoint} />\n      </>\n    )\n  }\n)\n"],"names":["forwardRef","useRef","useThree","scene","pointer","useContext","EffectComposerContext","useState","DepthPickingPass","CopyPass","useEffect","THREE","useCallback","easing","useFrame","useMemo","useImperativeHandle","jsxs","Fragment","createPortal","jsx","DepthOfField"],"mappings":"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"}