@react-three/drei 9.74.11 → 9.74.13

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.
Files changed (189) hide show
  1. package/core/CatmullRomLine.js +2 -0
  2. package/core/Cloud.js +3 -0
  3. package/core/CubeCamera.js +1 -0
  4. package/core/CubicBezierLine.js +2 -0
  5. package/core/Environment.js +1 -0
  6. package/core/Example.js +6 -0
  7. package/core/FaceControls.cjs.js +1 -1
  8. package/core/FaceControls.js +2 -0
  9. package/core/FaceLandmarker.cjs.js +1 -1
  10. package/core/FaceLandmarker.js +3 -2
  11. package/core/Facemesh.js +2 -0
  12. package/core/GizmoHelper.js +3 -0
  13. package/core/GizmoViewcube.js +4 -0
  14. package/core/GizmoViewport.js +4 -0
  15. package/core/Gltf.js +4 -0
  16. package/core/MeshDiscardMaterial.js +2 -0
  17. package/core/MeshDistortMaterial.js +2 -1
  18. package/core/MeshReflectorMaterial.js +1 -0
  19. package/core/MeshRefractionMaterial.js +2 -0
  20. package/core/MeshTransmissionMaterial.js +1 -0
  21. package/core/OrthographicCamera.js +1 -0
  22. package/core/PerspectiveCamera.js +1 -0
  23. package/core/QuadraticBezierLine.js +2 -0
  24. package/core/Reflector.js +1 -0
  25. package/core/SpotLight.js +2 -1
  26. package/core/Stage.js +7 -0
  27. package/core/Text3D.js +1 -0
  28. package/core/Wireframe.js +1 -0
  29. package/core/index.cjs.js +1 -1
  30. package/core/index.js +0 -1
  31. package/core/useKTX2.js +1 -0
  32. package/core/useMatcapTexture.js +2 -0
  33. package/core/useNormalTexture.js +1 -0
  34. package/index.cjs.js +1 -1
  35. package/materials/DiscardMaterial.js +1 -0
  36. package/materials/MeshRefractionMaterial.js +1 -1
  37. package/native/index.cjs.js +1 -1
  38. package/native/index.js +0 -1
  39. package/package.json +9 -9
  40. package/src/core/AccumulativeShadows.js +311 -0
  41. package/src/core/AdaptiveDpr.js +28 -0
  42. package/src/core/AdaptiveEvents.js +20 -0
  43. package/src/core/ArcballControls.js +67 -0
  44. package/src/core/AsciiRenderer.js +60 -0
  45. package/src/core/BBAnchor.js +37 -0
  46. package/src/core/Backdrop.js +36 -0
  47. package/src/core/BakeShadows.js +16 -0
  48. package/src/core/Billboard.js +41 -0
  49. package/src/core/Bounds.js +245 -0
  50. package/src/core/CameraControls.js +92 -0
  51. package/src/core/CameraShake.js +61 -0
  52. package/src/core/CatmullRomLine.js +44 -0
  53. package/src/core/Caustics.js +375 -0
  54. package/src/core/Center.js +66 -0
  55. package/src/core/Clone.js +102 -0
  56. package/src/core/Cloud.js +59 -0
  57. package/src/core/ComputedAttribute.js +34 -0
  58. package/src/core/ContactShadows.js +114 -0
  59. package/src/core/CubeCamera.js +43 -0
  60. package/src/core/CubicBezierLine.js +28 -0
  61. package/src/core/CurveModifier.js +34 -0
  62. package/src/core/Decal.js +92 -0
  63. package/src/core/Detailed.js +34 -0
  64. package/src/core/DeviceOrientationControls.js +51 -0
  65. package/src/core/Edges.js +36 -0
  66. package/src/core/Effects.js +93 -0
  67. package/src/core/Environment.js +132 -0
  68. package/src/core/Example.js +42 -0
  69. package/src/core/FaceControls.js +315 -0
  70. package/src/core/FaceLandmarker.js +43 -0
  71. package/src/core/Facemesh.js +4545 -0
  72. package/src/core/FirstPersonControls.js +38 -0
  73. package/src/core/Float.js +36 -0
  74. package/src/core/FlyControls.js +55 -0
  75. package/src/core/GizmoHelper.js +111 -0
  76. package/src/core/GizmoViewcube.js +152 -0
  77. package/src/core/GizmoViewport.js +152 -0
  78. package/src/core/Gltf.js +20 -0
  79. package/src/core/GradientTexture.js +33 -0
  80. package/src/core/Grid.js +112 -0
  81. package/src/core/Hud.js +58 -0
  82. package/src/core/Image.js +119 -0
  83. package/src/core/Instances.js +215 -0
  84. package/src/core/Lightformer.js +51 -0
  85. package/src/core/Line.js +68 -0
  86. package/src/core/MapControls.js +64 -0
  87. package/src/core/MarchingCubes.js +76 -0
  88. package/src/core/Mask.js +42 -0
  89. package/src/core/MeshDiscardMaterial.js +15 -0
  90. package/src/core/MeshDistortMaterial.js +79 -0
  91. package/src/core/MeshPortalMaterial.js +381 -0
  92. package/src/core/MeshReflectorMaterial.js +182 -0
  93. package/src/core/MeshRefractionMaterial.js +79 -0
  94. package/src/core/MeshTransmissionMaterial.js +395 -0
  95. package/src/core/MeshWobbleMaterial.js +65 -0
  96. package/src/core/OrbitControls.js +82 -0
  97. package/src/core/OrthographicCamera.js +77 -0
  98. package/src/core/PerformanceMonitor.js +121 -0
  99. package/src/core/PerspectiveCamera.js +73 -0
  100. package/src/core/PointMaterial.js +36 -0
  101. package/src/core/PointerLockControls.js +90 -0
  102. package/src/core/Points.js +227 -0
  103. package/src/core/PositionalAudio.js +51 -0
  104. package/src/core/Preload.js +45 -0
  105. package/src/core/QuadraticBezierLine.js +44 -0
  106. package/src/core/Reflector.js +182 -0
  107. package/src/core/RenderTexture.js +96 -0
  108. package/src/core/Resize.js +39 -0
  109. package/src/core/RoundedBox.js +52 -0
  110. package/src/core/Sampler.js +85 -0
  111. package/src/core/ScreenQuad.js +24 -0
  112. package/src/core/ScreenSpace.js +25 -0
  113. package/src/core/Segments.js +102 -0
  114. package/src/core/Shadow.js +42 -0
  115. package/src/core/Sky.js +39 -0
  116. package/src/core/Sparkles.js +139 -0
  117. package/src/core/SpotLight.js +231 -0
  118. package/src/core/SpriteAnimator.js +342 -0
  119. package/src/core/Stage.js +135 -0
  120. package/src/core/Stars.js +108 -0
  121. package/src/core/Stats.js +30 -0
  122. package/src/core/Svg.js +59 -0
  123. package/src/core/Text.js +58 -0
  124. package/src/core/Text3D.js +76 -0
  125. package/src/core/TrackballControls.js +72 -0
  126. package/src/core/Trail.js +161 -0
  127. package/src/core/TransformControls.js +106 -0
  128. package/src/core/Wireframe.js +185 -0
  129. package/src/core/meshBounds.js +38 -0
  130. package/src/core/shaderMaterial.js +39 -0
  131. package/src/core/shapes.js +68 -0
  132. package/src/core/softShadows.js +161 -0
  133. package/src/core/useAnimations.js +56 -0
  134. package/src/core/useAspect.js +10 -0
  135. package/src/core/useBVH.js +90 -0
  136. package/src/core/useBoxProjectedEnv.js +98 -0
  137. package/src/core/useCamera.js +27 -0
  138. package/src/core/useContextBridge.js +21 -0
  139. package/src/core/useCubeCamera.js +49 -0
  140. package/src/core/useCubeTexture.js +18 -0
  141. package/src/core/useDepthBuffer.js +38 -0
  142. package/src/core/useDetectGPU.js +6 -0
  143. package/src/core/useEnvironment.js +48 -0
  144. package/src/core/useFBO.js +53 -0
  145. package/src/core/useFBX.js +12 -0
  146. package/src/core/useFont.js +20 -0
  147. package/src/core/useGLTF.js +37 -0
  148. package/src/core/useHelper.js +31 -0
  149. package/src/core/useIntersect.js +39 -0
  150. package/src/core/useKTX2.js +38 -0
  151. package/src/core/useMatcapTexture.js +45 -0
  152. package/src/core/useNormalTexture.js +30 -0
  153. package/src/core/useProgress.js +50 -0
  154. package/src/core/useTexture.js +35 -0
  155. package/src/core/useTrailTexture.js +164 -0
  156. package/src/core/useVideoTexture.js +41 -0
  157. package/src/helpers/environment-assets.js +14 -0
  158. package/src/helpers/useEffectfulState.js +18 -0
  159. package/src/materials/BlurPass.js +75 -0
  160. package/src/materials/ConvolutionMaterial.js +99 -0
  161. package/src/materials/DiscardMaterial.js +5 -0
  162. package/src/materials/MeshReflectorMaterial.js +290 -0
  163. package/src/materials/MeshRefractionMaterial.js +171 -0
  164. package/src/materials/SpotLightMaterial.js +111 -0
  165. package/src/materials/WireframeMaterial.js +235 -0
  166. package/src/web/CycleRaycast.js +97 -0
  167. package/src/web/Html.js +417 -0
  168. package/src/web/KeyboardControls.js +101 -0
  169. package/src/web/Loader.js +98 -0
  170. package/src/web/PresentationControls.js +86 -0
  171. package/src/web/ScrollControls.js +246 -0
  172. package/src/web/Select.js +175 -0
  173. package/src/web/View.js +206 -0
  174. package/src/web/pivotControls/AxisArrow.js +202 -0
  175. package/src/web/pivotControls/AxisRotator.js +235 -0
  176. package/src/web/pivotControls/PlaneSlider.js +211 -0
  177. package/src/web/pivotControls/context.js +5 -0
  178. package/src/web/pivotControls/index.js +223 -0
  179. package/src/web/useCursor.js +12 -0
  180. package/web/Loader.js +2 -0
  181. package/web/index.cjs.js +1 -1
  182. package/web/index.js +0 -1
  183. package/web/pivotControls/AxisArrow.js +3 -0
  184. package/web/pivotControls/AxisRotator.js +3 -0
  185. package/web/pivotControls/PlaneSlider.js +3 -0
  186. package/web/pivotControls/index.js +5 -0
  187. /package/{helpers → src/helpers}/glsl/DefaultSpotlightShadowShadows.glsl.js +0 -0
  188. /package/{helpers → src/helpers}/glsl/distort.vert.glsl.js +0 -0
  189. /package/{index.js → src/index.js} +0 -0
@@ -0,0 +1,42 @@
1
+ import * as React from 'react';
2
+ import { Text3D } from './Text3D.js';
3
+ import { Center } from './Center.js';
4
+
5
+ /* eslint react-hooks/exhaustive-deps: 1 */
6
+ const Example = /*#__PURE__*/React.forwardRef(({
7
+ font,
8
+ color = '#cbcbcb',
9
+ bevelSize = 0.04,
10
+ debug = false,
11
+ children,
12
+ ...props
13
+ }, fref) => {
14
+ const [counter, setCounter] = React.useState(0);
15
+ const incr = React.useCallback((x = 1) => setCounter(counter + x), [counter]);
16
+ const decr = React.useCallback((x = 1) => setCounter(counter - x), [counter]); // ref-API
17
+
18
+ const api = React.useMemo(() => ({
19
+ incr,
20
+ decr
21
+ }), [incr, decr]);
22
+ React.useImperativeHandle(fref, () => api, [api]);
23
+ return /*#__PURE__*/React.createElement("group", props, /*#__PURE__*/React.createElement(React.Suspense, {
24
+ fallback: null
25
+ }, /*#__PURE__*/React.createElement(Center, {
26
+ top: true,
27
+ cacheKey: JSON.stringify({
28
+ counter,
29
+ font
30
+ })
31
+ }, /*#__PURE__*/React.createElement(Text3D, {
32
+ bevelEnabled: true,
33
+ bevelSize: bevelSize,
34
+ font: font
35
+ }, debug ? /*#__PURE__*/React.createElement("meshNormalMaterial", {
36
+ wireframe: true
37
+ }) : /*#__PURE__*/React.createElement("meshStandardMaterial", {
38
+ color: color
39
+ }), counter))), children);
40
+ });
41
+
42
+ export { Example };
@@ -0,0 +1,315 @@
1
+ import _extends from '@babel/runtime/helpers/esm/extends';
2
+ import * as THREE from 'three';
3
+ import * as React from 'react';
4
+ import { forwardRef, useRef, useState, useCallback, useMemo, useImperativeHandle, useEffect, Suspense, useContext, createContext } from 'react';
5
+ import { useThree, useFrame } from '@react-three/fiber';
6
+ import { easing } from 'maath';
7
+ import { suspend, clear } from 'suspend-react';
8
+ import { useVideoTexture } from './useVideoTexture.js';
9
+ import { Facemesh } from './Facemesh.js';
10
+ import { useFaceLandmarker } from './FaceLandmarker.js';
11
+
12
+ // useVideoTexture 1st arg `src` type
13
+ function mean(v1, v2) {
14
+ return v1.clone().add(v2).multiplyScalar(0.5);
15
+ }
16
+
17
+ function localToLocal(objSrc, v, objDst) {
18
+ // see: https://discourse.threejs.org/t/object3d-localtolocal/51564
19
+ const v_world = objSrc.localToWorld(v);
20
+ return objDst.worldToLocal(v_world);
21
+ } //
22
+ //
23
+ //
24
+
25
+
26
+ const FaceControlsContext = /*#__PURE__*/createContext({});
27
+ const FaceControls = /*#__PURE__*/forwardRef(({
28
+ camera,
29
+ autostart = true,
30
+ webcam = true,
31
+ webcamVideoTextureSrc,
32
+ manualUpdate = false,
33
+ manualDetect = false,
34
+ onVideoFrame,
35
+ smoothTime = 0.25,
36
+ offset = true,
37
+ offsetScalar = 80,
38
+ eyes = false,
39
+ eyesAsOrigin = true,
40
+ depth = 0.15,
41
+ debug = false,
42
+ facemesh,
43
+ makeDefault
44
+ }, fref) => {
45
+ var _faces$facialTransfor, _faces$faceBlendshape;
46
+
47
+ const scene = useThree(state => state.scene);
48
+ const defaultCamera = useThree(state => state.camera);
49
+ const set = useThree(state => state.set);
50
+ const get = useThree(state => state.get);
51
+ const explCamera = camera || defaultCamera;
52
+ const webcamApiRef = useRef(null);
53
+ const facemeshApiRef = useRef(null); //
54
+ // computeTarget()
55
+ //
56
+ // Compute `target` position and rotation for the camera (according to <Facemesh>)
57
+ //
58
+ // 1. 👀 either following the 2 eyes
59
+ // 2. 👤 or just the head mesh
60
+ //
61
+
62
+ const [target] = useState(() => new THREE.Object3D());
63
+ const [irisRightDirPos] = useState(() => new THREE.Vector3());
64
+ const [irisLeftDirPos] = useState(() => new THREE.Vector3());
65
+ const [irisRightLookAt] = useState(() => new THREE.Vector3());
66
+ const [irisLeftLookAt] = useState(() => new THREE.Vector3());
67
+ const computeTarget = useCallback(() => {
68
+ // same parent as the camera
69
+ target.parent = explCamera.parent;
70
+ const facemeshApi = facemeshApiRef.current;
71
+
72
+ if (facemeshApi) {
73
+ const {
74
+ outerRef,
75
+ eyeRightRef,
76
+ eyeLeftRef
77
+ } = facemeshApi;
78
+
79
+ if (eyeRightRef.current && eyeLeftRef.current) {
80
+ // 1. 👀
81
+ const {
82
+ irisDirRef: irisRightDirRef
83
+ } = eyeRightRef.current;
84
+ const {
85
+ irisDirRef: irisLeftDirRef
86
+ } = eyeLeftRef.current;
87
+
88
+ if (irisRightDirRef.current && irisLeftDirRef.current && outerRef.current) {
89
+ //
90
+ // position: mean of irisRightDirPos,irisLeftDirPos
91
+ //
92
+ irisRightDirPos.copy(localToLocal(irisRightDirRef.current, new THREE.Vector3(0, 0, 0), outerRef.current));
93
+ irisLeftDirPos.copy(localToLocal(irisLeftDirRef.current, new THREE.Vector3(0, 0, 0), outerRef.current));
94
+ target.position.copy(localToLocal(outerRef.current, mean(irisRightDirPos, irisLeftDirPos), explCamera.parent || scene)); //
95
+ // lookAt: mean of irisRightLookAt,irisLeftLookAt
96
+ //
97
+
98
+ irisRightLookAt.copy(localToLocal(irisRightDirRef.current, new THREE.Vector3(0, 0, 1), outerRef.current));
99
+ irisLeftLookAt.copy(localToLocal(irisLeftDirRef.current, new THREE.Vector3(0, 0, 1), outerRef.current));
100
+ target.lookAt(outerRef.current.localToWorld(mean(irisRightLookAt, irisLeftLookAt)));
101
+ }
102
+ } else {
103
+ // 2. 👤
104
+ if (outerRef.current) {
105
+ target.position.copy(localToLocal(outerRef.current, new THREE.Vector3(0, 0, 0), explCamera.parent || scene));
106
+ target.lookAt(outerRef.current.localToWorld(new THREE.Vector3(0, 0, 1)));
107
+ }
108
+ }
109
+ }
110
+
111
+ return target;
112
+ }, [explCamera, irisLeftDirPos, irisLeftLookAt, irisRightDirPos, irisRightLookAt, scene, target]); //
113
+ // update()
114
+ //
115
+ // Updating the camera `current` position and rotation, following `target`
116
+ //
117
+
118
+ const [current] = useState(() => new THREE.Object3D());
119
+ const update = useCallback(function (delta, target) {
120
+ if (explCamera) {
121
+ var _target;
122
+
123
+ (_target = target) !== null && _target !== void 0 ? _target : target = computeTarget();
124
+
125
+ if (smoothTime > 0) {
126
+ // damping current
127
+ const eps = 1e-9;
128
+ easing.damp3(current.position, target.position, smoothTime, delta, undefined, undefined, eps);
129
+ easing.dampE(current.rotation, target.rotation, smoothTime, delta, undefined, undefined, eps);
130
+ } else {
131
+ // instant
132
+ current.position.copy(target.position);
133
+ current.rotation.copy(target.rotation);
134
+ }
135
+
136
+ explCamera.position.copy(current.position);
137
+ explCamera.rotation.copy(current.rotation);
138
+ }
139
+ }, [explCamera, computeTarget, smoothTime, current.position, current.rotation]); //
140
+ // detect()
141
+ //
142
+
143
+ const [faces, setFaces] = useState();
144
+ const faceLandmarker = useFaceLandmarker();
145
+ const detect = useCallback((video, time) => {
146
+ const faces = faceLandmarker == null ? void 0 : faceLandmarker.detectForVideo(video, time);
147
+ setFaces(faces);
148
+ }, [faceLandmarker]);
149
+ useFrame((_, delta) => {
150
+ if (!manualUpdate) {
151
+ update(delta);
152
+ }
153
+ }); // Ref API
154
+
155
+ const api = useMemo(() => Object.assign(Object.create(THREE.EventDispatcher.prototype), {
156
+ detect,
157
+ computeTarget,
158
+ update,
159
+ facemeshApiRef,
160
+ webcamApiRef,
161
+ // shorthands
162
+ play: () => {
163
+ var _webcamApiRef$current, _webcamApiRef$current2;
164
+
165
+ (_webcamApiRef$current = webcamApiRef.current) == null ? void 0 : (_webcamApiRef$current2 = _webcamApiRef$current.videoTextureApiRef.current) == null ? void 0 : _webcamApiRef$current2.texture.source.data.play();
166
+ },
167
+ pause: () => {
168
+ var _webcamApiRef$current3, _webcamApiRef$current4;
169
+
170
+ (_webcamApiRef$current3 = webcamApiRef.current) == null ? void 0 : (_webcamApiRef$current4 = _webcamApiRef$current3.videoTextureApiRef.current) == null ? void 0 : _webcamApiRef$current4.texture.source.data.pause();
171
+ }
172
+ }), [detect, computeTarget, update]);
173
+ useImperativeHandle(fref, () => api, [api]); //
174
+ // events callbacks
175
+ //
176
+
177
+ useEffect(() => {
178
+ const onVideoFrameCb = e => {
179
+ if (!manualDetect) detect(e.texture.source.data, e.time);
180
+ if (onVideoFrame) onVideoFrame(e);
181
+ };
182
+
183
+ api.addEventListener('videoFrame', onVideoFrameCb);
184
+ return () => {
185
+ api.removeEventListener('videoFrame', onVideoFrameCb);
186
+ };
187
+ }, [api, detect, faceLandmarker, manualDetect, onVideoFrame]); // `controls` global state
188
+
189
+ useEffect(() => {
190
+ if (makeDefault) {
191
+ const old = get().controls;
192
+ set({
193
+ controls: api
194
+ });
195
+ return () => set({
196
+ controls: old
197
+ });
198
+ }
199
+ }, [makeDefault, api, get, set]);
200
+ const points = faces == null ? void 0 : faces.faceLandmarks[0];
201
+ const facialTransformationMatrix = faces == null ? void 0 : (_faces$facialTransfor = faces.facialTransformationMatrixes) == null ? void 0 : _faces$facialTransfor[0];
202
+ const faceBlendshapes = faces == null ? void 0 : (_faces$faceBlendshape = faces.faceBlendshapes) == null ? void 0 : _faces$faceBlendshape[0];
203
+ return /*#__PURE__*/React.createElement(FaceControlsContext.Provider, {
204
+ value: api
205
+ }, webcam && /*#__PURE__*/React.createElement(Suspense, {
206
+ fallback: null
207
+ }, /*#__PURE__*/React.createElement(Webcam, {
208
+ ref: webcamApiRef,
209
+ autostart: autostart,
210
+ videoTextureSrc: webcamVideoTextureSrc
211
+ })), /*#__PURE__*/React.createElement(Facemesh, _extends({
212
+ ref: facemeshApiRef
213
+ }, facemesh, {
214
+ points: points,
215
+ depth: depth,
216
+ facialTransformationMatrix: facialTransformationMatrix,
217
+ faceBlendshapes: faceBlendshapes,
218
+ eyes: eyes,
219
+ eyesAsOrigin: eyesAsOrigin,
220
+ offset: offset,
221
+ offsetScalar: offsetScalar,
222
+ debug: debug,
223
+ "rotation-z": Math.PI,
224
+ visible: debug
225
+ }), /*#__PURE__*/React.createElement("meshBasicMaterial", {
226
+ side: THREE.DoubleSide
227
+ })));
228
+ });
229
+ const useFaceControls = () => useContext(FaceControlsContext); //
230
+ // Webcam
231
+ //
232
+
233
+ const Webcam = /*#__PURE__*/forwardRef(({
234
+ videoTextureSrc,
235
+ autostart = true
236
+ }, fref) => {
237
+ const videoTextureApiRef = useRef(null);
238
+ const faceControls = useFaceControls();
239
+ const stream = suspend(async () => {
240
+ return !videoTextureSrc ? await navigator.mediaDevices.getUserMedia({
241
+ audio: false,
242
+ video: {
243
+ facingMode: 'user'
244
+ }
245
+ }) : Promise.resolve(null);
246
+ }, [videoTextureSrc]);
247
+ useEffect(() => {
248
+ faceControls.dispatchEvent({
249
+ type: 'stream',
250
+ stream
251
+ });
252
+ return () => {
253
+ stream == null ? void 0 : stream.getTracks().forEach(track => track.stop());
254
+ clear([videoTextureSrc]);
255
+ };
256
+ }, [stream, faceControls, videoTextureSrc]); // ref-api
257
+
258
+ const api = useMemo(() => ({
259
+ videoTextureApiRef
260
+ }), []);
261
+ useImperativeHandle(fref, () => api, [api]);
262
+ return /*#__PURE__*/React.createElement(Suspense, {
263
+ fallback: null
264
+ }, /*#__PURE__*/React.createElement(VideoTexture, {
265
+ ref: videoTextureApiRef,
266
+ src: videoTextureSrc || stream,
267
+ start: autostart
268
+ }));
269
+ }); //
270
+ // VideoTexture
271
+ //
272
+
273
+ const VideoTexture = /*#__PURE__*/forwardRef(({
274
+ src,
275
+ start
276
+ }, fref) => {
277
+ const texture = useVideoTexture(src, {
278
+ start
279
+ });
280
+ const video = texture.source.data;
281
+ const faceControls = useFaceControls();
282
+ const onVideoFrame = useCallback(time => {
283
+ faceControls.dispatchEvent({
284
+ type: 'videoFrame',
285
+ texture,
286
+ time
287
+ });
288
+ }, [texture, faceControls]);
289
+ useVideoFrame(video, onVideoFrame); // ref-api
290
+
291
+ const api = useMemo(() => ({
292
+ texture
293
+ }), [texture]);
294
+ useImperativeHandle(fref, () => api, [api]);
295
+ return /*#__PURE__*/React.createElement(React.Fragment, null);
296
+ });
297
+
298
+ const useVideoFrame = (video, f) => {
299
+ // https://web.dev/requestvideoframecallback-rvfc/
300
+ // https://www.remotion.dev/docs/video-manipulation
301
+ useEffect(() => {
302
+ if (!video || !video.requestVideoFrameCallback) return;
303
+ let handle;
304
+
305
+ function callback(...args) {
306
+ f(...args);
307
+ handle = video.requestVideoFrameCallback(callback);
308
+ }
309
+
310
+ video.requestVideoFrameCallback(callback);
311
+ return () => video.cancelVideoFrameCallback(handle);
312
+ }, [video, f]);
313
+ };
314
+
315
+ export { FaceControls, useFaceControls };
@@ -0,0 +1,43 @@
1
+ import * as React from 'react';
2
+ import { useEffect, useContext, createContext } from 'react';
3
+ import { FilesetResolver as FilesetResolver_1, FaceLandmarker as FaceLandmarker_1 } from '../../node_modules/@mediapipe/tasks-vision/vision_bundle.js';
4
+ import { suspend, clear } from 'suspend-react';
5
+
6
+ /* eslint react-hooks/exhaustive-deps: 1 */
7
+ const FaceLandmarkerContext = /*#__PURE__*/createContext({});
8
+ const FaceLandmarkerDefaults = {
9
+ basePath: 'https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@0.10.0/wasm',
10
+ options: {
11
+ baseOptions: {
12
+ modelAssetPath: 'https://storage.googleapis.com/mediapipe-models/face_landmarker/face_landmarker/float16/1/face_landmarker.task',
13
+ delegate: 'GPU'
14
+ },
15
+ runningMode: 'VIDEO',
16
+ outputFaceBlendshapes: true,
17
+ outputFacialTransformationMatrixes: true
18
+ }
19
+ };
20
+ function FaceLandmarker({
21
+ basePath = FaceLandmarkerDefaults.basePath,
22
+ options = FaceLandmarkerDefaults.options,
23
+ children
24
+ }) {
25
+ const opts = JSON.stringify(options);
26
+ const faceLandmarker = suspend(async () => {
27
+ return await FilesetResolver_1.forVisionTasks(basePath).then(vision => FaceLandmarker_1.createFromOptions(vision, options));
28
+ }, [basePath, opts]);
29
+ useEffect(() => {
30
+ return () => {
31
+ faceLandmarker == null ? void 0 : faceLandmarker.close();
32
+ clear([basePath, opts]);
33
+ };
34
+ }, [faceLandmarker, basePath, opts]);
35
+ return /*#__PURE__*/React.createElement(FaceLandmarkerContext.Provider, {
36
+ value: faceLandmarker
37
+ }, children);
38
+ }
39
+ function useFaceLandmarker() {
40
+ return useContext(FaceLandmarkerContext);
41
+ }
42
+
43
+ export { FaceLandmarker, FaceLandmarkerDefaults, useFaceLandmarker };