UNPKG

react-native-filament

Version:

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

72 lines (62 loc) 2.28 kB
import { useEffect, useMemo, useState } from 'react' import { FilamentBuffer } from '../native/FilamentBuffer' import { FilamentProxy } from '../native/FilamentProxy' import { withCleanupScope } from '../utilities/withCleanupScope' import { Image } from 'react-native' // In React Native, `require(..)` returns a number. type Require = number // ReturnType<typeof require> export type BufferSource = | Require | { /** * A web URL (http:// or https://), local file (file://) or asset path of the bundled asset. */ uri: string } export interface BufferProps { /** * If you are passing in a `.glb` model or similar from your app's bundle using `require(..)`, make sure to add `glb` as an asset extension to `metro.config.js`! * If you are passing in a `{ url: ... }`, make sure the URL points directly to a `.glb` model. This can either be a web URL (`http://..`/`https://..`), a local file (`file://..`), or an native asset path (`path/to/asset.glb`) */ source: BufferSource /** * @default true */ releaseOnUnmount?: boolean } /** * Asynchronously load an asset from the given web URL, local file path, or resource ID. */ export function useBuffer({ source: source, releaseOnUnmount = true }: BufferProps): FilamentBuffer | undefined { const [buffer, setBuffer] = useState<FilamentBuffer | undefined>(undefined) const uri = useMemo(() => { if (typeof source === 'object') { return source.uri } const asset = Image.resolveAssetSource(source) if (asset == null) { throw new Error( `Failed to load source: ${source}. Are you sure that\n-The asset exists on this path?\n-The metro bundler is configured correctly as explained in the documentation?` ) } return asset.uri }, [source]) // TODO: useDisposableResource useEffect(() => { let localBuffer: FilamentBuffer | undefined FilamentProxy.loadAsset(uri) .then((asset) => { localBuffer = asset setBuffer(asset) }) .catch((error) => { console.error(`Failed to load asset: ${uri}`, error) }) return withCleanupScope(() => { if (releaseOnUnmount) { localBuffer?.release() } }) }, [releaseOnUnmount, uri]) return buffer }