UNPKG

ocearo-ui

Version:

Ocean Robot UI: 3D visualization dashboard for signalk

38 lines (32 loc) 16.2 kB
(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,82897,60099,e=>{"use strict";let t,r;var n=e.i(31067),i=e.i(71645),o=e.i(15080),a=e.i(71753),s=e.i(90072);let l=i.forwardRef(({envMap:e,resolution:t=256,frames:r=1/0,makeDefault:l,children:c,...u},d)=>{let f=(0,o.useThree)(({set:e})=>e),h=(0,o.useThree)(({camera:e})=>e),m=(0,o.useThree)(({size:e})=>e),p=i.useRef(null);i.useImperativeHandle(d,()=>p.current,[]);let T=i.useRef(null),M=function(e,t,r){let n=(0,o.useThree)(e=>e.size),a=(0,o.useThree)(e=>e.viewport),l="number"==typeof e?e:n.width*a.dpr,c=n.height*a.dpr,u=("number"==typeof e?void 0:e)||{},{samples:d=0,depth:f,...h}=u,m=null!=f?f:u.depthBuffer,p=i.useMemo(()=>{let e=new s.WebGLRenderTarget(l,c,{minFilter:s.LinearFilter,magFilter:s.LinearFilter,type:s.HalfFloatType,...h});return m&&(e.depthTexture=new s.DepthTexture(l,c,s.FloatType)),e.samples=d,e},[]);return i.useLayoutEffect(()=>{p.setSize(l,c),d&&(p.samples=d)},[d,p,l,c]),i.useEffect(()=>()=>p.dispose(),[]),p}(t);i.useLayoutEffect(()=>{u.manual||(p.current.aspect=m.width/m.height)},[m,u]),i.useLayoutEffect(()=>{p.current.updateProjectionMatrix()});let x=0,E=null,g="function"==typeof c;return(0,a.useFrame)(t=>{g&&(r===1/0||x<r)&&(T.current.visible=!1,t.gl.setRenderTarget(M),E=t.scene.background,e&&(t.scene.background=e),t.gl.render(t.scene,p.current),t.scene.background=E,t.gl.setRenderTarget(null),T.current.visible=!0,x++)}),i.useLayoutEffect(()=>{if(l)return f(()=>({camera:p.current})),()=>f(()=>({camera:h}))},[p,l,f]),i.createElement(i.Fragment,null,i.createElement("perspectiveCamera",(0,n.default)({ref:p},u),!g&&c),i.createElement("group",{ref:T},g&&c(M.texture)))});e.s(["PerspectiveCamera",()=>l],82897);var c=e.i(88014);let u=new s.Vector3,d=new s.Vector3,f=new s.Vector3,h=new s.Vector2;function m(e,t,r){let n=u.setFromMatrixPosition(e.matrixWorld);n.project(t);let i=r.width/2,o=r.height/2;return[n.x*i+i,-(n.y*o)+o]}let p=e=>1e-10>Math.abs(e)?0:e;function T(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}let M=(t=[1,-1,1,1,1,-1,1,1,1,-1,1,1,1,-1,1,1],e=>T(e,t)),x=(r=e=>[1/e,1/e,1/e,1,-1/e,-1/e,-1/e,-1,1/e,1/e,1/e,1,1,1,1,1],(e,t)=>T(e,r(t),"translate(-50%,-50%)")),E=i.forwardRef(({children:e,eps:t=.001,style:r,className:l,prepend:T,center:E,fullscreen:g,portal:y,distanceFactor:R,sprite:v=!1,transform:I=!1,occlude:P,onOcclude:L,castShadow:b,receiveShadow:A,material:w,geometry:O,zIndexRange:S=[0x1000037,0],calculatePosition:C=m,as:_="div",wrapperClass:j,pointerEvents:U="auto",...F},V)=>{let{gl:N,camera:W,scene:z,size:B,raycaster:D,events:H,viewport:G}=(0,o.useThree)(),[$]=i.useState(()=>document.createElement(_)),k=i.useRef(null),Y=i.useRef(null),K=i.useRef(0),X=i.useRef([0,0]),q=i.useRef(null),Z=i.useRef(null),J=(null==y?void 0:y.current)||H.connected||N.domElement.parentNode,Q=i.useRef(null),ee=i.useRef(!1),et=i.useMemo(()=>{var e;return P&&"blending"!==P||Array.isArray(P)&&P.length&&(e=P[0])&&"object"==typeof e&&"current"in e},[P]);i.useLayoutEffect(()=>{let e=N.domElement;P&&"blending"===P?(e.style.zIndex=`${Math.floor(S[0]/2)}`,e.style.position="absolute",e.style.pointerEvents="none"):(e.style.zIndex=null,e.style.position=null,e.style.pointerEvents=null)},[P]),i.useLayoutEffect(()=>{if(Y.current){let e=k.current=c.createRoot($);if(z.updateMatrixWorld(),I)$.style.cssText="position:absolute;top:0;left:0;pointer-events:none;overflow:hidden;";else{let e=C(Y.current,W,B);$.style.cssText=`position:absolute;top:0;left:0;transform:translate3d(${e[0]}px,${e[1]}px,0);transform-origin:0 0;`}return J&&(T?J.prepend($):J.appendChild($)),()=>{J&&J.removeChild($),e.unmount()}}},[J,I]),i.useLayoutEffect(()=>{j&&($.className=j)},[j]);let er=i.useMemo(()=>I?{position:"absolute",top:0,left:0,width:B.width,height:B.height,transformStyle:"preserve-3d",pointerEvents:"none"}:{position:"absolute",transform:E?"translate3d(-50%,-50%,0)":"none",...g&&{top:-B.height/2,left:-B.width/2,width:B.width,height:B.height},...r},[r,E,g,B,I]),en=i.useMemo(()=>({position:"absolute",pointerEvents:U}),[U]);i.useLayoutEffect(()=>{var t,n;ee.current=!1,I?null==(t=k.current)||t.render(i.createElement("div",{ref:q,style:er},i.createElement("div",{ref:Z,style:en},i.createElement("div",{ref:V,className:l,style:r,children:e})))):null==(n=k.current)||n.render(i.createElement("div",{ref:V,style:er,className:l,children:e}))});let ei=i.useRef(!0);(0,a.useFrame)(e=>{if(Y.current){W.updateMatrixWorld(),Y.current.updateWorldMatrix(!0,!1);let e=I?X.current:C(Y.current,W,B);if(I||Math.abs(K.current-W.zoom)>t||Math.abs(X.current[0]-e[0])>t||Math.abs(X.current[1]-e[1])>t){var r;let t,n,i,o,a=(r=Y.current,t=u.setFromMatrixPosition(r.matrixWorld),n=d.setFromMatrixPosition(W.matrixWorld),i=t.sub(n),o=W.getWorldDirection(f),i.angleTo(o)>Math.PI/2),l=!1;et&&(Array.isArray(P)?l=P.map(e=>e.current):"blending"!==P&&(l=[z]));let c=ei.current;l?ei.current=function(e,t,r,n){let i=u.setFromMatrixPosition(e.matrixWorld),o=i.clone();o.project(t),h.set(o.x,o.y),r.setFromCamera(h,t);let a=r.intersectObjects(n,!0);if(a.length){let e=a[0].distance;return i.distanceTo(r.ray.origin)<e}return!0}(Y.current,W,D,l)&&!a:ei.current=!a,c!==ei.current&&(L?L(!ei.current):$.style.display=ei.current?"block":"none");let m=Math.floor(S[0]/2),T=P?et?[S[0],m]:[m-1,0]:S;if($.style.zIndex=`${function(e,t,r){if(t instanceof s.PerspectiveCamera||t instanceof s.OrthographicCamera){let n=u.setFromMatrixPosition(e.matrixWorld),i=d.setFromMatrixPosition(t.matrixWorld),o=n.distanceTo(i),a=(r[1]-r[0])/(t.far-t.near),s=r[1]-a*t.far;return Math.round(a*o+s)}}(Y.current,W,T)}`,I){let[e,t]=[B.width/2,B.height/2],r=W.projectionMatrix.elements[5]*t,{isOrthographicCamera:n,top:i,left:o,bottom:a,right:s}=W,l=M(W.matrixWorldInverse),c=n?`scale(${r})translate(${p(-(s+o)/2)}px,${p((i+a)/2)}px)`:`translateZ(${r}px)`,u=Y.current.matrixWorld;v&&((u=W.matrixWorldInverse.clone().transpose().copyPosition(u).scale(Y.current.scale)).elements[3]=u.elements[7]=u.elements[11]=0,u.elements[15]=1),$.style.width=B.width+"px",$.style.height=B.height+"px",$.style.perspective=n?"":`${r}px`,q.current&&Z.current&&(q.current.style.transform=`${c}${l}translate(${e}px,${t}px)`,Z.current.style.transform=x(u,1/((R||10)/400)))}else{let t=void 0===R?1:function(e,t){if(t instanceof s.OrthographicCamera)return t.zoom;if(!(t instanceof s.PerspectiveCamera))return 1;{let r=u.setFromMatrixPosition(e.matrixWorld),n=d.setFromMatrixPosition(t.matrixWorld);return 1/(2*Math.tan(t.fov*Math.PI/180/2)*r.distanceTo(n))}}(Y.current,W)*R;$.style.transform=`translate3d(${e[0]}px,${e[1]}px,0) scale(${t})`}X.current=e,K.current=W.zoom}}if(!et&&Q.current&&!ee.current)if(I){if(q.current){let e=q.current.children[0];if(null!=e&&e.clientWidth&&null!=e&&e.clientHeight){let{isOrthographicCamera:t}=W;if(t||O)F.scale&&(Array.isArray(F.scale)?F.scale instanceof s.Vector3?Q.current.scale.copy(F.scale.clone().divideScalar(1)):Q.current.scale.set(1/F.scale[0],1/F.scale[1],1/F.scale[2]):Q.current.scale.setScalar(1/F.scale));else{let t=(R||10)/400,r=e.clientWidth*t,n=e.clientHeight*t;Q.current.scale.set(r,n,1)}ee.current=!0}}}else{let t=$.children[0];if(null!=t&&t.clientWidth&&null!=t&&t.clientHeight){let e=1/G.factor,r=t.clientWidth*e,n=t.clientHeight*e;Q.current.scale.set(r,n,1),ee.current=!0}Q.current.lookAt(e.camera.position)}});let eo=i.useMemo(()=>({vertexShader:I?void 0:` /* This shader is from the THREE's SpriteMaterial. We need to turn the backing plane into a Sprite (make it always face the camera) if "transfrom" is false. */ #include <common> void main() { vec2 center = vec2(0., 1.); float rotation = 0.0; // This is somewhat arbitrary, but it seems to work well // Need to figure out how to derive this dynamically if it even matters float size = 0.03; vec4 mvPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 ); vec2 scale; scale.x = length( vec3( modelMatrix[ 0 ].x, modelMatrix[ 0 ].y, modelMatrix[ 0 ].z ) ); scale.y = length( vec3( modelMatrix[ 1 ].x, modelMatrix[ 1 ].y, modelMatrix[ 1 ].z ) ); bool isPerspective = isPerspectiveMatrix( projectionMatrix ); if ( isPerspective ) scale *= - mvPosition.z; vec2 alignedPosition = ( position.xy - ( center - vec2( 0.5 ) ) ) * scale * size; vec2 rotatedPosition; rotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y; rotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y; mvPosition.xy += rotatedPosition; gl_Position = projectionMatrix * mvPosition; } `,fragmentShader:` void main() { gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0); } `}),[I]);return i.createElement("group",(0,n.default)({},F,{ref:Y}),P&&!et&&i.createElement("mesh",{castShadow:b,receiveShadow:A,ref:Q},O||i.createElement("planeGeometry",null),w||i.createElement("shaderMaterial",{side:s.DoubleSide,vertexShader:eo.vertexShader,fragmentShader:eo.fragmentShader})))});e.s(["Html",()=>E],60099)},35235,e=>{"use strict";var t=e.i(43476),r=e.i(71645),n=e.i(30297),i=e.i(82897),o=e.i(60099),a=e.i(43257),s=e.i(66326),l=e.i(67561),c=e.i(46991),u=e.i(85709),d=e.i(84226),f=e.i(90072);let h={MOBILE_TEMPLATE:{COLOR:l.oYellow,WIDTH_FACTOR:.8,LENGTH_FACTOR:2.5,MAX_LENGTH_MULTIPLIER:3.5,CURVATURE_SENSITIVITY:{RUDDER:1.5,WIND:.25,CURRENT:.3,LEEWAY:.15,DRIFT:.1}},NEUTRAL_TEMPLATE:{COLOR:l.oBlue,WIDTH_FACTOR:.7,LENGTH_FACTOR:.9},ANTICOLLISION_TEMPLATE:{COLOR:l.oRed,WIDTH_FACTOR:1.5,LENGTH_FACTOR:.8}},m=({rudderAngle:e=0,sog:n=5,boatWidth:i=2,windSpeed:o=0,windDirection:a=0,currentSpeed:s=0,currentDirection:l=0,leewayAngle:c=0,driftFactor:u=0,maxCurvePoints:d=50})=>{let m=(0,r.useRef)(),p=(0,r.useRef)(),T=(0,r.useRef)(),M=(0,r.useCallback)(()=>{let e=f.MathUtils.degToRad(a),t=f.MathUtils.degToRad(c),r=Math.cos(e+t)*o*h.MOBILE_TEMPLATE.CURVATURE_SENSITIVITY.WIND,n=Math.sin(e+t)*o*h.MOBILE_TEMPLATE.CURVATURE_SENSITIVITY.WIND,i=f.MathUtils.degToRad(l),d=Math.cos(i)*s*h.MOBILE_TEMPLATE.CURVATURE_SENSITIVITY.CURRENT,m=Math.sin(i)*s*h.MOBILE_TEMPLATE.CURVATURE_SENSITIVITY.CURRENT;return{x:(r+d)*(1+u*h.MOBILE_TEMPLATE.CURVATURE_SENSITIVITY.DRIFT),z:(n+m)*(1+u*h.MOBILE_TEMPLATE.CURVATURE_SENSITIVITY.DRIFT)}},[o,a,s,l,c,u]),x=(0,r.useCallback)(()=>{let t=i*h.MOBILE_TEMPLATE.MAX_LENGTH_MULTIPLIER,r=Math.min(2*i*h.MOBILE_TEMPLATE.LENGTH_FACTOR,t),n=[],o=1.5*M().x;if(.1>Math.abs(e)){let e=.5*o,t=Math.max(i/Math.tan(f.MathUtils.degToRad(5+Math.abs(e))),.5*i),a=r/t,s=new f.Vector2(e>0?t:-t,0),l=e>0?Math.PI:0;for(let r=0;r<=d;r++){let i=l+r/d*(e>0?a:-a),o=s.x+t*Math.cos(i),c=s.y+t*Math.sin(i);n.push(new f.Vector3(o,0,c))}}else{let t=f.MathUtils.clamp(1.2*Math.abs(e)+o,0,85),a=i/Math.tan(f.MathUtils.degToRad(t*h.MOBILE_TEMPLATE.CURVATURE_SENSITIVITY.RUDDER)),s=f.MathUtils.clamp(r/a,0,1.25*Math.PI);if(e>0){let e=new f.Vector2(a,0),t=Math.PI;for(let r=0;r<=d;r++){let i=r/d,o=f.MathUtils.lerp(t,t+s,i),l=e.x+a*Math.cos(o),c=e.y+a*Math.sin(o);n.push(new f.Vector3(l,0,c))}}else{let e=new f.Vector2(-a,0);for(let t=0;t<=d;t++){let r=t/d,i=f.MathUtils.lerp(0,0-s,r),o=e.x+a*Math.cos(i),l=e.y+a*Math.sin(i);n.push(new f.Vector3(o,0,l))}}}let a=n.map((e,t)=>{let r;(r=0===t?n[1].clone().sub(e):e.clone().sub(n[t-1])).normalize();let o=new f.Vector3(-r.z,0,r.x),a=i/1.8;return{left:e.clone().add(o.multiplyScalar(a)),right:e.clone().sub(o.multiplyScalar(a))}});return[...a.map(e=>e.left),a[a.length-1].right,...a.reverse().map(e=>e.right)]},[i,e,d,M]),E=(0,r.useCallback)(e=>{if("MOBILE_TEMPLATE"===e)return x();let t=h[e],r=2*i*t.LENGTH_FACTOR,n=i*t.WIDTH_FACTOR,o=[],a=Math.floor(d/4);for(let e=0;e<=a;e++){let t=e/a;o.push(new f.Vector3(-n/2,0,-r*t))}o.push(new f.Vector3(n/2,0,-r));for(let e=a;e>=0;e--){let t=e/a;o.push(new f.Vector3(n/2,0,-r*t))}return o},[i,d,x]);return(0,r.useEffect)(()=>{m.current&&p.current&&T.current&&(m.current.geometry.setFromPoints(E("MOBILE_TEMPLATE")),p.current.geometry.setFromPoints(E("NEUTRAL_TEMPLATE")),T.current.geometry.setFromPoints(E("ANTICOLLISION_TEMPLATE")))},[E]),(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)("line",{ref:m,children:[(0,t.jsx)("bufferGeometry",{}),(0,t.jsx)("lineBasicMaterial",{color:h.MOBILE_TEMPLATE.COLOR,linewidth:3,transparent:!0,opacity:.8})]}),(0,t.jsxs)("line",{ref:p,children:[(0,t.jsx)("bufferGeometry",{}),(0,t.jsx)("lineBasicMaterial",{color:h.NEUTRAL_TEMPLATE.COLOR,linewidth:2,transparent:!0,opacity:.4})]}),(0,t.jsxs)("line",{ref:T,children:[(0,t.jsx)("bufferGeometry",{}),(0,t.jsx)("lineBasicMaterial",{color:h.ANTICOLLISION_TEMPLATE.COLOR,linewidth:4,transparent:!0,opacity:.6})]})]})};var p=e.i(57384),T=e.i(16196);let M=.5,x=({position:e,rotation:r,speed:n,color:i,fontSize:o=M,textPosition:a=[0,.8,0],arrowSize:s=1})=>{let{nightMode:c}=(0,l.useOcearoContext)(),u=i||(c?oNight:"#ffffff");return(0,t.jsxs)("group",{position:e,rotation:r,children:[(0,t.jsx)(T.Text,{characters:"0123456789.",color:u,fontSize:o*s,position:a,font:"fonts/Roboto-Bold.ttf",anchorX:"center",anchorY:"middle",fillOpacity:.9,children:n.toFixed(1)}),(0,t.jsxs)("mesh",{children:[(0,t.jsx)("shapeGeometry",{args:[new f.Shape([new f.Vector2(0,0),new f.Vector2(.4*s,.3*s),new f.Vector2(0,-.6*s),new f.Vector2(-.4*s,.3*s),new f.Vector2(0,0)])]}),(0,t.jsx)("meshBasicMaterial",{color:u,side:f.DoubleSide,transparent:!0,opacity:.8})]})]})};x.propTypes={position:p.default.arrayOf(p.default.number),rotation:p.default.arrayOf(p.default.number),speed:p.default.number.isRequired,color:p.default.string,fontSize:p.default.number,textPosition:p.default.arrayOf(p.default.number),arrowSize:p.default.number},x.defaultProps={position:[0,0,0],rotation:[0,0,0],color:null,fontSize:M,textPosition:[0,.8,0],arrowSize:1};let E=({outerRadius:e})=>{let n=(0,u.useSignalKPath)("environment.current"),i=(0,r.useMemo)(()=>n||{setTrue:0,drift:0},[n]),o=(0,r.useMemo)(()=>{let t=i.setTrue||0;return[(e+.7)*Math.cos(t),0,-(e+.7)*Math.sin(t)]},[e,i.setTrue]);return!i.drift||i.drift<=0?null:(0,t.jsx)("group",{children:(0,t.jsx)(x,{position:o,rotation:[-Math.PI/2,0,-(Math.PI/2-(i.setTrue||0))],speed:i.drift,color:l.oGreen,arrowSize:1.2})})};E.propTypes={outerRadius:p.default.number.isRequired},e.s(["default",0,({onUpdateInfoPanel:e})=>{let{nightMode:f}=(0,l.useOcearoContext)(),h=(0,r.useRef)(),p=(0,r.useMemo)(()=>["steering.rudderAngle","navigation.speedOverGround","environment.wind.angleApparent","environment.wind.speedApparent","environment.current"],[]),T=(0,u.useSignalKPaths)(p),M=T["steering.rudderAngle"]||0,x=T["navigation.speedOverGround"]||0,g=T["environment.wind.angleApparent"]||0,y=(0,r.useMemo)(()=>(0,c.convertWindSpeed)(T["environment.wind.speedApparent"])||0,[T]),R=(0,r.useMemo)(()=>T["environment.current"]||{setTrue:0,drift:0},[T]);return(0,t.jsxs)(r.Suspense,{fallback:(0,t.jsx)(o.Html,{center:!0,children:"Loading..."}),children:[(0,t.jsx)(i.PerspectiveCamera,{makeDefault:!0,fov:60,near:1,far:1e3,position:[0,1,10]}),(0,t.jsx)(n.OrbitControls,{enableZoom:!0,enableRotate:!0,maxPolarAngle:Math.PI/2,minPolarAngle:Math.PI/4}),(0,t.jsx)(a.Environment,{files:"./assets/ocearo_env.hdr",background:!1,intensity:.6}),(0,t.jsx)("ambientLight",{intensity:.2}),(0,t.jsx)("directionalLight",{position:[15,30,20],intensity:1.2,castShadow:!1,color:f?"#b0d8ff":"#ffffff"}),(0,t.jsx)("spotLight",{position:[0,50,100],intensity:.8,angle:.6,penumbra:1,color:f?"#4080ff":"#ffffff"}),(0,t.jsx)("pointLight",{position:[-10,10,-10],intensity:.5}),(0,t.jsxs)("group",{position:[0,-3,0],children:[(0,t.jsx)(s.default,{position:[0,0,.7],scale:[.5,.5,.5],ref:h,showSail:!1,onUpdateInfoPanel:e}),(0,t.jsx)(d.default,{outerRadius:5}),(0,t.jsx)(E,{outerRadius:5}),(0,t.jsx)("group",{position:[0,0,-5],children:(0,t.jsx)(m,{rudderAngle:M,sog:x,windSpeed:y,windDirection:g,currentSpeed:R.drift,currentDirection:R.setTrue,boatWidth:2,leewayAngle:Math.min(Math.sin(Math.abs(g*Math.PI/180))*y*.02,10),driftFactor:x<.1?0:Math.min(R.drift/x,1),maxCurvePoints:100})})]})]})}],35235)},27404,e=>{e.n(e.i(35235))}]);