@arcgis/core
Version:
ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API
6 lines (5 loc) • 4.08 kB
JavaScript
/*
All material copyright ESRI, All Rights Reserved, unless otherwise specified.
See https://js.arcgis.com/4.32/esri/copyright.txt for details.
*/
import e from"../../../core/Logger.js";import{I as t,g as n,h as r}from"../../../chunks/vec32.js";import{create as o}from"../../../core/libs/gl-matrix-2/factories/vec3f64.js";import i from"../MeshComponent.js";import{MeshVertexAttributes as s}from"../MeshVertexAttributes.js";import{convertVertexSpace as l}from"./vertexSpaceConversion.js";const a=()=>e.getLogger("esri.geometry.support.triangleMeshMerge");function c(e,t){if(0===e.length)return a().error("merge()","Must specify one more geometries to merge"),null;const n=e[0].spatialReference;for(const l of e){if(!l.spatialReference.equals(n))return a().error("merge()","Geometries must all be in the same spatial reference"),null;if(!l.loaded)return a().error("merge()","Geometries must all be loaded before merging"),null}const r=u(e);if(null==r)return null;const o=x(e),i=[],s={position:0,uv:0,normal:0,tangent:0,color:0},c=new Map,f=new Map;for(const u of e){const e=r.rebake?l(u,r.vertexSpace,{allowBufferReuse:!0}):u.vertexAttributes;if(!e)return a().error("merge()","Failed to convert vertex space due to projection errors"),null;if(t&&t.reuseMaterials&&u.components)for(const t of u.components)t.material&&c.set(t.material,t.material);m(u,s,c,f,i),g("position",e,o,s,0),g("normal",e,o,s,0),g("tangent",e,o,s,0),g("uv",u.vertexAttributes,o,s,0),g("color",u.vertexAttributes,o,s,255)}return{vertexAttributes:o,components:i,vertexSpace:r.vertexSpace,transform:r.rebake?null:r.transform,spatialReference:n}}function u(e){let i=null,s=null,l=!0,c=!0,u=null;const f=o();let p=0;for(const r of e){const{vertexSpace:e,transform:o}=r;if(null==s){s=e;const t=s.origin;t&&(u=t)}if(s.type!==e.type)return a().error("merge()",`Inconsistent mesh vertex space for provided geometries. One was ${s.type} while another is ${e.type}. Unable to merge geometries.`),null;null==i||null!=o&&o.equals(i)||(l=!1),null!=o&&null==i&&(i=o);const m=e.origin;m&&(u&&!t(m,u)&&(c=!1),p++,n(f,f,m))}if(null==s)throw new Error;const m=s.clone();if(null==m.origin)return{rebake:!1,vertexSpace:m};if(c&&l)return{rebake:!1,vertexSpace:m,transform:i?.clone()};const g=r(f,f,1/p);return m.origin=g,{rebake:!0,vertexSpace:m}}function f(e,t){return t.normal>0&&!e.vertexAttributes.normal}function p(e,t,n){f(e,t)&&"source"===n.shading&&(n.shading="flat")}function m(e,t,n,r,o){if(e.components)for(const i of e.components){const s=i.cloneWithDeduplication(n,r),l=t.position/3;if(s.faces)for(let e=0;e<s.faces.length;e++)s.faces[e]+=l;else{s.faces=new Uint32Array(e.vertexAttributes.position.length/3);for(let e=0;e<s.faces.length;e++)s.faces[e]=e+l}p(e,t,s),o.push(s)}else if(e.vertexAttributes&&e.vertexAttributes.position){const n=e.vertexAttributes.position.length/3,r=new Uint32Array(n),s=t.position/3;for(let e=0;e<n;e++)r[e]=e+s;const l=new i({faces:r});p(e,t,l),o.push(l)}}function g(e,t,n,r,o){if(!t)return;const i=t.position;if(!i)return;const s=t[e],l=n[e];if(null==s){let t=r[e];const n=b[e];if(null!=l){for(let e=0;e<i.length;e+=3)for(let r=0;r<n;r++)l[t++]=o;r[e]=t}}else null!=l&&null!=s&&(v(s,0,l,r[e],s.length),r[e]+=s.length)}function v(e,t,n,r,o){for(let i=0;i<o;i++)n[r++]=e[t++];return n}function h(e){let t=!1,n=!1,r=!1,o=!1;for(const i of e){const e=i.vertexAttributes;if(e?.position&&(e.uv&&(t=!0),e.normal&&(n=!0),e.tangent&&(o=!0),e.color&&(r=!0),n&&t&&r&&o))break}return{normal:n,uv:t,color:r,tangent:o}}function x(e){let t=0,n=0,r=0,o=0,i=0;const l=h(e);for(const s of e){const e=s.vertexAttributes;e?.position&&(t+=e.position.length,l.uv&&(n+=e.position.length/b.position*b.uv),l.normal&&(r+=e.position.length/b.position*b.normal),l.color&&(o+=e.position.length/b.position*b.color),l.tangent&&(i+=e.position.length/b.position*b.tangent))}return new s({position:new Float64Array(t),uv:n?new Float32Array(n):null,normal:r?new Float32Array(r):null,tangent:i?new Float32Array(i):null,color:o?new Uint8Array(o):null})}const b={position:3,normal:3,tangent:4,uv:2,color:4};export{c as merge};