@react-three/drei
Version:
useful add-ons for react-three-fiber
2 lines (1 loc) • 5.66 kB
JavaScript
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))))]};
;