import * as React from 'react' import { Object3D } from 'three' import { addEffect, addAfterEffect } from '@react-three/fiber' export function useIntersect(onChange: (visible: boolean) => void) { const ref = React.useRef(null!) const check = React.useRef(false) const temp = React.useRef(false) const callback = React.useRef(onChange) React.useLayoutEffect(() => void (callback.current = onChange), [onChange]) React.useEffect(() => { const obj = ref.current if (obj) { // Stamp out frustum check pre-emptively const unsub1 = addEffect(() => { check.current = false return true }) // If the object is inside the frustum three will call onRender const oldOnRender = obj.onBeforeRender obj.onBeforeRender = () => (check.current = true) // Compare the check value against the temp value, if it differs set state const unsub2 = addAfterEffect(() => { if (check.current !== temp.current) callback.current?.((temp.current = check.current)) return true }) return () => { obj.onBeforeRender = oldOnRender unsub1() unsub2() } } }, []) return ref }