UNPKG

@react-three/drei

Version:

useful add-ons for react-three-fiber

101 lines (96 loc) 2.9 kB
import _extends from '@babel/runtime/helpers/esm/extends'; import * as THREE from 'three'; import * as React from 'react'; import { SkeletonUtils } from 'three-stdlib'; function createSpread(child, { keys = ['near', 'far', 'color', 'distance', 'decay', 'penumbra', 'angle', 'intensity', 'skeleton', 'visible', 'castShadow', 'receiveShadow', 'morphTargetDictionary', 'morphTargetInfluences', 'name', 'geometry', 'material', 'position', 'rotation', 'scale', 'up', 'userData', 'bindMode', 'bindMatrix', 'bindMatrixInverse', 'skeleton'], deep, inject, castShadow, receiveShadow }) { let spread = {}; for (const key of keys) { spread[key] = child[key]; } if (deep) { if (spread.geometry && deep !== 'materialsOnly') spread.geometry = spread.geometry.clone(); if (spread.material && deep !== 'geometriesOnly') spread.material = spread.material.clone(); } if (inject) { if (typeof inject === 'function') spread = { ...spread, children: inject(child) };else if (/*#__PURE__*/React.isValidElement(inject)) spread = { ...spread, children: inject };else spread = { ...spread, ...inject }; } if (child instanceof THREE.Mesh) { if (castShadow) spread.castShadow = true; if (receiveShadow) spread.receiveShadow = true; } return spread; } const Clone = /* @__PURE__ */React.forwardRef(({ isChild = false, object, children, deep, castShadow, receiveShadow, inject, keys, ...props }, forwardRef) => { const config = { keys, deep, inject, castShadow, receiveShadow }; object = React.useMemo(() => { if (isChild === false && !Array.isArray(object)) { let isSkinned = false; object.traverse(object => { if (object.isSkinnedMesh) isSkinned = true; }); if (isSkinned) return SkeletonUtils.clone(object); } return object; }, [object, isChild]); // Deal with arrayed clones if (Array.isArray(object)) { return /*#__PURE__*/React.createElement("group", _extends({}, props, { ref: forwardRef }), object.map(o => /*#__PURE__*/React.createElement(Clone, _extends({ key: o.uuid, object: o }, config))), children); } // Singleton clones const { children: injectChildren, ...spread } = createSpread(object, config); const Element = object.type[0].toLowerCase() + object.type.slice(1); return /*#__PURE__*/React.createElement(Element, _extends({}, spread, props, { ref: forwardRef }), object.children.map(child => { if (child.type === 'Bone') return /*#__PURE__*/React.createElement("primitive", _extends({ key: child.uuid, object: child }, config)); return /*#__PURE__*/React.createElement(Clone, _extends({ key: child.uuid, object: child }, config, { isChild: true })); }), children, injectChildren); }); export { Clone };