UNPKG

react-native-filament

Version:

A real-time physically based 3D rendering engine for React Native

103 lines (98 loc) 4.41 kB
import { useMemo } from 'react'; import { FilamentProxy, FilamentWorkletContext } from '../native/FilamentProxy'; import { useEngine } from '../hooks/useEngine'; import { useDisposableResource } from '../hooks/useDisposableResource'; import { useWorklet } from 'react-native-worklets-core'; import React from 'react'; import { Configurator } from './Configurator'; import { FilamentContext } from '../hooks/useFilamentContext'; import { RenderCallbackContext } from './RenderCallbackContext'; /** * The `<FilamentScene>` holds contextual values for a Filament rendering scene. * * You need to wrap your rendering scene (= a component that uses `<FilamentView>`, hooks or * other Filament components) with a `<FilamentScene>`. * * @note Make sure to wrap your scene in a parent component, otherwise the React context cannot be inferred. * @example * ```tsx * function Scene() { * // in here you can use Filament's hooks and components * return ( * <FilamentView style={styles.container}> * <DefaultLight /> * <Model source={{ uri: modelPath }} /> * </FilamentView> * ) * } * * export function RocketModel() { * // in here you only need to wrap the child-component with <FilamentScene> * return ( * <FilamentScene> * <Scene /> * </FilamentScene> * ) * } * ``` */ export function FilamentScene({ children, fallback, config, backend, frameRateOptions, ...viewProps }) { // First create the engine, which we need to create (almost) all other filament APIs const engine = useEngine({ config, backend, context: FilamentWorkletContext }); // Create all Filament APIs using the engine const transformManager = useDisposableResource(() => Promise.resolve(engine === null || engine === void 0 ? void 0 : engine.createTransformManager()), [engine]); const renderableManager = useDisposableResource(() => Promise.resolve(engine === null || engine === void 0 ? void 0 : engine.createRenderableManager()), [engine]); const scene = useDisposableResource(() => Promise.resolve(engine === null || engine === void 0 ? void 0 : engine.getScene()), [engine]); const lightManager = useDisposableResource(() => Promise.resolve(engine === null || engine === void 0 ? void 0 : engine.createLightManager()), [engine]); const view = useDisposableResource(() => Promise.resolve(engine === null || engine === void 0 ? void 0 : engine.getView()), [engine]); const camera = useDisposableResource(() => Promise.resolve(engine === null || engine === void 0 ? void 0 : engine.getCamera()), [engine]); const renderer = useDisposableResource(() => Promise.resolve(engine === null || engine === void 0 ? void 0 : engine.createRenderer()), [engine]); const nameComponentManager = useDisposableResource(() => Promise.resolve(engine === null || engine === void 0 ? void 0 : engine.createNameComponentManager()), [engine]); // Create a choreographer for this context tree const choreographer = useDisposableResource(useWorklet(FilamentWorkletContext, () => { 'worklet'; return FilamentProxy.createChoreographer(); })); // Construct the context object value: const value = useMemo(() => { if (transformManager == null || renderableManager == null || scene == null || lightManager == null || view == null || camera == null || renderer == null || nameComponentManager == null || choreographer == null || engine == null) { return undefined; } return { engine, transformManager, renderableManager, scene, lightManager, view, camera, renderer, nameComponentManager, workletContext: FilamentWorkletContext, choreographer: choreographer }; }, [engine, transformManager, renderableManager, scene, lightManager, view, camera, renderer, nameComponentManager, choreographer]); const rendererProps = useMemo(() => ({ frameRateOptions }), [frameRateOptions]); // If the APIs aren't ready yet render the fallback component (or nothing) if (value == null) return fallback ?? null; return /*#__PURE__*/React.createElement(FilamentContext.Provider, { value: value }, /*#__PURE__*/React.createElement(Configurator, { rendererProps: rendererProps, viewProps: viewProps }, /*#__PURE__*/React.createElement(RenderCallbackContext.RenderContextProvider, null, children))); } //# sourceMappingURL=FilamentScene.js.map