@csi-foxbyte/cityjson-to-3d-tiles
Version:
A Node.js library that converts CityJSON files into Cesium 3D Tiles—complete with automatic texture atlas packing, Basis compression, three LOD levels, and customizable threading.
2 lines • 2.6 kB
JavaScript
import y from'sharp';import {Canvas}from'skia-canvas';function I(a,t,l,s){for(let m=0;m<s;m++){const g=m*l*4;for(let c=0;c<l;c++){const n=g+c*4;if(a[n+3]!==0){t[n]=a[n],t[n+1]=a[n+1],t[n+2]=a[n+2],t[n+3]=a[n+3];continue}const r=g+Math.max(0,c-1)*4,e=g+Math.min(l-1,c+1)*4;let i=0,o=[0,0,0,0];a[r+3]!==0&&(i++,o[0]+=a[r],o[1]+=a[r+1],o[2]+=a[r+2],o[3]+=a[r+3]),a[e+3]!==0&&(i++,o[0]+=a[e],o[1]+=a[e+1],o[2]+=a[e+2],o[3]+=a[e+3]),i!==0&&(t[n]=o[0]/i,t[n+1]=o[1]/i,t[n+2]=o[2]/i,t[n+3]=o[3]/i);}}}function T(a,t,l,s){for(let m=0;m<l;m++){const g=m*4;for(let c=0;c<s;c++){const n=c*l*4+g;if(a[n+3]!==0){t[n]=a[n],t[n+1]=a[n+1],t[n+2]=a[n+2],t[n+3]=a[n+3];continue}const r=g+Math.max(0,c-1)*l*4,e=g+Math.min(s-1,c+1)*l*4;let i=0,o=[0,0,0,0];a[r+3]!==0&&(i++,o[0]+=a[r],o[1]+=a[r+1],o[2]+=a[r+2],o[3]+=a[r+3]),a[e+3]!==0&&(i++,o[0]+=a[e],o[1]+=a[e+1],o[2]+=a[e+2],o[3]+=a[e+3]),i!==0&&(t[n]=o[0]/i,t[n+1]=o[1]/i,t[n+2]=o[2]/i,t[n+3]=o[3]/i);}}}function U(a,t,l,s,m,g=0){const n=new Canvas(a,t).getContext("2d");if(n.fillStyle="white",n.strokeStyle="white",n.lineWidth=g,m)for(let e=0;e<m.length;){const i=m[e++];n.beginPath(),n.moveTo(s[i]*a,s[i+1]*t);const o=m[e++];n.lineTo(s[o]*a,s[o+1]*t);const x=m[e++];n.lineTo(s[x]*a,s[x+1]*t),n.closePath(),n.fill(),n.stroke();}else for(let e=0;e<s.length;)n.beginPath(),n.moveTo(s[e++]*a,s[e++]*t),n.lineTo(s[e++]*a,s[e++]*t),n.lineTo(s[e++]*a,s[e++]*t),n.closePath(),n.fill(),n.stroke();const r=n.getImageData(0,0,a,t).data;for(let e=0;e<r.length;e++)l[e]=Math.max(r[e],l[e]);}function b(a,t){for(let l=0;l<t.length;l+=4)t[l+3]===0&&(a[l]=0,a[l+1]=0,a[l+2]=0,a[l+3]=0);}async function D(a){const t=a.getRoot(),l=new Map;for(const s of t.listMeshes())for(const m of s.listPrimitives()){const g=m.getMaterial();if(!g)continue;const c=g.getBaseColorTexture();if(!c)continue;const n=c.getImage();if(!n)continue;const r=m.getIndices()?.getArray()??void 0,e=m.getAttribute("TEXCOORD_0")?.getArray();if(!e)continue;const i=y(n,{limitInputPixels:false}),{width:o,height:x}=await i.metadata();!o||!x||(l.has(c)||l.set(c,new Uint8ClampedArray(o*x*4)),U(o,x,l.get(c),e,r,4));}for(const[s,m]of l.entries()){const g=s.getImage(),c=y(g,{limitInputPixels:false}),{width:n,height:r}=await c.metadata();if(!n||!r)continue;const e=(await c.raw().toArray())[0];b(e,m);const i=new Uint8Array(e);for(let o=16;o<0;o++)I(e,i,n,r),T(i,e,n,r);s.setImage(await y(e,{raw:{width:n,height:r,channels:4},limitInputPixels:false}).toFormat("png").toBuffer()),s.setMimeType("image/png");}}export{D as dilateTextures};//# sourceMappingURL=dilateTexture.js.map
//# sourceMappingURL=dilateTexture.js.map