@react-three/drei 10.0.0 → 10.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  import { Line2 } from 'three-stdlib';
2
2
  import { LineProps } from './Line';
3
3
  import { ForwardRefComponent } from '../helpers/ts-utils';
4
- export type CatmullRomLineProps = Omit<LineProps, 'ref'> & {
4
+ export type CatmullRomLineProps = Omit<LineProps, 'ref' | 'segments'> & {
5
5
  closed?: boolean;
6
6
  curveType?: 'centripetal' | 'chordal' | 'catmullrom';
7
7
  tension?: number;
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("@babel/runtime/helpers/extends"),t=require("three"),r=require("react"),n=require("@react-three/fiber"),a=require("../helpers/deprecated.cjs.js");function s(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}function c(e){if(e&&e.__esModule)return e;var t=Object.create(null);return e&&Object.keys(e).forEach((function(r){if("default"!==r){var n=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,n.get?n:{enumerable:!0,get:function(){return e[r]}})}})),t.default=e,Object.freeze(t)}var u=s(e),i=c(t),o=c(r);const l=new i.Matrix4,f=new i.Matrix4,d=[],m=new i.Mesh;class y extends i.Group{constructor(){super(),this.color=new i.Color("white"),this.instance={current:void 0},this.instanceKey={current:void 0}}get geometry(){var e;return null==(e=this.instance.current)?void 0:e.geometry}raycast(e,t){const r=this.instance.current;if(!r)return;if(!r.geometry||!r.material)return;m.geometry=r.geometry;const n=r.matrixWorld,a=r.userData.instances.indexOf(this.instanceKey);if(!(-1===a||a>r.count)){r.getMatrixAt(a,l),f.multiplyMatrices(n,l),m.matrixWorld=f,r.material instanceof i.Material?m.material.side=r.material.side:m.material.side=r.material[0].side,m.raycast(e,d);for(let e=0,r=d.length;e<r;e++){const r=d[e];r.instanceId=a,r.object=this,t.push(r)}d.length=0}}}const p=o.createContext(null),g=new i.Matrix4,x=new i.Matrix4,h=new i.Matrix4,b=new i.Vector3,M=new i.Quaternion,w=new i.Vector3,A=o.forwardRef((({context:e,children:t,...r},a)=>{o.useMemo((()=>n.extend({PositionMesh:y})),[]);const s=o.useRef(null);o.useImperativeHandle(a,(()=>s.current),[]);const{subscribe:c,getParent:i}=o.useContext(e||p);return o.useLayoutEffect((()=>c(s)),[]),o.createElement("positionMesh",u.default({instance:i(),instanceKey:s,ref:s},r),t)})),v=o.forwardRef((({context:e,children:t,range:r,limit:s=1e3,frames:c=1/0,...l},f)=>{const[{localContext:d,instance:m}]=o.useState((()=>{const e=o.createContext(null);return{localContext:e,instance:o.forwardRef(((t,r)=>o.createElement(A,u.default({context:e},t,{ref:r}))))}})),y=o.useRef(null);o.useImperativeHandle(f,(()=>y.current),[]);const[v,E]=o.useState([]),[[j,D]]=o.useState((()=>{const e=new Float32Array(16*s);for(let t=0;t<s;t++)h.identity().toArray(e,16*t);return[e,new Float32Array([...new Array(3*s)].map((()=>1)))]}));o.useEffect((()=>{y.current.instanceMatrix.needsUpdate=!0}));let R=0,C=0;const P=o.useRef([]);o.useLayoutEffect((()=>{P.current=Object.entries(y.current.geometry.attributes).filter((([e,t])=>t.isInstancedBufferAttribute))})),n.useFrame((()=>{if(c===1/0||R<c){y.current.updateMatrix(),y.current.updateMatrixWorld(),g.copy(y.current.matrixWorld).invert(),C=Math.min(s,void 0!==r?r:s,v.length),y.current.count=C,a.setUpdateRange(y.current.instanceMatrix,{start:0,count:16*C}),a.setUpdateRange(y.current.instanceColor,{start:0,count:3*C});for(let e=0;e<v.length;e++){const t=v[e].current;t.matrixWorld.decompose(b,M,w),x.compose(b,M,w).premultiply(g),x.toArray(j,16*e),y.current.instanceMatrix.needsUpdate=!0,t.color.toArray(D,3*e),y.current.instanceColor.needsUpdate=!0}R++}}));const U=o.useMemo((()=>({getParent:()=>y,subscribe:e=>(E((t=>[...t,e])),()=>E((t=>t.filter((t=>t.current!==e.current)))))})),[]);return o.createElement("instancedMesh",u.default({userData:{instances:v,limit:s,frames:c},matrixAutoUpdate:!1,ref:y,args:[null,null,0],raycast:()=>null},l),o.createElement("instancedBufferAttribute",{attach:"instanceMatrix",args:[j,16],usage:i.DynamicDrawUsage}),o.createElement("instancedBufferAttribute",{attach:"instanceColor",args:[D,3],usage:i.DynamicDrawUsage}),"function"==typeof t?o.createElement(d.Provider,{value:U},t(m)):e?o.createElement(e.Provider,{value:U},t):o.createElement(p.Provider,{value:U},t))})),E=o.forwardRef((function({meshes:e,children:t,...r},n){const a=[];if(Array.isArray(e))for(const t of e)null!=t&&t.isMesh&&a.push((e=>o.createElement(v,u.default({key:t.geometry.uuid,geometry:t.geometry,material:t.material},r,e))));else if(null!=e&&"object"==typeof e)for(const t in e){const n=e[t];null!=n&&n.isMesh&&a.push((e=>o.createElement(v,u.default({key:n.geometry.uuid,geometry:n.geometry,material:n.material},r,e))))}return o.createElement("group",{ref:n},t(a))}));const j=o.forwardRef((({name:e,defaultValue:t,normalized:r,usage:a=i.DynamicDrawUsage},s)=>{const c=o.useRef(null);o.useImperativeHandle(s,(()=>c.current),[]),o.useLayoutEffect((()=>{const r=c.current.__r3f.parent.object;r.geometry.attributes[e]=c.current;const n=Array.isArray(t)?t:[t],a=Array.from({length:r.userData.limit},(()=>n)).flat();return c.current.array=new Float32Array(a),c.current.itemSize=n.length,c.current.count=a.length/c.current.itemSize,()=>{delete r.geometry.attributes[e]}}),[e]);let u=0;return n.useFrame((()=>{const t=c.current.__r3f.parent.object;if(t.userData.frames===1/0||u<t.userData.frames){for(let r=0;r<t.userData.instances.length;r++){const n=t.userData.instances[r].current[e];void 0!==n&&(c.current.set(Array.isArray(n)?n:"function"==typeof n.toArray?n.toArray():[n],r*c.current.itemSize),c.current.needsUpdate=!0)}u++}})),o.createElement("instancedBufferAttribute",{ref:c,usage:a,normalized:r})}));exports.Instance=A,exports.InstancedAttribute=j,exports.Instances=v,exports.Merged=E,exports.PositionMesh=y,exports.createInstances=function(){const e=o.createContext(null);return[o.forwardRef(((t,r)=>o.createElement(v,u.default({ref:r,context:e},t)))),o.forwardRef(((t,r)=>o.createElement(A,u.default({ref:r,context:e},t))))]};
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("@babel/runtime/helpers/extends"),t=require("three"),r=require("react"),n=require("@react-three/fiber"),a=require("../helpers/deprecated.cjs.js");function c(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}function s(e){if(e&&e.__esModule)return e;var t=Object.create(null);return e&&Object.keys(e).forEach((function(r){if("default"!==r){var n=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,n.get?n:{enumerable:!0,get:function(){return e[r]}})}})),t.default=e,Object.freeze(t)}var u=c(e),i=s(t),o=s(r);const l=new i.Matrix4,f=new i.Matrix4,d=[],m=new i.Mesh;class y extends i.Group{constructor(){super(),this.color=new i.Color("white"),this.instance={current:void 0},this.instanceKey={current:void 0}}get geometry(){var e;return null==(e=this.instance.current)?void 0:e.geometry}raycast(e,t){const r=this.instance.current;if(!r)return;if(!r.geometry||!r.material)return;m.geometry=r.geometry;const n=r.matrixWorld,a=r.userData.instances.indexOf(this.instanceKey);if(!(-1===a||a>r.count)){r.getMatrixAt(a,l),f.multiplyMatrices(n,l),m.matrixWorld=f,r.material instanceof i.Material?m.material.side=r.material.side:m.material.side=r.material[0].side,m.raycast(e,d);for(let e=0,r=d.length;e<r;e++){const r=d[e];r.instanceId=a,r.object=this,t.push(r)}d.length=0}}}const p=o.createContext(null),g=new i.Matrix4,x=new i.Matrix4,h=new i.Matrix4,b=new i.Vector3,M=new i.Quaternion,w=new i.Vector3,A=o.forwardRef((({context:e,children:t,...r},a)=>{o.useMemo((()=>n.extend({PositionMesh:y})),[]);const c=o.useRef(null);o.useImperativeHandle(a,(()=>c.current),[]);const{subscribe:s,getParent:i}=o.useContext(e||p);return o.useLayoutEffect((()=>s(c)),[]),o.createElement("positionMesh",u.default({instance:i(),instanceKey:c,ref:c},r),t)})),v=o.forwardRef((({context:e,children:t,range:r,limit:c=1e3,frames:s=1/0,...l},f)=>{const[{localContext:d,instance:m}]=o.useState((()=>{const e=o.createContext(null);return{localContext:e,instance:o.forwardRef(((t,r)=>o.createElement(A,u.default({context:e},t,{ref:r}))))}})),y=o.useRef(null);o.useImperativeHandle(f,(()=>y.current),[]);const[v,E]=o.useState([]),[[j,D]]=o.useState((()=>{const e=new Float32Array(16*c);for(let t=0;t<c;t++)h.identity().toArray(e,16*t);return[e,new Float32Array([...new Array(3*c)].map((()=>1)))]}));o.useEffect((()=>{y.current.instanceMatrix.needsUpdate=!0}));let R=0,O=0;const C=o.useRef([]);o.useLayoutEffect((()=>{C.current=Object.entries(y.current.geometry.attributes).filter((([e,t])=>t.isInstancedBufferAttribute))})),n.useFrame((()=>{if(s===1/0||R<s){y.current.updateMatrix(),y.current.updateMatrixWorld(),g.copy(y.current.matrixWorld).invert(),O=Math.min(c,void 0!==r?r:c,v.length),y.current.count=O,a.setUpdateRange(y.current.instanceMatrix,{start:0,count:16*O}),a.setUpdateRange(y.current.instanceColor,{start:0,count:3*O});for(let e=0;e<v.length;e++){const t=v[e].current;t.matrixWorld.decompose(b,M,w),x.compose(b,M,w).premultiply(g),x.toArray(j,16*e),y.current.instanceMatrix.needsUpdate=!0,t.color.toArray(D,3*e),y.current.instanceColor.needsUpdate=!0}R++}}));const P=o.useMemo((()=>({getParent:()=>y,subscribe:e=>(E((t=>[...t,e])),()=>E((t=>t.filter((t=>t.current!==e.current)))))})),[]);return o.createElement("instancedMesh",u.default({userData:{instances:v,limit:c,frames:s},matrixAutoUpdate:!1,ref:y,args:[null,null,0],raycast:()=>null},l),o.createElement("instancedBufferAttribute",{attach:"instanceMatrix",args:[j,16],usage:i.DynamicDrawUsage}),o.createElement("instancedBufferAttribute",{attach:"instanceColor",args:[D,3],usage:i.DynamicDrawUsage}),"function"==typeof t?o.createElement(d.Provider,{value:P},t(m)):e?o.createElement(e.Provider,{value:P},t):o.createElement(p.Provider,{value:P},t))})),E=o.forwardRef((function({meshes:e,children:t,...r},n){const a=Array.isArray(e);if(!a)for(const t of Object.keys(e))e[t].isMesh||delete e[t];const c=(a?e:Object.values(e)).map((({geometry:e,material:t})=>o.createElement(v,u.default({key:e.uuid,geometry:e,material:t},r))));return o.createElement("group",{ref:n},j((r=>a?t(...r):t(Object.keys(e).filter((t=>e[t].isMesh)).reduce(((e,t,n)=>({...e,[t]:r[n]})),{}))),c))}));function j(e,t,r=[]){if(!t[0])return e(r);function n(n){return j(e,t.slice(1),r.concat([n]))}return"function"==typeof t[0]?t[0]({results:r,render:n}):o.cloneElement(t[0],{children:n})}const D=o.forwardRef((({name:e,defaultValue:t,normalized:r,usage:a=i.DynamicDrawUsage},c)=>{const s=o.useRef(null);o.useImperativeHandle(c,(()=>s.current),[]),o.useLayoutEffect((()=>{const r=s.current.__r3f.parent.object;r.geometry.attributes[e]=s.current;const n=Array.isArray(t)?t:[t],a=Array.from({length:r.userData.limit},(()=>n)).flat();return s.current.array=new Float32Array(a),s.current.itemSize=n.length,s.current.count=a.length/s.current.itemSize,()=>{delete r.geometry.attributes[e]}}),[e]);let u=0;return n.useFrame((()=>{const t=s.current.__r3f.parent.object;if(t.userData.frames===1/0||u<t.userData.frames){for(let r=0;r<t.userData.instances.length;r++){const n=t.userData.instances[r].current[e];void 0!==n&&(s.current.set(Array.isArray(n)?n:"function"==typeof n.toArray?n.toArray():[n],r*s.current.itemSize),s.current.needsUpdate=!0)}u++}})),o.createElement("instancedBufferAttribute",{ref:s,usage:a,normalized:r})}));exports.Instance=A,exports.InstancedAttribute=D,exports.Instances=v,exports.Merged=E,exports.PositionMesh=y,exports.createInstances=function(){const e=o.createContext(null);return[o.forwardRef(((t,r)=>o.createElement(v,u.default({ref:r,context:e},t)))),o.forwardRef(((t,r)=>o.createElement(A,u.default({ref:r,context:e},t))))]};
@@ -42,11 +42,11 @@ export declare const Instance: React.ForwardRefExoticComponent<Omit<import("@rea
42
42
  context?: React.Context<Api>;
43
43
  } & React.RefAttributes<unknown>>;
44
44
  export declare const Instances: ForwardRefComponent<InstancesProps, THREE.InstancedMesh>;
45
- export interface MergedProps extends InstancesProps {
46
- meshes: THREE.Mesh[];
47
- children: React.ReactNode;
45
+ export interface MergedProps extends Omit<InstancesProps, 'children'> {
46
+ meshes: THREE.Mesh[] | Record<string, THREE.Object3D>;
47
+ children: (...instances: [React.FC<InstanceProps> & Record<string, React.FC<InstanceProps>>, ...React.FC<InstanceProps>[]]) => React.ReactNode;
48
48
  }
49
- export declare const Merged: ForwardRefComponent<any, THREE.Group>;
49
+ export declare const Merged: ForwardRefComponent<MergedProps, THREE.Group>;
50
50
  export declare function createInstances<T = InstanceProps>(): readonly [React.ForwardRefExoticComponent<Omit<import("@react-three/fiber/dist/declarations/src/core/utils").Mutable<import("@react-three/fiber/dist/declarations/src/core/utils").Overwrite<Partial<import("@react-three/fiber/dist/declarations/src/core/utils").Overwrite<THREE.InstancedMesh<THREE.BufferGeometry<THREE.NormalBufferAttributes>, THREE.Material | THREE.Material[]>, import("@react-three/fiber").MathProps<THREE.InstancedMesh<THREE.BufferGeometry<THREE.NormalBufferAttributes>, THREE.Material | THREE.Material[]>> & import("@react-three/fiber").ReactProps<THREE.InstancedMesh<THREE.BufferGeometry<THREE.NormalBufferAttributes>, THREE.Material | THREE.Material[]>> & Partial<import("@react-three/fiber").EventHandlers>>>, Omit<import("@react-three/fiber").InstanceProps<THREE.InstancedMesh<THREE.BufferGeometry<THREE.NormalBufferAttributes>, THREE.Material | THREE.Material[]>, typeof THREE.InstancedMesh>, "object">>>, "ref" | "args"> & {
51
51
  context?: React.Context<Api>;
52
52
  range?: number;
package/core/Instances.js CHANGED
@@ -188,39 +188,68 @@ const Instances = /* @__PURE__ */React.forwardRef(({
188
188
  value: api
189
189
  }, children));
190
190
  });
191
- const Merged = /*#__PURE__*/React.forwardRef(function Merged({
191
+ // TODO: make this non-recursive and type-safe
192
+ const Merged = /* @__PURE__ */React.forwardRef(function Merged({
192
193
  meshes,
193
194
  children,
194
- ...rest
195
+ ...props
195
196
  }, ref) {
196
- const instances = [];
197
- if (Array.isArray(meshes)) {
198
- for (const mesh of meshes) {
199
- if (mesh != null && mesh.isMesh) {
200
- instances.push(props => /*#__PURE__*/React.createElement(Instances, _extends({
201
- key: mesh.geometry.uuid,
202
- geometry: mesh.geometry,
203
- material: mesh.material
204
- }, rest, props)));
205
- }
206
- }
207
- } else if (meshes != null && typeof meshes === 'object') {
208
- for (const key in meshes) {
209
- const mesh = meshes[key];
210
- if (mesh != null && mesh.isMesh) {
211
- instances.push(props => /*#__PURE__*/React.createElement(Instances, _extends({
212
- key: mesh.geometry.uuid,
213
- geometry: mesh.geometry,
214
- material: mesh.material
215
- }, rest, props)));
216
- }
217
- }
218
- }
197
+ const isArray = Array.isArray(meshes);
198
+ // Filter out meshes from collections, which may contain non-meshes
199
+ // @ts-expect-error
200
+ if (!isArray) for (const key of Object.keys(meshes)) if (!meshes[key].isMesh) delete meshes[key];
201
+ const render = args => isArray ?
202
+ // @ts-expect-error
203
+ children(...args) : children(
204
+ // @ts-expect-error
205
+ Object.keys(meshes)
206
+ // @ts-expect-error
207
+ .filter(key => meshes[key].isMesh).reduce((acc, key, i) => ({
208
+ ...acc,
209
+ [key]: args[i]
210
+ }), {}));
211
+
212
+ // @ts-expect-error
213
+ const components = (isArray ? meshes : Object.values(meshes)).map(({
214
+ geometry,
215
+ material
216
+ }) => /*#__PURE__*/React.createElement(Instances, _extends({
217
+ key: geometry.uuid,
218
+ geometry: geometry,
219
+ material: material
220
+ }, props)));
219
221
  return /*#__PURE__*/React.createElement("group", {
220
222
  ref: ref
221
- }, children(instances));
223
+ }, renderRecursive(render, components));
222
224
  });
223
225
 
226
+ // https://github.com/jamesplease/react-composer
227
+ function renderRecursive(render, components, results = []) {
228
+ // Once components is exhausted, we can render out the results array.
229
+ if (!components[0]) {
230
+ return render(results);
231
+ }
232
+
233
+ // Continue recursion for remaining items.
234
+ // results.concat([value]) ensures [...results, value] instead of [...results, ...value]
235
+ function nextRender(value) {
236
+ return renderRecursive(render, components.slice(1), results.concat([value]));
237
+ }
238
+
239
+ // Each props.components entry is either an element or function [element factory]
240
+ return typeof components[0] === 'function' ?
241
+ // When it is a function, produce an element by invoking it with "render component values".
242
+ components[0]({
243
+ results,
244
+ render: nextRender
245
+ }) :
246
+ /*#__PURE__*/
247
+ // When it is an element, enhance the element's props with the render prop.
248
+ React.cloneElement(components[0], {
249
+ children: nextRender
250
+ });
251
+ }
252
+
224
253
  /** Idea and implementation for global instances and instanced attributes by
225
254
  /* Matias Gonzalez Fernandez https://x.com/matiNotFound
226
255
  /* and Paul Henschel https://x.com/0xca0a