@arcgis/core
Version:
ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API
6 lines (5 loc) • 4.25 kB
JavaScript
/*
All material copyright ESRI, All Rights Reserved, unless otherwise specified.
See https://js.arcgis.com/4.33/esri/copyright.txt for details.
*/
import e from"../../../core/Logger.js";import{clone as o}from"../../../core/libs/gl-matrix-2/factories/mat4f64.js";import{makeMaterialParameters as t,makeTextureSource as r}from"./LoaderResult.js";import{GLTFResource as s}from"./internal/Resource.js";import{PrimitiveType as a,TextureSamplingMode as n}from"../../webgl/enums.js";let i=0;async function l(t,r,n={},l=!0){const m=await s.load(t,r,n),T="gltf_"+i++,p={lods:[],materials:new Map,textures:new Map,meta:u(m)},f=!(!m.json.asset.extras||"symbolResource"!==m.json.asset.extras.ESRI_type),x=m.json.asset.extras?.ESRI_webstyleSymbol?.webstyle,g=new Map;await c(m,(async(t,r,s,i)=>{const u=g.get(s)??0;g.set(s,u+1);const c=void 0!==t.mode?t.mode:a.TRIANGLES,f=c===a.TRIANGLES||c===a.TRIANGLE_STRIP||c===a.TRIANGLE_FAN?c:null;if(null==f)return void e.getLogger("esri.views.3d.glTF").warn("[Unsupported Feature] Unsupported primitive mode ("+a[c]+"). Skipping primitive.");if(!m.hasPositions(t))return void e.getLogger("esri.views.3d.glTF").warn("Skipping primitive without POSITION vertex attribute.");const x=m.getPositionData(t,n),h=m.getMaterial(t,n,l),w=m.hasNormals(t)?m.getNormalData(t,n):null,v=m.hasTangents(t)?m.getTangentData(t,n):null,S=m.hasTextureCoordinates(t)?m.getTextureCoordinates(t,n):null,R=m.hasVertexColors(t)?m.getVertexColors(t,n):null,_=m.getIndexData(t,n),E={name:i,transform:o(r),attributes:{position:await x,normal:w?await w:null,texCoord0:S?await S:null,color:R?await R:null,tangent:v?await v:null},indices:await _,primitiveType:f,material:d(p,await h,T)};let I=null;null!=p.meta?.ESRI_lod&&"screenSpaceRadius"===p.meta.ESRI_lod.metric&&(I=p.meta.ESRI_lod.thresholds[s]),p.lods[s]=p.lods[s]||{parts:[],name:i,lodThreshold:I},p.lods[s].parts[u]=E}));for(const e of p.lods)e.parts=e.parts.filter((e=>!!e));const h=await m.getLoadedBuffersSize();return{model:p,meta:{isEsriSymbolResource:f,uri:m.uri,ESRI_webstyle:x},customMeta:{},cachedMemory:h}}function u(e){const o=e.json;let t=null;return o.nodes.forEach((e=>{const o=e.extras;null!=o&&(o.ESRI_proxyEllipsoid||o.ESRI_lod)&&(t=o)})),t}async function c(o,t){const r=o.json,s=r.scenes[r.scene||0].nodes,a=s.length>1,n=[];for(const e of s){const o=r.nodes[e];if(n.push(i(e,0)),m(o)&&!a){o.extensions.MSFT_lod.ids.forEach(((e,o)=>i(e,o+1)))}}async function i(s,a){const l=r.nodes[s],u=o.getNodeTransform(s);if(null!=l.weights&&e.getLogger("esri.views.3d.glTF").warn("[Unsupported Feature] Morph targets are not supported."),null!=l.mesh){const e=r.meshes[l.mesh];for(const o of e.primitives)n.push(t(o,u,a,e.name))}for(const e of l.children||[])n.push(i(e,a))}await Promise.all(n)}function m(e){return e.extensions?.MSFT_lod&&Array.isArray(e.extensions.MSFT_lod.ids)}function d(e,o,s){const a=o=>{const t=`${s}_tex_${o&&o.id}${o?.name?"_"+o.name:""}`;if(o&&!e.textures.has(t)){const s=r(o.data,{wrap:{s:o.wrapS,t:o.wrapT},mipmap:T.has(o.minFilter),noUnpackFlip:!0});e.textures.set(t,s)}return t},n=`${s}_mat_${o.id}_${o.name}`;if(!e.materials.has(n)){const r=t({color:[o.color[0],o.color[1],o.color[2]],opacity:o.color[3],alphaMode:o.alphaMode,alphaCutoff:o.alphaCutoff,doubleSided:o.doubleSided,colorMixMode:o.ESRI_externalColorMixMode,colorTexture:o.colorTexture?a(o.colorTexture):void 0,normalTexture:o.normalTexture?a(o.normalTexture):void 0,occlusionTexture:o.occlusionTexture?a(o.occlusionTexture):void 0,emissiveTexture:o.emissiveTexture?a(o.emissiveTexture):void 0,metallicRoughnessTexture:o.metallicRoughnessTexture?a(o.metallicRoughnessTexture):void 0,emissiveFactor:[o.emissiveFactor[0],o.emissiveFactor[1],o.emissiveFactor[2]],colorTextureTransform:o.colorTextureTransform,normalTextureTransform:o.normalTextureTransform,occlusionTextureTransform:o.occlusionTextureTransform,emissiveTextureTransform:o.emissiveTextureTransform,metallicRoughnessTextureTransform:o.metallicRoughnessTextureTransform,metallicFactor:o.metallicFactor,roughnessFactor:o.roughnessFactor,receiveShadows:o.receiveShadows,receiveAmbientOcclusion:o.receiveAmbientOcclusion});e.materials.set(n,r)}return n}const T=new Set([n.LINEAR_MIPMAP_LINEAR,n.LINEAR_MIPMAP_NEAREST]);export{l as loadGLTF};