@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.22 kB
JavaScript
import B from'sharp';import {MaxRectsPacker}from'maxrects-packer/dist/maxrects-packer.js';async function H(c,f=1,M=16384,R=false,X=true){const U=c.getRoot(),Y=c.createMaterial("base"),T=[];for(const e of U.listScenes())e.traverse(h=>{const u=h.getMesh();if(!u)return;const A=u.listPrimitives();for(const m of A){const s=m.getMaterial();if(!s)continue;const r=s.getBaseColorTexture();if(!r)continue;const o=r.getMimeType(),a=r.getImage(),n=r.getSize();if(!a||!o||!n)continue;const l=Buffer.from(a);T.push({width:n[0],height:n[1],imageData:l,imageName:s.getName(),primitive:m,id:crypto.randomUUID()}),m.setMaterial(Y);}});const g=new Map;T.forEach(e=>{g.has(e.imageName)?g.get(e.imageName).primitives.push(e.primitive):g.set(e.imageName,{height:e.height,width:e.width,imageData:e.imageData,primitives:[e.primitive]});});const x=new MaxRectsPacker(M/f,M/f,2,{allowRotation:false,pot:X,smart:true,square:false,border:0,logic:1});x.addArray(Array.from(g.values()));let P=[];for(const e of x.bins){const h=[];for(const a of e.rects)h.push({input:a.rot?await B(a.imageData).rotate(90).toBuffer():a.imageData,top:a.y,left:a.x});const u=await B({create:{width:e.width,height:e.height,background:{r:128,g:128,b:128,alpha:0},channels:4},limitInputPixels:false}).composite(h).toFormat("png").toBuffer(),m=await B(u,{limitInputPixels:false}).resize({width:e.width*f,height:e.height*f,background:{alpha:1,r:128,g:128,b:128}}).toFormat("png").toBuffer(),s=crypto.randomUUID(),r=c.createMaterial(s),o=c.createTexture("base");o.setMimeType("image/png"),o.setImage(m),R&&P.push({texture:o,name:s}),r.setBaseColorTexture(o),r.setDoubleSided(true);for(const{primitives:a,x:n,y:l,width:N,height:I,rot:C}of e.rects)for(const k of a){const p=k.getAttribute("TEXCOORD_0");if(!p)continue;const i=p.getArray();if(i){if(C){const d=I/e.height,v=N/e.width,w=l/e.height,b=n/e.width;for(let t=0;t<i.length;t+=2){const D=i[t+1]*d+w,y=i[t]*v+b;i[t]=D,i[t+1]=y;}}else {const d=N/e.width,v=I/e.height,w=n/e.width,b=l/e.height;for(let t=0;t<i.length;t+=2){const D=i[t]*d+w,y=i[t+1]*v+b;i[t]=D,i[t+1]=y;}}p.setArray(i),k.setMaterial(r);}}}return P}export{H as mergeTextures};//# sourceMappingURL=mergeTextures.js.map
//# sourceMappingURL=mergeTextures.js.map