UNPKG

@arcgis/core

Version:

ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API

3 lines (2 loc) 4.12 kB
/* COPYRIGHT Esri - https://js.arcgis.com/5.0.8/LICENSE.txt */ import e from"../../../core/Logger.js";import{equals as t,add as r,scale as o}from"../../../core/libs/gl-matrix-2/math/vec3.js";import{create as n}from"../../../core/libs/gl-matrix-2/factories/vec3f64.js";import i from"../MeshComponent.js";import l from"../MeshVertexAttributes.js";import{addMeshMaterialCloneContext as s,addMeshTextureCloneContext as a,getMeshMaterialCloneContext as c}from"./meshCloneUtils.js";import{convertVertexSpace as u}from"./vertexSpaceConversion.js";const f=()=>e.getLogger("esri.geometry.support.triangleMeshMerge");function m(e,t){if(0===e.length)return f().error("merge()","Must specify one more geometries to merge"),null;const r=e[0].spatialReference;for(const s of e){if(!s.spatialReference.equals(r))return f().error("merge()","Geometries must all be in the same spatial reference"),null;if(!s.loaded)return f().error("merge()","Geometries must all be loaded before merging"),null}const o=p(e);if(null==o)return null;const n=w(e),i=[],l={position:0,uv:0,normal:0,tangent:0,color:0},m=s(a()),g=c(m);for(const s of e){const e=o.rebake?u(s,o.vertexSpace,{allowBufferReuse:!0}):s.vertexAttributes;if(!e)return f().error("merge()","Failed to convert vertex space due to projection errors"),null;if(t&&t.reuseMaterials&&s.components)for(const t of s.components)t.material&&g?.materialMap?.set(t.material,t.material);h(s,l,m,i),x("position",e,n,l,0),x("normal",e,n,l,0),x("tangent",e,n,l,0),x("uv",s.vertexAttributes,n,l,0),x("color",s.vertexAttributes,n,l,255)}return{vertexAttributes:n,components:i,vertexSpace:o.vertexSpace,transform:o.rebake?null:o.transform,spatialReference:r}}function p(e){let i=null,l=null,s=!0,a=!0,c=null;const u=n();let m=0;for(const o of e){const{vertexSpace:e,transform:n}=o;if(null==l){l=e;const t=l.origin;t&&(c=t)}if(l.type!==e.type)return f().error("merge()",`Inconsistent mesh vertex space for provided geometries. One was ${l.type} while another is ${e.type}. Unable to merge geometries.`),null;null==i||null!=n&&n.equals(i)||(s=!1),null!=n&&null==i&&(i=n);const p=e.origin;p&&(c&&!t(p,c)&&(a=!1),m++,r(u,u,p))}if(null==l)throw new Error;const p=l.clone();if(null==p.origin)return{rebake:!1,vertexSpace:p};if(a&&s)return{rebake:!1,vertexSpace:p,transform:i?.clone()};const g=o(u,u,1/m);return p.origin=g,{rebake:!0,vertexSpace:p}}function g(e,t){return t.normal>0&&!e.vertexAttributes.normal}function v(e,t,r){g(e,t)&&"source"===r.shading&&(r.shading="flat")}function h(e,t,r,o){if(e.components)for(const n of e.components){const i=n.clone(r),l=t.position/3;if(i.faces)for(let e=0;e<i.faces.length;e++)i.faces[e]+=l;else{i.faces=new Uint32Array(e.vertexAttributes.position.length/3);for(let e=0;e<i.faces.length;e++)i.faces[e]=e+l}v(e,t,i),o.push(i)}else if(e.vertexAttributes&&e.vertexAttributes.position){const r=e.vertexAttributes.position.length/3,n=new Uint32Array(r),l=t.position/3;for(let e=0;e<r;e++)n[e]=e+l;const s=new i({faces:n});v(e,t,s),o.push(s)}}function x(e,t,r,o,n){if(!t)return;const i=t.position;if(!i)return;const l=t[e],s=r[e];if(null==l){let t=o[e];const r=y[e];if(null!=s){for(let e=0;e<i.length;e+=3)for(let o=0;o<r;o++)s[t++]=n;o[e]=t}}else null!=s&&null!=l&&(b(l,0,s,o[e],l.length),o[e]+=l.length)}function b(e,t,r,o,n){for(let i=0;i<n;i++)r[o++]=e[t++];return r}function A(e){let t=!1,r=!1,o=!1,n=!1;for(const i of e){const e=i.vertexAttributes;if(e?.position&&(e.uv&&(t=!0),e.normal&&(r=!0),e.tangent&&(n=!0),e.color&&(o=!0),r&&t&&o&&n))break}return{normal:r,uv:t,color:o,tangent:n}}function w(e){let t=0,r=0,o=0,n=0,i=0;const s=A(e);for(const l of e){const e=l.vertexAttributes;e?.position&&(t+=e.position.length,s.uv&&(r+=e.position.length/y.position*y.uv),s.normal&&(o+=e.position.length/y.position*y.normal),s.color&&(n+=e.position.length/y.position*y.color),s.tangent&&(i+=e.position.length/y.position*y.tangent))}return new l({position:new Float64Array(t),uv:r?new Float32Array(r):null,normal:o?new Float32Array(o):null,tangent:i?new Float32Array(i):null,color:n?new Uint8Array(n):null})}const y={position:3,normal:3,tangent:4,uv:2,color:4};export{m as merge};