@react-three/drei 9.49.0 → 9.50.0

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-three/drei",
3
- "version": "9.49.0",
3
+ "version": "9.50.0",
4
4
  "private": false,
5
5
  "description": "useful add-ons for react-three-fiber",
6
6
  "keywords": [
package/web/Html.cjs.js CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("@babel/runtime/helpers/extends"),t=require("react"),r=require("react-dom/client"),n=require("three"),o=require("@react-three/fiber");function s(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}function a(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 i=s(e),c=a(t),l=a(r);const u=new n.Vector3,d=new n.Vector3,f=new n.Vector3;function m(e,t,r){const n=u.setFromMatrixPosition(e.matrixWorld);n.project(t);const o=r.width/2,s=r.height/2;return[n.x*o+o,-n.y*s+s]}const p=e=>Math.abs(e)<1e-10?0:e;function h(e,t,r=""){let n="matrix3d(";for(let r=0;16!==r;r++)n+=p(t[r]*e.elements[r])+(15!==r?",":")");return r+n}const x=(y=[1,-1,1,1,1,-1,1,1,1,-1,1,1,1,-1,1,1],e=>h(e,y));var y;const v=(e,t)=>{return h(e,[1/(r=t),1/r,1/r,1,-1/r,-1/r,-1/r,-1,1/r,1/r,1/r,1,1,1,1,1],"translate(-50%,-50%)");var r},b=c.forwardRef((({children:e,eps:t=.001,style:r,className:s,prepend:a,center:h,fullscreen:y,portal:b,distanceFactor:g,sprite:M=!1,transform:P=!1,occlude:w,onOcclude:W,zIndexRange:$=[16777271,0],calculatePosition:E=m,as:O="div",wrapperClass:j,pointerEvents:F="auto",...R},C)=>{const{gl:z,camera:T,scene:I,size:q,raycaster:N,events:_}=o.useThree(),[L]=c.useState((()=>document.createElement(O))),V=c.useRef(),k=c.useRef(null),A=c.useRef(0),D=c.useRef([0,0]),S=c.useRef(null),H=c.useRef(null),Z=(null==b?void 0:b.current)||_.connected||z.domElement.parentNode;c.useLayoutEffect((()=>{if(k.current){const e=V.current=l.createRoot(L);if(I.updateMatrixWorld(),P)L.style.cssText="position:absolute;top:0;left:0;pointer-events:none;overflow:hidden;";else{const e=E(k.current,T,q);L.style.cssText=`position:absolute;top:0;left:0;transform:translate3d(${e[0]}px,${e[1]}px,0);transform-origin:0 0;`}return Z&&(a?Z.prepend(L):Z.appendChild(L)),()=>{Z&&Z.removeChild(L),e.unmount()}}}),[Z,P]),c.useLayoutEffect((()=>{j&&(L.className=j)}),[j]);const B=c.useMemo((()=>P?{position:"absolute",top:0,left:0,width:q.width,height:q.height,transformStyle:"preserve-3d",pointerEvents:"none"}:{position:"absolute",transform:h?"translate3d(-50%,-50%,0)":"none",...y&&{top:-q.height/2,left:-q.width/2,width:q.width,height:q.height},...r}),[r,h,y,q,P]),G=c.useMemo((()=>({position:"absolute",pointerEvents:F})),[F]);c.useLayoutEffect((()=>{var t,n;P?null==(t=V.current)||t.render(c.createElement("div",{ref:S,style:B},c.createElement("div",{ref:H,style:G},c.createElement("div",{ref:C,className:s,style:r,children:e})))):null==(n=V.current)||n.render(c.createElement("div",{ref:C,style:B,className:s,children:e}))}));const J=c.useRef(!0);return o.useFrame((()=>{if(k.current){T.updateMatrixWorld(),k.current.updateWorldMatrix(!0,!1);const e=P?D.current:E(k.current,T,q);if(P||Math.abs(A.current-T.zoom)>t||Math.abs(D.current[0]-e[0])>t||Math.abs(D.current[1]-e[1])>t){const t=function(e,t){const r=u.setFromMatrixPosition(e.matrixWorld),n=d.setFromMatrixPosition(t.matrixWorld),o=r.sub(n),s=t.getWorldDirection(f);return o.angleTo(s)>Math.PI/2}(k.current,T);let r=!1;"boolean"==typeof w?!0===w&&(r=[I]):Array.isArray(w)&&(r=w.map((e=>e.current)));const o=J.current;if(r){const e=function(e,t,r,n){const o=u.setFromMatrixPosition(e.matrixWorld),s=o.clone();s.project(t),r.setFromCamera(s,t);const a=r.intersectObjects(n,!0);if(a.length){const e=a[0].distance;return o.distanceTo(r.ray.origin)<e}return!0}(k.current,T,N,r);J.current=e&&!t}else J.current=!t;if(o!==J.current&&(W?W(!J.current):L.style.display=J.current?"block":"none"),L.style.zIndex=`${function(e,t,r){if(t instanceof n.PerspectiveCamera||t instanceof n.OrthographicCamera){const n=u.setFromMatrixPosition(e.matrixWorld),o=d.setFromMatrixPosition(t.matrixWorld),s=n.distanceTo(o),a=(r[1]-r[0])/(t.far-t.near),i=r[1]-a*t.far;return Math.round(a*s+i)}}(k.current,T,$)}`,P){const[e,t]=[q.width/2,q.height/2],r=T.projectionMatrix.elements[5]*t,{isOrthographicCamera:n,top:o,left:s,bottom:a,right:i}=T,c=x(T.matrixWorldInverse),l=n?`scale(${r})translate(${p(-(i+s)/2)}px,${p((o+a)/2)}px)`:`translateZ(${r}px)`;let u=k.current.matrixWorld;M&&(u=T.matrixWorldInverse.clone().transpose().copyPosition(u).scale(k.current.scale),u.elements[3]=u.elements[7]=u.elements[11]=0,u.elements[15]=1),L.style.width=q.width+"px",L.style.height=q.height+"px",L.style.perspective=n?"":`${r}px`,S.current&&H.current&&(S.current.style.transform=`${l}${c}translate(${e}px,${t}px)`,H.current.style.transform=v(u,1/((g||10)/400)))}else{const t=void 0===g?1:function(e,t){if(t instanceof n.OrthographicCamera)return t.zoom;if(t instanceof n.PerspectiveCamera){const r=u.setFromMatrixPosition(e.matrixWorld),n=d.setFromMatrixPosition(t.matrixWorld),o=t.fov*Math.PI/180,s=r.distanceTo(n);return 1/(2*Math.tan(o/2)*s)}return 1}(k.current,T)*g;L.style.transform=`translate3d(${e[0]}px,${e[1]}px,0) scale(${t})`}D.current=e,A.current=T.zoom}}})),c.createElement("group",i.default({},R,{ref:k}))}));exports.Html=b;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("@babel/runtime/helpers/extends"),t=require("react"),r=require("react-dom/client"),n=require("three"),o=require("@react-three/fiber");function i(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 a=i(e),c=s(t),l=s(r);const u=new n.Vector3,d=new n.Vector3,m=new n.Vector3;function f(e,t,r){const n=u.setFromMatrixPosition(e.matrixWorld);n.project(t);const o=r.width/2,i=r.height/2;return[n.x*o+o,-n.y*i+i]}const h=e=>Math.abs(e)<1e-10?0:e;function p(e,t,r=""){let n="matrix3d(";for(let r=0;16!==r;r++)n+=h(t[r]*e.elements[r])+(15!==r?",":")");return r+n}const x=(v=[1,-1,1,1,1,-1,1,1,1,-1,1,1,1,-1,1,1],e=>p(e,v));var v;const y=(e,t)=>{return p(e,[1/(r=t),1/r,1/r,1,-1/r,-1/r,-1/r,-1,1/r,1/r,1/r,1,1,1,1,1],"translate(-50%,-50%)");var r};const g=c.forwardRef((({children:e,eps:t=.001,style:r,className:i,prepend:s,center:p,fullscreen:v,portal:g,distanceFactor:M,sprite:P=!1,transform:b=!1,occlude:w,onOcclude:E,castShadow:W,receiveShadow:S,material:$,geometry:j,zIndexRange:z=[16777271,0],calculatePosition:O=f,as:R="div",wrapperClass:F,pointerEvents:C="auto",...T},I)=>{const{gl:A,camera:k,scene:H,size:N,raycaster:_,events:q,viewport:V}=o.useThree(),[L]=c.useState((()=>document.createElement(R))),D=c.useRef(),G=c.useRef(null),Z=c.useRef(0),B=c.useRef([0,0]),J=c.useRef(null),K=c.useRef(null),Q=(null==g?void 0:g.current)||q.connected||A.domElement.parentNode,U=c.useRef(null),X=c.useRef(!1),Y=c.useMemo((()=>"raycast"===w||Array.isArray(w)&&w.length&&function(e){return e&&"object"==typeof e&&"current"in e}(w[0])),[w]);c.useLayoutEffect((()=>{const e=A.domElement;w?(e.style.zIndex=`${Math.floor(z[0]/2)}`,e.style.position="absolute",e.style.pointerEvents="none"):(e.style.zIndex=null,e.style.position=null,e.style.pointerEvents=null)}),[w,Y]),c.useLayoutEffect((()=>{if(G.current){const e=D.current=l.createRoot(L);if(H.updateMatrixWorld(),b)L.style.cssText="position:absolute;top:0;left:0;pointer-events:none;overflow:hidden;";else{const e=O(G.current,k,N);L.style.cssText=`position:absolute;top:0;left:0;transform:translate3d(${e[0]}px,${e[1]}px,0);transform-origin:0 0;`}return Q&&(s?Q.prepend(L):Q.appendChild(L)),()=>{Q&&Q.removeChild(L),e.unmount()}}}),[Q,b]),c.useLayoutEffect((()=>{F&&(L.className=F)}),[F]);const ee=c.useMemo((()=>b?{position:"absolute",top:0,left:0,width:N.width,height:N.height,transformStyle:"preserve-3d",pointerEvents:"none"}:{position:"absolute",transform:p?"translate3d(-50%,-50%,0)":"none",...v&&{top:-N.height/2,left:-N.width/2,width:N.width,height:N.height},...r}),[r,p,v,N,b]),te=c.useMemo((()=>({position:"absolute",pointerEvents:C})),[C]);c.useLayoutEffect((()=>{var t,n;(X.current=!1,b)?null==(t=D.current)||t.render(c.createElement("div",{ref:J,style:ee},c.createElement("div",{ref:K,style:te},c.createElement("div",{ref:I,className:i,style:r,children:e})))):null==(n=D.current)||n.render(c.createElement("div",{ref:I,style:ee,className:i,children:e}))}));const re=c.useRef(!0);o.useFrame((e=>{if(G.current){k.updateMatrixWorld(),G.current.updateWorldMatrix(!0,!1);const e=b?B.current:O(G.current,k,N);if(b||Math.abs(Z.current-k.zoom)>t||Math.abs(B.current[0]-e[0])>t||Math.abs(B.current[1]-e[1])>t){const t=function(e,t){const r=u.setFromMatrixPosition(e.matrixWorld),n=d.setFromMatrixPosition(t.matrixWorld),o=r.sub(n),i=t.getWorldDirection(m);return o.angleTo(i)>Math.PI/2}(G.current,k);let r=!1;Y&&("raycast"===w?r=[H]:Array.isArray(w)&&(r=w.map((e=>e.current))));const o=re.current;if(r){const e=function(e,t,r,n){const o=u.setFromMatrixPosition(e.matrixWorld),i=o.clone();i.project(t),r.setFromCamera(i,t);const s=r.intersectObjects(n,!0);if(s.length){const e=s[0].distance;return o.distanceTo(r.ray.origin)<e}return!0}(G.current,k,_,r);re.current=e&&!t}else re.current=!t;o!==re.current&&(E?E(!re.current):L.style.display=re.current?"block":"none");const i=Math.floor(z[0]/2),s=w?Y?[z[0],i]:[i-1,0]:z;if(L.style.zIndex=`${function(e,t,r){if(t instanceof n.PerspectiveCamera||t instanceof n.OrthographicCamera){const n=u.setFromMatrixPosition(e.matrixWorld),o=d.setFromMatrixPosition(t.matrixWorld),i=n.distanceTo(o),s=(r[1]-r[0])/(t.far-t.near),a=r[1]-s*t.far;return Math.round(s*i+a)}}(G.current,k,s)}`,b){const[e,t]=[N.width/2,N.height/2],r=k.projectionMatrix.elements[5]*t,{isOrthographicCamera:n,top:o,left:i,bottom:s,right:a}=k,c=x(k.matrixWorldInverse),l=n?`scale(${r})translate(${h(-(a+i)/2)}px,${h((o+s)/2)}px)`:`translateZ(${r}px)`;let u=G.current.matrixWorld;P&&(u=k.matrixWorldInverse.clone().transpose().copyPosition(u).scale(G.current.scale),u.elements[3]=u.elements[7]=u.elements[11]=0,u.elements[15]=1),L.style.width=N.width+"px",L.style.height=N.height+"px",L.style.perspective=n?"":`${r}px`,J.current&&K.current&&(J.current.style.transform=`${l}${c}translate(${e}px,${t}px)`,K.current.style.transform=y(u,1/((M||10)/400)))}else{const t=void 0===M?1:function(e,t){if(t instanceof n.OrthographicCamera)return t.zoom;if(t instanceof n.PerspectiveCamera){const r=u.setFromMatrixPosition(e.matrixWorld),n=d.setFromMatrixPosition(t.matrixWorld),o=t.fov*Math.PI/180,i=r.distanceTo(n);return 1/(2*Math.tan(o/2)*i)}return 1}(G.current,k)*M;L.style.transform=`translate3d(${e[0]}px,${e[1]}px,0) scale(${t})`}B.current=e,Z.current=k.zoom}}if(!Y&&U.current&&!X.current)if(b){if(J.current){const e=J.current.children[0];if(null!=e&&e.clientWidth&&null!=e&&e.clientHeight){const{isOrthographicCamera:t}=k;if(t||j)T.scale&&(Array.isArray(T.scale)?T.scale instanceof n.Vector3?U.current.scale.copy(T.scale.clone().divideScalar(1)):U.current.scale.set(1/T.scale[0],1/T.scale[1],1/T.scale[2]):U.current.scale.setScalar(1/T.scale));else{const t=(M||10)/400,r=e.clientWidth*t,n=e.clientHeight*t;U.current.scale.set(r,n,1)}X.current=!0}}}else{const t=L.children[0];if(null!=t&&t.clientWidth&&null!=t&&t.clientHeight){const e=1/V.factor,r=t.clientWidth*e,n=t.clientHeight*e;U.current.scale.set(r,n,1),X.current=!0}U.current.lookAt(e.camera.position)}}));const ne=c.useMemo((()=>({vertexShader:b?void 0:'\n /*\n This shader is from the THREE\'s SpriteMaterial.\n We need to turn the backing plane into a Sprite\n (make it always face the camera) if "transfrom" \n is false. \n */\n #include <common>\n\n void main() {\n vec2 center = vec2(0., 1.);\n float rotation = 0.0;\n \n // This is somewhat arbitrary, but it seems to work well\n // Need to figure out how to derive this dynamically if it even matters\n float size = 0.03;\n\n vec4 mvPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );\n vec2 scale;\n scale.x = length( vec3( modelMatrix[ 0 ].x, modelMatrix[ 0 ].y, modelMatrix[ 0 ].z ) );\n scale.y = length( vec3( modelMatrix[ 1 ].x, modelMatrix[ 1 ].y, modelMatrix[ 1 ].z ) );\n\n bool isPerspective = isPerspectiveMatrix( projectionMatrix );\n if ( isPerspective ) scale *= - mvPosition.z;\n\n vec2 alignedPosition = ( position.xy - ( center - vec2( 0.5 ) ) ) * scale * size;\n vec2 rotatedPosition;\n rotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;\n rotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;\n mvPosition.xy += rotatedPosition;\n\n gl_Position = projectionMatrix * mvPosition;\n }\n ',fragmentShader:"\n void main() {\n gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);\n }\n "})),[b]);return c.createElement("group",a.default({},T,{ref:G}),w&&!Y&&c.createElement("mesh",{castShadow:W,receiveShadow:S,ref:U},j||c.createElement("planeGeometry",null),$||c.createElement("shaderMaterial",{side:n.DoubleSide,vertexShader:ne.vertexShader,fragmentShader:ne.fragmentShader})))}));exports.Html=g;
package/web/Html.d.ts CHANGED
@@ -18,12 +18,16 @@ export interface HtmlProps extends Omit<Assign<React.HTMLAttributes<HTMLDivEleme
18
18
  sprite?: boolean;
19
19
  transform?: boolean;
20
20
  zIndexRange?: Array<number>;
21
- occlude?: React.RefObject<Object3D>[] | boolean;
22
- onOcclude?: (visible: boolean) => null;
23
21
  calculatePosition?: CalculatePosition;
24
22
  as?: string;
25
23
  wrapperClass?: string;
26
24
  pointerEvents?: PointerEventsProperties;
25
+ occlude?: React.RefObject<Object3D>[] | boolean | 'raycast' | 'blending';
26
+ onOcclude?: (visible: boolean) => null;
27
+ material?: React.ReactNode;
28
+ geometry?: React.ReactNode;
29
+ castShadow?: boolean;
30
+ receiveShadow?: boolean;
27
31
  }
28
32
  export declare const Html: React.ForwardRefExoticComponent<HtmlProps & React.RefAttributes<HTMLDivElement>>;
29
33
  export {};
package/web/Html.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import _extends from '@babel/runtime/helpers/esm/extends';
2
2
  import * as React from 'react';
3
3
  import * as ReactDOM from 'react-dom/client';
4
- import { Vector3, OrthographicCamera, PerspectiveCamera } from 'three';
4
+ import { Vector3, DoubleSide, OrthographicCamera, PerspectiveCamera } from 'three';
5
5
  import { useThree, useFrame } from '@react-three/fiber';
6
6
 
7
7
  const v1 = new Vector3();
@@ -88,6 +88,10 @@ const getObjectCSSMatrix = (scaleMultipliers => {
88
88
  return (matrix, factor) => getCSSMatrix(matrix, scaleMultipliers(factor), 'translate(-50%,-50%)');
89
89
  })(f => [1 / f, 1 / f, 1 / f, 1, -1 / f, -1 / f, -1 / f, -1, 1 / f, 1 / f, 1 / f, 1, 1, 1, 1, 1]);
90
90
 
91
+ function isRefObject(ref) {
92
+ return ref && typeof ref === 'object' && 'current' in ref;
93
+ }
94
+
91
95
  const Html = /*#__PURE__*/React.forwardRef(({
92
96
  children,
93
97
  eps = 0.001,
@@ -102,6 +106,10 @@ const Html = /*#__PURE__*/React.forwardRef(({
102
106
  transform = false,
103
107
  occlude,
104
108
  onOcclude,
109
+ castShadow,
110
+ receiveShadow,
111
+ material,
112
+ geometry,
105
113
  zIndexRange = [16777271, 0],
106
114
  calculatePosition = defaultCalculatePosition,
107
115
  as = 'div',
@@ -115,7 +123,8 @@ const Html = /*#__PURE__*/React.forwardRef(({
115
123
  scene,
116
124
  size,
117
125
  raycaster,
118
- events
126
+ events,
127
+ viewport
119
128
  } = useThree();
120
129
  const [el] = React.useState(() => document.createElement(as));
121
130
  const root = React.useRef();
@@ -126,6 +135,24 @@ const Html = /*#__PURE__*/React.forwardRef(({
126
135
  const transformInnerRef = React.useRef(null); // Append to the connected element, which makes HTML work with views
127
136
 
128
137
  const target = (portal == null ? void 0 : portal.current) || events.connected || gl.domElement.parentNode;
138
+ const occlusionMeshRef = React.useRef(null);
139
+ const isMeshSizeSet = React.useRef(false);
140
+ const isRayCastOcclusion = React.useMemo(() => {
141
+ return occlude === 'raycast' || Array.isArray(occlude) && occlude.length && isRefObject(occlude[0]);
142
+ }, [occlude]);
143
+ React.useLayoutEffect(() => {
144
+ const el = gl.domElement;
145
+
146
+ if (occlude) {
147
+ el.style.zIndex = `${Math.floor(zIndexRange[0] / 2)}`;
148
+ el.style.position = 'absolute';
149
+ el.style.pointerEvents = 'none';
150
+ } else {
151
+ el.style.zIndex = null;
152
+ el.style.position = null;
153
+ el.style.pointerEvents = null;
154
+ }
155
+ }, [occlude, isRayCastOcclusion]);
129
156
  React.useLayoutEffect(() => {
130
157
  if (group.current) {
131
158
  const currentRoot = root.current = ReactDOM.createRoot(el);
@@ -181,6 +208,8 @@ const Html = /*#__PURE__*/React.forwardRef(({
181
208
  pointerEvents
182
209
  }), [pointerEvents]);
183
210
  React.useLayoutEffect(() => {
211
+ isMeshSizeSet.current = false;
212
+
184
213
  if (transform) {
185
214
  var _root$current;
186
215
 
@@ -208,7 +237,7 @@ const Html = /*#__PURE__*/React.forwardRef(({
208
237
  }
209
238
  });
210
239
  const visible = React.useRef(true);
211
- useFrame(() => {
240
+ useFrame(gl => {
212
241
  if (group.current) {
213
242
  camera.updateMatrixWorld();
214
243
  group.current.updateWorldMatrix(true, false);
@@ -218,12 +247,12 @@ const Html = /*#__PURE__*/React.forwardRef(({
218
247
  const isBehindCamera = isObjectBehindCamera(group.current, camera);
219
248
  let raytraceTarget = false;
220
249
 
221
- if (typeof occlude === 'boolean') {
222
- if (occlude === true) {
250
+ if (isRayCastOcclusion) {
251
+ if (occlude === 'raycast') {
223
252
  raytraceTarget = [scene];
253
+ } else if (Array.isArray(occlude)) {
254
+ raytraceTarget = occlude.map(item => item.current);
224
255
  }
225
- } else if (Array.isArray(occlude)) {
226
- raytraceTarget = occlude.map(item => item.current);
227
256
  }
228
257
 
229
258
  const previouslyVisible = visible.current;
@@ -239,7 +268,10 @@ const Html = /*#__PURE__*/React.forwardRef(({
239
268
  if (onOcclude) onOcclude(!visible.current);else el.style.display = visible.current ? 'block' : 'none';
240
269
  }
241
270
 
242
- el.style.zIndex = `${objectZIndex(group.current, camera, zIndexRange)}`;
271
+ const halfRange = Math.floor(zIndexRange[0] / 2);
272
+ const zRange = occlude ? isRayCastOcclusion //
273
+ ? [zIndexRange[0], halfRange] : [halfRange - 1, 0] : zIndexRange;
274
+ el.style.zIndex = `${objectZIndex(group.current, camera, zRange)}`;
243
275
 
244
276
  if (transform) {
245
277
  const [widthHalf, heightHalf] = [size.width / 2, size.height / 2];
@@ -278,10 +310,108 @@ const Html = /*#__PURE__*/React.forwardRef(({
278
310
  oldZoom.current = camera.zoom;
279
311
  }
280
312
  }
313
+
314
+ if (!isRayCastOcclusion && occlusionMeshRef.current && !isMeshSizeSet.current) {
315
+ if (transform) {
316
+ if (transformOuterRef.current) {
317
+ const el = transformOuterRef.current.children[0];
318
+
319
+ if (el != null && el.clientWidth && el != null && el.clientHeight) {
320
+ const {
321
+ isOrthographicCamera
322
+ } = camera;
323
+
324
+ if (isOrthographicCamera || geometry) {
325
+ if (props.scale) {
326
+ if (!Array.isArray(props.scale)) {
327
+ occlusionMeshRef.current.scale.setScalar(1 / props.scale);
328
+ } else if (props.scale instanceof Vector3) {
329
+ occlusionMeshRef.current.scale.copy(props.scale.clone().divideScalar(1));
330
+ } else {
331
+ occlusionMeshRef.current.scale.set(1 / props.scale[0], 1 / props.scale[1], 1 / props.scale[2]);
332
+ }
333
+ }
334
+ } else {
335
+ const ratio = (distanceFactor || 10) / 400;
336
+ const w = el.clientWidth * ratio;
337
+ const h = el.clientHeight * ratio;
338
+ occlusionMeshRef.current.scale.set(w, h, 1);
339
+ }
340
+
341
+ isMeshSizeSet.current = true;
342
+ }
343
+ }
344
+ } else {
345
+ const ele = el.children[0];
346
+
347
+ if (ele != null && ele.clientWidth && ele != null && ele.clientHeight) {
348
+ const ratio = 1 / viewport.factor;
349
+ const w = ele.clientWidth * ratio;
350
+ const h = ele.clientHeight * ratio;
351
+ occlusionMeshRef.current.scale.set(w, h, 1);
352
+ isMeshSizeSet.current = true;
353
+ }
354
+
355
+ occlusionMeshRef.current.lookAt(gl.camera.position);
356
+ }
357
+ }
281
358
  });
359
+ const shaders = React.useMemo(() => ({
360
+ vertexShader: !transform ?
361
+ /* glsl */
362
+ `
363
+ /*
364
+ This shader is from the THREE's SpriteMaterial.
365
+ We need to turn the backing plane into a Sprite
366
+ (make it always face the camera) if "transfrom"
367
+ is false.
368
+ */
369
+ #include <common>
370
+
371
+ void main() {
372
+ vec2 center = vec2(0., 1.);
373
+ float rotation = 0.0;
374
+
375
+ // This is somewhat arbitrary, but it seems to work well
376
+ // Need to figure out how to derive this dynamically if it even matters
377
+ float size = 0.03;
378
+
379
+ vec4 mvPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );
380
+ vec2 scale;
381
+ scale.x = length( vec3( modelMatrix[ 0 ].x, modelMatrix[ 0 ].y, modelMatrix[ 0 ].z ) );
382
+ scale.y = length( vec3( modelMatrix[ 1 ].x, modelMatrix[ 1 ].y, modelMatrix[ 1 ].z ) );
383
+
384
+ bool isPerspective = isPerspectiveMatrix( projectionMatrix );
385
+ if ( isPerspective ) scale *= - mvPosition.z;
386
+
387
+ vec2 alignedPosition = ( position.xy - ( center - vec2( 0.5 ) ) ) * scale * size;
388
+ vec2 rotatedPosition;
389
+ rotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;
390
+ rotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;
391
+ mvPosition.xy += rotatedPosition;
392
+
393
+ gl_Position = projectionMatrix * mvPosition;
394
+ }
395
+ ` : undefined,
396
+ fragmentShader:
397
+ /* glsl */
398
+ `
399
+ void main() {
400
+ gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
401
+ }
402
+ `
403
+ }), [transform]);
282
404
  return /*#__PURE__*/React.createElement("group", _extends({}, props, {
283
405
  ref: group
284
- }));
406
+ }), occlude && !isRayCastOcclusion && /*#__PURE__*/React.createElement("mesh", {
407
+ castShadow: castShadow,
408
+ receiveShadow: receiveShadow,
409
+ ref: occlusionMeshRef
410
+ }, geometry || /*#__PURE__*/React.createElement("planeGeometry", null), material || /*#__PURE__*/React.createElement("shaderMaterial", {
411
+ side: DoubleSide,
412
+ vertexShader: shaders.vertexShader,
413
+ fragmentShader: shaders.fragmentShader
414
+ })));
285
415
  });
286
416
 
287
417
  export { Html };