@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 • 3.32 kB
JavaScript
import {Logger,Document}from'@gltf-transform/core';import {mergeDocuments,dedup,flatten,weld,join,unpartition,simplify,draco,prune}from'@gltf-transform/functions';import {MeshoptSimplifier}from'meshoptimizer';import X from'proj4';import {Box3,Vector3,Matrix4}from'three';import {assignFeatureIdToTexCoord2}from'../functions/assignFeatureIdToTexCoord2.js';import {assignFeatureIds}from'../functions/assignFeaturesIds.js';import {compressBasisUniversal}from'../functions/compressBasisUniversal.js';import {getTextures}from'../functions/getTextures.js';import {mergeTextures}from'../functions/mergeTextures.js';import {disposeDocument}from'../functions/disposeDocument.js';Logger.DEFAULT_INSTANCE=new Logger(Logger.Verbosity.SILENT);const P="+proj=longlat +datum=WGS84 +no_defs +type=crs",W="+proj=geocent +datum=WGS84 +units=m +no_defs +type=crs",E=X(W,P);async function v(i,a,f){const u=await i.all(`SELECT doc, isInstanced, transformationMatrix, refId FROM data WHERE name IN (${a.map(()=>"?").join(", ")})`,a),d=[];for(const r of u){if(!r)throw new Error(`No CityObject found with name "${name}"`);let n;if(r.isInstanced?n=(await i.get("SELECT doc FROM instancedData WHERE id = ?",[r.refId])).doc:n=r.doc,!n)throw new Error(`CityObject with name "${name}" has no associated document!`);const e=await f.readBinary(new Uint8Array(n));if(r.isInstanced){const o=new Matrix4().fromArray(r.transformationMatrix.split("@").map(s=>parseFloat(s)));e.getRoot().listScenes()[0].listChildren()[0].setMatrix(o.toArray());}d.push(e);}return d}function z(i){return i?a=>{const[f,u,d]=E.inverse([a.data.minX,a.data.minY,a.data.minHeight]),[r,n,e]=E.inverse([a.data.maxX,a.data.maxY,a.data.maxHeight]),o=new Box3(new Vector3(f,u,d),new Vector3(r,n,e)),s=new Vector3;return o.getSize(s),s.x*s.y*s.z>i}:()=>true}async function rt(i,a,f,u,d,r){if(i.length===0)return null;const n=new Box3;let e=null;try{i.forEach(t=>{n.expandByPoint(new Vector3(t.data.minX,t.data.minY,t.data.minHeight)),n.expandByPoint(new Vector3(t.data.maxX,t.data.maxY,t.data.maxHeight));});const o=i.filter(z(d)),s=await v(a,o.map(t=>t.data.name),f);if(o.length===0)return {localBBox:n,document:new Document};e=s[0],await getTextures(e,a),assignFeatureIdToTexCoord2(e,0);for(let t=1;t<o.length;t++){const c=o[t];n.union(new Box3(new Vector3(c.data.minX,c.data.minY,c.data.minHeight),new Vector3(c.data.maxX,c.data.maxY,c.data.maxHeight)));const p=s[t];await getTextures(p,a),assignFeatureIdToTexCoord2(p,t);const D=mergeDocuments(e,p),I=e.getRoot().listScenes()[0],l=D.get(p.getRoot().listScenes()[0]),h=e.createNode().setName("SceneB");for(const B of l.listChildren())h.addChild(B);I.addChild(h),l.dispose(),disposeDocument(p);}return await mergeTextures(e,r),await e.transform(dedup(),flatten(),weld({}),join({}),unpartition(),simplify({simplifier:MeshoptSimplifier,ratio:0,error:.001}),draco({})),await compressBasisUniversal(e),await assignFeatureIds(e,o.map(t=>t.data.name),o.map(t=>t.data.attributes)),e.getRoot().listMaterials().forEach(t=>{if(t.getBaseColorTexture()===null){t.setAlphaMode("OPAQUE");return}t.setAlphaMode(u?"BLEND":"OPAQUE");}),await e.transform(prune()),{document:e,localBBox:n}}catch(o){throw e&&disposeDocument(e),o}}export{rt as generateDocument};//# sourceMappingURL=generateDocument.js.map
//# sourceMappingURL=generateDocument.js.map