UNPKG

@animech-public/playcanvas

Version:
2 lines (1 loc) 6.66 kB
import{GSplatData as t}from"../../scene/gsplat/gsplat-data.js";import{GSplatCompressedData as e}from"../../scene/gsplat/gsplat-compressed-data.js";import{GSplatResource as a}from"./gsplat-resource.js";const r=new Uint8Array([112,108,121,10]),n=new Uint8Array([10,101,110,100,95,104,101,97,100,101,114,10]),i=new Map([["char",Int8Array],["uchar",Uint8Array],["short",Int16Array],["ushort",Uint16Array],["int",Int32Array],["uint",Uint32Array],["float",Float32Array],["double",Float64Array]]);class s{constructor(t){this.reader=void 0,this.data=void 0,this.view=void 0,this.head=0,this.tail=0,this.reader=t}async read(){const{value:t,done:e}=await this.reader.read();if(e)throw new Error("Stream finished before end of header");this.push(t)}push(t){if(this.data){const e=this.tail-this.head,a=e+t.length;if(this.data.length>=a)this.head>0?(this.data.copyWithin(0,this.head,this.tail),this.data.set(t,e),this.head=0,this.tail=a):(this.data.set(t,this.tail),this.tail+=t.length);else{const r=new Uint8Array(a);this.head>0||this.tail<this.data.length?r.set(this.data.subarray(this.head,this.tail),0):r.set(this.data,0),r.set(t,e),this.data=r,this.view=new DataView(this.data.buffer),this.head=0,this.tail=a}}else this.data=t,this.view=new DataView(this.data.buffer),this.tail=t.length}compact(){this.head>0&&(this.data.copyWithin(0,this.head,this.tail),this.tail-=this.head,this.head=0)}get remaining(){return this.tail-this.head}getInt8(){const t=this.view.getInt8(this.head);return this.head++,t}getUint8(){const t=this.view.getUint8(this.head);return this.head++,t}getInt16(){const t=this.view.getInt16(this.head,!0);return this.head+=2,t}getUint16(){const t=this.view.getUint16(this.head,!0);return this.head+=2,t}getInt32(){const t=this.view.getInt32(this.head,!0);return this.head+=4,t}getUint32(){const t=this.view.getUint32(this.head,!0);return this.head+=4,t}getFloat32(){const t=this.view.getFloat32(this.head,!0);return this.head+=4,t}getFloat64(){const t=this.view.getFloat64(this.head,!0);return this.head+=8,t}}const h=async(a,h=null)=>{const o=(t,e)=>{const a=t.length-e.length;let r,n;for(r=0;r<=a;++r){for(n=0;n<e.length&&t[r+n]===e[n];++n);if(n===e.length)return r}return-1},l=(t,e)=>{if(t.length<e.length)return!1;for(let a=0;a<e.length;++a)if(t[a]!==e[a])return!1;return!0},c=new s(a);let d;for(;;){if(await c.read(),c.tail>=r.length&&!l(c.data,r))throw new Error("Invalid ply header");if(d=o(c.data,n),-1!==d)break}const p=new TextDecoder("ascii").decode(c.data.subarray(0,d)).split("\n").filter((t=>!t.startsWith("comment "))),{elements:u,format:g}=(t=>{const e=[];let a;for(let r=1;r<t.length;++r){const n=t[r].split(" ");switch(n[0]){case"format":a=n[1];break;case"element":e.push({name:n[1],count:parseInt(n[2],10),properties:[]});break;case"property":if(!i.has(n[1]))throw new Error(`Unrecognized property data type '${n[1]}' in ply header`);e[e.length-1].properties.push({type:n[1],name:n[2],storage:null,byteSize:i.get(n[1]).BYTES_PER_ELEMENT});break;default:throw new Error(`Unrecognized header value '${n[0]}' in ply header`)}}return{elements:e,format:a}})(p);if("binary_little_endian"!==g&&"binary_big_endian"!==g)throw new Error("Unsupported ply format");return c.head=d+n.length,c.compact(),(t=>{const e=["min_x","min_y","min_z","max_x","max_y","max_z","min_scale_x","min_scale_y","min_scale_z","max_scale_x","max_scale_y","max_scale_z","min_r","min_g","min_b","max_r","max_g","max_b"],a=["packed_position","packed_rotation","packed_scale","packed_color"],r=new Array(45).fill("").map(((t,e)=>`f_rest_${e}`)),n=()=>"chunk"===t[0].name&&t[0].properties.every(((t,a)=>t.name===e[a]&&"float"===t.type))&&"vertex"===t[1].name&&t[1].properties.every(((t,e)=>t.name===a[e]&&"uint"===t.type));return 2===t.length&&n()||3===t.length&&n()&&"sh"===t[2].name&&-1!==[9,24,45].indexOf(t[2].properties.length)&&t[2].properties.every(((t,e)=>t.name===r[e]&&"uchar"===t.type))})(u)?await(async(t,a)=>{const r=new e,n=a[0].count,i=a[0].properties.length,s=a[1].count;r.numSplats=s,r.chunkData=new Float32Array(n*i),r.vertexData=new Uint32Array(4*(t=>{const e=Math.ceil(Math.sqrt(t));return e*Math.ceil(t/e)})(s));const h=async(e,a)=>{const r=new Uint8Array(e);let n=0;for(;n<a;){for(;0===t.remaining;)await t.read();const e=Math.min(a-n,t.remaining),i=t.data;for(let a=0;a<e;++a)r[n++]=i[t.head++]}};return await h(r.chunkData.buffer,n*i*4),await h(r.vertexData.buffer,4*s*4),3===a.length&&(r.shData=new Uint8Array(a[2].count*a[2].properties.length),await h(r.shData.buffer,r.shData.byteLength)),r})(c,u):(u.forEach((t=>{t.properties.forEach((e=>{const a=i.get(e.type);if(a){const r=!h||h(e.name)?new a(t.count):null;e.storage=r}}))})),(t=>1===t.length&&"vertex"===t[0].name&&t[0].properties.every((t=>"float"===t.type)))(u)?await(async(e,a)=>{const r=a[0],n=r.properties,i=n.length,s=n.map((t=>t.storage)),h=n.reduce(((t,e)=>t+e.byteSize),0);let o,l=0;const c=()=>{var t;const a=e.data.buffer;(null==(t=o)?void 0:t.buffer)!==a&&(o=new Float32Array(a,0,a.byteLength/4))};for(c();l<r.count;){for(;e.remaining<h;)await e.read(),c();const t=Math.min(r.count-l,Math.floor(e.remaining/h));for(let e=0;e<i;++e){const a=s[e];for(let r=0;r<t;++r)a[r+l]=o[r*i+e]}l+=t,e.head+=t*h}return new t(a)})(c,u):await(async(e,a)=>{for(let t=0;t<a.length;++t){const r=a[t],n=r.properties.reduce(((t,e)=>t+e.byteSize),0),i=r.properties.map((t=>{if(!t.storage)return e=>{e.head+=t.byteSize};switch(t.type){case"char":return(e,a)=>{t.storage[a]=e.getInt8()};case"uchar":return(e,a)=>{t.storage[a]=e.getUint8()};case"short":return(e,a)=>{t.storage[a]=e.getInt16()};case"ushort":return(e,a)=>{t.storage[a]=e.getUint16()};case"int":return(e,a)=>{t.storage[a]=e.getInt32()};case"uint":return(e,a)=>{t.storage[a]=e.getUint32()};case"float":return(e,a)=>{t.storage[a]=e.getFloat32()};case"double":return(e,a)=>{t.storage[a]=e.getFloat64()};default:throw new Error(`Unsupported property data type '${t.type}' in ply header`)}}));let s=0;for(;s<r.count;){for(;e.remaining<n;)await e.read();const t=Math.min(r.count-s,Math.floor(e.remaining/n));for(let a=0;a<t;++a){for(let t=0;t<r.properties.length;++t)i[t](e,s);s++}}}return new t(a)})(c,u))},o=t=>!0;class l{constructor(t,e,a){this.device=void 0,this.assets=void 0,this.maxRetries=void 0,this.device=t,this.assets=e,this.maxRetries=a}async load(t,e,r){const n=await fetch(t.load);var i;n&&n.body?h(n.body.getReader(),null!=(i=r.data.elementFilter)?i:o).then((t=>{var n;t.isCompressed||(null==(n=r.data.reorder)||n)&&t.reorderData();const i=new a(this.device,t.isCompressed&&r.data.decompress?t.decompress():t);e(null,i)})).catch((t=>{e(t,null)})):e("Error loading resource",null)}open(t,e){return e}}export{l as PlyParser};