UNPKG

react-native-filament-buildcores

Version:

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

103 lines (98 loc) 4.23 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.useApplyTransformations = useApplyTransformations; var _react = require("react"); var _useFilamentContext = require("../useFilamentContext"); var _helper = require("../../utilities/helper"); var _useWorkletEffect = require("../useWorkletEffect"); /** * Takes the next entity from the context and applies all transformations from the next * transformation context to it */ function useApplyTransformations({ to: entity, transformProps, aabb }) { const { translate: position, scale, rotate, transformToUnitCube, multiplyWithCurrentTransform = true } = transformProps ?? {}; const { transformManager } = (0, _useFilamentContext.useFilamentContext)(); // TODO: multiplying current transformations is a bit problematic with react. // E.g. in strict mode or concurrent rendering our effects can be called multiple times. // Running an effect multiple times with transformation multiplication can lead to unexpected results. const prevScale = (0, _react.useRef)(null); const prevRotate = (0, _react.useRef)(null); const prevPosition = (0, _react.useRef)(null); (0, _react.useEffect)(() => { if (entity == null) return; if (transformToUnitCube && aabb != null) { transformManager.transformToUnitCube(entity, aabb); } if (Array.isArray(scale) && (prevScale.current == null || !(0, _helper.areFloat3Equal)(scale, prevScale.current))) { transformManager.setEntityScale(entity, scale, multiplyWithCurrentTransform); prevScale.current = scale; } if (Array.isArray(rotate) && (prevRotate.current == null || !(0, _helper.areFloat3Equal)(rotate, prevRotate.current))) { const [x, y, z] = rotate; transformManager.setEntityRotation(entity, x, [1, 0, 0], multiplyWithCurrentTransform); // Rotation across axis is one operation so we need to always multiply the remaining rotations: transformManager.setEntityRotation(entity, y, [0, 1, 0], true); transformManager.setEntityRotation(entity, z, [0, 0, 1], true); prevRotate.current = rotate; } if (Array.isArray(position) && (prevPosition.current == null || !(0, _helper.areFloat3Equal)(position, prevPosition.current))) { transformManager.setEntityPosition(entity, position, multiplyWithCurrentTransform); prevPosition.current = position; } }, [aabb, entity, multiplyWithCurrentTransform, position, prevPosition, prevRotate, prevScale, rotate, scale, transformManager, transformToUnitCube]); // Effects for when a transform option is a shared value (SRT) (0, _react.useEffect)(() => { if (entity == null) return; if (scale == null || Array.isArray(scale)) return; const unsubscribeScale = scale.addListener(() => { transformManager.setEntityScale(entity, scale.value, multiplyWithCurrentTransform); }); return () => { unsubscribeScale(); }; }, [entity, multiplyWithCurrentTransform, scale, transformManager]); (0, _useWorkletEffect.useWorkletEffect)(() => { 'worklet'; if (entity == null) return; if (rotate == null || !(0, _helper.isWorkletSharedValue)(rotate)) { return; } const unsubscribeRotate = rotate.addListener(() => { 'worklet'; const [x, y, z] = rotate.value; transformManager.setEntityRotation(entity, x, [1, 0, 0], multiplyWithCurrentTransform); // Rotation across axis is one operation so we need to always multiply the remaining rotations: transformManager.setEntityRotation(entity, y, [0, 1, 0], true); transformManager.setEntityRotation(entity, z, [0, 0, 1], true); }); return () => { 'worklet'; unsubscribeRotate(); }; }); (0, _react.useEffect)(() => { if (entity == null) return; if (position == null || Array.isArray(position)) return; const unsubscribePosition = position.addListener(() => { transformManager.setEntityPosition(entity, position.value, multiplyWithCurrentTransform); }); return () => { unsubscribePosition(); }; }, [entity, multiplyWithCurrentTransform, position, transformManager]); } //# sourceMappingURL=useApplyTransformations.js.map