@react-three/drei 7.8.1 → 7.8.5

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.
@@ -7,7 +7,7 @@ export declare const useGizmoContext: () => GizmoHelperContext;
7
7
  export declare type GizmoHelperProps = JSX.IntrinsicElements['group'] & {
8
8
  alignment?: 'top-left' | 'top-right' | 'bottom-right' | 'bottom-left';
9
9
  margin?: [number, number];
10
- onUpdate: () => void;
10
+ onUpdate?: () => void;
11
11
  onTarget?: () => Vector3;
12
12
  };
13
13
  export declare const GizmoHelper: ({ alignment, margin, onUpdate, onTarget, children: GizmoHelperComponent, }: GizmoHelperProps) => any;
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("@babel/runtime/helpers/extends"),r=require("@babel/runtime/helpers/objectWithoutPropertiesLoose"),t=require("three"),n=require("react"),u=require("@react-three/fiber"),a=require("react-merge-refs"),c=require("../helpers/Position.cjs.js");function i(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}function o(e){if(e&&e.__esModule)return e;var r=Object.create(null);return e&&Object.keys(e).forEach((function(t){if("default"!==t){var n=Object.getOwnPropertyDescriptor(e,t);Object.defineProperty(r,t,n.get?n:{enumerable:!0,get:function(){return e[t]}})}})),r.default=e,Object.freeze(r)}require("@babel/runtime/helpers/inheritsLoose");var l,s=i(e),f=i(r),d=o(t),m=o(n),b=i(a),h=m.createContext(null),p=new d.Matrix4,v=new d.Matrix4,y=new d.Matrix4,g=new d.Color;var x=m.forwardRef((function(e,r){var t=e.children,n=f.default(e,["children"]);m.useMemo((function(){return u.extend({Position:c.Position})}),[]);var a=m.useRef(),i=m.useContext(h).subscribe;return m.useLayoutEffect((function(){return i(a)}),[]),m.createElement("position",s.default({ref:b.default([r,a])},n),t)}));exports.Instance=x,exports.Instances=function(e){var r=e.children,t=e.range,n=e.limit,a=void 0===n?1e3:n,c=f.default(e,["children","range","limit"]),i=m.useRef(null),o=m.useState([]),d=o[0],b=o[1],x=m.useState((function(){var e=[].concat(new Array(16*a)).map((function(){return 0})),r=[].concat(new Array(3*a)).map((function(){return 1}));return[new Float32Array(e),new Float32Array(r)]}))[0],M=x[0],j=x[1];m.useLayoutEffect((function(){i.current.count=i.current.instanceMatrix.updateRange.count=i.current.instanceColor.updateRange.count=Math.min(a,void 0!==t?t:a,d.length)}),[d,t]),u.useFrame((function(){for(p.copy(i.current.matrixWorld).invert(),l=0;l<d.length;l++)v.copy(d[l].current.matrixWorld).multiply(p),p.equals(y.fromArray(M,16*l))||(v.toArray(M,16*l),i.current.instanceMatrix.needsUpdate=!0),d[l].current.color.equals(g.fromArray(j,3*l))||(d[l].current.color.toArray(j,3*l),i.current.instanceColor.needsUpdate=!0)}));var q=m.useMemo((function(){var e={};for(l=0;l<d.length;l++){var r;Object.assign(e,null==(r=d[l].current)?void 0:r.__r3f.handlers)}return Object.keys(e).reduce((function(e,r){var t;return s.default({},e,((t={})[r]=function(e){var t,n,u;return null==(t=d[e.instanceId].current)||null==(n=t.__r3f)||null==(u=n.handlers)?void 0:u[r](e)},t))}),{})}),[d]),w=m.useMemo((function(){return{subscribe:function(e){return b((function(r){return[].concat(r,[e])})),function(){return b((function(r){return r.filter((function(r){return r.current!==e.current}))}))}}}}),[]);return m.createElement("instancedMesh",s.default({ref:i,args:[null,null,0]},q,c),m.createElement("instancedBufferAttribute",{attach:"instanceMatrix",count:M.length/16,array:M,itemSize:16}),m.createElement("instancedBufferAttribute",{attach:"instanceColor",count:j.length/3,array:j,itemSize:3}),m.createElement(h.Provider,{value:w},r))};
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("@babel/runtime/helpers/extends"),r=require("@babel/runtime/helpers/objectWithoutPropertiesLoose"),t=require("three"),n=require("react"),u=require("@react-three/fiber"),a=require("react-merge-refs"),i=require("../helpers/Position.cjs.js");function o(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}function c(e){if(e&&e.__esModule)return e;var r=Object.create(null);return e&&Object.keys(e).forEach((function(t){if("default"!==t){var n=Object.getOwnPropertyDescriptor(e,t);Object.defineProperty(r,t,n.get?n:{enumerable:!0,get:function(){return e[t]}})}})),r.default=e,Object.freeze(r)}require("@babel/runtime/helpers/inheritsLoose");var l,s,f=o(e),d=o(r),m=c(t),p=c(n),b=o(a),h=p.createContext(null),v=new m.Matrix4,y=new m.Matrix4,x=new m.Matrix4,M=new m.Color,g=new m.Vector3,w=new m.Quaternion,j=new m.Vector3,A=p.forwardRef((function(e,r){var t=e.children,n=e.range,a=e.limit,i=void 0===a?1e3:a,o=d.default(e,["children","range","limit"]),c=p.useRef(null),m=p.useState([]),A=m[0],q=m[1],E=p.useState((function(){var e=new Float32Array(16*i);for(l=0;l<i;l++)x.identity().toArray(e,16*l);return[e,new Float32Array([].concat(new Array(3*i)).map((function(){return 1})))]}))[0],O=E[0],P=E[1];p.useLayoutEffect((function(){c.current.count=c.current.instanceMatrix.updateRange.count=c.current.instanceColor.updateRange.count=Math.min(i,void 0!==n?n:i,A.length)}),[A,n]),p.useEffect((function(){c.current.instanceMatrix.needsUpdate=!0})),u.useFrame((function(e){for(c.current.updateMatrix(),c.current.updateMatrixWorld(),v.copy(c.current.matrixWorld).invert(),l=0;l<A.length;l++)(s=A[l].current).matrixWorld.decompose(g,w,j),y.compose(g,w,j).premultiply(v),y.equals(x.fromArray(O,16*l))||(y.toArray(O,16*l),c.current.instanceMatrix.needsUpdate=!0),s.color.equals(M.fromArray(P,3*l))||(s.color.toArray(P,3*l),c.current.instanceColor.needsUpdate=!0)}));var _=p.useMemo((function(){var e={};for(l=0;l<A.length;l++){var r;Object.assign(e,null==(r=A[l].current)?void 0:r.__r3f.handlers)}return Object.keys(e).reduce((function(e,r){var t;return f.default({},e,((t={})[r]=function(e){var t,n,u;return null==(t=A[e.instanceId].current)||null==(n=t.__r3f)||null==(u=n.handlers)?void 0:u[r](e)},t))}),{})}),[A]),C=p.useMemo((function(){return{subscribe:function(e){return q((function(r){return[].concat(r,[e])})),function(){return q((function(r){return r.filter((function(r){return r.current!==e.current}))}))}}}}),[]);return p.createElement("instancedMesh",f.default({matrixAutoUpdate:!1,ref:b.default([r,c]),args:[null,null,0]},_,o),p.createElement("instancedBufferAttribute",{attach:"instanceMatrix",count:O.length/16,array:O,itemSize:16}),p.createElement("instancedBufferAttribute",{attach:"instanceColor",count:P.length/3,array:P,itemSize:3}),p.createElement(h.Provider,{value:C},t))})),q=p.forwardRef((function(e,r){var t=e.children,n=d.default(e,["children"]);p.useMemo((function(){return u.extend({Position:i.Position})}),[]);var a=p.useRef(),o=p.useContext(h).subscribe;return p.useLayoutEffect((function(){return o(a)}),[]),p.createElement("position",f.default({ref:b.default([r,a])},n),t)}));exports.Instance=q,exports.Instances=A;
@@ -1,8 +1,26 @@
1
+ import * as THREE from 'three';
1
2
  import * as React from 'react';
2
- declare type InstancesProps = JSX.IntrinsicElements['instancedMesh'] & {
3
- range?: number;
4
- limit?: number;
5
- };
6
- declare function Instances({ children, range, limit, ...props }: InstancesProps): JSX.Element;
3
+ declare const Instances: React.ForwardRefExoticComponent<Pick<Omit<import("@react-three/fiber").Node<THREE.InstancedMesh<THREE.BufferGeometry, THREE.Material | THREE.Material[]>, typeof THREE.InstancedMesh>, import("@react-three/fiber").NonFunctionKeys<{
4
+ position?: import("@react-three/fiber").Vector3 | undefined;
5
+ up?: import("@react-three/fiber").Vector3 | undefined;
6
+ scale?: import("@react-three/fiber").Vector3 | undefined;
7
+ rotation?: import("@react-three/fiber").Euler | undefined;
8
+ matrix?: import("@react-three/fiber").Matrix4 | undefined;
9
+ quaternion?: import("@react-three/fiber").Quaternion | undefined;
10
+ layers?: import("@react-three/fiber").Layers | undefined;
11
+ dispose?: (() => void) | null | undefined;
12
+ }>> & {
13
+ position?: import("@react-three/fiber").Vector3 | undefined;
14
+ up?: import("@react-three/fiber").Vector3 | undefined;
15
+ scale?: import("@react-three/fiber").Vector3 | undefined;
16
+ rotation?: import("@react-three/fiber").Euler | undefined;
17
+ matrix?: import("@react-three/fiber").Matrix4 | undefined;
18
+ quaternion?: import("@react-three/fiber").Quaternion | undefined;
19
+ layers?: import("@react-three/fiber").Layers | undefined;
20
+ dispose?: (() => void) | null | undefined;
21
+ } & import("@react-three/fiber/dist/declarations/src/core/events").EventHandlers & {
22
+ range?: number | undefined;
23
+ limit?: number | undefined;
24
+ }, "visible" | "attach" | "attachArray" | "attachObject" | "args" | "children" | "key" | "onUpdate" | "position" | "up" | "scale" | "rotation" | "matrix" | "quaternion" | "layers" | "dispose" | "type" | "id" | "uuid" | "name" | "parent" | "modelViewMatrix" | "normalMatrix" | "matrixWorld" | "matrixAutoUpdate" | "matrixWorldNeedsUpdate" | "castShadow" | "receiveShadow" | "frustumCulled" | "renderOrder" | "animations" | "userData" | "customDepthMaterial" | "customDistanceMaterial" | "isObject3D" | "onBeforeRender" | "onAfterRender" | "applyMatrix4" | "applyQuaternion" | "setRotationFromAxisAngle" | "setRotationFromEuler" | "setRotationFromMatrix" | "setRotationFromQuaternion" | "rotateOnAxis" | "rotateOnWorldAxis" | "rotateX" | "rotateY" | "rotateZ" | "translateOnAxis" | "translateX" | "translateY" | "translateZ" | "localToWorld" | "worldToLocal" | "lookAt" | "add" | "remove" | "clear" | "getObjectById" | "getObjectByName" | "getObjectByProperty" | "getWorldPosition" | "getWorldQuaternion" | "getWorldScale" | "getWorldDirection" | "raycast" | "traverse" | "traverseVisible" | "traverseAncestors" | "updateMatrix" | "updateMatrixWorld" | "updateWorldMatrix" | "toJSON" | "clone" | "copy" | "addEventListener" | "hasEventListener" | "removeEventListener" | "dispatchEvent" | keyof import("@react-three/fiber/dist/declarations/src/core/events").EventHandlers | "range" | "material" | "geometry" | "morphTargetInfluences" | "morphTargetDictionary" | "isMesh" | "updateMorphTargets" | "count" | "instanceColor" | "instanceMatrix" | "isInstancedMesh" | "getColorAt" | "getMatrixAt" | "setColorAt" | "setMatrixAt" | "limit"> & React.RefAttributes<THREE.InstancedMesh<THREE.BufferGeometry, THREE.Material | THREE.Material[]>>>;
7
25
  declare const Instance: React.ForwardRefExoticComponent<React.RefAttributes<unknown>>;
8
26
  export { Instances, Instance };
package/core/Instances.js CHANGED
@@ -5,73 +5,86 @@ import { useFrame, extend } from '@react-three/fiber';
5
5
  import mergeRefs from 'react-merge-refs';
6
6
  import { Position } from '../helpers/Position.js';
7
7
 
8
+ let i, instanceRef;
8
9
  const context = /*#__PURE__*/React.createContext(null);
9
- const m1 = new THREE.Matrix4();
10
- const m2 = new THREE.Matrix4();
11
- const m3 = new THREE.Matrix4();
12
- const c = new THREE.Color();
13
- let i;
14
-
15
- function Instances({
10
+ const parentMatrix = new THREE.Matrix4();
11
+ const instanceMatrix = new THREE.Matrix4();
12
+ const tempMatrix = new THREE.Matrix4();
13
+ const color = new THREE.Color();
14
+ const translation = new THREE.Vector3();
15
+ const rotation = new THREE.Quaternion();
16
+ const scale = new THREE.Vector3();
17
+ const Instances = /*#__PURE__*/React.forwardRef(({
16
18
  children,
17
19
  range,
18
20
  limit = 1000,
19
21
  ...props
20
- }) {
21
- const ref = React.useRef(null);
22
- const [refs, setRefs] = React.useState([]);
22
+ }, ref) => {
23
+ const parentRef = React.useRef(null);
24
+ const [instances, setInstances] = React.useState([]);
23
25
  const [[matrices, colors]] = React.useState(() => {
24
- const matrices = [...new Array(limit * 16)].map(() => 0);
25
- const colors = [...new Array(limit * 3)].map(() => 1);
26
- return [new Float32Array(matrices), new Float32Array(colors)];
26
+ const mArray = new Float32Array(limit * 16);
27
+
28
+ for (i = 0; i < limit; i++) tempMatrix.identity().toArray(mArray, i * 16);
29
+
30
+ return [mArray, new Float32Array([...new Array(limit * 3)].map(() => 1))];
27
31
  });
28
32
  React.useLayoutEffect(() => {
29
- ref.current.count = ref.current.instanceMatrix.updateRange.count = ref.current.instanceColor.updateRange.count = Math.min(limit, range !== undefined ? range : limit, refs.length);
30
- }, [refs, range]);
31
- useFrame(() => {
32
- m1.copy(ref.current.matrixWorld).invert();
33
+ parentRef.current.count = parentRef.current.instanceMatrix.updateRange.count = parentRef.current.instanceColor.updateRange.count = Math.min(limit, range !== undefined ? range : limit, instances.length);
34
+ }, [instances, range]);
35
+ React.useEffect(() => {
36
+ // We might be a frame too late? 🤷‍♂️
37
+ parentRef.current.instanceMatrix.needsUpdate = true;
38
+ });
39
+ useFrame(state => {
40
+ parentRef.current.updateMatrix();
41
+ parentRef.current.updateMatrixWorld();
42
+ parentMatrix.copy(parentRef.current.matrixWorld).invert();
43
+
44
+ for (i = 0; i < instances.length; i++) {
45
+ instanceRef = instances[i].current; // Multiply the inverse of the InstancedMesh world matrix or else
46
+ // Instances will be double-transformed if <Instances> isn't at identity
33
47
 
34
- for (i = 0; i < refs.length; i++) {
35
- // Multiply the inverse of the InstancedMesh world matrix or else
36
- // <Instance> will be double-transformed if <Instances> isn't at identity
37
- m2.copy(refs[i].current.matrixWorld).multiply(m1);
48
+ instanceRef.matrixWorld.decompose(translation, rotation, scale);
49
+ instanceMatrix.compose(translation, rotation, scale).premultiply(parentMatrix);
38
50
 
39
- if (!m1.equals(m3.fromArray(matrices, i * 16))) {
40
- m2.toArray(matrices, i * 16);
41
- ref.current.instanceMatrix.needsUpdate = true;
51
+ if (!instanceMatrix.equals(tempMatrix.fromArray(matrices, i * 16))) {
52
+ instanceMatrix.toArray(matrices, i * 16);
53
+ parentRef.current.instanceMatrix.needsUpdate = true;
42
54
  }
43
55
 
44
- if (!refs[i].current.color.equals(c.fromArray(colors, i * 3))) {
45
- refs[i].current.color.toArray(colors, i * 3);
46
- ref.current.instanceColor.needsUpdate = true;
56
+ if (!instanceRef.color.equals(color.fromArray(colors, i * 3))) {
57
+ instanceRef.color.toArray(colors, i * 3);
58
+ parentRef.current.instanceColor.needsUpdate = true;
47
59
  }
48
60
  }
49
61
  });
50
62
  const events = React.useMemo(() => {
51
63
  const events = {};
52
64
 
53
- for (i = 0; i < refs.length; i++) {
54
- var _refs$i$current;
65
+ for (i = 0; i < instances.length; i++) {
66
+ var _instances$i$current;
55
67
 
56
- Object.assign(events, (_refs$i$current = refs[i].current) == null ? void 0 : _refs$i$current.__r3f.handlers);
68
+ Object.assign(events, (_instances$i$current = instances[i].current) == null ? void 0 : _instances$i$current.__r3f.handlers);
57
69
  }
58
70
 
59
71
  return Object.keys(events).reduce((prev, key) => ({ ...prev,
60
72
  [key]: e => {
61
- var _refs$e$instanceId$cu, _refs$e$instanceId$cu2, _refs$e$instanceId$cu3;
73
+ var _instances$e$instance, _instances$e$instance2, _instances$e$instance3;
62
74
 
63
- return (_refs$e$instanceId$cu = refs[e.instanceId].current) == null ? void 0 : (_refs$e$instanceId$cu2 = _refs$e$instanceId$cu.__r3f) == null ? void 0 : (_refs$e$instanceId$cu3 = _refs$e$instanceId$cu2.handlers) == null ? void 0 : _refs$e$instanceId$cu3[key](e);
75
+ return (_instances$e$instance = instances[e.instanceId].current) == null ? void 0 : (_instances$e$instance2 = _instances$e$instance.__r3f) == null ? void 0 : (_instances$e$instance3 = _instances$e$instance2.handlers) == null ? void 0 : _instances$e$instance3[key](e);
64
76
  }
65
77
  }), {});
66
- }, [refs]);
78
+ }, [instances]);
67
79
  const api = React.useMemo(() => ({
68
80
  subscribe: ref => {
69
- setRefs(refs => [...refs, ref]);
70
- return () => setRefs(refs => refs.filter(item => item.current !== ref.current));
81
+ setInstances(instances => [...instances, ref]);
82
+ return () => setInstances(instances => instances.filter(item => item.current !== ref.current));
71
83
  }
72
84
  }), []);
73
85
  return /*#__PURE__*/React.createElement("instancedMesh", _extends({
74
- ref: ref,
86
+ matrixAutoUpdate: false,
87
+ ref: mergeRefs([ref, parentRef]),
75
88
  args: [null, null, 0]
76
89
  }, events, props), /*#__PURE__*/React.createElement("instancedBufferAttribute", {
77
90
  attach: "instanceMatrix",
@@ -86,8 +99,7 @@ function Instances({
86
99
  }), /*#__PURE__*/React.createElement(context.Provider, {
87
100
  value: api
88
101
  }, children));
89
- }
90
-
102
+ });
91
103
  const Instance = /*#__PURE__*/React.forwardRef(({
92
104
  children,
93
105
  ...props
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("@babel/runtime/helpers/extends"),r=require("@babel/runtime/helpers/objectWithoutPropertiesLoose"),t=require("three"),n=require("react"),u=require("@react-three/fiber"),o=require("react-merge-refs"),i=require("../helpers/Position.cjs.js");function a(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}function c(e){if(e&&e.__esModule)return e;var r=Object.create(null);return e&&Object.keys(e).forEach((function(t){if("default"!==t){var n=Object.getOwnPropertyDescriptor(e,t);Object.defineProperty(r,t,n.get?n:{enumerable:!0,get:function(){return e[t]}})}})),r.default=e,Object.freeze(r)}require("@babel/runtime/helpers/inheritsLoose");var l,f=a(e),s=a(r),d=c(t),b=c(n),m=a(o),p=b.createContext(null),y=new d.Matrix4,h=new d.Vector3,v=new d.Color;var g=b.forwardRef((function(e,r){var t=e.children,n=s.default(e,["children"]);b.useMemo((function(){return u.extend({Position:i.Position})}),[]);var o=b.useRef(),a=b.useContext(p).subscribe;return b.useLayoutEffect((function(){return a(o)}),[]),b.createElement("position",f.default({ref:m.default([r,o])},n),t)}));exports.Point=g,exports.Points=function(e){var r=e.children,t=e.range,n=e.limit,o=void 0===n?1e3:n,i=s.default(e,["children","range","limit"]),a=b.useRef(null),c=b.useState([]),d=c[0],m=c[1],g=b.useState((function(){var e=[].concat(new Array(3*o)).map((function(){return 0})),r=[].concat(new Array(3*o)).map((function(){return 1}));return[new Float32Array(e),new Float32Array(r)]}))[0],j=g[0],x=g[1];b.useLayoutEffect((function(){a.current.geometry.drawRange.count=Math.min(o,void 0!==t?t:o,d.length)}),[d,t]),u.useFrame((function(){for(y.copy(a.current.matrixWorld).invert(),l=0;l<d.length;l++)d[l].current.getWorldPosition(h).applyMatrix4(y),h.x===j[3*l]&&h.y===j[3*l+1]&&h.z===j[3*l+2]||(h.toArray(j,3*l),a.current.geometry.attributes.position.needsUpdate=!0),d[l].current.color.equals(v.fromArray(x,3*l))||(d[l].current.color.toArray(x,3*l),a.current.geometry.attributes.color.needsUpdate=!0)}));var O=b.useMemo((function(){var e={};for(l=0;l<d.length;l++){var r;Object.assign(e,null==(r=d[l].current)?void 0:r.__r3f.handlers)}return Object.keys(e).reduce((function(e,r){var t;return f.default({},e,((t={})[r]=function(e){var t,n,u;return null==(t=d[e.index].current)||null==(n=t.__r3f)||null==(u=n.handlers)?void 0:u[r](e)},t))}),{})}),[d]),P=b.useMemo((function(){return{subscribe:function(e){return m((function(r){return[].concat(r,[e])})),function(){return m((function(r){return r.filter((function(r){return r.current!==e.current}))}))}}}}),[]);return b.createElement("points",f.default({ref:a},O,i),b.createElement("bufferGeometry",null,b.createElement("bufferAttribute",{attachObject:["attributes","position"],count:j.length/3,array:j,itemSize:3}),b.createElement("bufferAttribute",{attachObject:["attributes","color"],count:x.length/3,array:x,itemSize:3})),b.createElement(p.Provider,{value:P},r))};
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("@babel/runtime/helpers/extends"),t=require("@babel/runtime/helpers/objectWithoutPropertiesLoose"),r=require("three"),n=require("react"),u=require("@react-three/fiber"),o=require("react-merge-refs"),i=require("../helpers/Position.cjs.js");function a(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)}require("@babel/runtime/helpers/inheritsLoose");var l,f,s=a(e),d=a(t),b=c(r),m=c(n),p=a(o),y=m.createContext(null),h=new b.Matrix4,v=new b.Vector3,g=new b.Color,x=m.forwardRef((function(e,t){var r=e.children,n=e.range,o=e.limit,i=void 0===o?1e3:o,a=d.default(e,["children","range","limit"]),c=m.useRef(null),b=m.useState([]),x=b[0],j=b[1],O=m.useState((function(){return[new Float32Array(3*i),new Float32Array([].concat(new Array(3*i)).map((function(){return 1})))]}))[0],P=O[0],w=O[1];m.useLayoutEffect((function(){c.current.geometry.drawRange.count=Math.min(i,void 0!==n?n:i,x.length)}),[x,n]),m.useEffect((function(){c.current.geometry.attributes.position.needsUpdate=!0})),u.useFrame((function(){for(c.current.updateMatrix(),c.current.updateMatrixWorld(),h.copy(c.current.matrixWorld).invert(),l=0;l<x.length;l++)(f=x[l].current).getWorldPosition(v).applyMatrix4(h),v.x===P[3*l]&&v.y===P[3*l+1]&&v.z===P[3*l+2]||(v.toArray(P,3*l),c.current.geometry.attributes.position.needsUpdate=!0,f.matrixWorldNeedsUpdate=!0),f.color.equals(g.fromArray(w,3*l))||(f.color.toArray(w,3*l),c.current.geometry.attributes.color.needsUpdate=!0)}));var E=m.useMemo((function(){var e={};for(l=0;l<x.length;l++){var t;Object.assign(e,null==(t=x[l].current)?void 0:t.__r3f.handlers)}return Object.keys(e).reduce((function(e,t){var r;return s.default({},e,((r={})[t]=function(e){var r,n,u;return null==(r=x[e.index].current)||null==(n=r.__r3f)||null==(u=n.handlers)?void 0:u[t](e)},r))}),{})}),[x]),M=m.useMemo((function(){return{subscribe:function(e){return j((function(t){return[].concat(t,[e])})),function(){return j((function(t){return t.filter((function(t){return t.current!==e.current}))}))}}}}),[]);return m.createElement("points",s.default({matrixAutoUpdate:!1,ref:p.default([t,c])},E,a),m.createElement("bufferGeometry",null,m.createElement("bufferAttribute",{attachObject:["attributes","position"],count:P.length/3,array:P,itemSize:3}),m.createElement("bufferAttribute",{attachObject:["attributes","color"],count:w.length/3,array:w,itemSize:3})),m.createElement(y.Provider,{value:M},r))})),j=m.forwardRef((function(e,t){var r=e.children,n=d.default(e,["children"]);m.useMemo((function(){return u.extend({Position:i.Position})}),[]);var o=m.useRef(),a=m.useContext(y).subscribe;return m.useLayoutEffect((function(){return a(o)}),[]),m.createElement("position",s.default({ref:p.default([t,o])},n),r)}));exports.Point=j,exports.Points=x;
package/core/Points.d.ts CHANGED
@@ -1,8 +1,26 @@
1
+ import * as THREE from 'three';
1
2
  import * as React from 'react';
2
- declare type PointsProps = JSX.IntrinsicElements['points'] & {
3
- range?: number;
4
- limit?: number;
5
- };
6
- declare function Points({ children, range, limit, ...props }: PointsProps): JSX.Element;
3
+ declare const Points: React.ForwardRefExoticComponent<Pick<Omit<import("@react-three/fiber").Node<THREE.Points<THREE.BufferGeometry, THREE.Material | THREE.Material[]>, typeof THREE.Points>, import("@react-three/fiber").NonFunctionKeys<{
4
+ position?: import("@react-three/fiber").Vector3 | undefined;
5
+ up?: import("@react-three/fiber").Vector3 | undefined;
6
+ scale?: import("@react-three/fiber").Vector3 | undefined;
7
+ rotation?: import("@react-three/fiber").Euler | undefined;
8
+ matrix?: import("@react-three/fiber").Matrix4 | undefined;
9
+ quaternion?: import("@react-three/fiber").Quaternion | undefined;
10
+ layers?: import("@react-three/fiber").Layers | undefined;
11
+ dispose?: (() => void) | null | undefined;
12
+ }>> & {
13
+ position?: import("@react-three/fiber").Vector3 | undefined;
14
+ up?: import("@react-three/fiber").Vector3 | undefined;
15
+ scale?: import("@react-three/fiber").Vector3 | undefined;
16
+ rotation?: import("@react-three/fiber").Euler | undefined;
17
+ matrix?: import("@react-three/fiber").Matrix4 | undefined;
18
+ quaternion?: import("@react-three/fiber").Quaternion | undefined;
19
+ layers?: import("@react-three/fiber").Layers | undefined;
20
+ dispose?: (() => void) | null | undefined;
21
+ } & import("@react-three/fiber/dist/declarations/src/core/events").EventHandlers & {
22
+ range?: number | undefined;
23
+ limit?: number | undefined;
24
+ }, "visible" | "attach" | "attachArray" | "attachObject" | "args" | "children" | "key" | "onUpdate" | "position" | "up" | "scale" | "rotation" | "matrix" | "quaternion" | "layers" | "dispose" | "type" | "id" | "uuid" | "name" | "parent" | "modelViewMatrix" | "normalMatrix" | "matrixWorld" | "matrixAutoUpdate" | "matrixWorldNeedsUpdate" | "castShadow" | "receiveShadow" | "frustumCulled" | "renderOrder" | "animations" | "userData" | "customDepthMaterial" | "customDistanceMaterial" | "isObject3D" | "onBeforeRender" | "onAfterRender" | "applyMatrix4" | "applyQuaternion" | "setRotationFromAxisAngle" | "setRotationFromEuler" | "setRotationFromMatrix" | "setRotationFromQuaternion" | "rotateOnAxis" | "rotateOnWorldAxis" | "rotateX" | "rotateY" | "rotateZ" | "translateOnAxis" | "translateX" | "translateY" | "translateZ" | "localToWorld" | "worldToLocal" | "lookAt" | "add" | "remove" | "clear" | "getObjectById" | "getObjectByName" | "getObjectByProperty" | "getWorldPosition" | "getWorldQuaternion" | "getWorldScale" | "getWorldDirection" | "raycast" | "traverse" | "traverseVisible" | "traverseAncestors" | "updateMatrix" | "updateMatrixWorld" | "updateWorldMatrix" | "toJSON" | "clone" | "copy" | "addEventListener" | "hasEventListener" | "removeEventListener" | "dispatchEvent" | keyof import("@react-three/fiber/dist/declarations/src/core/events").EventHandlers | "range" | "material" | "geometry" | "morphTargetInfluences" | "morphTargetDictionary" | "updateMorphTargets" | "isPoints" | "limit"> & React.RefAttributes<THREE.Points<THREE.BufferGeometry, THREE.Material | THREE.Material[]>>>;
7
25
  declare const Point: React.ForwardRefExoticComponent<React.RefAttributes<unknown>>;
8
26
  export { Points, Point };
package/core/Points.js CHANGED
@@ -5,40 +5,45 @@ import { useFrame, extend } from '@react-three/fiber';
5
5
  import mergeRefs from 'react-merge-refs';
6
6
  import { Position } from '../helpers/Position.js';
7
7
 
8
+ let i, positionRef;
8
9
  const context = /*#__PURE__*/React.createContext(null);
9
- const m = new THREE.Matrix4();
10
- const v = new THREE.Vector3();
11
- const c = new THREE.Color();
12
- let i;
13
-
14
- function Points({
10
+ const parentMatrix = new THREE.Matrix4();
11
+ const position = new THREE.Vector3();
12
+ const color = new THREE.Color();
13
+ const Points = /*#__PURE__*/React.forwardRef(({
15
14
  children,
16
15
  range,
17
16
  limit = 1000,
18
17
  ...props
19
- }) {
20
- const ref = React.useRef(null);
18
+ }, ref) => {
19
+ const parentRef = React.useRef(null);
21
20
  const [refs, setRefs] = React.useState([]);
22
- const [[positions, colors]] = React.useState(() => {
23
- const positions = [...new Array(limit * 3)].map(() => 0);
24
- const colors = [...new Array(limit * 3)].map(() => 1);
25
- return [new Float32Array(positions), new Float32Array(colors)];
21
+ const [[positions, colors]] = React.useState(() => [new Float32Array(limit * 3), new Float32Array([...new Array(limit * 3)].map(() => 1))]);
22
+ React.useLayoutEffect(() => {
23
+ parentRef.current.geometry.drawRange.count = Math.min(limit, range !== undefined ? range : limit, refs.length);
24
+ }, [refs, range]);
25
+ React.useEffect(() => {
26
+ // We might be a frame too late? 🤷‍♂️
27
+ parentRef.current.geometry.attributes.position.needsUpdate = true;
26
28
  });
27
- React.useLayoutEffect(() => void (ref.current.geometry.drawRange.count = Math.min(limit, range !== undefined ? range : limit, refs.length)), [refs, range]);
28
29
  useFrame(() => {
29
- m.copy(ref.current.matrixWorld).invert();
30
+ parentRef.current.updateMatrix();
31
+ parentRef.current.updateMatrixWorld();
32
+ parentMatrix.copy(parentRef.current.matrixWorld).invert();
30
33
 
31
34
  for (i = 0; i < refs.length; i++) {
32
- refs[i].current.getWorldPosition(v).applyMatrix4(m);
35
+ positionRef = refs[i].current;
36
+ positionRef.getWorldPosition(position).applyMatrix4(parentMatrix);
33
37
 
34
- if (v.x !== positions[i * 3] || v.y !== positions[i * 3 + 1] || v.z !== positions[i * 3 + 2]) {
35
- v.toArray(positions, i * 3);
36
- ref.current.geometry.attributes.position.needsUpdate = true;
38
+ if (position.x !== positions[i * 3] || position.y !== positions[i * 3 + 1] || position.z !== positions[i * 3 + 2]) {
39
+ position.toArray(positions, i * 3);
40
+ parentRef.current.geometry.attributes.position.needsUpdate = true;
41
+ positionRef.matrixWorldNeedsUpdate = true;
37
42
  }
38
43
 
39
- if (!refs[i].current.color.equals(c.fromArray(colors, i * 3))) {
40
- refs[i].current.color.toArray(colors, i * 3);
41
- ref.current.geometry.attributes.color.needsUpdate = true;
44
+ if (!positionRef.color.equals(color.fromArray(colors, i * 3))) {
45
+ positionRef.color.toArray(colors, i * 3);
46
+ parentRef.current.geometry.attributes.color.needsUpdate = true;
42
47
  }
43
48
  }
44
49
  });
@@ -66,7 +71,8 @@ function Points({
66
71
  }
67
72
  }), []);
68
73
  return /*#__PURE__*/React.createElement("points", _extends({
69
- ref: ref
74
+ matrixAutoUpdate: false,
75
+ ref: mergeRefs([ref, parentRef])
70
76
  }, events, props), /*#__PURE__*/React.createElement("bufferGeometry", null, /*#__PURE__*/React.createElement("bufferAttribute", {
71
77
  attachObject: ['attributes', 'position'],
72
78
  count: positions.length / 3,
@@ -80,8 +86,7 @@ function Points({
80
86
  })), /*#__PURE__*/React.createElement(context.Provider, {
81
87
  value: api
82
88
  }, children));
83
- }
84
-
89
+ });
85
90
  const Point = /*#__PURE__*/React.forwardRef(({
86
91
  children,
87
92
  ...props