UNPKG

react-native-filament

Version:

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

79 lines (74 loc) 3.77 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 { Context } from './Context'; import { RenderCallbackContext } from './RenderCallbackContext'; /** * Creates an engine and all filament APIs and provides them to the children using the react context. * * @note You only need this for doing offscreen recording. For an on-screen surface use the `Filament` component. */ export function FilamentContext({ 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(Context.Provider, { value: value }, /*#__PURE__*/React.createElement(Configurator, { rendererProps: rendererProps, viewProps: viewProps }, /*#__PURE__*/React.createElement(RenderCallbackContext.RenderContextProvider, null, children))); } //# sourceMappingURL=FilamentContext.js.map