UNPKG

react-native-filament

Version:

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

114 lines (105 loc) 3.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.useModel = useModel; var _useBuffer = require("./useBuffer"); var _useFilamentContext = require("./useFilamentContext"); var _useDisposableResource = require("./useDisposableResource"); var _usePrevious = _interopRequireDefault(require("./usePrevious")); var _useWorkletEffect = require("./useWorkletEffect"); var _react = require("react"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * The resulting filament model, or `'loading'` if not yet available. */ /** * Loads a model from the given source. * * * 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`) * * @worklet * @example * ```ts * const model = useModel(require('model.glb')) * ``` */ function useModel(source, props) { const { shouldReleaseSourceData = true, addToScene = true, instanceCount } = props ?? {}; const { engine, scene, workletContext } = (0, _useFilamentContext.useFilamentContext)(); const assetBuffer = (0, _useBuffer.useBuffer)({ source: source, releaseOnUnmount: false }); // Note: the native cleanup of the asset will remove it automatically from the scene const asset = (0, _useDisposableResource.useDisposableResource)(() => { if (assetBuffer == null) return; if (instanceCount === 0) { throw new Error('instanceCount must be greater than 0'); } return workletContext.runAsync(() => { 'worklet'; let loadedAsset; if (instanceCount == null || instanceCount === 1) { loadedAsset = engine.loadAsset(assetBuffer); } else { loadedAsset = engine.loadInstancedAsset(assetBuffer, instanceCount); } // After loading the asset we can release the buffer assetBuffer.release(); return loadedAsset; }); }, [assetBuffer, workletContext, engine, instanceCount]); (0, _useWorkletEffect.useWorkletEffect)(() => { 'worklet'; if (asset == null || !shouldReleaseSourceData) { return; } // releases CPU memory for bindings asset.releaseSourceData(); }); // Add or remove from the scene: const previousAddToScene = (0, _usePrevious.default)(addToScene); (0, _useWorkletEffect.useWorkletEffect)(() => { 'worklet'; if (asset == null) return; if (addToScene) { scene.addAssetEntities(asset); } else if (!addToScene && previousAddToScene) { // Only remove when it was previously added (ie. the user set addToScene: false) scene.removeAssetEntities(asset); } }); const boundingBox = (0, _react.useMemo)(() => { if (asset == null) return undefined; return asset.getBoundingBox(); }, [asset]); const rootEntity = (0, _react.useMemo)(() => { if (asset == null) { return null; } return asset.getRoot(); }, [asset]); if (assetBuffer == null || asset == null || boundingBox == null || rootEntity == null) { return { state: 'loading' }; } return { state: 'loaded', asset: asset, rootEntity: rootEntity, boundingBox: boundingBox }; } //# sourceMappingURL=useModel.js.map