From 7645061a4e1cafdacc8988b99ae07b3bde820e2b Mon Sep 17 00:00:00 2001 From: Antoine BERNIER Date: Fri, 14 Jun 2024 14:24:26 +0200 Subject: [PATCH] fix: component Helper now useHelper (#1992) --- src/core/Caustics.tsx | 2 +- src/core/Helper.tsx | 68 +++++++++++++++++++++++++----------------- src/core/index.ts | 1 - src/core/useHelper.tsx | 38 ----------------------- 4 files changed, 42 insertions(+), 67 deletions(-) delete mode 100644 src/core/useHelper.tsx diff --git a/src/core/Caustics.tsx b/src/core/Caustics.tsx index 1c21c4a7a..695287b21 100644 --- a/src/core/Caustics.tsx +++ b/src/core/Caustics.tsx @@ -6,7 +6,7 @@ import * as THREE from 'three' import * as React from 'react' import { extend, ReactThreeFiber, useFrame, useThree } from '@react-three/fiber' import { useFBO } from './useFBO' -import { useHelper } from './useHelper' +import { useHelper } from './Helper' import { shaderMaterial } from './shaderMaterial' import { Edges } from './Edges' import { FullScreenQuad } from 'three-stdlib' diff --git a/src/core/Helper.tsx b/src/core/Helper.tsx index d1601190d..599cb42a3 100644 --- a/src/core/Helper.tsx +++ b/src/core/Helper.tsx @@ -1,11 +1,44 @@ -import { useFrame, useThree } from '@react-three/fiber' import * as React from 'react' import { Object3D } from 'three' +import { useThree, useFrame } from '@react-three/fiber' +import { Falsey } from 'utility-types' type HelperType = Object3D & { update: () => void; dispose: () => void } -type HelperConstructor = new (...args: any[]) => HelperType +type HelperConstructor = new (...args: any[]) => any type HelperArgs = T extends [infer _, ...infer R] ? R : never +export function useHelper( + object3D: React.MutableRefObject | Falsey, + helperConstructor: T, + ...args: HelperArgs> +) { + const helper = React.useRef() + const scene = useThree((state) => state.scene) + React.useLayoutEffect(() => { + let currentHelper: HelperType = undefined! + + if (object3D && object3D?.current && helperConstructor) { + helper.current = currentHelper = new (helperConstructor as any)(object3D.current, ...args) + } + + if (currentHelper) { + // Prevent the helpers from blocking rays + currentHelper.traverse((child) => (child.raycast = () => null)) + scene.add(currentHelper) + return () => { + helper.current = undefined + scene.remove(currentHelper) + currentHelper.dispose?.() + } + } + }, [scene, helperConstructor, object3D, ...args]) + + useFrame(() => void helper.current?.update?.()) + return helper +} + +// + export type HelperProps = { type: T args?: HelperArgs> @@ -15,33 +48,14 @@ export const Helper = ({ type: helperConstructor, args = [] as never, }: HelperProps) => { - const objectRef = React.useRef(null!) - const helperRef = React.useRef() - - const scene = useThree((state) => state.scene) + const thisRef = React.useRef(null!) + const parentRef = React.useRef(null!) React.useLayoutEffect(() => { - const parent = objectRef.current?.parent - - if (!helperConstructor || !parent) return - - const helper = new helperConstructor(parent, ...args) - - helperRef.current = helper - - // Prevent the helpers from blocking rays - helper.traverse((child) => (child.raycast = () => null)) - - scene.add(helper) - - return () => { - helperRef.current = undefined - scene.remove(helper) - helper.dispose?.() - } - }, [scene, helperConstructor, ...args]) + parentRef.current = thisRef.current.parent! + }) - useFrame(() => void helperRef.current?.update?.()) + useHelper(parentRef, helperConstructor, ...args) - return + return } diff --git a/src/core/index.ts b/src/core/index.ts index 6dd7dece9..4599bd310 100644 --- a/src/core/index.ts +++ b/src/core/index.ts @@ -68,7 +68,6 @@ export * from './useDepthBuffer' export * from './useAspect' export * from './useCamera' export * from './useDetectGPU' -export * from './useHelper' export * from './useBVH' export * from './useContextBridge' export * from './useAnimations' diff --git a/src/core/useHelper.tsx b/src/core/useHelper.tsx deleted file mode 100644 index e5acdd8a0..000000000 --- a/src/core/useHelper.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import * as React from 'react' -import { Object3D } from 'three' -import { useThree, useFrame } from '@react-three/fiber' -import { Falsey } from 'utility-types' - -type Helper = Object3D & { update: () => void; dispose: () => void } -type Constructor = new (...args: any[]) => any -type Rest = T extends [infer _, ...infer R] ? R : never - -export function useHelper( - object3D: React.MutableRefObject | Falsey, - helperConstructor: T, - ...args: Rest> -) { - const helper = React.useRef() - const scene = useThree((state) => state.scene) - React.useLayoutEffect(() => { - let currentHelper: Helper = undefined! - - if (object3D && object3D?.current && helperConstructor) { - helper.current = currentHelper = new (helperConstructor as any)(object3D.current, ...args) - } - - if (currentHelper) { - // Prevent the helpers from blocking rays - currentHelper.traverse((child) => (child.raycast = () => null)) - scene.add(currentHelper) - return () => { - helper.current = undefined - scene.remove(currentHelper) - currentHelper.dispose?.() - } - } - }, [scene, helperConstructor, object3D, ...args]) - - useFrame(() => void helper.current?.update?.()) - return helper -}