Socket
Socket
Sign inDemoInstall

@gltf-transform/core

Package Overview
Dependencies
Maintainers
1
Versions
205
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@gltf-transform/core - npm Package Compare versions

Comparing version 0.8.4 to 0.9.0

2

dist/constants.d.ts

@@ -54,3 +54,3 @@ /**

/**
* Abstraction representing any one of the typed array constructors supported by glTF and JavaScript.
* Abstraction representing the typed array constructors supported by glTF and JavaScript.
* @hidden

@@ -57,0 +57,0 @@ */

export { Document, Transform } from './document';
export { JSONDocument } from './json-document';
export { Extension } from './extension';
export { Accessor, Animation, AnimationChannel, AnimationSampler, Buffer, Camera, ExtensionProperty, Property, Material, Mesh, Node, Primitive, PrimitiveTarget, Root, Scene, Skin, Texture, TextureInfo, COPY_IDENTITY } from './properties';
export { Accessor, Animation, AnimationChannel, AnimationSampler, Buffer, Camera, ExtensionProperty, Property, Material, Mesh, Node, Primitive, PrimitiveTarget, Root, Scene, Skin, Texture, TextureInfo, AttributeLink, IndexLink, COPY_IDENTITY } from './properties';
export { Graph, GraphChild, GraphChildList, Link } from './graph/';

@@ -5,0 +6,0 @@ export { NodeIO, WebIO, ReaderContext, WriterContext } from './io/';

@@ -1,2 +0,2 @@

import{fromRotationTranslationScale as t,getTranslation as s,getRotation as e,getScaling as i,multiply as r,determinant as n}from"gl-matrix/mat4";import{length as h}from"gl-matrix/vec3";const o="@glb.bin";var u;function c(t,s,e,i){var r,n=arguments.length,h=n<3?s:null===i?i=Object.getOwnPropertyDescriptor(s,e):i;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)h=Reflect.decorate(t,s,e,i);else for(var o=t.length-1;o>=0;o--)(r=t[o])&&(h=(n<3?r(h):n>3?r(s,e,h):r(s,e))||h);return n>3&&h&&Object.defineProperty(s,e,h),h}!function(t){t.ACCESSOR="Accessor",t.ANIMATION="Animation",t.ANIMATION_CHANNEL="AnimationChannel",t.ANIMATION_SAMPLER="AnimationSampler",t.BUFFER="Buffer",t.CAMERA="Camera",t.MATERIAL="Material",t.MESH="Mesh",t.PRIMITIVE="Primitive",t.PRIMITIVE_TARGET="PrimitiveTarget",t.NODE="Node",t.ROOT="Root",t.SCENE="Scene",t.SKIN="Skin",t.TEXTURE="Texture",t.TEXTURE_INFO="TextureInfo"}(u||(u={}));class a{constructor(t,s,e){if(this.t=t,this.s=s,this.i=e,this.h=!1,this.o=[],!s.canLink(e))throw new Error("Cannot link disconnected graphs/documents.")}getName(){return this.t}getParent(){return this.s}getChild(){return this.i}setChild(t){return this.i=t,this}dispose(){this.h||(this.h=!0,this.o.forEach(t=>t()),this.o.length=0)}onDispose(t){return this.o.push(t),this}isDisposed(){return this.h}}class l{constructor(){this.u=new Set,this.l=new Set,this.p=new Map,this.g=new Map,this.o={}}on(t,s){return this.o[t]=this.o[t]||[],this.o[t].push(s),this}emit(t,s){for(const e of this.o[t]||[])e(s);return this}getLinks(){return Array.from(this.l)}listParents(t){const s=this.g.get(t)||this.u;return Array.from(s).map(t=>t.getParent())}listChildren(t){const s=this.p.get(t)||this.u;return Array.from(s).map(t=>t.getChild())}disconnectChildren(t){return(this.p.get(t)||this.u).forEach(t=>t.dispose()),this}disconnectParents(t,s){let e=Array.from(this.g.get(t)||this.u);return s&&(e=e.filter(t=>s(t.getParent()))),e.forEach(t=>t.dispose()),this}swapChild(t,s,e){const i=this.p.get(t)||this.u;return Array.from(i).filter(t=>t.getChild()===s).forEach(t=>{this.g.get(s).delete(t),t.setChild(e),this.g.has(e)||this.g.set(e,new Set),this.g.get(e).add(t)}),this}link(t,s,e){if(!e)return null;const i=new a(t,s,e);return this.registerLink(i),i}registerLink(t){this.l.add(t);const s=t.getParent();this.p.has(s)||this.p.set(s,new Set),this.p.get(s).add(t);const e=t.getChild();return this.g.has(e)||this.g.set(e,new Set),this.g.get(e).add(t),t.onDispose(()=>this.unlink(t)),t}unlink(t){return this.l.delete(t),this.p.get(t.getParent()).delete(t),this.g.get(t.getChild()).delete(t),this}}function f(t,s){Object.defineProperty(t,s,{get:function(){return this["__"+s]},set:function(t){const e=this["__"+s];e&&!Array.isArray(e)&&e.dispose(),t&&!Array.isArray(t)&&t.onDispose(()=>{this["__"+s]=null}),this["__"+s]=t},enumerable:!0})}function d(t,s){}class p{static createBufferFromDataURI(t){if("undefined"==typeof Buffer){const s=atob(t.split(",")[1]),e=new Uint8Array(s.length);for(let t=0;t<s.length;t++)e[t]=s.charCodeAt(t);return e.buffer}{const s=t.split(",")[1],e=t.indexOf("base64")>=0;return this.trim(Buffer.from(s,e?"base64":"utf8"))}}static encodeText(t){return"undefined"!=typeof TextEncoder?(new TextEncoder).encode(t).buffer:this.trim(Buffer.from(t))}static decodeText(t){return"undefined"!=typeof TextDecoder?(new TextDecoder).decode(t):Buffer.from(t).toString("utf8")}static trim(t){const{byteOffset:s,byteLength:e}=t;return t.buffer.slice(s,s+e)}static concat(t){let s=0;for(const e of t)s+=e.byteLength;const e=new Uint8Array(s);let i=0;for(const s of t)e.set(new Uint8Array(s),i),i+=s.byteLength;return e.buffer}static pad(t,s=0){const e=this.padNumber(t.byteLength);if(e!==t.byteLength){const i=new Uint8Array(e);if(i.set(new Uint8Array(t)),0!==s)for(let r=t.byteLength;r<e;r++)i[r]=s;return i.buffer}return t}static padNumber(t){return 4*Math.ceil(t/4)}static equals(t,s){if(t===s)return!0;if(t.byteLength!==s.byteLength)return!1;const e=new DataView(t),i=new DataView(s);let r=t.byteLength;for(;r--;)if(e.getUint8(r)!==i.getUint8(r))return!1;return!0}}class g{static hexToFactor(t,s){return t=Math.floor(t),s[0]=(t>>16&255)/255,s[1]=(t>>8&255)/255,s[2]=(255&t)/255,this.convertSRGBToLinear(s,s)}static factorToHex(t){const s=[...t],[e,i,r]=this.convertLinearToSRGB(t,s);return 255*e<<16^255*i<<8^255*r<<0}static convertSRGBToLinear(t,s){for(let e=0;e<3;e++)s[e]=t[e]<.04045?.0773993808*t[e]:Math.pow(.9478672986*t[e]+.0521327014,2.4);return s}static convertLinearToSRGB(t,s){for(let e=0;e<3;e++)s[e]=t[e]<.0031308?12.92*t[e]:1.055*Math.pow(t[e],.41666)-.055;return s}}class w{static basename(t){const s=t.split(/[\\/]/).pop();return s.substr(0,s.lastIndexOf("."))}static extension(t){return 0!==t.indexOf("data:")?t.split(/[\\/]/).pop().split(/[.]/).pop():0===t.indexOf("data:image/png")?"png":0===t.indexOf("data:image/jpeg")?"jpeg":"bin"}}class m{static getSize(t,s){switch(s){case"image/png":return this.m(t);case"image/jpeg":return this.v(t);case"image/webp":return this.T(t);case"image/ktx2":return this.A(t);default:return null}}static getChannels(t,s){switch(s){case"image/png":return 4;case"image/jpeg":return 3;case"image/webp":case"image/ktx2":default:return 4}}static getMemSize(t,s){if("image/ktx2"===s){const s=new DataView(t);v(s);const e=s.getUint32(40,!0),i=80;let r=0;for(let t=0;t<e;t++)r+=y(s,i+3*t*8+16,!0)||y(s,i+3*t*8+8,!0);return r}const e=this.getSize(t,s),i=this.getChannels(t,s);return e?e[0]*e[1]*i:null}static v(t){let s,e,i=new DataView(t,4);for(;i.byteLength;){if(s=i.getUint16(0,!1),x(i,s),e=i.getUint8(s+1),192===e||193===e||194===e)return[i.getUint16(s+7,!1),i.getUint16(s+5,!1)];i=new DataView(t,i.byteOffset+s+2)}throw new TypeError("Invalid JPG, no size found")}static m(t){const s=new DataView(t);return"CgBI"===p.decodeText(t.slice(12,16))?[s.getUint32(32,!1),s.getUint32(36,!1)]:[s.getUint32(16,!1),s.getUint32(20,!1)]}static T(t){const s=p.decodeText(t.slice(0,4)),e=p.decodeText(t.slice(8,12));if("RIFF"!==s||"WEBP"!==e)return null;const i=new DataView(t);let r=12;for(;r<t.byteLength;){const s=p.decodeText(t.slice(r,r+4)),e=i.getUint32(r+4,!0);if("VP8 "===s)return[16383&i.getInt16(r+14,!0),16383&i.getInt16(r+16,!0)];if("VP8L"===s){const t=i.getUint8(r+9),s=i.getUint8(r+10),e=i.getUint8(r+11);return[1+((63&s)<<8|t),1+((15&i.getUint8(r+12))<<10|e<<2|(192&s)>>6)]}r+=8+e+e%2}return null}static A(t){v(new DataView(t));const s=new DataView(t);return[s.getUint32(20,!0),s.getUint32(24,!0)]}static mimeTypeToExtension(t){return"image/jpeg"===t?"jpg":t.split("/").pop()}static extensionToMimeType(t){return"jpg"===t?"image/jpeg":"image/"+t}}function v(t){const s=t.buffer.slice(t.byteOffset+1,t.byteOffset+7);if("KTX 20"!==p.decodeText(s))throw new TypeError("Corrupt KTX2.")}function x(t,s){if(s>t.byteLength)throw new TypeError("Corrupt JPG, exceeded buffer limits");if(255!==t.getUint8(s))throw new TypeError("Invalid JPG, marker table corrupted")}function y(t,s,e){const i=t.getUint32(s,e),r=t.getUint32(s+4,e);return e?i+2**32*r:2**32*i+r}class T{static identity(t){return t}static denormalize(t,s){switch(s){case 5126:return t;case 5123:return t/65535;case 5121:return t/255;case 5122:return Math.max(t/32767,-1);case 5120:return Math.max(t/127,-1)}}static normalize(t,s){switch(s){case 5126:return t;case 5123:return Math.round(65535*t);case 5121:return Math.round(255*t);case 5122:return Math.round(32767*t);case 5120:return Math.round(127*t)}}}class A{constructor(t){this.verbosity=t}debug(t){this.verbosity<=A.Verbosity.DEBUG&&console.debug(t)}info(t){this.verbosity<=A.Verbosity.INFO&&console.info(t)}warn(t){this.verbosity<=A.Verbosity.WARN&&console.warn(t)}error(t){this.verbosity<=A.Verbosity.ERROR&&console.error(t)}}A.Verbosity={SILENT:4,ERROR:3,WARN:2,INFO:1,DEBUG:0},A.DEFAULT_INSTANCE=new A(A.Verbosity.INFO);const b="23456789abdegjkmnpqrvwxyzABDEGJKMNPQRVWXYZ",E=new Set,M=function(){let t="";for(let s=0;s<6;s++)t+=b.charAt(Math.floor(Math.random()*b.length));return t},S=function(){for(let t=0;t<999;t++){const t=M();if(!E.has(t))return E.add(t),t}},I=t=>t;class R extends class{constructor(t){this.h=!1,this.graph=t}canLink(t){return this.graph===t.graph}isDisposed(){return this.h}dispose(){this.graph.disconnectChildren(this),this.graph.disconnectParents(this),this.h=!0}detach(){return this.graph.disconnectParents(this),this}swap(t,s){return this.graph.swapChild(this,t,s),this}addGraphChild(t,s){return t.push(s),s.onDispose(()=>{const e=t.filter(t=>t!==s);t.length=0;for(const s of e)t.push(s)}),this}removeGraphChild(t,s){return t.filter(t=>t.getChild()===s).forEach(t=>t.dispose()),this}clearGraphChildList(t){for(;t.length>0;)t[0].dispose();return this}listGraphParents(){return this.graph.listParents(this)}}{constructor(t,s=""){super(t),this.M={},this.t="",this.t=s}getName(){return this.t}setName(t){return this.t=t,this}getExtras(){return this.M}setExtras(t){return this.M=t,this}clone(){const t=new(0,this.constructor)(this.graph).copy(this,I);return this.graph.emit("clone",t),t}copy(t,s=I){return this.t=t.t,this.M=JSON.parse(JSON.stringify(t.M)),this}detach(){return this.graph.disconnectParents(this,t=>"Root"!==t.propertyType),this}listParents(){return this.listGraphParents()}}const C="Pass extension name (string) as lookup token, not a constructor.";class N extends R{constructor(){super(...arguments),this.extensions=[]}copy(t,s=I){return super.copy(t,s),this.clearGraphChildList(this.extensions),t.extensions.forEach(t=>{const e=t.getChild();this.setExtension(e.extensionName,s(e))}),this}getExtension(t){if("string"!=typeof t)throw new Error(C);const s=this.extensions.find(s=>s.getChild().extensionName===t);return s?s.getChild():null}setExtension(t,s){if("string"!=typeof t)throw new Error(C);const e=this.getExtension(t);return e&&this.removeGraphChild(this.extensions,e),s?(s.S(this),this.addGraphChild(this.extensions,this.graph.link(t,this,s))):this}listExtensions(){return this.extensions.map(t=>t.getChild())}}c([d],N.prototype,"extensions",void 0);class _ extends N{constructor(){super(...arguments),this.propertyType=u.ACCESSOR,this.I=null,this.R="SCALAR",this.C=null,this.N=!1,this._=T.identity,this.B=T.identity,this.buffer=null}copy(t,s=I){return super.copy(t,s),this.R=t.R,this.C=t.C,this.N=t.N,this._=t._,this.B=t.B,t.I&&(this.I=t.I.slice()),t.buffer&&this.setBuffer(s(t.buffer.getChild())),this}static getElementSize(t){switch(t){case"SCALAR":return 1;case"VEC2":return 2;case"VEC3":return 3;case"VEC4":case"MAT2":return 4;case"MAT3":return 9;case"MAT4":return 16;default:throw new Error("Unexpected type: "+t)}}static getComponentSize(t){switch(t){case 5120:case 5121:return 1;case 5122:case 5123:return 2;case 5125:case 5126:return 4;default:throw new Error("Unexpected component type: "+t)}}getMinNormalized(t){const s=this.getElementSize();this.getMin(t);for(let e=0;e<s;e++)t[e]=this.B(t[e]);return t}getMin(t){const s=this.getCount(),e=this.getElementSize();for(let s=0;s<e;s++)t[s]=Infinity;for(let i=0;i<s*e;i+=e)for(let s=0;s<e;s++){const e=this.I[i+s];Number.isFinite(e)&&(t[s]=Math.min(t[s],e))}return t}getMaxNormalized(t){const s=this.getElementSize();this.getMax(t);for(let e=0;e<s;e++)t[e]=this.B(t[e]);return t}getMax(t){const s=this.getCount(),e=this.getElementSize();for(let s=0;s<e;s++)t[s]=-Infinity;for(let i=0;i<s*e;i+=e)for(let s=0;s<e;s++){const e=this.I[i+s];Number.isFinite(e)&&(t[s]=Math.max(t[s],e))}return t}getCount(){return this.I.length/this.getElementSize()}getType(){return this.R}setType(t){return this.R=t,this}getElementSize(){return _.getElementSize(this.R)}getComponentSize(){return this.I.BYTES_PER_ELEMENT}getComponentType(){return this.C}getNormalized(){return this.N}setNormalized(t){return this.N=t,t?(this.B=t=>T.denormalize(t,this.C),this._=t=>T.normalize(t,this.C)):(this.B=T.identity,this._=T.identity),this}getScalar(t){const s=this.getElementSize();return this.B(this.I[t*s])}setScalar(t,s){return this.I[t*this.getElementSize()]=this._(s),this}getElement(t,s){const e=this.getElementSize();for(let i=0;i<e;i++)s[i]=this.B(this.I[t*e+i]);return s}setElement(t,s){const e=this.getElementSize();for(let i=0;i<e;i++)this.I[t*e+i]=this._(s[i]);return this}getBuffer(){return this.buffer?this.buffer.getChild():null}setBuffer(t){return this.buffer=this.graph.link("buffer",this,t),this}getArray(){return this.I}setArray(t){return this.C=function(t){switch(t.constructor){case Float32Array:return 5126;case Uint32Array:return 5125;case Uint16Array:return 5123;case Uint8Array:return 5121;case Int16Array:return 5122;case Int8Array:return 5120;default:throw new Error("Unknown accessor componentType.")}}(t),this.I=t,this}getByteLength(){return this.I.byteLength}}_.Type={SCALAR:"SCALAR",VEC2:"VEC2",VEC3:"VEC3",VEC4:"VEC4",MAT3:"MAT3",MAT4:"MAT4"},_.ComponentType={BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,UNSIGNED_INT:5125,FLOAT:5126},c([f],_.prototype,"buffer",void 0);class B extends N{constructor(){super(...arguments),this.propertyType=u.ANIMATION,this.channels=[],this.samplers=[]}copy(t,s=I){return super.copy(t,s),this.clearGraphChildList(this.channels),this.clearGraphChildList(this.samplers),t.channels.forEach(t=>this.addChannel(s(t.getChild()))),t.samplers.forEach(t=>this.addSampler(s(t.getChild()))),this}addChannel(t){const s=this.graph.link("channel",this,t);return this.addGraphChild(this.channels,s)}removeChannel(t){return this.removeGraphChild(this.channels,t)}listChannels(){return this.channels.map(t=>t.getChild())}addSampler(t){const s=this.graph.link("sampler",this,t);return this.addGraphChild(this.samplers,s)}removeSampler(t){return this.removeGraphChild(this.samplers,t)}listSamplers(){return this.samplers.map(t=>t.getChild())}}c([d],B.prototype,"channels",void 0),c([d],B.prototype,"samplers",void 0);class L extends R{constructor(){super(...arguments),this.propertyType=u.ANIMATION_CHANNEL,this.L=null,this.targetNode=null,this.sampler=null}copy(t,s=I){return super.copy(t,s),this.L=t.L,t.targetNode&&this.setTargetNode(s(t.targetNode.getChild())),t.sampler&&this.setSampler(s(t.sampler.getChild())),this}getTargetPath(){return this.L}setTargetPath(t){return this.L=t,this}getTargetNode(){return this.targetNode?this.targetNode.getChild():null}setTargetNode(t){return this.targetNode=this.graph.link("target.node",this,t),this}getSampler(){return this.sampler?this.sampler.getChild():null}setSampler(t){return this.sampler=this.graph.link("sampler",this,t),this}}c([f],L.prototype,"targetNode",void 0),c([f],L.prototype,"sampler",void 0);class O extends R{constructor(){super(...arguments),this.propertyType=u.ANIMATION_SAMPLER,this.O="LINEAR",this.input=null,this.output=null}copy(t,s=I){return super.copy(t,s),this.O=t.O,t.input&&this.setInput(s(t.input.getChild())),t.output&&this.setOutput(s(t.output.getChild())),this}getInterpolation(){return this.O}setInterpolation(t){return this.O=t,this}getInput(){return this.input?this.input.getChild():null}setInput(t){return this.input=this.graph.link("input",this,t),this}getOutput(){return this.output?this.output.getChild():null}setOutput(t){return this.output=this.graph.link("output",this,t),this}}c([f],O.prototype,"input",void 0),c([f],O.prototype,"output",void 0);class k extends N{constructor(){super(...arguments),this.propertyType=u.BUFFER}copy(t,s=I){return super.copy(t,s),this.k=t.k,this}getURI(){return this.k}setURI(t){return this.k=t,this}}class P extends N{constructor(){super(...arguments),this.propertyType=u.CAMERA,this.R="perspective"}copy(t,s=I){return super.copy(t,s),this.R=t.R,this.P=t.P,this.U=t.U,this.F=t.F,this.D=t.D,this.j=t.j,this.G=t.G,this}getType(){return this.R}setType(t){return this.R=t,this}getZNear(){return this.P}setZNear(t){return this.P=t,this}getZFar(){return this.U}setZFar(t){return this.U=t,this}getAspectRatio(){return this.F}setAspectRatio(t){return this.F=t,this}getYFov(){return this.D}setYFov(t){return this.D=t,this}getXMag(){return this.j}setXMag(t){return this.j=t,this}getYMag(){return this.G}setYMag(t){return this.G=t,this}}class U extends R{constructor(t,s){super(t),this.V=s,this.V.addExtensionProperty(this)}dispose(){this.V.removeExtensionProperty(this),super.dispose()}S(t){if(!this.parentTypes.includes(t.propertyType))throw new Error(`Parent "${t.propertyType}" invalid for child "${this.propertyType}".`)}}class F extends a{constructor(){super(...arguments),this.semantic=""}copy(t){return this.semantic=t.semantic,this}}class D extends a{copy(t){return this}}class j extends l{linkAttribute(t,s,e){if(!e)return null;const i=new F(t,s,e);return this.registerLink(i),i}linkIndex(t,s,e){if(!e)return null;const i=new D(t,s,e);return this.registerLink(i),i}}class G extends N{constructor(){super(...arguments),this.propertyType=u.TEXTURE_INFO,this.J=0,this.$=null,this.W=null,this.q=10497,this.H=10497}copy(t,s=I){return super.copy(t,s),this.J=t.J,this.$=t.$,this.W=t.W,this.q=t.q,this.H=t.H,this}getTexCoord(){return this.J}setTexCoord(t){return this.J=t,this}getMagFilter(){return this.$}setMagFilter(t){return this.$=t,this}getMinFilter(){return this.W}setMinFilter(t){return this.W=t,this}getWrapS(){return this.q}setWrapS(t){return this.q=t,this}getWrapT(){return this.H}setWrapT(t){return this.H=t,this}}G.TextureWrapMode={CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,REPEAT:10497},G.TextureMagFilter={NEAREST:9728,LINEAR:9729},G.TextureMinFilter={NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987};class z extends N{constructor(){super(...arguments),this.propertyType=u.MATERIAL,this.Y="OPAQUE",this.X=.5,this.K=!1,this.Z=[1,1,1,1],this.tt=[0,0,0],this.st=1,this.et=1,this.it=1,this.rt=1,this.baseColorTexture=null,this.baseColorTextureInfo=this.graph.link("baseColorTextureInfo",this,new G(this.graph)),this.emissiveTexture=null,this.emissiveTextureInfo=this.graph.link("emissiveTextureInfo",this,new G(this.graph)),this.normalTexture=null,this.normalTextureInfo=this.graph.link("normalTextureInfo",this,new G(this.graph)),this.occlusionTexture=null,this.occlusionTextureInfo=this.graph.link("occlusionTextureInfo",this,new G(this.graph)),this.metallicRoughnessTexture=null,this.metallicRoughnessTextureInfo=this.graph.link("metallicRoughnessTextureInfo",this,new G(this.graph))}copy(t,s=I){return super.copy(t,s),this.Y=t.Y,this.X=t.X,this.K=t.K,this.Z=[...t.Z],this.tt=[...t.tt],this.st=t.st,this.et=t.et,this.it=t.it,this.rt=t.rt,t.baseColorTexture&&(this.setBaseColorTexture(s(t.baseColorTexture.getChild())),this.getBaseColorTextureInfo().copy(s(t.baseColorTextureInfo.getChild()),s)),t.emissiveTexture&&(this.setEmissiveTexture(s(t.emissiveTexture.getChild())),this.getEmissiveTextureInfo().copy(s(t.emissiveTextureInfo.getChild()),s)),t.normalTexture&&(this.setNormalTexture(s(t.normalTexture.getChild())),this.getNormalTextureInfo().copy(s(t.normalTextureInfo.getChild()),s)),t.occlusionTexture&&(this.setOcclusionTexture(s(t.occlusionTexture.getChild())),this.getOcclusionTextureInfo().copy(s(t.occlusionTextureInfo.getChild()),s)),t.metallicRoughnessTexture&&(this.setMetallicRoughnessTexture(s(t.metallicRoughnessTexture.getChild())),this.getMetallicRoughnessTextureInfo().copy(s(t.metallicRoughnessTextureInfo.getChild()),s)),this}dispose(){this.baseColorTextureInfo.getChild().dispose(),this.emissiveTextureInfo.getChild().dispose(),this.normalTextureInfo.getChild().dispose(),this.occlusionTextureInfo.getChild().dispose(),this.metallicRoughnessTextureInfo.getChild().dispose(),super.dispose()}getDoubleSided(){return this.K}setDoubleSided(t){return this.K=t,this}getAlpha(){return this.Z[3]}setAlpha(t){return this.Z[3]=t,this}getAlphaMode(){return this.Y}setAlphaMode(t){return this.Y=t,this}getAlphaCutoff(){return this.X}setAlphaCutoff(t){return this.X=t,this}getBaseColorFactor(){return this.Z}setBaseColorFactor(t){return this.Z=t,this}getBaseColorHex(){return g.factorToHex(this.Z)}setBaseColorHex(t){return g.hexToFactor(t,this.Z),this}getBaseColorTexture(){return this.baseColorTexture?this.baseColorTexture.getChild():null}getBaseColorTextureInfo(){return this.baseColorTexture?this.baseColorTextureInfo.getChild():null}setBaseColorTexture(t){return this.baseColorTexture=this.graph.link("baseColorTexture",this,t),this}getEmissiveFactor(){return this.tt}setEmissiveFactor(t){return this.tt=t,this}getEmissiveHex(){return g.factorToHex(this.tt)}setEmissiveHex(t){return g.hexToFactor(t,this.tt),this}getEmissiveTexture(){return this.emissiveTexture?this.emissiveTexture.getChild():null}getEmissiveTextureInfo(){return this.emissiveTexture?this.emissiveTextureInfo.getChild():null}setEmissiveTexture(t){return this.emissiveTexture=this.graph.link("emissiveTexture",this,t),this}getNormalScale(){return this.st}setNormalScale(t){return this.st=t,this}getNormalTexture(){return this.normalTexture?this.normalTexture.getChild():null}getNormalTextureInfo(){return this.normalTexture?this.normalTextureInfo.getChild():null}setNormalTexture(t){return this.normalTexture=this.graph.link("normalTexture",this,t),this}getOcclusionStrength(){return this.et}setOcclusionStrength(t){return this.et=t,this}getOcclusionTexture(){return this.occlusionTexture?this.occlusionTexture.getChild():null}getOcclusionTextureInfo(){return this.occlusionTexture?this.occlusionTextureInfo.getChild():null}setOcclusionTexture(t){return this.occlusionTexture=this.graph.link("occlusionTexture",this,t),this}getRoughnessFactor(){return this.it}setRoughnessFactor(t){return this.it=t,this}getMetallicFactor(){return this.rt}setMetallicFactor(t){return this.rt=t,this}getMetallicRoughnessTexture(){return this.metallicRoughnessTexture?this.metallicRoughnessTexture.getChild():null}getMetallicRoughnessTextureInfo(){return this.metallicRoughnessTexture?this.metallicRoughnessTextureInfo.getChild():null}setMetallicRoughnessTexture(t){return this.metallicRoughnessTexture=this.graph.link("metallicRoughnessTexture",this,t),this}}c([f],z.prototype,"baseColorTexture",void 0),c([f],z.prototype,"baseColorTextureInfo",void 0),c([f],z.prototype,"emissiveTexture",void 0),c([f],z.prototype,"emissiveTextureInfo",void 0),c([f],z.prototype,"normalTexture",void 0),c([f],z.prototype,"normalTextureInfo",void 0),c([f],z.prototype,"occlusionTexture",void 0),c([f],z.prototype,"occlusionTextureInfo",void 0),c([f],z.prototype,"metallicRoughnessTexture",void 0),c([f],z.prototype,"metallicRoughnessTextureInfo",void 0);class V extends N{constructor(){super(...arguments),this.propertyType=u.MESH,this.nt=[],this.primitives=[]}copy(t,s=I){return super.copy(t,s),this.nt=[...t.nt],this.clearGraphChildList(this.primitives),t.primitives.forEach(t=>this.addPrimitive(s(t.getChild()))),this}addPrimitive(t){return this.addGraphChild(this.primitives,this.graph.link("primitive",this,t))}removePrimitive(t){return this.removeGraphChild(this.primitives,t)}listPrimitives(){return this.primitives.map(t=>t.getChild())}getWeights(){return this.nt}setWeights(t){return this.nt=t,this}}c([d],V.prototype,"primitives",void 0);class J extends N{constructor(){super(...arguments),this.propertyType=u.NODE,this.ht=[0,0,0],this.ot=[0,0,0,1],this.ut=[1,1,1],this.nt=[],this.s=null,this.camera=null,this.mesh=null,this.skin=null,this.children=[]}copy(t,s=I){return super.copy(t,s),this.ht=[...t.ht],this.ot=[...t.ot],this.ut=[...t.ut],this.nt=[...t.nt],t.camera&&this.setCamera(s(t.camera.getChild())),t.mesh&&this.setMesh(s(t.mesh.getChild())),t.skin&&this.setSkin(s(t.skin.getChild())),s!==I&&(this.clearGraphChildList(this.children),t.children.forEach(t=>this.addChild(s(t.getChild())))),this}getTranslation(){return this.ht}getRotation(){return this.ot}getScale(){return this.ut}setTranslation(t){return this.ht=t,this}setRotation(t){return this.ot=t,this}setScale(t){return this.ut=t,this}getMatrix(){return t([],this.ot,this.ht,this.ut)}getWorldTranslation(){return s([],this.getWorldMatrix())}getWorldRotation(){return e([],this.getWorldMatrix())}getWorldScale(){return i([],this.getWorldMatrix())}getWorldMatrix(){const t=[];for(let s=this;s instanceof J;s=s.s)t.push(s);let s;const e=t.pop().getMatrix();for(;s=t.pop();)r(e,e,s.getMatrix());return e}addChild(t){t.s&&t.s.removeChild(t);const s=this.graph.link("child",this,t);return this.addGraphChild(this.children,s),t.s=this,s.onDispose(()=>t.s=null),this}removeChild(t){return this.removeGraphChild(this.children,t)}listChildren(){return this.children.map(t=>t.getChild())}getParent(){return this.s}getMesh(){return this.mesh?this.mesh.getChild():null}setMesh(t){return this.mesh=this.graph.link("mesh",this,t),this}getCamera(){return this.camera?this.camera.getChild():null}setCamera(t){return this.camera=this.graph.link("camera",this,t),this}getSkin(){return this.skin?this.skin.getChild():null}setSkin(t){return this.skin=this.graph.link("skin",this,t),this}getWeights(){return this.nt}setWeights(t){return this.nt=t,this}traverse(t){t(this);for(const s of this.listChildren())s.traverse(t);return this}}c([f],J.prototype,"camera",void 0),c([f],J.prototype,"mesh",void 0),c([f],J.prototype,"skin",void 0),c([d],J.prototype,"children",void 0);class $ extends N{constructor(){super(...arguments),this.propertyType=u.PRIMITIVE,this.ct=4,this.material=null,this.indices=null,this.attributes=[],this.targets=[]}copy(t,s=I){return super.copy(t,s),this.ct=t.ct,t.indices&&this.setIndices(s(t.indices.getChild())),t.material&&this.setMaterial(s(t.material.getChild())),this.clearGraphChildList(this.attributes),t.listSemantics().forEach(e=>{this.setAttribute(e,s(t.getAttribute(e)))}),this.clearGraphChildList(this.targets),t.targets.forEach(t=>this.addTarget(s(t.getChild()))),this}getIndices(){return this.indices?this.indices.getChild():null}setIndices(t){return this.indices=this.graph.linkIndex("index",this,t),this}getAttribute(t){const s=this.attributes.find(s=>s.semantic===t);return s?s.getChild():null}setAttribute(t,s){const e=this.getAttribute(t);if(e&&this.removeGraphChild(this.attributes,e),!s)return this;const i=this.graph.linkAttribute(t.toLowerCase(),this,s);return i.semantic=t,this.addGraphChild(this.attributes,i)}listAttributes(){return this.attributes.map(t=>t.getChild())}listSemantics(){return this.attributes.map(t=>t.semantic)}getMaterial(){return this.material?this.material.getChild():null}setMaterial(t){return this.material=this.graph.link("material",this,t),this}getMode(){return this.ct}setMode(t){return this.ct=t,this}listTargets(){return this.targets.map(t=>t.getChild())}addTarget(t){return this.addGraphChild(this.targets,this.graph.link("target",this,t)),this}removeTarget(t){return this.removeGraphChild(this.targets,t)}}c([f],$.prototype,"material",void 0),c([f],$.prototype,"indices",void 0),c([d],$.prototype,"attributes",void 0),c([d],$.prototype,"targets",void 0);class W extends R{constructor(){super(...arguments),this.propertyType=u.PRIMITIVE_TARGET,this.attributes=[]}copy(t,s=I){return super.copy(t,s),this.clearGraphChildList(this.attributes),t.listSemantics().forEach(e=>{this.setAttribute(e,s(t.getAttribute(e)))}),this}getAttribute(t){const s=this.attributes.find(s=>s.semantic===t);return s?s.getChild():null}setAttribute(t,s){const e=this.getAttribute(t);if(e&&this.removeGraphChild(this.attributes,e),!s)return this;const i=this.graph.linkAttribute(t.toLowerCase(),this,s);return i.semantic=t,this.addGraphChild(this.attributes,i)}listAttributes(){return this.attributes.map(t=>t.getChild())}listSemantics(){return this.attributes.map(t=>t.semantic)}}c([d],W.prototype,"attributes",void 0);class q extends N{constructor(){super(...arguments),this.propertyType=u.SCENE,this.children=[]}copy(t,s=I){return super.copy(t,s),s!==I&&(this.clearGraphChildList(this.children),t.children.forEach(t=>this.addChild(s(t.getChild())))),this}addChild(t){t.s&&t.s.removeChild(t);const s=this.graph.link("child",this,t);return this.addGraphChild(this.children,s),t.s=this,s.onDispose(()=>t.s=null),this}removeChild(t){return this.removeGraphChild(this.children,t)}listChildren(){return this.children.map(t=>t.getChild())}traverse(t){for(const s of this.listChildren())s.traverse(t);return this}}c([d],q.prototype,"children",void 0);class H extends N{constructor(){super(...arguments),this.propertyType=u.SKIN,this.skeleton=null,this.inverseBindMatrices=null,this.joints=[]}copy(t,s=I){return super.copy(t,s),t.skeleton&&this.setSkeleton(s(t.skeleton.getChild())),t.inverseBindMatrices&&this.setInverseBindMatrices(s(t.inverseBindMatrices.getChild())),this.clearGraphChildList(this.joints),t.joints.forEach(t=>this.addJoint(s(t.getChild()))),this}getSkeleton(){return this.skeleton?this.skeleton.getChild():null}setSkeleton(t){return this.skeleton=this.graph.link("skeleton",this,t),this}getInverseBindMatrices(){return this.inverseBindMatrices?this.inverseBindMatrices.getChild():null}setInverseBindMatrices(t){return this.inverseBindMatrices=this.graph.link("inverseBindMatrices",this,t),this}addJoint(t){const s=this.graph.link("joint",this,t);return this.addGraphChild(this.joints,s)}removeJoint(t){return this.removeGraphChild(this.joints,t)}listJoints(){return this.joints.map(t=>t.getChild())}}c([f],H.prototype,"skeleton",void 0),c([f],H.prototype,"inverseBindMatrices",void 0),c([d],H.prototype,"joints",void 0);class Y extends N{constructor(){super(...arguments),this.propertyType=u.TEXTURE,this.at=null,this.lt="",this.k=""}copy(t,s=I){return super.copy(t,s),this.lt=t.lt,this.k=t.k,t.at&&(this.at=t.at.slice(0)),this}getMimeType(){return this.lt||m.extensionToMimeType(w.extension(this.k))}setMimeType(t){return this.lt=t,this}getURI(){return this.k}setURI(t){return this.k=t,this.lt=m.extensionToMimeType(w.extension(t)),this}getImage(){return this.at}setImage(t){return this.at=t,this}getSize(){return m.getSize(this.at,this.getMimeType())}}class X extends R{constructor(t){super(t),this.propertyType=u.ROOT,this.ft={generator:"glTF-Transform v0.8.4",version:"2.0"},this.dt=new Set,this.accessors=[],this.animations=[],this.buffers=[],this.cameras=[],this.materials=[],this.meshes=[],this.nodes=[],this.scenes=[],this.skins=[],this.textures=[],t.on("clone",t=>this.pt(t))}clone(){throw new Error("Root cannot be cloned.")}copy(t,s=I){if(super.copy(t,s),s===I)throw new Error("Root cannot be copied.");return Object.assign(this.ft,t.ft),t.accessors.forEach(t=>this.gt(s(t.getChild()))),t.animations.forEach(t=>this.wt(s(t.getChild()))),t.buffers.forEach(t=>this.vt(s(t.getChild()))),t.cameras.forEach(t=>this.xt(s(t.getChild()))),t.materials.forEach(t=>this.yt(s(t.getChild()))),t.meshes.forEach(t=>this.Tt(s(t.getChild()))),t.nodes.forEach(t=>this.At(s(t.getChild()))),t.scenes.forEach(t=>this.bt(s(t.getChild()))),t.skins.forEach(t=>this.Et(s(t.getChild()))),t.textures.forEach(t=>this.Mt(s(t.getChild()))),this}pt(t){return t instanceof q?this.bt(t):t instanceof J?this.At(t):t instanceof P?this.xt(t):t instanceof H?this.Et(t):t instanceof V?this.Tt(t):t instanceof z?this.yt(t):t instanceof Y?this.Mt(t):t instanceof B?this.wt(t):t instanceof _?this.gt(t):t instanceof k&&this.vt(t),this}getAsset(){return this.ft}listExtensionsUsed(){return Array.from(this.dt)}listExtensionsRequired(){return this.listExtensionsUsed().filter(t=>t.isRequired())}St(t){return this.dt.add(t),this}It(t){return this.dt.delete(t),this}bt(t){return this.addGraphChild(this.scenes,this.graph.link("scene",this,t))}listScenes(){return this.scenes.map(t=>t.getChild())}At(t){return this.addGraphChild(this.nodes,this.graph.link("node",this,t))}listNodes(){return this.nodes.map(t=>t.getChild())}xt(t){return this.addGraphChild(this.cameras,this.graph.link("camera",this,t))}listCameras(){return this.cameras.map(t=>t.getChild())}Et(t){return this.addGraphChild(this.skins,this.graph.link("skin",this,t))}listSkins(){return this.skins.map(t=>t.getChild())}Tt(t){return this.addGraphChild(this.meshes,this.graph.link("mesh",this,t))}listMeshes(){return this.meshes.map(t=>t.getChild())}yt(t){return this.addGraphChild(this.materials,this.graph.link("material",this,t))}listMaterials(){return this.materials.map(t=>t.getChild())}Mt(t){return this.addGraphChild(this.textures,this.graph.link("texture",this,t))}listTextures(){return this.textures.map(t=>t.getChild())}wt(t){return this.addGraphChild(this.animations,this.graph.link("animation",this,t))}listAnimations(){return this.animations.map(t=>t.getChild())}gt(t){return this.addGraphChild(this.accessors,this.graph.link("accessor",this,t))}listAccessors(){return this.accessors.map(t=>t.getChild())}vt(t){return this.addGraphChild(this.buffers,this.graph.link("buffer",this,t))}listBuffers(){return this.buffers.map(t=>t.getChild())}}c([d],X.prototype,"accessors",void 0),c([d],X.prototype,"animations",void 0),c([d],X.prototype,"buffers",void 0),c([d],X.prototype,"cameras",void 0),c([d],X.prototype,"materials",void 0),c([d],X.prototype,"meshes",void 0),c([d],X.prototype,"nodes",void 0),c([d],X.prototype,"scenes",void 0),c([d],X.prototype,"skins",void 0),c([d],X.prototype,"textures",void 0);class K{constructor(){this.Rt=new j,this.Ct=new X(this.Rt),this.Nt=A.DEFAULT_INSTANCE}getRoot(){return this.Ct}getGraph(){return this.Rt}getLogger(){return this.Nt}setLogger(t){return this.Nt=t,this}clone(){return(new K).merge(this)}merge(t){const s={};for(const e of t.getRoot().listExtensionsUsed()){const t=this.createExtension(e.constructor);e.isRequired()&&t.setRequired(!0),s[t.extensionName]=t}const e=new Set,i=new Map;e.add(t.Ct),i.set(t.Ct,this.Ct);for(const r of t.Rt.getLinks())for(const t of[r.getParent(),r.getChild()]){if(e.has(t))continue;let r;if(t.propertyType===u.TEXTURE_INFO)r=t;else{const e=t.constructor;r=t instanceof U?new e(this.Rt,s[t.extensionName]):new e(this.Rt)}i.set(t,r),e.add(t)}const r=t=>i.get(t);for(const t of e)i.get(t).copy(t,r);return this}async transform(...t){for(const s of t)await s(this);return this}createExtension(t){return this.getRoot().listExtensionsUsed().find(s=>s.extensionName===t.EXTENSION_NAME)||new t(this)}createScene(t=""){const s=new q(this.Rt,t);return this.Ct.bt(s),s}createNode(t=""){const s=new J(this.Rt,t);return this.Ct.At(s),s}createCamera(t=""){const s=new P(this.Rt,t);return this.Ct.xt(s),s}createSkin(t=""){const s=new H(this.Rt,t);return this.Ct.Et(s),s}createMesh(t=""){const s=new V(this.Rt,t);return this.Ct.Tt(s),s}createPrimitive(){return new $(this.Rt)}createPrimitiveTarget(t=""){return new W(this.Rt,t)}createMaterial(t=""){const s=new z(this.Rt,t);return this.Ct.yt(s),s}createTexture(t=""){const s=new Y(this.Rt,t);return this.Ct.Mt(s),s}createAnimation(t=""){const s=new B(this.Rt,t);return this.Ct.wt(s),s}createAnimationChannel(t=""){return new L(this.Rt,t)}createAnimationSampler(t=""){return new O(this.Rt,t)}createAccessor(t="",s=null){s||(s=this.getRoot().listBuffers()[0]);const e=new _(this.Rt,t).setBuffer(s);return this.Ct.gt(e),e}createBuffer(t=""){const s=new k(this.Rt,t);return this.Ct.vt(s),s}}class Z{constructor(t){this.doc=t,this.prereadTypes=[],this.prewriteTypes=[],this.dependencies=[],this.required=!1,this.properties=new Set,t.getRoot().St(this)}dispose(){this.doc.getRoot().It(this);for(const t of this.properties)t.dispose()}isRequired(){return this.required}setRequired(t){return this.required=t,this}addExtensionProperty(t){return this.properties.add(t),this}removeExtensionProperty(t){return this.properties.delete(t),this}install(t,s){return this}preread(t,s){return this}prewrite(t,s){return this}}class Q{constructor(t){this.jsonDoc=t,this.buffers=[],this.bufferViewBuffers=[],this.accessors=[],this.textures=[],this.textureInfos=new Map,this.materials=[],this.meshes=[],this.cameras=[],this.nodes=[],this.skins=[],this.animations=[],this.scenes=[]}setTextureInfo(t,s){this.textureInfos.set(t,s),void 0!==s.texCoord&&t.setTexCoord(s.texCoord);const e=this.jsonDoc.json.textures[s.index];if(void 0===e.sampler)return;const i=this.jsonDoc.json.samplers[e.sampler];void 0!==i.magFilter&&t.setMagFilter(i.magFilter),void 0!==i.minFilter&&t.setMinFilter(i.minFilter),void 0!==i.wrapS&&t.setWrapS(i.wrapS),void 0!==i.wrapT&&t.setWrapT(i.wrapT)}}const tt={5120:Int8Array,5121:Uint8Array,5122:Int16Array,5123:Uint16Array,5125:Uint32Array,5126:Float32Array},st={logger:A.DEFAULT_INSTANCE,extensions:[],dependencies:{}};class et{static read(t,s=st){const{json:i}=t,r=new K;this.validate(t,s);const o=new Q(t),c=t.json.asset,a=r.getRoot().getAsset();c.copyright&&(a.copyright=c.copyright),c.extras&&(a.extras=c.extras),c.generator&&(a.generator=c.generator),c.minVersion&&(a.minVersion=c.minVersion);const l=i.extensionsUsed||[],f=i.extensionsRequired||[];for(const t of s.extensions)if(l.includes(t.EXTENSION_NAME)){const e=r.createExtension(t).setRequired(f.includes(t.EXTENSION_NAME));for(const t of e.dependencies)e.install(t,s.dependencies[t])}o.buffers=(i.buffers||[]).map(t=>{const s=r.createBuffer(t.name);return t.extras&&s.setExtras(t.extras),t.uri&&0!==t.uri.indexOf("__")&&s.setURI(t.uri),s}),o.bufferViewBuffers=(i.bufferViews||[]).map(t=>o.buffers[t.buffer]),o.accessors=(i.accessors||[]).map(s=>{const e=r.createAccessor(s.name,o.bufferViewBuffers[s.bufferView]).setType(s.type);if(s.extras&&e.setExtras(s.extras),void 0!==s.normalized&&e.setNormalized(s.normalized),void 0===s.bufferView&&!s.sparse)return e;let i;return i=void 0!==s.sparse?function(t,s){const e=tt[t.componentType],i=_.getElementSize(t.type);let r;r=void 0!==t.bufferView?it(t,s).slice():new e(t.count*i);const n=t.sparse.count,h={...t,...t.sparse.indices,count:n,type:"SCALAR"},o={...t,...t.sparse.values,count:n},u=it(h,s),c=it(o,s);for(let t=0;t<h.count;t++)for(let s=0;s<i;s++)r[u[t]*i+s]=c[t*i+s];return r}(s,t):it(s,t).slice(),e.setArray(i),e});const d=i.images||[],p=i.textures||[];r.getRoot().listExtensionsUsed().filter(t=>t.prereadTypes.includes(u.TEXTURE)).forEach(t=>t.preread(o,u.TEXTURE)),o.textures=d.map(s=>{const e=r.createTexture(s.name);if(s.extras&&e.setExtras(s.extras),void 0!==s.bufferView){const r=i.bufferViews[s.bufferView],n=t.json.buffers[r.buffer],h=r.byteOffset||0,o=(n.uri?t.resources[n.uri]:t.resources["@glb.bin"]).slice(h,h+r.byteLength);e.setImage(o)}else void 0!==s.uri&&(e.setImage(t.resources[s.uri]),0!==s.uri.indexOf("__")&&e.setURI(s.uri));if(void 0!==s.mimeType)e.setMimeType(s.mimeType);else if(s.uri){const t=w.extension(s.uri);e.setMimeType(m.extensionToMimeType(t))}return e}),o.materials=(i.materials||[]).map(t=>{const s=r.createMaterial(t.name);t.extras&&s.setExtras(t.extras),void 0!==t.alphaMode&&s.setAlphaMode(t.alphaMode),void 0!==t.alphaCutoff&&s.setAlphaCutoff(t.alphaCutoff),void 0!==t.doubleSided&&s.setDoubleSided(t.doubleSided);const e=t.pbrMetallicRoughness||{};if(void 0!==e.baseColorFactor&&s.setBaseColorFactor(e.baseColorFactor),void 0!==t.emissiveFactor&&s.setEmissiveFactor(t.emissiveFactor),void 0!==e.metallicFactor&&s.setMetallicFactor(e.metallicFactor),void 0!==e.roughnessFactor&&s.setRoughnessFactor(e.roughnessFactor),void 0!==e.baseColorTexture){const t=e.baseColorTexture;s.setBaseColorTexture(o.textures[p[t.index].source]),o.setTextureInfo(s.getBaseColorTextureInfo(),t)}if(void 0!==t.emissiveTexture){const e=t.emissiveTexture;s.setEmissiveTexture(o.textures[p[e.index].source]),o.setTextureInfo(s.getEmissiveTextureInfo(),e)}if(void 0!==t.normalTexture){const e=t.normalTexture;s.setNormalTexture(o.textures[p[e.index].source]),o.setTextureInfo(s.getNormalTextureInfo(),e),void 0!==t.normalTexture.scale&&s.setNormalScale(t.normalTexture.scale)}if(void 0!==t.occlusionTexture){const e=t.occlusionTexture;s.setOcclusionTexture(o.textures[p[e.index].source]),o.setTextureInfo(s.getOcclusionTextureInfo(),e),void 0!==t.occlusionTexture.strength&&s.setOcclusionStrength(t.occlusionTexture.strength)}if(void 0!==e.metallicRoughnessTexture){const t=e.metallicRoughnessTexture;s.setMetallicRoughnessTexture(o.textures[p[t.index].source]),o.setTextureInfo(s.getMetallicRoughnessTextureInfo(),t)}return s});const g=i.meshes||[];r.getRoot().listExtensionsUsed().filter(t=>t.prereadTypes.includes(u.PRIMITIVE)).forEach(t=>t.preread(o,u.PRIMITIVE)),o.meshes=g.map(t=>{const s=r.createMesh(t.name);return t.extras&&s.setExtras(t.extras),void 0!==t.weights&&s.setWeights(t.weights),(t.primitives||[]).forEach(e=>{const i=r.createPrimitive();e.extras&&i.setExtras(e.extras),void 0!==e.material&&i.setMaterial(o.materials[e.material]),void 0!==e.mode&&i.setMode(e.mode);for(const[t,s]of Object.entries(e.attributes||{}))i.setAttribute(t,o.accessors[s]);void 0!==e.indices&&i.setIndices(o.accessors[e.indices]);const n=t.extras&&t.extras.targetNames||[];(e.targets||[]).forEach((t,s)=>{const e=n[s]||s.toString(),h=r.createPrimitiveTarget(e);for(const[s,e]of Object.entries(t))h.setAttribute(s,o.accessors[e]);i.addTarget(h)}),s.addPrimitive(i)}),s}),o.cameras=(i.cameras||[]).map(t=>{const s=r.createCamera(t.name).setType(t.type);return t.extras&&s.setExtras(t.extras),"perspective"===t.type?s.setZNear(t.perspective.znear).setZFar(t.perspective.zfar).setYFov(t.perspective.yfov).setAspectRatio(t.perspective.aspectRatio):s.setZNear(t.orthographic.znear).setZFar(t.orthographic.zfar).setXMag(t.orthographic.xmag).setYMag(t.orthographic.ymag),s});const v=i.nodes||[];return o.nodes=v.map(t=>{const s=r.createNode(t.name);if(t.extras&&s.setExtras(t.extras),void 0!==t.translation&&s.setTranslation(t.translation),void 0!==t.rotation&&s.setRotation(t.rotation),void 0!==t.scale&&s.setScale(t.scale),void 0!==t.matrix){const i=[0,0,0],r=[0,0,0,1],o=[1,1,1];!function(t,s,i,r){let o=h([t[0],t[1],t[2]]);const u=h([t[4],t[5],t[6]]),c=h([t[8],t[9],t[10]]);n(t)<0&&(o=-o),i[0]=t[12],i[1]=t[13],i[2]=t[14];const a=t.slice(),l=1/o,f=1/u,d=1/c;a[0]*=l,a[1]*=l,a[2]*=l,a[4]*=f,a[5]*=f,a[6]*=f,a[8]*=d,a[9]*=d,a[10]*=d,e(s,a),r[0]=o,r[1]=u,r[2]=c}(t.matrix,r,i,o),s.setTranslation(i),s.setRotation(r),s.setScale(o)}return void 0!==t.weights&&s.setWeights(t.weights),s}),o.skins=(i.skins||[]).map(t=>{const s=r.createSkin(t.name);t.extras&&s.setExtras(t.extras),void 0!==t.inverseBindMatrices&&s.setInverseBindMatrices(o.accessors[t.inverseBindMatrices]),void 0!==t.skeleton&&s.setSkeleton(o.nodes[t.skeleton]);for(const e of t.joints)s.addJoint(o.nodes[e]);return s}),v.map((t,s)=>{const e=o.nodes[s];(t.children||[]).forEach(t=>e.addChild(o.nodes[t])),void 0!==t.mesh&&e.setMesh(o.meshes[t.mesh]),void 0!==t.camera&&e.setCamera(o.cameras[t.camera]),void 0!==t.skin&&e.setSkin(o.skins[t.skin])}),o.animations=(i.animations||[]).map(t=>{const s=r.createAnimation(t.name);t.extras&&s.setExtras(t.extras);const e=(t.samplers||[]).map(t=>{const e=r.createAnimationSampler().setInput(o.accessors[t.input]).setOutput(o.accessors[t.output]).setInterpolation(t.interpolation||"LINEAR");return t.extras&&e.setExtras(t.extras),s.addSampler(e),e});return(t.channels||[]).forEach(t=>{const i=r.createAnimationChannel().setSampler(e[t.sampler]).setTargetNode(o.nodes[t.target.node]).setTargetPath(t.target.path);t.extras&&i.setExtras(t.extras),s.addChannel(i)}),s}),o.scenes=(i.scenes||[]).map(t=>{const s=r.createScene(t.name);return t.extras&&s.setExtras(t.extras),(t.nodes||[]).map(t=>o.nodes[t]).forEach(t=>s.addChild(t)),s}),r.getRoot().listExtensionsUsed().forEach(t=>t.read(o)),r}static validate(t,s){const e=t.json;if("2.0"!==e.asset.version)throw new Error(`Unsupported glTF version, "${e.asset.version}".`);if(e.extensionsRequired)for(const t of e.extensionsRequired)if(!s.extensions.find(s=>s.EXTENSION_NAME===t))throw new Error(`Missing required extension, "${t}".`);if(e.extensionsUsed)for(const t of e.extensionsUsed)s.extensions.find(s=>s.EXTENSION_NAME===t)||s.logger.warn(`Missing optional extension, "${t}".`)}}function it(t,s){const e=s.json.bufferViews[t.bufferView],i=s.json.buffers[e.buffer],r=i.uri?s.resources[i.uri]:s.resources["@glb.bin"],n=tt[t.componentType],h=_.getElementSize(t.type);if(void 0!==e.byteStride&&e.byteStride!==h*n.BYTES_PER_ELEMENT)return function(t,s){const e=s.json.bufferViews[t.bufferView],i=s.json.buffers[e.buffer],r=i.uri?s.resources[i.uri]:s.resources["@glb.bin"],n=tt[t.componentType],h=_.getElementSize(t.type),o=n.BYTES_PER_ELEMENT,u=t.byteOffset||0,c=new n(t.count*h),a=new DataView(r,e.byteOffset,e.byteLength),l=e.byteStride;for(let s=0;s<t.count;s++)for(let e=0;e<h;e++){const i=u+s*l+e*o;let r;switch(t.componentType){case 5126:r=a.getFloat32(i,!0);break;case 5125:r=a.getUint32(i,!0);break;case 5123:r=a.getUint16(i,!0);break;case 5121:r=a.getUint8(i);break;case 5122:r=a.getInt16(i,!0);break;case 5120:r=a.getInt8(i);break;default:throw new Error(`Unexpected componentType "${t.componentType}".`)}c[s*h+e]=r}return c}(t,s);const o=(e.byteOffset||0)+(t.byteOffset||0);switch(t.componentType){case 5126:return new Float32Array(r,o,t.count*h);case 5125:return new Uint32Array(r,o,t.count*h);case 5123:return new Uint16Array(r,o,t.count*h);case 5121:return new Uint8Array(r,o,t.count*h);case 5122:return new Int16Array(r,o,t.count*h);case 5120:return new Int8Array(r,o,t.count*h);default:throw new Error(`Unexpected componentType "${t.componentType}".`)}}class rt{constructor(t,s){this.jsonDoc=t,this.options=s,this.accessorIndexMap=new Map,this.cameraIndexMap=new Map,this.skinIndexMap=new Map,this.materialIndexMap=new Map,this.meshIndexMap=new Map,this.nodeIndexMap=new Map,this.imageIndexMap=new Map,this.textureDefIndexMap=new Map,this.textureInfoDefMap=new Map,this.samplerDefIndexMap=new Map,this.imageBufferViews=[],this.otherBufferViews=new Map,this.otherBufferViewsIndexMap=new Map,this.extensionData={}}createTextureInfoDef(t,s){const e={magFilter:s.getMagFilter()||void 0,minFilter:s.getMinFilter()||void 0,wrapS:s.getWrapS(),wrapT:s.getWrapT()},i=JSON.stringify(e);this.samplerDefIndexMap.has(i)||(this.samplerDefIndexMap.set(i,this.jsonDoc.json.samplers.length),this.jsonDoc.json.samplers.push(e));const r={source:this.imageIndexMap.get(t),sampler:this.samplerDefIndexMap.get(i)},n=JSON.stringify(r);this.textureDefIndexMap.has(n)||(this.textureDefIndexMap.set(n,this.jsonDoc.json.textures.length),this.jsonDoc.json.textures.push(r));const h={index:this.textureDefIndexMap.get(n),texCoord:s.getTexCoord()};return this.textureInfoDefMap.set(s,h),h}createPropertyDef(t){const s={};return t.getName()&&(s.name=t.getName()),Object.keys(t.getExtras()).length>0&&(s.extras=t.getExtras()),s}createAccessorDef(t){const s=this.createPropertyDef(t);return s.type=t.getType(),s.componentType=t.getComponentType(),s.count=t.getCount(),t.getMax(s.max=[]),t.getMin(s.min=[]),s.normalized=t.getNormalized(),s}createImageData(t,s,e){if(this.options.isGLB)this.imageBufferViews.push(s),t.bufferView=this.jsonDoc.json.bufferViews.length,this.jsonDoc.json.bufferViews.push({buffer:0,byteOffset:-1,byteLength:s.byteLength});else{const i=m.mimeTypeToExtension(e.getMimeType());t.uri=this.imageURIGenerator.createURI(e,i),this.jsonDoc.resources[t.uri]=s}}}class nt{constructor(t,s){this.multiple=t,this.basename=s,this.counter=1}createURI(t,s){return t.getURI()?t.getURI():this.multiple?`${this.basename}_${this.counter++}.${s}`:`${this.basename}.${s}`}}const ht={logger:A.DEFAULT_INSTANCE,basename:"",isGLB:!0,dependencies:{}};class ot{static write(t,s=ht){const e=t.getRoot(),i={json:{asset:e.getAsset()},resources:{}},r=s.logger||A.DEFAULT_INSTANCE,n=i.json;n.asset.generator="glTF-Transform v0.8.4";const h=new rt(i,s),o=e.listBuffers().length,c=e.listTextures().length;h.bufferURIGenerator=new nt(o>1,s.basename),h.imageURIGenerator=new nt(c>1,s.basename),h.logger=t.getLogger();for(const e of t.getRoot().listExtensionsUsed())for(const t of e.dependencies)e.install(t,s.dependencies[t]);function a(t,s,e,i){const r=[];let o=0;for(const s of t){const t=h.createAccessorDef(s);t.bufferView=n.bufferViews.length;const e=p.pad(s.getArray().buffer);t.byteOffset=o,o+=e.byteLength,r.push(e),h.accessorIndexMap.set(s,n.accessors.length),n.accessors.push(t)}const u={buffer:s,byteOffset:e,byteLength:p.concat(r).byteLength};return i&&(u.target=i),n.bufferViews.push(u),{buffers:r,byteLength:o}}function l(t,s,e){const i=t[0].getCount();let r=0;for(const s of t){const t=h.createAccessorDef(s);t.bufferView=n.bufferViews.length,t.byteOffset=r;const e=s.getElementSize(),i=s.getComponentSize();r+=p.padNumber(e*i),h.accessorIndexMap.set(s,n.accessors.length),n.accessors.push(t)}const o=i*r,u=new ArrayBuffer(o),c=new DataView(u);for(let s=0;s<i;s++){let e=0;for(const i of t){const t=i.getElementSize(),n=i.getComponentSize(),h=i.getComponentType(),o=i.getArray();for(let i=0;i<t;i++){const u=s*r+e+i*n,a=o[s*t+i];switch(h){case 5126:c.setFloat32(u,a,!0);break;case 5120:c.setInt8(u,a);break;case 5122:c.setInt16(u,a,!0);break;case 5121:c.setUint8(u,a);break;case 5123:c.setUint16(u,a,!0);break;case 5125:c.setUint32(u,a,!0);break;default:throw new Error("Unexpected component type: "+h)}}e+=p.padNumber(t*n)}}return n.bufferViews.push({buffer:s,byteOffset:e,byteLength:o,byteStride:r,target:34962}),{byteLength:o,buffers:[u]}}const f=new Map;for(const s of t.getGraph().getLinks()){if(s.getParent()===e)continue;const t=s.getChild();if(t instanceof _){const e=f.get(t)||[];e.push(s),f.set(t,e)}}return n.accessors=[],n.bufferViews=[],n.samplers=[],n.textures=[],n.images=e.listTextures().map((t,s)=>{const e=h.createPropertyDef(t);return t.getMimeType()&&(e.mimeType=t.getMimeType()),t.getImage()&&h.createImageData(e,t.getImage(),t),h.imageIndexMap.set(t,s),e}),t.getRoot().listExtensionsUsed().filter(t=>t.prewriteTypes.includes(u.ACCESSOR)).forEach(t=>t.prewrite(h,u.ACCESSOR)),n.buffers=[],e.listBuffers().forEach(t=>{const e=h.createPropertyDef(t),r=new Map,o=new Set,u=new Set,c=new Set,d=t.listParents().filter(t=>!(t instanceof X));for(const t of d){if(!(t instanceof _))throw new Error("Unimplemented buffer reference: "+t);if(h.accessorIndexMap.has(t))continue;let s=!1,e=!1,i=!1,n=!1;const a=f.get(t)||[];for(const t of a)t instanceof F?s=!0:t instanceof D?e=!0:"inverseBindMatrices"===t.getName()?i=!0:n=!0;if(s||e||i||n||(n=!0),!s||e||i||n)if(!e||s||i||n)if(!i||s||e||n){if(!n||s||e||i)throw new Error("Attribute, index, or IBM accessors must be used only for that purpose.");c.add(t)}else u.add(t);else o.add(t);else{const s=a[0].getParent(),e=r.get(s)||new Set;e.add(t),r.set(s,e)}}const g=[],w=n.buffers.length;let m,v=0;if(o.size){const t=a(Array.from(o),w,v,34963);v+=t.byteLength,g.push(...t.buffers)}for(const t of Array.from(r.values()))if(t.size){const s=l(Array.from(t),w,v);v+=s.byteLength,g.push(...s.buffers)}if(u.size){const t=a(Array.from(u),w,v);v+=t.byteLength,g.push(...t.buffers)}if(c.size){const t=a(Array.from(c),w,v);v+=t.byteLength,g.push(...t.buffers)}if(h.imageBufferViews.length)for(let t=0;t<h.imageBufferViews.length;t++)n.bufferViews[n.images[t].bufferView].byteOffset=v,v+=h.imageBufferViews[t].byteLength,g.push(h.imageBufferViews[t]);if(h.otherBufferViews.has(t))for(const s of h.otherBufferViews.get(t))n.bufferViews.push({buffer:w,byteOffset:v,byteLength:s.byteLength}),h.otherBufferViewsIndexMap.set(s,n.bufferViews.length-1),v+=s.byteLength,g.push(s);v?(s.isGLB?m="@glb.bin":(m=h.bufferURIGenerator.createURI(t,"bin"),e.uri=m),e.byteLength=v,i.resources[m]=p.concat(g),n.buffers.push(e)):h.logger.warn(`@gltf-transform/core: Skipping empty buffer, "${t.getName()}".`)}),e.listAccessors().find(t=>!t.getBuffer())&&r.warn("Skipped writing one or more Accessors: no Buffer assigned."),n.materials=e.listMaterials().map((t,s)=>{const e=h.createPropertyDef(t);if(e.alphaMode=t.getAlphaMode(),"MASK"===t.getAlphaMode()&&(e.alphaCutoff=t.getAlphaCutoff()),e.doubleSided=t.getDoubleSided(),e.pbrMetallicRoughness={},e.pbrMetallicRoughness.baseColorFactor=t.getBaseColorFactor(),e.emissiveFactor=t.getEmissiveFactor(),e.pbrMetallicRoughness.roughnessFactor=t.getRoughnessFactor(),e.pbrMetallicRoughness.metallicFactor=t.getMetallicFactor(),t.getBaseColorTexture()){const s=t.getBaseColorTexture(),i=t.getBaseColorTextureInfo();e.pbrMetallicRoughness.baseColorTexture=h.createTextureInfoDef(s,i)}if(t.getEmissiveTexture()){const s=t.getEmissiveTexture(),i=t.getEmissiveTextureInfo();e.emissiveTexture=h.createTextureInfoDef(s,i)}if(t.getNormalTexture()){const s=t.getNormalTexture(),i=t.getNormalTextureInfo(),r=h.createTextureInfoDef(s,i);1!==t.getNormalScale()&&(r.scale=t.getNormalScale()),e.normalTexture=r}if(t.getOcclusionTexture()){const s=t.getOcclusionTexture(),i=t.getOcclusionTextureInfo(),r=h.createTextureInfoDef(s,i);1!==t.getOcclusionStrength()&&(r.strength=t.getOcclusionStrength()),e.occlusionTexture=r}if(t.getMetallicRoughnessTexture()){const s=t.getMetallicRoughnessTexture(),i=t.getMetallicRoughnessTextureInfo();e.pbrMetallicRoughness.metallicRoughnessTexture=h.createTextureInfoDef(s,i)}return h.materialIndexMap.set(t,s),e}),n.meshes=e.listMeshes().map((t,s)=>{const e=h.createPropertyDef(t);let i;return e.primitives=t.listPrimitives().map(t=>{const s={attributes:{}};s.mode=t.getMode(),t.getMaterial()&&(s.material=h.materialIndexMap.get(t.getMaterial())),Object.keys(t.getExtras()).length&&(s.extras=t.getExtras()),t.getIndices()&&(s.indices=h.accessorIndexMap.get(t.getIndices()));for(const e of t.listSemantics())s.attributes[e]=h.accessorIndexMap.get(t.getAttribute(e));for(const e of t.listTargets()){const t={};for(const s of e.listSemantics())t[s]=h.accessorIndexMap.get(e.getAttribute(s));s.targets=s.targets||[],s.targets.push(t)}return t.listTargets().length&&!i&&(i=t.listTargets().map(t=>t.getName())),s}),t.getWeights().length&&(e.weights=t.getWeights()),i&&(e.extras=e.extras||{},e.extras.targetNames=i),h.meshIndexMap.set(t,s),e}),n.cameras=e.listCameras().map((t,s)=>{const e=h.createPropertyDef(t);return e.type=t.getType(),"perspective"===e.type?e.perspective={znear:t.getZNear(),zfar:t.getZFar(),yfov:t.getYFov(),aspectRatio:t.getAspectRatio()}:e.orthographic={znear:t.getZNear(),zfar:t.getZFar(),xmag:t.getXMag(),ymag:t.getYMag()},h.cameraIndexMap.set(t,s),e}),n.nodes=e.listNodes().map((t,s)=>{const e=h.createPropertyDef(t);return e.translation=t.getTranslation(),e.rotation=t.getRotation(),e.scale=t.getScale(),t.getWeights().length&&(e.weights=t.getWeights()),h.nodeIndexMap.set(t,s),e}),n.skins=e.listSkins().map((t,s)=>{const e=h.createPropertyDef(t);return t.getInverseBindMatrices()&&(e.inverseBindMatrices=h.accessorIndexMap.get(t.getInverseBindMatrices())),t.getSkeleton()&&(e.skeleton=h.nodeIndexMap.get(t.getSkeleton())),e.joints=t.listJoints().map(t=>h.nodeIndexMap.get(t)),h.skinIndexMap.set(t,s),e}),e.listNodes().forEach((t,s)=>{const e=n.nodes[s];t.getMesh()&&(e.mesh=h.meshIndexMap.get(t.getMesh())),t.getCamera()&&(e.camera=h.cameraIndexMap.get(t.getCamera())),t.getSkin()&&(e.skin=h.skinIndexMap.get(t.getSkin())),t.listChildren().length>0&&(e.children=t.listChildren().map(t=>h.nodeIndexMap.get(t)))}),n.animations=e.listAnimations().map(t=>{const s=h.createPropertyDef(t),e=new Map;return s.samplers=t.listSamplers().map((t,s)=>{const i=h.createPropertyDef(t);return i.input=h.accessorIndexMap.get(t.getInput()),i.output=h.accessorIndexMap.get(t.getOutput()),i.interpolation=t.getInterpolation(),e.set(t,s),i}),s.channels=t.listChannels().map(t=>{const s=h.createPropertyDef(t);return s.sampler=e.get(t.getSampler()),s.target={node:h.nodeIndexMap.get(t.getTargetNode()),path:t.getTargetPath()},s}),s}),n.scenes=e.listScenes().map(t=>{const s=h.createPropertyDef(t);return s.nodes=t.listChildren().map(t=>h.nodeIndexMap.get(t)),s}),n.extensionsUsed=e.listExtensionsUsed().map(t=>t.extensionName),n.extensionsRequired=e.listExtensionsRequired().map(t=>t.extensionName),e.listExtensionsUsed().forEach(t=>t.write(h)),function(t){const s=[];for(const e in t){const i=t[e];Array.isArray(i)&&0===i.length?s.push(e):null!==i&&""!==i||s.push(i)}for(const e of s)delete t[e]}(n),i}}class ut{constructor(){this.Nt=A.DEFAULT_INSTANCE,this.dt=[],this._t={}}setLogger(t){return this.Nt=t,this}registerExtensions(t){return this.dt.push(...t),this}registerDependencies(t){return Object.assign(this._t,t),this}readJSON(t){return et.read(t,{extensions:this.dt,dependencies:this._t,logger:this.Nt})}writeJSON(t,s){if(s.isGLB&&1!==t.getRoot().listBuffers().length)throw new Error("GLB must have exactly 1 buffer.");return s.dependencies={...this._t,...s.dependencies},ot.write(t,s)}binaryToJSON(t){const s=new Uint32Array(t,0,3);if(1179937895!==s[0])throw new Error("Invalid glTF asset.");if(2!==s[1])throw new Error(`Unsupported glTF binary version, "${s[1]}".`);const e=new Uint32Array(t,12,2),i=e[0],r=new Uint32Array(t,20+i,2);if(1313821514!==e[1]||5130562!==r[1])throw new Error("Unexpected GLB layout.");const n=p.decodeText(t.slice(20,20+i)),h=20+i+8;return{json:JSON.parse(n),resources:{"@glb.bin":t.slice(h,h+r[0])}}}readBinary(t){return this.readJSON(this.binaryToJSON(t))}writeBinary(t){const{json:s,resources:e}=this.writeJSON(t,{basename:"",isGLB:!0,logger:this.Nt,dependencies:this._t}),i=JSON.stringify(s),r=p.pad(p.encodeText(i),32),n=new Uint32Array([r.byteLength,1313821514]).buffer,h=p.concat([n,r]),o=p.pad(Object.values(e)[0]||new ArrayBuffer(0),0),u=new Uint32Array([o.byteLength,5130562]).buffer,c=p.concat([u,o]),a=new Uint32Array([1179937895,2,12+h.byteLength+c.byteLength]).buffer;return p.concat([a,h,c])}}class ct extends ut{constructor(){super(),this.lastReadBytes=0,this.lastWriteBytes=0,this.Bt=require("fs"),this.Lt=require("path")}read(t){const s=this.readAsJSON(t);return et.read(s,{extensions:this.dt,dependencies:this._t,logger:this.Nt})}readAsJSON(t){return t.match(/\.glb$/)||t.match(/^data:application\/octet-stream;/)?this.Ot(t):this.kt(t)}write(t,s){t.match(/\.glb$/)?this.Pt(t,s):this.Ut(t,s)}Ot(t){const s=this.Bt.readFileSync(t),e=p.trim(s);return this.lastReadBytes=e.byteLength,this.binaryToJSON(e)}kt(t){this.lastReadBytes=0;const s=this.Lt.dirname(t),e=this.Bt.readFileSync(t,"utf8");this.lastReadBytes+=e.length;const i={json:JSON.parse(e),resources:{}};return[...i.json.images||[],...i.json.buffers||[]].forEach(t=>{if(t.uri)if(t.uri.match(/data:/)){const s=`__${S()}.${w.extension(t.uri)}`;i.resources[s]=p.createBufferFromDataURI(t.uri),t.uri=s}else{const e=this.Lt.resolve(s,t.uri);i.resources[t.uri]=p.trim(this.Bt.readFileSync(e)),this.lastReadBytes+=i.resources[t.uri].byteLength}}),i}Ut(t,s){this.lastWriteBytes=0;const{json:e,resources:i}=ot.write(s,{basename:w.basename(t),isGLB:!1,logger:this.Nt,dependencies:this._t}),{Bt:r,Lt:n}=this,h=n.dirname(t),o=JSON.stringify(e,null,2);this.lastWriteBytes+=o.length,r.writeFileSync(t,o),Object.keys(i).forEach(t=>{const s=Buffer.from(i[t]);r.writeFileSync(n.join(h,t),s),this.lastWriteBytes+=s.byteLength})}Pt(t,s){const e=Buffer.from(this.writeBinary(s));this.Bt.writeFileSync(t,e),this.lastWriteBytes=e.byteLength}}const at={};class lt extends ut{constructor(t=at){super(),this.Ft=t}read(t){return this.readAsJSON(t).then(t=>this.readJSON(t))}readAsJSON(t){return t.match(/\.glb$/)||t.match(/^data:application\/octet-stream;/)?this.Ot(t):this.kt(t)}kt(t){const s={json:{},resources:{}};return fetch(t,this.Ft).then(t=>t.json()).then(t=>{s.json=t;const e=[...t.images||[],...t.buffers||[]].map(t=>{if(t.uri)return fetch(t.uri,this.Ft).then(t=>t.arrayBuffer()).then(e=>{s.resources[t.uri]=e})});return Promise.all(e).then(()=>s)})}Ot(t){return fetch(t,this.Ft).then(t=>t.arrayBuffer()).then(t=>this.binaryToJSON(t))}}export{_ as Accessor,B as Animation,L as AnimationChannel,O as AnimationSampler,k as Buffer,p as BufferUtils,I as COPY_IDENTITY,P as Camera,g as ColorUtils,K as Document,Z as Extension,U as ExtensionProperty,w as FileUtils,o as GLB_BUFFER,l as Graph,f as GraphChild,d as GraphChildList,m as ImageUtils,a as Link,A as Logger,z as Material,T as MathUtils,V as Mesh,J as Node,ct as NodeIO,$ as Primitive,W as PrimitiveTarget,R as Property,u as PropertyType,Q as ReaderContext,X as Root,q as Scene,H as Skin,Y as Texture,G as TextureInfo,lt as WebIO,rt as WriterContext,S as uuid};
import{fromRotationTranslationScale as t,getTranslation as s,getRotation as e,getScaling as i,multiply as r,determinant as n}from"gl-matrix/mat4";import{length as h}from"gl-matrix/vec3";const o="@glb.bin";var u;function c(t,s,e,i){var r,n=arguments.length,h=n<3?s:null===i?i=Object.getOwnPropertyDescriptor(s,e):i;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)h=Reflect.decorate(t,s,e,i);else for(var o=t.length-1;o>=0;o--)(r=t[o])&&(h=(n<3?r(h):n>3?r(s,e,h):r(s,e))||h);return n>3&&h&&Object.defineProperty(s,e,h),h}!function(t){t.ACCESSOR="Accessor",t.ANIMATION="Animation",t.ANIMATION_CHANNEL="AnimationChannel",t.ANIMATION_SAMPLER="AnimationSampler",t.BUFFER="Buffer",t.CAMERA="Camera",t.MATERIAL="Material",t.MESH="Mesh",t.PRIMITIVE="Primitive",t.PRIMITIVE_TARGET="PrimitiveTarget",t.NODE="Node",t.ROOT="Root",t.SCENE="Scene",t.SKIN="Skin",t.TEXTURE="Texture",t.TEXTURE_INFO="TextureInfo"}(u||(u={}));class a{constructor(t,s,e){if(this.t=t,this.s=s,this.i=e,this.h=!1,this.o=[],!s.canLink(e))throw new Error("Cannot link disconnected graphs/documents.")}getName(){return this.t}getParent(){return this.s}getChild(){return this.i}setChild(t){return this.i=t,this}dispose(){this.h||(this.h=!0,this.o.forEach(t=>t()),this.o.length=0)}onDispose(t){return this.o.push(t),this}isDisposed(){return this.h}}class l{constructor(){this.u=new Set,this.l=new Set,this.p=new Map,this.g=new Map,this.o={}}on(t,s){return this.o[t]=this.o[t]||[],this.o[t].push(s),this}emit(t,s){for(const e of this.o[t]||[])e(s);return this}getLinks(){return Array.from(this.l)}listParents(t){const s=this.g.get(t)||this.u;return Array.from(s).map(t=>t.getParent())}listChildren(t){const s=this.p.get(t)||this.u;return Array.from(s).map(t=>t.getChild())}disconnectChildren(t){return(this.p.get(t)||this.u).forEach(t=>t.dispose()),this}disconnectParents(t,s){let e=Array.from(this.g.get(t)||this.u);return s&&(e=e.filter(t=>s(t.getParent()))),e.forEach(t=>t.dispose()),this}swapChild(t,s,e){const i=this.p.get(t)||this.u;return Array.from(i).filter(t=>t.getChild()===s).forEach(t=>{this.g.get(s).delete(t),t.setChild(e),this.g.has(e)||this.g.set(e,new Set),this.g.get(e).add(t)}),this}link(t,s,e){if(!e)return null;const i=new a(t,s,e);return this.registerLink(i),i}registerLink(t){this.l.add(t);const s=t.getParent();this.p.has(s)||this.p.set(s,new Set),this.p.get(s).add(t);const e=t.getChild();return this.g.has(e)||this.g.set(e,new Set),this.g.get(e).add(t),t.onDispose(()=>this.unlink(t)),t}unlink(t){return this.l.delete(t),this.p.get(t.getParent()).delete(t),this.g.get(t.getChild()).delete(t),this}}function f(t,s){Object.defineProperty(t,s,{get:function(){return this["__"+s]},set:function(t){const e=this["__"+s];e&&!Array.isArray(e)&&e.dispose(),t&&!Array.isArray(t)&&t.onDispose(()=>{this["__"+s]=null}),this["__"+s]=t},enumerable:!0})}function d(t,s){}class p{static createBufferFromDataURI(t){if("undefined"==typeof Buffer){const s=atob(t.split(",")[1]),e=new Uint8Array(s.length);for(let t=0;t<s.length;t++)e[t]=s.charCodeAt(t);return e.buffer}{const s=t.split(",")[1],e=t.indexOf("base64")>=0;return this.trim(Buffer.from(s,e?"base64":"utf8"))}}static encodeText(t){return"undefined"!=typeof TextEncoder?(new TextEncoder).encode(t).buffer:this.trim(Buffer.from(t))}static decodeText(t){return"undefined"!=typeof TextDecoder?(new TextDecoder).decode(t):Buffer.from(t).toString("utf8")}static trim(t){const{byteOffset:s,byteLength:e}=t;return t.buffer.slice(s,s+e)}static concat(t){let s=0;for(const e of t)s+=e.byteLength;const e=new Uint8Array(s);let i=0;for(const s of t)e.set(new Uint8Array(s),i),i+=s.byteLength;return e.buffer}static pad(t,s=0){const e=this.padNumber(t.byteLength);if(e!==t.byteLength){const i=new Uint8Array(e);if(i.set(new Uint8Array(t)),0!==s)for(let r=t.byteLength;r<e;r++)i[r]=s;return i.buffer}return t}static padNumber(t){return 4*Math.ceil(t/4)}static equals(t,s){if(t===s)return!0;if(t.byteLength!==s.byteLength)return!1;const e=new DataView(t),i=new DataView(s);let r=t.byteLength;for(;r--;)if(e.getUint8(r)!==i.getUint8(r))return!1;return!0}}class g{static hexToFactor(t,s){return t=Math.floor(t),s[0]=(t>>16&255)/255,s[1]=(t>>8&255)/255,s[2]=(255&t)/255,this.convertSRGBToLinear(s,s)}static factorToHex(t){const s=[...t],[e,i,r]=this.convertLinearToSRGB(t,s);return 255*e<<16^255*i<<8^255*r<<0}static convertSRGBToLinear(t,s){for(let e=0;e<3;e++)s[e]=t[e]<.04045?.0773993808*t[e]:Math.pow(.9478672986*t[e]+.0521327014,2.4);return s}static convertLinearToSRGB(t,s){for(let e=0;e<3;e++)s[e]=t[e]<.0031308?12.92*t[e]:1.055*Math.pow(t[e],.41666)-.055;return s}}class w{static basename(t){const s=t.split(/[\\/]/).pop();return s.substr(0,s.lastIndexOf("."))}static extension(t){return 0!==t.indexOf("data:")?t.split(/[\\/]/).pop().split(/[.]/).pop():0===t.indexOf("data:image/png")?"png":0===t.indexOf("data:image/jpeg")?"jpeg":"bin"}}class m{static getSize(t,s){switch(s){case"image/png":return this.m(t);case"image/jpeg":return this.v(t);case"image/webp":return this.A(t);case"image/ktx2":return this.T(t);default:return null}}static getChannels(t,s){switch(s){case"image/png":return 4;case"image/jpeg":return 3;case"image/webp":case"image/ktx2":default:return 4}}static getMemSize(t,s){if("image/ktx2"===s){const s=new DataView(t);v(s);const e=s.getUint32(40,!0),i=80;let r=0;for(let t=0;t<e;t++)r+=T(s,i+3*t*8+16,!0)||T(s,i+3*t*8+8,!0);return r}const e=this.getSize(t,s);return e?e[0]*e[1]*4:null}static v(t){let s,e,i=new DataView(t,4);for(;i.byteLength;){if(s=i.getUint16(0,!1),A(i,s),e=i.getUint8(s+1),192===e||193===e||194===e)return[i.getUint16(s+7,!1),i.getUint16(s+5,!1)];i=new DataView(t,i.byteOffset+s+2)}throw new TypeError("Invalid JPG, no size found")}static m(t){const s=new DataView(t);return"CgBI"===p.decodeText(t.slice(12,16))?[s.getUint32(32,!1),s.getUint32(36,!1)]:[s.getUint32(16,!1),s.getUint32(20,!1)]}static A(t){const s=p.decodeText(t.slice(0,4)),e=p.decodeText(t.slice(8,12));if("RIFF"!==s||"WEBP"!==e)return null;const i=new DataView(t);let r=12;for(;r<t.byteLength;){const s=p.decodeText(t.slice(r,r+4)),e=i.getUint32(r+4,!0);if("VP8 "===s)return[16383&i.getInt16(r+14,!0),16383&i.getInt16(r+16,!0)];if("VP8L"===s){const t=i.getUint8(r+9),s=i.getUint8(r+10),e=i.getUint8(r+11);return[1+((63&s)<<8|t),1+((15&i.getUint8(r+12))<<10|e<<2|(192&s)>>6)]}r+=8+e+e%2}return null}static T(t){v(new DataView(t));const s=new DataView(t);return[s.getUint32(20,!0),s.getUint32(24,!0)]}static mimeTypeToExtension(t){return"image/jpeg"===t?"jpg":t.split("/").pop()}static extensionToMimeType(t){return"jpg"===t?"image/jpeg":"image/"+t}}function v(t){const s=t.buffer.slice(t.byteOffset+1,t.byteOffset+7);if("KTX 20"!==p.decodeText(s))throw new TypeError("Corrupt KTX2.")}function A(t,s){if(s>t.byteLength)throw new TypeError("Corrupt JPG, exceeded buffer limits");if(255!==t.getUint8(s))throw new TypeError("Invalid JPG, marker table corrupted")}function T(t,s,e){const i=t.getUint32(s,e),r=t.getUint32(s+4,e);return e?i+2**32*r:2**32*i+r}class E{static identity(t){return t}static eq(t,s){if(t.length!==s.length)return!1;for(let e=0;e<t.length;e++)if(Math.abs(t[e]-s[e])>1e-5)return!1;return!0}static denormalize(t,s){switch(s){case 5126:return t;case 5123:return t/65535;case 5121:return t/255;case 5122:return Math.max(t/32767,-1);case 5120:return Math.max(t/127,-1);default:throw new Error("Invalid component type.")}}static normalize(t,s){switch(s){case 5126:return t;case 5123:return Math.round(65535*t);case 5121:return Math.round(255*t);case 5122:return Math.round(32767*t);case 5120:return Math.round(127*t);default:throw new Error("Invalid component type.")}}}class x{constructor(t){this.verbosity=t}debug(t){this.verbosity<=x.Verbosity.DEBUG&&console.debug(t)}info(t){this.verbosity<=x.Verbosity.INFO&&console.info(t)}warn(t){this.verbosity<=x.Verbosity.WARN&&console.warn(t)}error(t){this.verbosity<=x.Verbosity.ERROR&&console.error(t)}}x.Verbosity={SILENT:4,ERROR:3,WARN:2,INFO:1,DEBUG:0},x.DEFAULT_INSTANCE=new x(x.Verbosity.INFO);const y="23456789abdegjkmnpqrvwxyzABDEGJKMNPQRVWXYZ",S=new Set,M=function(){let t="";for(let s=0;s<6;s++)t+=y.charAt(Math.floor(Math.random()*y.length));return t},b=function(){for(let t=0;t<999;t++){const t=M();if(!S.has(t))return S.add(t),t}return""},R=t=>t;class I extends class{constructor(t){this.graph=t,this.h=!1,this.graph=t}canLink(t){return this.graph===t.graph}isDisposed(){return this.h}dispose(){this.graph.disconnectChildren(this),this.graph.disconnectParents(this),this.h=!0}detach(){return this.graph.disconnectParents(this),this}swap(t,s){return this.graph.swapChild(this,t,s),this}addGraphChild(t,s){return t.push(s),s.onDispose(()=>{const e=t.filter(t=>t!==s);t.length=0;for(const s of e)t.push(s)}),this}removeGraphChild(t,s){return t.filter(t=>t.getChild()===s).forEach(t=>t.dispose()),this}clearGraphChildList(t){for(;t.length>0;)t[0].dispose();return this}listGraphParents(){return this.graph.listParents(this)}}{constructor(t,s=""){super(t),this.graph=t,this.S={},this.t="",this.t=s}getName(){return this.t}setName(t){return this.t=t,this}getExtras(){return this.S}setExtras(t){return this.S=t,this}clone(){const t=new(0,this.constructor)(this.graph).copy(this,R);return this.graph.emit("clone",t),t}copy(t,s=R){return this.t=t.t,this.S=JSON.parse(JSON.stringify(t.S)),this}detach(){return this.graph.disconnectParents(this,t=>"Root"!==t.propertyType),this}listParents(){return this.listGraphParents()}}const N="Pass extension name (string) as lookup token, not a constructor.";class C extends I{constructor(){super(...arguments),this.extensions=[]}copy(t,s=R){return super.copy(t,s),this.clearGraphChildList(this.extensions),t.extensions.forEach(t=>{const e=t.getChild();this.setExtension(e.extensionName,s(e))}),this}getExtension(t){if("string"!=typeof t)throw new Error(N);const s=this.extensions.find(s=>s.getChild().extensionName===t);return s?s.getChild():null}setExtension(t,s){if("string"!=typeof t)throw new Error(N);const e=this.getExtension(t);return e&&this.removeGraphChild(this.extensions,e),s?(s.M(this),this.addGraphChild(this.extensions,this.graph.link(t,this,s))):this}listExtensions(){return this.extensions.map(t=>t.getChild())}}c([d],C.prototype,"extensions",void 0);class _ extends C{constructor(){super(...arguments),this.propertyType=u.ACCESSOR,this.R=null,this.I=_.Type.SCALAR,this.N=_.ComponentType.FLOAT,this.C=!1,this._=E.identity,this.B=E.identity,this.buffer=null}copy(t,s=R){return super.copy(t,s),this.I=t.I,this.N=t.N,this.C=t.C,this._=t._,this.B=t.B,t.R&&(this.R=t.R.slice()),t.buffer&&this.setBuffer(s(t.buffer.getChild())),this}static getElementSize(t){switch(t){case _.Type.SCALAR:return 1;case _.Type.VEC2:return 2;case _.Type.VEC3:return 3;case _.Type.VEC4:case _.Type.MAT2:return 4;case _.Type.MAT3:return 9;case _.Type.MAT4:return 16;default:throw new Error("Unexpected type: "+t)}}static getComponentSize(t){switch(t){case _.ComponentType.BYTE:case _.ComponentType.UNSIGNED_BYTE:return 1;case _.ComponentType.SHORT:case _.ComponentType.UNSIGNED_SHORT:return 2;case _.ComponentType.UNSIGNED_INT:case _.ComponentType.FLOAT:return 4;default:throw new Error("Unexpected component type: "+t)}}getMinNormalized(t){const s=this.getElementSize();this.getMin(t);for(let e=0;e<s;e++)t[e]=this.B(t[e]);return t}getMin(t){const s=this.getCount(),e=this.getElementSize();for(let s=0;s<e;s++)t[s]=Infinity;for(let i=0;i<s*e;i+=e)for(let s=0;s<e;s++){const e=this.R[i+s];Number.isFinite(e)&&(t[s]=Math.min(t[s],e))}return t}getMaxNormalized(t){const s=this.getElementSize();this.getMax(t);for(let e=0;e<s;e++)t[e]=this.B(t[e]);return t}getMax(t){const s=this.getCount(),e=this.getElementSize();for(let s=0;s<e;s++)t[s]=-Infinity;for(let i=0;i<s*e;i+=e)for(let s=0;s<e;s++){const e=this.R[i+s];Number.isFinite(e)&&(t[s]=Math.max(t[s],e))}return t}getCount(){return this.R?this.R.length/this.getElementSize():0}getType(){return this.I}setType(t){return this.I=t,this}getElementSize(){return _.getElementSize(this.I)}getComponentSize(){return this.R.BYTES_PER_ELEMENT}getComponentType(){return this.N}getNormalized(){return this.C}setNormalized(t){return this.C=t,t?(this.B=t=>E.denormalize(t,this.N),this._=t=>E.normalize(t,this.N)):(this.B=E.identity,this._=E.identity),this}getScalar(t){const s=this.getElementSize();return this.B(this.R[t*s])}setScalar(t,s){return this.R[t*this.getElementSize()]=this._(s),this}getElement(t,s){const e=this.getElementSize();for(let i=0;i<e;i++)s[i]=this.B(this.R[t*e+i]);return s}setElement(t,s){const e=this.getElementSize();for(let i=0;i<e;i++)this.R[t*e+i]=this._(s[i]);return this}getBuffer(){return this.buffer?this.buffer.getChild():null}setBuffer(t){return this.buffer=this.graph.link("buffer",this,t),this}getArray(){return this.R}setArray(t){return this.N=t?function(t){switch(t.constructor){case Float32Array:return _.ComponentType.FLOAT;case Uint32Array:return _.ComponentType.UNSIGNED_INT;case Uint16Array:return _.ComponentType.UNSIGNED_SHORT;case Uint8Array:return _.ComponentType.UNSIGNED_BYTE;case Int16Array:return _.ComponentType.SHORT;case Int8Array:return _.ComponentType.BYTE;default:throw new Error("Unknown accessor componentType.")}}(t):_.ComponentType.FLOAT,this.R=t,this}getByteLength(){return this.R?this.R.byteLength:0}}_.Type={SCALAR:"SCALAR",VEC2:"VEC2",VEC3:"VEC3",VEC4:"VEC4",MAT2:"MAT2",MAT3:"MAT3",MAT4:"MAT4"},_.ComponentType={BYTE:5120,UNSIGNED_BYTE:5121,SHORT:5122,UNSIGNED_SHORT:5123,UNSIGNED_INT:5125,FLOAT:5126},c([f],_.prototype,"buffer",void 0);class B extends C{constructor(){super(...arguments),this.propertyType=u.ANIMATION,this.channels=[],this.samplers=[]}copy(t,s=R){return super.copy(t,s),this.clearGraphChildList(this.channels),this.clearGraphChildList(this.samplers),t.channels.forEach(t=>this.addChannel(s(t.getChild()))),t.samplers.forEach(t=>this.addSampler(s(t.getChild()))),this}addChannel(t){const s=this.graph.link("channel",this,t);return this.addGraphChild(this.channels,s)}removeChannel(t){return this.removeGraphChild(this.channels,t)}listChannels(){return this.channels.map(t=>t.getChild())}addSampler(t){const s=this.graph.link("sampler",this,t);return this.addGraphChild(this.samplers,s)}removeSampler(t){return this.removeGraphChild(this.samplers,t)}listSamplers(){return this.samplers.map(t=>t.getChild())}}c([d],B.prototype,"channels",void 0),c([d],B.prototype,"samplers",void 0);class L extends I{constructor(){super(...arguments),this.propertyType=u.ANIMATION_CHANNEL,this.L=null,this.targetNode=null,this.sampler=null}copy(t,s=R){return super.copy(t,s),this.L=t.L,t.targetNode&&this.setTargetNode(s(t.targetNode.getChild())),t.sampler&&this.setSampler(s(t.sampler.getChild())),this}getTargetPath(){return this.L}setTargetPath(t){return this.L=t,this}getTargetNode(){return this.targetNode?this.targetNode.getChild():null}setTargetNode(t){return this.targetNode=this.graph.link("target.node",this,t),this}getSampler(){return this.sampler?this.sampler.getChild():null}setSampler(t){return this.sampler=this.graph.link("sampler",this,t),this}}L.TargetPath={TRANSLATION:"translation",ROTATION:"rotation",SCALE:"scale",WEIGHTS:"weights"},c([f],L.prototype,"targetNode",void 0),c([f],L.prototype,"sampler",void 0);class P extends I{constructor(){super(...arguments),this.propertyType=u.ANIMATION_SAMPLER,this.P=P.Interpolation.LINEAR,this.input=null,this.output=null}copy(t,s=R){return super.copy(t,s),this.P=t.P,t.input&&this.setInput(s(t.input.getChild())),t.output&&this.setOutput(s(t.output.getChild())),this}getInterpolation(){return this.P}setInterpolation(t){return this.P=t,this}getInput(){return this.input?this.input.getChild():null}setInput(t){return this.input=this.graph.link("input",this,t),this}getOutput(){return this.output?this.output.getChild():null}setOutput(t){return this.output=this.graph.link("output",this,t),this}}P.Interpolation={LINEAR:"LINEAR",STEP:"STEP",CUBICSPLINE:"CUBICSPLINE"},c([f],P.prototype,"input",void 0),c([f],P.prototype,"output",void 0);class O extends C{constructor(){super(...arguments),this.propertyType=u.BUFFER,this.O=""}copy(t,s=R){return super.copy(t,s),this.O=t.O,this}getURI(){return this.O}setURI(t){return this.O=t,this}}class U extends C{constructor(){super(...arguments),this.propertyType=u.CAMERA,this.I=U.Type.PERSPECTIVE,this.U=.1,this.F=100,this.k=null,this.D=2*Math.PI*50/360,this.G=1,this.j=1}copy(t,s=R){return super.copy(t,s),this.I=t.I,this.U=t.U,this.F=t.F,this.k=t.k,this.D=t.D,this.G=t.G,this.j=t.j,this}getType(){return this.I}setType(t){return this.I=t,this}getZNear(){return this.U}setZNear(t){return this.U=t,this}getZFar(){return this.F}setZFar(t){return this.F=t,this}getAspectRatio(){return this.k}setAspectRatio(t){return this.k=t,this}getYFov(){return this.D}setYFov(t){return this.D=t,this}getXMag(){return this.G}setXMag(t){return this.G=t,this}getYMag(){return this.j}setYMag(t){return this.j=t,this}}U.Type={PERSPECTIVE:"perspective",ORTHOGRAPHIC:"orthographic"};class F extends I{constructor(t,s){super(t),this.V=s,this.V.addExtensionProperty(this)}dispose(){this.V.removeExtensionProperty(this),super.dispose()}M(t){if(!this.parentTypes.includes(t.propertyType))throw new Error(`Parent "${t.propertyType}" invalid for child "${this.propertyType}".`)}}class k extends a{constructor(){super(...arguments),this.semantic=""}copy(t){return this.semantic=t.semantic,this}}class D extends a{copy(t){return this}}class G extends l{linkAttribute(t,s,e){if(!e)return null;const i=new k(t,s,e);return this.registerLink(i),i}linkIndex(t,s,e){if(!e)return null;const i=new D(t,s,e);return this.registerLink(i),i}}class j extends C{constructor(){super(...arguments),this.propertyType=u.TEXTURE_INFO,this.J=0,this.$=null,this.W=null,this.Y=j.WrapMode.REPEAT,this.H=j.WrapMode.REPEAT}copy(t,s=R){return super.copy(t,s),this.J=t.J,this.$=t.$,this.W=t.W,this.Y=t.Y,this.H=t.H,this}getTexCoord(){return this.J}setTexCoord(t){return this.J=t,this}getMagFilter(){return this.$}setMagFilter(t){return this.$=t,this}getMinFilter(){return this.W}setMinFilter(t){return this.W=t,this}getWrapS(){return this.Y}setWrapS(t){return this.Y=t,this}getWrapT(){return this.H}setWrapT(t){return this.H=t,this}}j.WrapMode={CLAMP_TO_EDGE:33071,MIRRORED_REPEAT:33648,REPEAT:10497},j.MagFilter={NEAREST:9728,LINEAR:9729},j.MinFilter={NEAREST:9728,LINEAR:9729,NEAREST_MIPMAP_NEAREST:9984,LINEAR_MIPMAP_NEAREST:9985,NEAREST_MIPMAP_LINEAR:9986,LINEAR_MIPMAP_LINEAR:9987};class z extends C{constructor(){super(...arguments),this.propertyType=u.MATERIAL,this.q=z.AlphaMode.OPAQUE,this.K=.5,this.X=!1,this.Z=[1,1,1,1],this.tt=[0,0,0],this.st=1,this.et=1,this.it=1,this.rt=1,this.baseColorTexture=null,this.baseColorTextureInfo=this.graph.link("baseColorTextureInfo",this,new j(this.graph)),this.emissiveTexture=null,this.emissiveTextureInfo=this.graph.link("emissiveTextureInfo",this,new j(this.graph)),this.normalTexture=null,this.normalTextureInfo=this.graph.link("normalTextureInfo",this,new j(this.graph)),this.occlusionTexture=null,this.occlusionTextureInfo=this.graph.link("occlusionTextureInfo",this,new j(this.graph)),this.metallicRoughnessTexture=null,this.metallicRoughnessTextureInfo=this.graph.link("metallicRoughnessTextureInfo",this,new j(this.graph))}copy(t,s=R){return super.copy(t,s),this.q=t.q,this.K=t.K,this.X=t.X,this.Z=[...t.Z],this.tt=[...t.tt],this.st=t.st,this.et=t.et,this.it=t.it,this.rt=t.rt,t.baseColorTexture&&(this.setBaseColorTexture(s(t.baseColorTexture.getChild())),this.getBaseColorTextureInfo().copy(s(t.baseColorTextureInfo.getChild()),s)),t.emissiveTexture&&(this.setEmissiveTexture(s(t.emissiveTexture.getChild())),this.getEmissiveTextureInfo().copy(s(t.emissiveTextureInfo.getChild()),s)),t.normalTexture&&(this.setNormalTexture(s(t.normalTexture.getChild())),this.getNormalTextureInfo().copy(s(t.normalTextureInfo.getChild()),s)),t.occlusionTexture&&(this.setOcclusionTexture(s(t.occlusionTexture.getChild())),this.getOcclusionTextureInfo().copy(s(t.occlusionTextureInfo.getChild()),s)),t.metallicRoughnessTexture&&(this.setMetallicRoughnessTexture(s(t.metallicRoughnessTexture.getChild())),this.getMetallicRoughnessTextureInfo().copy(s(t.metallicRoughnessTextureInfo.getChild()),s)),this}dispose(){this.baseColorTextureInfo.getChild().dispose(),this.emissiveTextureInfo.getChild().dispose(),this.normalTextureInfo.getChild().dispose(),this.occlusionTextureInfo.getChild().dispose(),this.metallicRoughnessTextureInfo.getChild().dispose(),super.dispose()}getDoubleSided(){return this.X}setDoubleSided(t){return this.X=t,this}getAlpha(){return this.Z[3]}setAlpha(t){return this.Z[3]=t,this}getAlphaMode(){return this.q}setAlphaMode(t){return this.q=t,this}getAlphaCutoff(){return this.K}setAlphaCutoff(t){return this.K=t,this}getBaseColorFactor(){return this.Z}setBaseColorFactor(t){return this.Z=t,this}getBaseColorHex(){return g.factorToHex(this.Z)}setBaseColorHex(t){return g.hexToFactor(t,this.Z),this}getBaseColorTexture(){return this.baseColorTexture?this.baseColorTexture.getChild():null}getBaseColorTextureInfo(){return this.baseColorTexture?this.baseColorTextureInfo.getChild():null}setBaseColorTexture(t){return this.baseColorTexture=this.graph.link("baseColorTexture",this,t),this}getEmissiveFactor(){return this.tt}setEmissiveFactor(t){return this.tt=t,this}getEmissiveHex(){return g.factorToHex(this.tt)}setEmissiveHex(t){return g.hexToFactor(t,this.tt),this}getEmissiveTexture(){return this.emissiveTexture?this.emissiveTexture.getChild():null}getEmissiveTextureInfo(){return this.emissiveTexture?this.emissiveTextureInfo.getChild():null}setEmissiveTexture(t){return this.emissiveTexture=this.graph.link("emissiveTexture",this,t),this}getNormalScale(){return this.st}setNormalScale(t){return this.st=t,this}getNormalTexture(){return this.normalTexture?this.normalTexture.getChild():null}getNormalTextureInfo(){return this.normalTexture?this.normalTextureInfo.getChild():null}setNormalTexture(t){return this.normalTexture=this.graph.link("normalTexture",this,t),this}getOcclusionStrength(){return this.et}setOcclusionStrength(t){return this.et=t,this}getOcclusionTexture(){return this.occlusionTexture?this.occlusionTexture.getChild():null}getOcclusionTextureInfo(){return this.occlusionTexture?this.occlusionTextureInfo.getChild():null}setOcclusionTexture(t){return this.occlusionTexture=this.graph.link("occlusionTexture",this,t),this}getRoughnessFactor(){return this.it}setRoughnessFactor(t){return this.it=t,this}getMetallicFactor(){return this.rt}setMetallicFactor(t){return this.rt=t,this}getMetallicRoughnessTexture(){return this.metallicRoughnessTexture?this.metallicRoughnessTexture.getChild():null}getMetallicRoughnessTextureInfo(){return this.metallicRoughnessTexture?this.metallicRoughnessTextureInfo.getChild():null}setMetallicRoughnessTexture(t){return this.metallicRoughnessTexture=this.graph.link("metallicRoughnessTexture",this,t),this}}z.AlphaMode={OPAQUE:"OPAQUE",MASK:"MASK",BLEND:"BLEND"},c([f],z.prototype,"baseColorTexture",void 0),c([f],z.prototype,"baseColorTextureInfo",void 0),c([f],z.prototype,"emissiveTexture",void 0),c([f],z.prototype,"emissiveTextureInfo",void 0),c([f],z.prototype,"normalTexture",void 0),c([f],z.prototype,"normalTextureInfo",void 0),c([f],z.prototype,"occlusionTexture",void 0),c([f],z.prototype,"occlusionTextureInfo",void 0),c([f],z.prototype,"metallicRoughnessTexture",void 0),c([f],z.prototype,"metallicRoughnessTextureInfo",void 0);class V extends C{constructor(){super(...arguments),this.propertyType=u.MESH,this.nt=[],this.primitives=[]}copy(t,s=R){return super.copy(t,s),this.nt=[...t.nt],this.clearGraphChildList(this.primitives),t.primitives.forEach(t=>this.addPrimitive(s(t.getChild()))),this}addPrimitive(t){return this.addGraphChild(this.primitives,this.graph.link("primitive",this,t))}removePrimitive(t){return this.removeGraphChild(this.primitives,t)}listPrimitives(){return this.primitives.map(t=>t.getChild())}getWeights(){return this.nt}setWeights(t){return this.nt=t,this}}c([d],V.prototype,"primitives",void 0);class J extends C{constructor(){super(...arguments),this.propertyType=u.NODE,this.ht=[0,0,0],this.ot=[0,0,0,1],this.ut=[1,1,1],this.nt=[],this.s=null,this.camera=null,this.mesh=null,this.skin=null,this.children=[]}copy(t,s=R){return super.copy(t,s),this.ht=[...t.ht],this.ot=[...t.ot],this.ut=[...t.ut],this.nt=[...t.nt],t.camera&&this.setCamera(s(t.camera.getChild())),t.mesh&&this.setMesh(s(t.mesh.getChild())),t.skin&&this.setSkin(s(t.skin.getChild())),s!==R&&(this.clearGraphChildList(this.children),t.children.forEach(t=>this.addChild(s(t.getChild())))),this}getTranslation(){return this.ht}getRotation(){return this.ot}getScale(){return this.ut}setTranslation(t){return this.ht=t,this}setRotation(t){return this.ot=t,this}setScale(t){return this.ut=t,this}getMatrix(){return t([],this.ot,this.ht,this.ut)}getWorldTranslation(){return s([],this.getWorldMatrix())}getWorldRotation(){return e([],this.getWorldMatrix())}getWorldScale(){return i([],this.getWorldMatrix())}getWorldMatrix(){const t=[];for(let s=this;s instanceof J;s=s.s)t.push(s);let s;const e=t.pop().getMatrix();for(;s=t.pop();)r(e,e,s.getMatrix());return e}addChild(t){t.s&&t.s.removeChild(t);const s=this.graph.link("child",this,t);return this.addGraphChild(this.children,s),t.s=this,s.onDispose(()=>t.s=null),this}removeChild(t){return this.removeGraphChild(this.children,t)}listChildren(){return this.children.map(t=>t.getChild())}getParent(){return this.s}getMesh(){return this.mesh?this.mesh.getChild():null}setMesh(t){return this.mesh=this.graph.link("mesh",this,t),this}getCamera(){return this.camera?this.camera.getChild():null}setCamera(t){return this.camera=this.graph.link("camera",this,t),this}getSkin(){return this.skin?this.skin.getChild():null}setSkin(t){return this.skin=this.graph.link("skin",this,t),this}getWeights(){return this.nt}setWeights(t){return this.nt=t,this}traverse(t){t(this);for(const s of this.listChildren())s.traverse(t);return this}}c([f],J.prototype,"camera",void 0),c([f],J.prototype,"mesh",void 0),c([f],J.prototype,"skin",void 0),c([d],J.prototype,"children",void 0);class $ extends C{constructor(){super(...arguments),this.propertyType=u.PRIMITIVE,this.ct=$.Mode.TRIANGLES,this.material=null,this.indices=null,this.attributes=[],this.targets=[]}copy(t,s=R){return super.copy(t,s),this.ct=t.ct,t.indices&&this.setIndices(s(t.indices.getChild())),t.material&&this.setMaterial(s(t.material.getChild())),this.clearGraphChildList(this.attributes),t.listSemantics().forEach(e=>{this.setAttribute(e,s(t.getAttribute(e)))}),this.clearGraphChildList(this.targets),t.targets.forEach(t=>this.addTarget(s(t.getChild()))),this}getIndices(){return this.indices?this.indices.getChild():null}setIndices(t){return this.indices=this.graph.linkIndex("index",this,t),this}getAttribute(t){const s=this.attributes.find(s=>s.semantic===t);return s?s.getChild():null}setAttribute(t,s){const e=this.getAttribute(t);if(e&&this.removeGraphChild(this.attributes,e),!s)return this;const i=this.graph.linkAttribute(t.toLowerCase(),this,s);return i.semantic=t,this.addGraphChild(this.attributes,i)}listAttributes(){return this.attributes.map(t=>t.getChild())}listSemantics(){return this.attributes.map(t=>t.semantic)}getMaterial(){return this.material?this.material.getChild():null}setMaterial(t){return this.material=this.graph.link("material",this,t),this}getMode(){return this.ct}setMode(t){return this.ct=t,this}listTargets(){return this.targets.map(t=>t.getChild())}addTarget(t){return this.addGraphChild(this.targets,this.graph.link("target",this,t)),this}removeTarget(t){return this.removeGraphChild(this.targets,t)}}$.Mode={POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6},c([f],$.prototype,"material",void 0),c([f],$.prototype,"indices",void 0),c([d],$.prototype,"attributes",void 0),c([d],$.prototype,"targets",void 0);class W extends I{constructor(){super(...arguments),this.propertyType=u.PRIMITIVE_TARGET,this.attributes=[]}copy(t,s=R){return super.copy(t,s),this.clearGraphChildList(this.attributes),t.listSemantics().forEach(e=>{this.setAttribute(e,s(t.getAttribute(e)))}),this}getAttribute(t){const s=this.attributes.find(s=>s.semantic===t);return s?s.getChild():null}setAttribute(t,s){const e=this.getAttribute(t);if(e&&this.removeGraphChild(this.attributes,e),!s)return this;const i=this.graph.linkAttribute(t.toLowerCase(),this,s);return i.semantic=t,this.addGraphChild(this.attributes,i)}listAttributes(){return this.attributes.map(t=>t.getChild())}listSemantics(){return this.attributes.map(t=>t.semantic)}}c([d],W.prototype,"attributes",void 0);class Y extends C{constructor(){super(...arguments),this.propertyType=u.SCENE,this.children=[]}copy(t,s=R){return super.copy(t,s),s!==R&&(this.clearGraphChildList(this.children),t.children.forEach(t=>this.addChild(s(t.getChild())))),this}addChild(t){t.s&&t.s.removeChild(t);const s=this.graph.link("child",this,t);return this.addGraphChild(this.children,s),t.s=this,s.onDispose(()=>t.s=null),this}removeChild(t){return this.removeGraphChild(this.children,t)}listChildren(){return this.children.map(t=>t.getChild())}traverse(t){for(const s of this.listChildren())s.traverse(t);return this}}c([d],Y.prototype,"children",void 0);class H extends C{constructor(){super(...arguments),this.propertyType=u.SKIN,this.skeleton=null,this.inverseBindMatrices=null,this.joints=[]}copy(t,s=R){return super.copy(t,s),t.skeleton&&this.setSkeleton(s(t.skeleton.getChild())),t.inverseBindMatrices&&this.setInverseBindMatrices(s(t.inverseBindMatrices.getChild())),this.clearGraphChildList(this.joints),t.joints.forEach(t=>this.addJoint(s(t.getChild()))),this}getSkeleton(){return this.skeleton?this.skeleton.getChild():null}setSkeleton(t){return this.skeleton=this.graph.link("skeleton",this,t),this}getInverseBindMatrices(){return this.inverseBindMatrices?this.inverseBindMatrices.getChild():null}setInverseBindMatrices(t){return this.inverseBindMatrices=this.graph.link("inverseBindMatrices",this,t),this}addJoint(t){const s=this.graph.link("joint",this,t);return this.addGraphChild(this.joints,s)}removeJoint(t){return this.removeGraphChild(this.joints,t)}listJoints(){return this.joints.map(t=>t.getChild())}}c([f],H.prototype,"skeleton",void 0),c([f],H.prototype,"inverseBindMatrices",void 0),c([d],H.prototype,"joints",void 0);class q extends C{constructor(){super(...arguments),this.propertyType=u.TEXTURE,this.at=null,this.lt="",this.O=""}copy(t,s=R){return super.copy(t,s),this.lt=t.lt,this.O=t.O,t.at&&(this.at=t.at.slice(0)),this}getMimeType(){return this.lt||m.extensionToMimeType(w.extension(this.O))}setMimeType(t){return this.lt=t,this}getURI(){return this.O}setURI(t){return this.O=t,this.lt=m.extensionToMimeType(w.extension(t)),this}getImage(){return this.at}setImage(t){return this.at=t,this}getSize(){return this.at?m.getSize(this.at,this.getMimeType()):null}}class K extends I{constructor(t){super(t),this.propertyType=u.ROOT,this.ft={generator:"glTF-Transform v0.9.0",version:"2.0"},this.dt=new Set,this.accessors=[],this.animations=[],this.buffers=[],this.cameras=[],this.materials=[],this.meshes=[],this.nodes=[],this.scenes=[],this.skins=[],this.textures=[],t.on("clone",t=>this.pt(t))}clone(){throw new Error("Root cannot be cloned.")}copy(t,s=R){if(super.copy(t,s),s===R)throw new Error("Root cannot be copied.");return Object.assign(this.ft,t.ft),t.accessors.forEach(t=>this.gt(s(t.getChild()))),t.animations.forEach(t=>this.wt(s(t.getChild()))),t.buffers.forEach(t=>this.vt(s(t.getChild()))),t.cameras.forEach(t=>this.At(s(t.getChild()))),t.materials.forEach(t=>this.Tt(s(t.getChild()))),t.meshes.forEach(t=>this.Et(s(t.getChild()))),t.nodes.forEach(t=>this.xt(s(t.getChild()))),t.scenes.forEach(t=>this.yt(s(t.getChild()))),t.skins.forEach(t=>this.St(s(t.getChild()))),t.textures.forEach(t=>this.Mt(s(t.getChild()))),this}pt(t){return t instanceof Y?this.yt(t):t instanceof J?this.xt(t):t instanceof U?this.At(t):t instanceof H?this.St(t):t instanceof V?this.Et(t):t instanceof z?this.Tt(t):t instanceof q?this.Mt(t):t instanceof B?this.wt(t):t instanceof _?this.gt(t):t instanceof O&&this.vt(t),this}getAsset(){return this.ft}listExtensionsUsed(){return Array.from(this.dt)}listExtensionsRequired(){return this.listExtensionsUsed().filter(t=>t.isRequired())}bt(t){return this.dt.add(t),this}Rt(t){return this.dt.delete(t),this}yt(t){return this.addGraphChild(this.scenes,this.graph.link("scene",this,t))}listScenes(){return this.scenes.map(t=>t.getChild())}xt(t){return this.addGraphChild(this.nodes,this.graph.link("node",this,t))}listNodes(){return this.nodes.map(t=>t.getChild())}At(t){return this.addGraphChild(this.cameras,this.graph.link("camera",this,t))}listCameras(){return this.cameras.map(t=>t.getChild())}St(t){return this.addGraphChild(this.skins,this.graph.link("skin",this,t))}listSkins(){return this.skins.map(t=>t.getChild())}Et(t){return this.addGraphChild(this.meshes,this.graph.link("mesh",this,t))}listMeshes(){return this.meshes.map(t=>t.getChild())}Tt(t){return this.addGraphChild(this.materials,this.graph.link("material",this,t))}listMaterials(){return this.materials.map(t=>t.getChild())}Mt(t){return this.addGraphChild(this.textures,this.graph.link("texture",this,t))}listTextures(){return this.textures.map(t=>t.getChild())}wt(t){return this.addGraphChild(this.animations,this.graph.link("animation",this,t))}listAnimations(){return this.animations.map(t=>t.getChild())}gt(t){return this.addGraphChild(this.accessors,this.graph.link("accessor",this,t))}listAccessors(){return this.accessors.map(t=>t.getChild())}vt(t){return this.addGraphChild(this.buffers,this.graph.link("buffer",this,t))}listBuffers(){return this.buffers.map(t=>t.getChild())}}c([d],K.prototype,"accessors",void 0),c([d],K.prototype,"animations",void 0),c([d],K.prototype,"buffers",void 0),c([d],K.prototype,"cameras",void 0),c([d],K.prototype,"materials",void 0),c([d],K.prototype,"meshes",void 0),c([d],K.prototype,"nodes",void 0),c([d],K.prototype,"scenes",void 0),c([d],K.prototype,"skins",void 0),c([d],K.prototype,"textures",void 0);class X{constructor(){this.It=new G,this.Nt=new K(this.It),this.Ct=x.DEFAULT_INSTANCE}getRoot(){return this.Nt}getGraph(){return this.It}getLogger(){return this.Ct}setLogger(t){return this.Ct=t,this}clone(){return(new X).merge(this)}merge(t){const s={};for(const e of t.getRoot().listExtensionsUsed()){const t=this.createExtension(e.constructor);e.isRequired()&&t.setRequired(!0),s[t.extensionName]=t}const e=new Set,i=new Map;e.add(t.Nt),i.set(t.Nt,this.Nt);for(const r of t.It.getLinks())for(const t of[r.getParent(),r.getChild()]){if(e.has(t))continue;let r;if(t.propertyType===u.TEXTURE_INFO)r=t;else{const e=t.constructor;r=t instanceof F?new e(this.It,s[t.extensionName]):new e(this.It)}i.set(t,r),e.add(t)}const r=t=>{const s=i.get(t);if(!s)throw new Error("Could resolve property.");return s};for(const t of e){const s=i.get(t);if(!s)throw new Error("Could resolve property.");s.copy(t,r)}return this}async transform(...t){for(const s of t)await s(this);return this}createExtension(t){return this.getRoot().listExtensionsUsed().find(s=>s.extensionName===t.EXTENSION_NAME)||new t(this)}createScene(t=""){const s=new Y(this.It,t);return this.Nt.yt(s),s}createNode(t=""){const s=new J(this.It,t);return this.Nt.xt(s),s}createCamera(t=""){const s=new U(this.It,t);return this.Nt.At(s),s}createSkin(t=""){const s=new H(this.It,t);return this.Nt.St(s),s}createMesh(t=""){const s=new V(this.It,t);return this.Nt.Et(s),s}createPrimitive(){return new $(this.It)}createPrimitiveTarget(t=""){return new W(this.It,t)}createMaterial(t=""){const s=new z(this.It,t);return this.Nt.Tt(s),s}createTexture(t=""){const s=new q(this.It,t);return this.Nt.Mt(s),s}createAnimation(t=""){const s=new B(this.It,t);return this.Nt.wt(s),s}createAnimationChannel(t=""){return new L(this.It,t)}createAnimationSampler(t=""){return new P(this.It,t)}createAccessor(t="",s=null){s||(s=this.getRoot().listBuffers()[0]);const e=new _(this.It,t).setBuffer(s);return this.Nt.gt(e),e}createBuffer(t=""){const s=new O(this.It,t);return this.Nt.vt(s),s}}class Z{constructor(t){this.doc=t,this.prereadTypes=[],this.prewriteTypes=[],this.dependencies=[],this.required=!1,this.properties=new Set,t.getRoot().bt(this)}dispose(){this.doc.getRoot().Rt(this);for(const t of this.properties)t.dispose()}isRequired(){return this.required}setRequired(t){return this.required=t,this}addExtensionProperty(t){return this.properties.add(t),this}removeExtensionProperty(t){return this.properties.delete(t),this}install(t,s){return this}preread(t,s){return this}prewrite(t,s){return this}}class Q{constructor(t){this.jsonDoc=t,this.buffers=[],this.bufferViewBuffers=[],this.accessors=[],this.textures=[],this.textureInfos=new Map,this.materials=[],this.meshes=[],this.cameras=[],this.nodes=[],this.skins=[],this.animations=[],this.scenes=[]}setTextureInfo(t,s){this.textureInfos.set(t,s),void 0!==s.texCoord&&t.setTexCoord(s.texCoord);const e=this.jsonDoc.json.textures[s.index];if(void 0===e.sampler)return;const i=this.jsonDoc.json.samplers[e.sampler];void 0!==i.magFilter&&t.setMagFilter(i.magFilter),void 0!==i.minFilter&&t.setMinFilter(i.minFilter),void 0!==i.wrapS&&t.setWrapS(i.wrapS),void 0!==i.wrapT&&t.setWrapT(i.wrapT)}}const tt={5120:Int8Array,5121:Uint8Array,5122:Int16Array,5123:Uint16Array,5125:Uint32Array,5126:Float32Array},st={logger:x.DEFAULT_INSTANCE,extensions:[],dependencies:{}};class et{static read(t,s=st){const{json:i}=t,r=new X;this.validate(t,s);const o=new Q(t),c=t.json.asset,a=r.getRoot().getAsset();c.copyright&&(a.copyright=c.copyright),c.extras&&(a.extras=c.extras),c.generator&&(a.generator=c.generator),c.minVersion&&(a.minVersion=c.minVersion);const l=i.extensionsUsed||[],f=i.extensionsRequired||[];for(const t of s.extensions)if(l.includes(t.EXTENSION_NAME)){const e=r.createExtension(t).setRequired(f.includes(t.EXTENSION_NAME));for(const t of e.dependencies)e.install(t,s.dependencies[t])}o.buffers=(i.buffers||[]).map(t=>{const s=r.createBuffer(t.name);return t.extras&&s.setExtras(t.extras),t.uri&&0!==t.uri.indexOf("__")&&s.setURI(t.uri),s}),o.bufferViewBuffers=(i.bufferViews||[]).map(t=>o.buffers[t.buffer]),o.accessors=(i.accessors||[]).map(s=>{const e=r.createAccessor(s.name,o.bufferViewBuffers[s.bufferView]).setType(s.type);if(s.extras&&e.setExtras(s.extras),void 0!==s.normalized&&e.setNormalized(s.normalized),void 0===s.bufferView&&!s.sparse)return e;let i;return i=void 0!==s.sparse?function(t,s){const e=tt[t.componentType],i=_.getElementSize(t.type);let r;r=void 0!==t.bufferView?it(t,s).slice():new e(t.count*i);const n=t.sparse.count,h={...t,...t.sparse.indices,count:n,type:"SCALAR"},o={...t,...t.sparse.values,count:n},u=it(h,s),c=it(o,s);for(let t=0;t<h.count;t++)for(let s=0;s<i;s++)r[u[t]*i+s]=c[t*i+s];return r}(s,t):it(s,t).slice(),e.setArray(i),e});const d=i.images||[],p=i.textures||[];r.getRoot().listExtensionsUsed().filter(t=>t.prereadTypes.includes(u.TEXTURE)).forEach(t=>t.preread(o,u.TEXTURE)),o.textures=d.map(s=>{const e=r.createTexture(s.name);if(s.extras&&e.setExtras(s.extras),void 0!==s.bufferView){const r=i.bufferViews[s.bufferView],n=t.json.buffers[r.buffer],h=r.byteOffset||0,o=(n.uri?t.resources[n.uri]:t.resources["@glb.bin"]).slice(h,h+r.byteLength);e.setImage(o)}else void 0!==s.uri&&(e.setImage(t.resources[s.uri]),0!==s.uri.indexOf("__")&&e.setURI(s.uri));if(void 0!==s.mimeType)e.setMimeType(s.mimeType);else if(s.uri){const t=w.extension(s.uri);e.setMimeType(m.extensionToMimeType(t))}return e}),o.materials=(i.materials||[]).map(t=>{const s=r.createMaterial(t.name);t.extras&&s.setExtras(t.extras),void 0!==t.alphaMode&&s.setAlphaMode(t.alphaMode),void 0!==t.alphaCutoff&&s.setAlphaCutoff(t.alphaCutoff),void 0!==t.doubleSided&&s.setDoubleSided(t.doubleSided);const e=t.pbrMetallicRoughness||{};if(void 0!==e.baseColorFactor&&s.setBaseColorFactor(e.baseColorFactor),void 0!==t.emissiveFactor&&s.setEmissiveFactor(t.emissiveFactor),void 0!==e.metallicFactor&&s.setMetallicFactor(e.metallicFactor),void 0!==e.roughnessFactor&&s.setRoughnessFactor(e.roughnessFactor),void 0!==e.baseColorTexture){const t=e.baseColorTexture;s.setBaseColorTexture(o.textures[p[t.index].source]),o.setTextureInfo(s.getBaseColorTextureInfo(),t)}if(void 0!==t.emissiveTexture){const e=t.emissiveTexture;s.setEmissiveTexture(o.textures[p[e.index].source]),o.setTextureInfo(s.getEmissiveTextureInfo(),e)}if(void 0!==t.normalTexture){const e=t.normalTexture;s.setNormalTexture(o.textures[p[e.index].source]),o.setTextureInfo(s.getNormalTextureInfo(),e),void 0!==t.normalTexture.scale&&s.setNormalScale(t.normalTexture.scale)}if(void 0!==t.occlusionTexture){const e=t.occlusionTexture;s.setOcclusionTexture(o.textures[p[e.index].source]),o.setTextureInfo(s.getOcclusionTextureInfo(),e),void 0!==t.occlusionTexture.strength&&s.setOcclusionStrength(t.occlusionTexture.strength)}if(void 0!==e.metallicRoughnessTexture){const t=e.metallicRoughnessTexture;s.setMetallicRoughnessTexture(o.textures[p[t.index].source]),o.setTextureInfo(s.getMetallicRoughnessTextureInfo(),t)}return s});const g=i.meshes||[];r.getRoot().listExtensionsUsed().filter(t=>t.prereadTypes.includes(u.PRIMITIVE)).forEach(t=>t.preread(o,u.PRIMITIVE)),o.meshes=g.map(t=>{const s=r.createMesh(t.name);return t.extras&&s.setExtras(t.extras),void 0!==t.weights&&s.setWeights(t.weights),(t.primitives||[]).forEach(e=>{const i=r.createPrimitive();e.extras&&i.setExtras(e.extras),void 0!==e.material&&i.setMaterial(o.materials[e.material]),void 0!==e.mode&&i.setMode(e.mode);for(const[t,s]of Object.entries(e.attributes||{}))i.setAttribute(t,o.accessors[s]);void 0!==e.indices&&i.setIndices(o.accessors[e.indices]);const n=t.extras&&t.extras.targetNames||[];(e.targets||[]).forEach((t,s)=>{const e=n[s]||s.toString(),h=r.createPrimitiveTarget(e);for(const[s,e]of Object.entries(t))h.setAttribute(s,o.accessors[e]);i.addTarget(h)}),s.addPrimitive(i)}),s}),o.cameras=(i.cameras||[]).map(t=>{const s=r.createCamera(t.name).setType(t.type);return t.extras&&s.setExtras(t.extras),t.type===U.Type.PERSPECTIVE?s.setZNear(t.perspective.znear).setZFar(t.perspective.zfar).setYFov(t.perspective.yfov).setAspectRatio(t.perspective.aspectRatio):s.setZNear(t.orthographic.znear).setZFar(t.orthographic.zfar).setXMag(t.orthographic.xmag).setYMag(t.orthographic.ymag),s});const v=i.nodes||[];return o.nodes=v.map(t=>{const s=r.createNode(t.name);if(t.extras&&s.setExtras(t.extras),void 0!==t.translation&&s.setTranslation(t.translation),void 0!==t.rotation&&s.setRotation(t.rotation),void 0!==t.scale&&s.setScale(t.scale),void 0!==t.matrix){const i=[0,0,0],r=[0,0,0,1],o=[1,1,1];!function(t,s,i,r){let o=h([t[0],t[1],t[2]]);const u=h([t[4],t[5],t[6]]),c=h([t[8],t[9],t[10]]);n(t)<0&&(o=-o),i[0]=t[12],i[1]=t[13],i[2]=t[14];const a=t.slice(),l=1/o,f=1/u,d=1/c;a[0]*=l,a[1]*=l,a[2]*=l,a[4]*=f,a[5]*=f,a[6]*=f,a[8]*=d,a[9]*=d,a[10]*=d,e(s,a),r[0]=o,r[1]=u,r[2]=c}(t.matrix,r,i,o),s.setTranslation(i),s.setRotation(r),s.setScale(o)}return void 0!==t.weights&&s.setWeights(t.weights),s}),o.skins=(i.skins||[]).map(t=>{const s=r.createSkin(t.name);t.extras&&s.setExtras(t.extras),void 0!==t.inverseBindMatrices&&s.setInverseBindMatrices(o.accessors[t.inverseBindMatrices]),void 0!==t.skeleton&&s.setSkeleton(o.nodes[t.skeleton]);for(const e of t.joints)s.addJoint(o.nodes[e]);return s}),v.map((t,s)=>{const e=o.nodes[s];(t.children||[]).forEach(t=>e.addChild(o.nodes[t])),void 0!==t.mesh&&e.setMesh(o.meshes[t.mesh]),void 0!==t.camera&&e.setCamera(o.cameras[t.camera]),void 0!==t.skin&&e.setSkin(o.skins[t.skin])}),o.animations=(i.animations||[]).map(t=>{const s=r.createAnimation(t.name);t.extras&&s.setExtras(t.extras);const e=(t.samplers||[]).map(t=>{const e=r.createAnimationSampler().setInput(o.accessors[t.input]).setOutput(o.accessors[t.output]).setInterpolation(t.interpolation||P.Interpolation.LINEAR);return t.extras&&e.setExtras(t.extras),s.addSampler(e),e});return(t.channels||[]).forEach(t=>{const i=r.createAnimationChannel().setSampler(e[t.sampler]).setTargetNode(o.nodes[t.target.node]).setTargetPath(t.target.path);t.extras&&i.setExtras(t.extras),s.addChannel(i)}),s}),o.scenes=(i.scenes||[]).map(t=>{const s=r.createScene(t.name);return t.extras&&s.setExtras(t.extras),(t.nodes||[]).map(t=>o.nodes[t]).forEach(t=>s.addChild(t)),s}),r.getRoot().listExtensionsUsed().forEach(t=>t.read(o)),r}static validate(t,s){const e=t.json;if("2.0"!==e.asset.version)throw new Error(`Unsupported glTF version, "${e.asset.version}".`);if(e.extensionsRequired)for(const t of e.extensionsRequired)if(!s.extensions.find(s=>s.EXTENSION_NAME===t))throw new Error(`Missing required extension, "${t}".`);if(e.extensionsUsed)for(const t of e.extensionsUsed)s.extensions.find(s=>s.EXTENSION_NAME===t)||s.logger.warn(`Missing optional extension, "${t}".`)}}function it(t,s){const e=s.json.bufferViews[t.bufferView],i=s.json.buffers[e.buffer],r=i.uri?s.resources[i.uri]:s.resources["@glb.bin"],n=tt[t.componentType],h=_.getElementSize(t.type);if(void 0!==e.byteStride&&e.byteStride!==h*n.BYTES_PER_ELEMENT)return function(t,s){const e=s.json.bufferViews[t.bufferView],i=s.json.buffers[e.buffer],r=i.uri?s.resources[i.uri]:s.resources["@glb.bin"],n=tt[t.componentType],h=_.getElementSize(t.type),o=n.BYTES_PER_ELEMENT,u=t.byteOffset||0,c=new n(t.count*h),a=new DataView(r,e.byteOffset,e.byteLength),l=e.byteStride;for(let s=0;s<t.count;s++)for(let e=0;e<h;e++){const i=u+s*l+e*o;let r;switch(t.componentType){case _.ComponentType.FLOAT:r=a.getFloat32(i,!0);break;case _.ComponentType.UNSIGNED_INT:r=a.getUint32(i,!0);break;case _.ComponentType.UNSIGNED_SHORT:r=a.getUint16(i,!0);break;case _.ComponentType.UNSIGNED_BYTE:r=a.getUint8(i);break;case _.ComponentType.SHORT:r=a.getInt16(i,!0);break;case _.ComponentType.BYTE:r=a.getInt8(i);break;default:throw new Error(`Unexpected componentType "${t.componentType}".`)}c[s*h+e]=r}return c}(t,s);const o=(e.byteOffset||0)+(t.byteOffset||0);switch(t.componentType){case _.ComponentType.FLOAT:return new Float32Array(r,o,t.count*h);case _.ComponentType.UNSIGNED_INT:return new Uint32Array(r,o,t.count*h);case _.ComponentType.UNSIGNED_SHORT:return new Uint16Array(r,o,t.count*h);case _.ComponentType.UNSIGNED_BYTE:return new Uint8Array(r,o,t.count*h);case _.ComponentType.SHORT:return new Int16Array(r,o,t.count*h);case _.ComponentType.BYTE:return new Int8Array(r,o,t.count*h);default:throw new Error(`Unexpected componentType "${t.componentType}".`)}}class rt{constructor(t,s){this.jsonDoc=t,this.options=s,this.accessorIndexMap=new Map,this.cameraIndexMap=new Map,this.skinIndexMap=new Map,this.materialIndexMap=new Map,this.meshIndexMap=new Map,this.nodeIndexMap=new Map,this.imageIndexMap=new Map,this.textureDefIndexMap=new Map,this.textureInfoDefMap=new Map,this.samplerDefIndexMap=new Map,this.imageBufferViews=[],this.otherBufferViews=new Map,this.otherBufferViewsIndexMap=new Map,this.extensionData={},this._t=new Map,this.accessorUsageGroupedByParent=new Set(["ARRAY_BUFFER"])}createTextureInfoDef(t,s){const e={magFilter:s.getMagFilter()||void 0,minFilter:s.getMinFilter()||void 0,wrapS:s.getWrapS(),wrapT:s.getWrapT()},i=JSON.stringify(e);this.samplerDefIndexMap.has(i)||(this.samplerDefIndexMap.set(i,this.jsonDoc.json.samplers.length),this.jsonDoc.json.samplers.push(e));const r={source:this.imageIndexMap.get(t),sampler:this.samplerDefIndexMap.get(i)},n=JSON.stringify(r);this.textureDefIndexMap.has(n)||(this.textureDefIndexMap.set(n,this.jsonDoc.json.textures.length),this.jsonDoc.json.textures.push(r));const h={index:this.textureDefIndexMap.get(n),texCoord:s.getTexCoord()};return this.textureInfoDefMap.set(s,h),h}createPropertyDef(t){const s={};return t.getName()&&(s.name=t.getName()),Object.keys(t.getExtras()).length>0&&(s.extras=t.getExtras()),s}createAccessorDef(t){const s=this.createPropertyDef(t);return s.type=t.getType(),s.componentType=t.getComponentType(),s.count=t.getCount(),t.getMax(s.max=[]),t.getMin(s.min=[]),s.normalized=t.getNormalized(),s}createImageData(t,s,e){if(this.options.isGLB)this.imageBufferViews.push(s),t.bufferView=this.jsonDoc.json.bufferViews.length,this.jsonDoc.json.bufferViews.push({buffer:0,byteOffset:-1,byteLength:s.byteLength});else{const i=m.mimeTypeToExtension(e.getMimeType());t.uri=this.imageURIGenerator.createURI(e,i),this.jsonDoc.resources[t.uri]=s}}getAccessorUsage(t){return this._t.get(t)}setAccessorUsage(t,s){const e=this._t.get(t);if(e&&e!==s)throw new Error(`Accessor with usage "${e}" cannot be reused as "${s}".`);return this._t.set(t,s),this}listAccessorsByUsage(){const t={};for(const[s,e]of Array.from(this._t.entries()))t[e]=t[e]||[],t[e].push(s);return t}}class nt{constructor(t,s){this.multiple=t,this.basename=s,this.counter=1}createURI(t,s){return t.getURI()?t.getURI():this.multiple?`${this.basename}_${this.counter++}.${s}`:`${this.basename}.${s}`}}const ht={logger:x.DEFAULT_INSTANCE,basename:"",isGLB:!0,dependencies:{}};class ot{static write(t,s=ht){const e=t.getRoot(),i={json:{asset:e.getAsset()},resources:{}},r=s.logger||x.DEFAULT_INSTANCE,n=i.json;n.asset.generator="glTF-Transform v0.9.0";const h=new rt(i,s),o=e.listBuffers().length,c=e.listTextures().length;h.bufferURIGenerator=new nt(o>1,s.basename),h.imageURIGenerator=new nt(c>1,s.basename),h.logger=t.getLogger();for(const e of t.getRoot().listExtensionsUsed())for(const t of e.dependencies)e.install(t,s.dependencies[t]);function a(t,s,e,i){const r=[];let o=0;for(const s of t){const t=h.createAccessorDef(s);t.bufferView=n.bufferViews.length;const e=p.pad(s.getArray().buffer);t.byteOffset=o,o+=e.byteLength,r.push(e),h.accessorIndexMap.set(s,n.accessors.length),n.accessors.push(t)}const u={buffer:s,byteOffset:e,byteLength:p.concat(r).byteLength};return i&&(u.target=i),n.bufferViews.push(u),{buffers:r,byteLength:o}}function l(t,s,e){const i=t[0].getCount();let r=0;for(const s of t){const t=h.createAccessorDef(s);t.bufferView=n.bufferViews.length,t.byteOffset=r;const e=s.getElementSize(),i=s.getComponentSize();r+=p.padNumber(e*i),h.accessorIndexMap.set(s,n.accessors.length),n.accessors.push(t)}const o=i*r,u=new ArrayBuffer(o),c=new DataView(u);for(let s=0;s<i;s++){let e=0;for(const i of t){const t=i.getElementSize(),n=i.getComponentSize(),h=i.getComponentType(),o=i.getArray();for(let i=0;i<t;i++){const u=s*r+e+i*n,a=o[s*t+i];switch(h){case _.ComponentType.FLOAT:c.setFloat32(u,a,!0);break;case _.ComponentType.BYTE:c.setInt8(u,a);break;case _.ComponentType.SHORT:c.setInt16(u,a,!0);break;case _.ComponentType.UNSIGNED_BYTE:c.setUint8(u,a);break;case _.ComponentType.UNSIGNED_SHORT:c.setUint16(u,a,!0);break;case _.ComponentType.UNSIGNED_INT:c.setUint32(u,a,!0);break;default:throw new Error("Unexpected component type: "+h)}}e+=p.padNumber(t*n)}}return n.bufferViews.push({buffer:s,byteOffset:e,byteLength:o,byteStride:r,target:34962}),{byteLength:o,buffers:[u]}}const f=new Map;for(const s of t.getGraph().getLinks()){if(s.getParent()===e)continue;const t=s.getChild();if(t instanceof _){const e=f.get(t)||[];e.push(s),f.set(t,e)}}return n.accessors=[],n.bufferViews=[],n.samplers=[],n.textures=[],n.images=e.listTextures().map((t,s)=>{const e=h.createPropertyDef(t);return t.getMimeType()&&(e.mimeType=t.getMimeType()),t.getImage()&&h.createImageData(e,t.getImage(),t),h.imageIndexMap.set(t,s),e}),t.getRoot().listExtensionsUsed().filter(t=>t.prewriteTypes.includes(u.ACCESSOR)).forEach(t=>t.prewrite(h,u.ACCESSOR)),n.buffers=[],e.listBuffers().forEach(t=>{const e=h.createPropertyDef(t),r=h.accessorUsageGroupedByParent,o=new Map,u=t.listParents().filter(t=>t instanceof _),c=new Set(u);for(const t of u){if(h.accessorIndexMap.has(t))continue;const s=f.get(t)||[];for(const e of s){if(h.getAccessorUsage(t))break;e instanceof k?h.setAccessorUsage(t,"ARRAY_BUFFER"):e instanceof D?h.setAccessorUsage(t,"ELEMENT_ARRAY_BUFFER"):"inverseBindMatrices"===e.getName()&&h.setAccessorUsage(t,"INVERSE_BIND_MATRICES")}if(h.getAccessorUsage(t)||h.setAccessorUsage(t,"OTHER"),r.has(h.getAccessorUsage(t))){const e=s[0].getParent(),i=o.get(e)||new Set;i.add(t),o.set(e,i)}}const d=[],g=n.buffers.length;let w=0;const m=h.listAccessorsByUsage();for(const t in m)if(r.has(t))for(const s of Array.from(o.values())){const e=Array.from(s).filter(t=>c.has(t)).filter(s=>h.getAccessorUsage(s)===t);if(!e.length)continue;const i="ARRAY_BUFFER"===t?l(e,g,w):a(e,g,w);w+=i.byteLength,d.push(...i.buffers)}else{const s=m[t].filter(t=>c.has(t));if(!s.length)continue;const e=a(s,g,w,"ELEMENT_ARRAY_BUFFER"===t?34963:null);w+=e.byteLength,d.push(...e.buffers)}if(h.imageBufferViews.length)for(let t=0;t<h.imageBufferViews.length;t++)if(n.bufferViews[n.images[t].bufferView].byteOffset=w,w+=h.imageBufferViews[t].byteLength,d.push(h.imageBufferViews[t]),w%4){const t=4-w%4;w+=t,d.push(new ArrayBuffer(t))}if(h.otherBufferViews.has(t))for(const s of h.otherBufferViews.get(t))n.bufferViews.push({buffer:g,byteOffset:w,byteLength:s.byteLength}),h.otherBufferViewsIndexMap.set(s,n.bufferViews.length-1),w+=s.byteLength,d.push(s);if(!w)return void h.logger.warn(`@gltf-transform/core: Skipping empty buffer, "${t.getName()}".`);let v;s.isGLB?v="@glb.bin":(v=h.bufferURIGenerator.createURI(t,"bin"),e.uri=v),e.byteLength=w,i.resources[v]=p.concat(d),n.buffers.push(e)}),e.listAccessors().find(t=>!t.getBuffer())&&r.warn("Skipped writing one or more Accessors: no Buffer assigned."),n.materials=e.listMaterials().map((t,s)=>{const e=h.createPropertyDef(t);if(e.alphaMode=t.getAlphaMode(),t.getAlphaMode()===z.AlphaMode.MASK&&(e.alphaCutoff=t.getAlphaCutoff()),e.doubleSided=t.getDoubleSided(),e.pbrMetallicRoughness={},e.pbrMetallicRoughness.baseColorFactor=t.getBaseColorFactor(),e.emissiveFactor=t.getEmissiveFactor(),e.pbrMetallicRoughness.roughnessFactor=t.getRoughnessFactor(),e.pbrMetallicRoughness.metallicFactor=t.getMetallicFactor(),t.getBaseColorTexture()){const s=t.getBaseColorTexture(),i=t.getBaseColorTextureInfo();e.pbrMetallicRoughness.baseColorTexture=h.createTextureInfoDef(s,i)}if(t.getEmissiveTexture()){const s=t.getEmissiveTexture(),i=t.getEmissiveTextureInfo();e.emissiveTexture=h.createTextureInfoDef(s,i)}if(t.getNormalTexture()){const s=t.getNormalTexture(),i=t.getNormalTextureInfo(),r=h.createTextureInfoDef(s,i);1!==t.getNormalScale()&&(r.scale=t.getNormalScale()),e.normalTexture=r}if(t.getOcclusionTexture()){const s=t.getOcclusionTexture(),i=t.getOcclusionTextureInfo(),r=h.createTextureInfoDef(s,i);1!==t.getOcclusionStrength()&&(r.strength=t.getOcclusionStrength()),e.occlusionTexture=r}if(t.getMetallicRoughnessTexture()){const s=t.getMetallicRoughnessTexture(),i=t.getMetallicRoughnessTextureInfo();e.pbrMetallicRoughness.metallicRoughnessTexture=h.createTextureInfoDef(s,i)}return h.materialIndexMap.set(t,s),e}),n.meshes=e.listMeshes().map((t,s)=>{const e=h.createPropertyDef(t);let i;return e.primitives=t.listPrimitives().map(t=>{const s={attributes:{}};s.mode=t.getMode(),t.getMaterial()&&(s.material=h.materialIndexMap.get(t.getMaterial())),Object.keys(t.getExtras()).length&&(s.extras=t.getExtras()),t.getIndices()&&(s.indices=h.accessorIndexMap.get(t.getIndices()));for(const e of t.listSemantics())s.attributes[e]=h.accessorIndexMap.get(t.getAttribute(e));for(const e of t.listTargets()){const t={};for(const s of e.listSemantics())t[s]=h.accessorIndexMap.get(e.getAttribute(s));s.targets=s.targets||[],s.targets.push(t)}return t.listTargets().length&&!i&&(i=t.listTargets().map(t=>t.getName())),s}),t.getWeights().length&&(e.weights=t.getWeights()),i&&(e.extras=e.extras||{},e.extras.targetNames=i),h.meshIndexMap.set(t,s),e}),n.cameras=e.listCameras().map((t,s)=>{const e=h.createPropertyDef(t);return e.type=t.getType(),e.type===U.Type.PERSPECTIVE?e.perspective={znear:t.getZNear(),zfar:t.getZFar(),yfov:t.getYFov(),aspectRatio:t.getAspectRatio()}:e.orthographic={znear:t.getZNear(),zfar:t.getZFar(),xmag:t.getXMag(),ymag:t.getYMag()},h.cameraIndexMap.set(t,s),e}),n.nodes=e.listNodes().map((t,s)=>{const e=h.createPropertyDef(t);return e.translation=t.getTranslation(),e.rotation=t.getRotation(),e.scale=t.getScale(),t.getWeights().length&&(e.weights=t.getWeights()),h.nodeIndexMap.set(t,s),e}),n.skins=e.listSkins().map((t,s)=>{const e=h.createPropertyDef(t);return t.getInverseBindMatrices()&&(e.inverseBindMatrices=h.accessorIndexMap.get(t.getInverseBindMatrices())),t.getSkeleton()&&(e.skeleton=h.nodeIndexMap.get(t.getSkeleton())),e.joints=t.listJoints().map(t=>h.nodeIndexMap.get(t)),h.skinIndexMap.set(t,s),e}),e.listNodes().forEach((t,s)=>{const e=n.nodes[s];t.getMesh()&&(e.mesh=h.meshIndexMap.get(t.getMesh())),t.getCamera()&&(e.camera=h.cameraIndexMap.get(t.getCamera())),t.getSkin()&&(e.skin=h.skinIndexMap.get(t.getSkin())),t.listChildren().length>0&&(e.children=t.listChildren().map(t=>h.nodeIndexMap.get(t)))}),n.animations=e.listAnimations().map(t=>{const s=h.createPropertyDef(t),e=new Map;return s.samplers=t.listSamplers().map((t,s)=>{const i=h.createPropertyDef(t);return i.input=h.accessorIndexMap.get(t.getInput()),i.output=h.accessorIndexMap.get(t.getOutput()),i.interpolation=t.getInterpolation(),e.set(t,s),i}),s.channels=t.listChannels().map(t=>{const s=h.createPropertyDef(t);return s.sampler=e.get(t.getSampler()),s.target={node:h.nodeIndexMap.get(t.getTargetNode()),path:t.getTargetPath()},s}),s}),n.scenes=e.listScenes().map(t=>{const s=h.createPropertyDef(t);return s.nodes=t.listChildren().map(t=>h.nodeIndexMap.get(t)),s}),n.extensionsUsed=e.listExtensionsUsed().map(t=>t.extensionName),n.extensionsRequired=e.listExtensionsRequired().map(t=>t.extensionName),e.listExtensionsUsed().forEach(t=>t.write(h)),function(t){const s=[];for(const e in t){const i=t[e];Array.isArray(i)&&0===i.length?s.push(e):null!==i&&""!==i||s.push(i)}for(const e of s)delete t[e]}(n),i}}class ut{constructor(){this.Ct=x.DEFAULT_INSTANCE,this.dt=[],this.Bt={}}setLogger(t){return this.Ct=t,this}registerExtensions(t){return this.dt.push(...t),this}registerDependencies(t){return Object.assign(this.Bt,t),this}readJSON(t){return et.read(t,{extensions:this.dt,dependencies:this.Bt,logger:this.Ct})}writeJSON(t,s){if(s.isGLB&&1!==t.getRoot().listBuffers().length)throw new Error("GLB must have exactly 1 buffer.");return s.dependencies={...this.Bt,...s.dependencies},ot.write(t,s)}binaryToJSON(t){const s=new Uint32Array(t,0,3);if(1179937895!==s[0])throw new Error("Invalid glTF asset.");if(2!==s[1])throw new Error(`Unsupported glTF binary version, "${s[1]}".`);const e=new Uint32Array(t,12,2),i=e[0],r=new Uint32Array(t,20+i,2);if(1313821514!==e[1]||5130562!==r[1])throw new Error("Unexpected GLB layout.");const n=p.decodeText(t.slice(20,20+i)),h=20+i+8;return{json:JSON.parse(n),resources:{"@glb.bin":t.slice(h,h+r[0])}}}readBinary(t){return this.readJSON(this.binaryToJSON(t))}writeBinary(t){const{json:s,resources:e}=this.writeJSON(t,{basename:"",isGLB:!0,logger:this.Ct,dependencies:this.Bt}),i=JSON.stringify(s),r=p.pad(p.encodeText(i),32),n=new Uint32Array([r.byteLength,1313821514]).buffer,h=p.concat([n,r]),o=p.pad(Object.values(e)[0]||new ArrayBuffer(0),0),u=new Uint32Array([o.byteLength,5130562]).buffer,c=p.concat([u,o]),a=new Uint32Array([1179937895,2,12+h.byteLength+c.byteLength]).buffer;return p.concat([a,h,c])}}class ct extends ut{constructor(){super(),this.lastReadBytes=0,this.lastWriteBytes=0,this.Lt=require("fs"),this.Pt=require("path")}read(t){const s=this.readAsJSON(t);return et.read(s,{extensions:this.dt,dependencies:this.Bt,logger:this.Ct})}readAsJSON(t){return t.match(/\.glb$/)||t.match(/^data:application\/octet-stream;/)?this.Ot(t):this.Ut(t)}write(t,s){t.match(/\.glb$/)?this.Ft(t,s):this.kt(t,s)}Ot(t){const s=this.Lt.readFileSync(t),e=p.trim(s);return this.lastReadBytes=e.byteLength,this.binaryToJSON(e)}Ut(t){this.lastReadBytes=0;const s=this.Pt.dirname(t),e=this.Lt.readFileSync(t,"utf8");this.lastReadBytes+=e.length;const i={json:JSON.parse(e),resources:{}};return[...i.json.images||[],...i.json.buffers||[]].forEach(t=>{if(t.uri)if(t.uri.match(/data:/)){const s=`__${b()}.${w.extension(t.uri)}`;i.resources[s]=p.createBufferFromDataURI(t.uri),t.uri=s}else{const e=this.Pt.resolve(s,t.uri);i.resources[t.uri]=p.trim(this.Lt.readFileSync(e)),this.lastReadBytes+=i.resources[t.uri].byteLength}}),i}kt(t,s){this.lastWriteBytes=0;const{json:e,resources:i}=ot.write(s,{basename:w.basename(t),isGLB:!1,logger:this.Ct,dependencies:this.Bt}),{Lt:r,Pt:n}=this,h=n.dirname(t),o=JSON.stringify(e,null,2);this.lastWriteBytes+=o.length,r.writeFileSync(t,o),Object.keys(i).forEach(t=>{const s=Buffer.from(i[t]);r.writeFileSync(n.join(h,t),s),this.lastWriteBytes+=s.byteLength})}Ft(t,s){const e=Buffer.from(this.writeBinary(s));this.Lt.writeFileSync(t,e),this.lastWriteBytes=e.byteLength}}const at={};class lt extends ut{constructor(t=at){super(),this.Dt=t}read(t){return this.readAsJSON(t).then(t=>this.readJSON(t))}readAsJSON(t){return t.match(/\.glb$/)||t.match(/^data:application\/octet-stream;/)?this.Ot(t):this.Ut(t)}Ut(t){const s={json:{},resources:{}};return fetch(t,this.Dt).then(t=>t.json()).then(t=>{s.json=t;const e=[...t.images||[],...t.buffers||[]].map(t=>{if(t.uri)return fetch(t.uri,this.Dt).then(t=>t.arrayBuffer()).then(e=>{s.resources[t.uri]=e})});return Promise.all(e).then(()=>s)})}Ot(t){return fetch(t,this.Dt).then(t=>t.arrayBuffer()).then(t=>this.binaryToJSON(t))}}export{_ as Accessor,B as Animation,L as AnimationChannel,P as AnimationSampler,k as AttributeLink,O as Buffer,p as BufferUtils,R as COPY_IDENTITY,U as Camera,g as ColorUtils,X as Document,Z as Extension,F as ExtensionProperty,w as FileUtils,o as GLB_BUFFER,l as Graph,f as GraphChild,d as GraphChildList,m as ImageUtils,D as IndexLink,a as Link,x as Logger,z as Material,E as MathUtils,V as Mesh,J as Node,ct as NodeIO,$ as Primitive,W as PrimitiveTarget,I as Property,u as PropertyType,Q as ReaderContext,K as Root,Y as Scene,H as Skin,q as Texture,j as TextureInfo,lt as WebIO,rt as WriterContext,b as uuid};
//# sourceMappingURL=core.modern.js.map

@@ -147,5 +147,5 @@ import { Extension } from './extension';

/** Creates a new {@link Accessor} attached to this document's {@link Root}. */
createAccessor(name?: string, buffer?: Buffer): Accessor;
createAccessor(name?: string, buffer?: Buffer | null): Accessor;
/** Creates a new {@link Buffer} attached to this document's {@link Root}. */
createBuffer(name?: string): Buffer;
}

@@ -83,3 +83,3 @@ import { PropertyType } from './constants';

*/
preread(readerContext: ReaderContext, propertyType: PropertyType): this;
preread(_readerContext: ReaderContext, _propertyType: PropertyType): this;
/**

@@ -93,3 +93,3 @@ * Used by the {@link PlatformIO} utilities when writing a glTF asset. This method may

*/
prewrite(writerContext: WriterContext, propertyType: PropertyType): this;
prewrite(_writerContext: WriterContext, _propertyType: PropertyType): this;
/**

@@ -96,0 +96,0 @@ * Used by the {@link PlatformIO} utilities when reading a glTF asset. This method must be

@@ -30,3 +30,5 @@ import { Link } from './graph-links';

*/
link<A extends T>(name: string, a: A, b: null): null;
link<A extends T, B extends T>(name: string, a: A, b: B): Link<A, B>;
link<A extends T, B extends T>(name: string, a: A, b: B | null): Link<A, B> | null;
protected registerLink(link: Link<T, T>): Link<T, T>;

@@ -33,0 +35,0 @@ /**

@@ -33,2 +33,4 @@ import { JSONDocument } from '../json-document';

logger: Logger;
private readonly _accessorUsageMap;
readonly accessorUsageGroupedByParent: Set<string>;
constructor(jsonDoc: JSONDocument, options: WriterOptions);

@@ -43,2 +45,19 @@ /**

createImageData(imageDef: GLTF.IImage, data: ArrayBuffer, texture: Texture): void;
/**
* Returns usage for the given accessor, if any. Some accessor types must be grouped into
* buffer views with like accessors. This includes the specified buffer view "targets", but
* also implicit usage like IBMs or instanced mesh attributes.
*/
getAccessorUsage(accessor: Accessor): string;
/**
* Sets usage for the given accessor. Some accessor types must be grouped into
* buffer views with like accessors. This includes the specified buffer view "targets", but
* also implicit usage like IBMs or instanced mesh attributes. If unspecified, an accessor
* will be grouped with other accessors of unspecified usage.
*/
setAccessorUsage(accessor: Accessor, usage: string): this;
/** Lists accessors grouped by usage. Accessors with unspecified usage are not included. */
listAccessorsByUsage(): {
[key: string]: Accessor[];
};
}

@@ -45,0 +64,0 @@ export declare class UniqueURIGenerator {

@@ -18,14 +18,4 @@ import { PropertyType, TypedArray } from '../constants';

* {@link getCount}(). The number of components in an element — e.g. 9 for `"MAT3"` — are its
* {@link getElementSize}().
* {@link getElementSize}(). See {@link Accessor.Type}.
*
* | `type` | Components |
* |:----------:|:----------:|
* | `"SCALAR"` | 1 |
* | `"VEC2"` | 2 |
* | `"VEC3"` | 3 |
* | `"VEC4"` | 4 |
* | `"MAT2"` | 4 |
* | `"MAT3"` | 9 |
* | `"MAT4"` | 16 |
*
* *Components* are the numeric values within an element — e.g. `.x` and `.y` for `"VEC2"`. Various

@@ -35,13 +25,4 @@ * component types are available: `BYTE`, `UNSIGNED_BYTE`, `SHORT`, `UNSIGNED_SHORT`,

* {@link getComponentType} method, and the number of bytes in each component determine its
* {@link getComponentSize}. Component types are identified by WebGL enum values, below.
* {@link getComponentSize}. See {@link Accessor.ComponentType}.
*
* | `componentType` | Bytes |
* |:-----------------------:|:-----:|
* | `5120` (BYTE) | 1 |
* | `5121` (UNSIGNED_BYTE) | 1 |
* | `5122` (SHORT) | 2 |
* | `5123` (UNSIGNED_SHORT) | 2 |
* | `5125` (UNSIGNED_INT) | 4 |
* | `5126` (FLOAT) | 4 |
*
* Usage:

@@ -52,3 +33,3 @@ *

* .setArray(new Float32Array([1,2,3,4,5,6,7,8,9,10,11,12]))
* .setType(GLTF.AccessorType.VEC3)
* .setType(Accessor.Type.VEC3)
* .setBuffer(doc.listBuffers()[0]);

@@ -103,20 +84,6 @@ *

*/
/** Supported element types. */
static Type: {
SCALAR: GLTF.AccessorType;
VEC2: GLTF.AccessorType;
VEC3: GLTF.AccessorType;
VEC4: GLTF.AccessorType;
MAT3: GLTF.AccessorType;
MAT4: GLTF.AccessorType;
};
/** Supported component types. */
static ComponentType: {
BYTE: GLTF.AccessorComponentType;
UNSIGNED_BYTE: GLTF.AccessorComponentType;
SHORT: GLTF.AccessorComponentType;
UNSIGNED_SHORT: GLTF.AccessorComponentType;
UNSIGNED_INT: GLTF.AccessorComponentType;
FLOAT: GLTF.AccessorComponentType;
};
/** Element type contained by the accessor (SCALAR, VEC2, ...). */
static Type: Record<string, GLTF.AccessorType>;
/** Data type of the values composing each element in the accessor. */
static ComponentType: Record<string, GLTF.AccessorComponentType>;
/** Returns size of a given element type, in components. */

@@ -226,7 +193,7 @@ static getElementSize(type: GLTF.AccessorType): number;

/** Returns the {@link Buffer} into which this accessor will be organized. */
getBuffer(): Buffer;
getBuffer(): Buffer | null;
/** Assigns the {@link Buffer} into which this accessor will be organized. */
setBuffer(buffer: Buffer): this;
/** Returns the raw typed array underlying this accessor. */
getArray(): TypedArray;
getArray(): TypedArray | null;
/** Assigns the raw typed array underlying this accessor. */

@@ -233,0 +200,0 @@ setArray(array: TypedArray): this;

@@ -14,5 +14,6 @@ import { PropertyType } from '../constants';

* Node that can be affected by animation: `translation`, `rotation`, `scale`, or `weights`. An
* {@link Animation} affecting the positions and rotations of several {@link Node}s would contain one
* channel for each Node-position or Node-rotation pair. The keyframe data for an AnimationChannel
* is stored in an {@link AnimationSampler}, which must be attached to the same {@link Animation}.
* {@link Animation} affecting the positions and rotations of several {@link Node}s would contain
* one channel for each Node-position or Node-rotation pair. The keyframe data for an
* AnimationChannel is stored in an {@link AnimationSampler}, which must be attached to the same
* {@link Animation}.
*

@@ -27,3 +28,3 @@ * Usage:

* const channel = doc.createAnimationChannel('cogRotation')
* .setTargetPath(GLTF.AnimationChannelTargetPath.ROTATION)
* .setTargetPath('rotation')
* .setTargetNode(node)

@@ -42,2 +43,10 @@ * .setSampler(rotateSampler);

copy(other: this, resolve?: <T extends Property>(t: T) => T): this;
/**********************************************************************************************
* Static.
*/
/** Name of the property to be modified by an animation channel. */
static TargetPath: Record<string, GLTF.AnimationChannelTargetPath>;
/**********************************************************************************************
* Properties.
*/
/**

@@ -47,3 +56,3 @@ * Path (property) animated on the target {@link Node}. Supported values include:

*/
getTargetPath(): GLTF.AnimationChannelTargetPath;
getTargetPath(): GLTF.AnimationChannelTargetPath | null;
/**

@@ -55,3 +64,3 @@ * Path (property) animated on the target {@link Node}. Supported values include:

/** Target {@link Node} animated by the channel. */
getTargetNode(): Node;
getTargetNode(): Node | null;
/** Target {@link Node} animated by the channel. */

@@ -63,3 +72,3 @@ setTargetNode(targetNode: Node): this;

*/
getSampler(): AnimationSampler;
getSampler(): AnimationSampler | null;
/**

@@ -66,0 +75,0 @@ * Keyframe data input/output values for the channel. Must be attached to the same

@@ -15,3 +15,4 @@ import { PropertyType } from '../constants';

*
* in<sub>1</sub>, value<sub>1</sub>, out<sub>1</sub>, in<sub>2</sub>, value<sub>2</sub>, out<sub>2</sub>,
* in<sub>1</sub>, value<sub>1</sub>, out<sub>1</sub>,
* in<sub>2</sub>, value<sub>2</sub>, out<sub>2</sub>,
* in<sub>3</sub>, value<sub>3</sub>, out<sub>3</sub>, ...

@@ -25,3 +26,3 @@ *

* .setArray(new Float32Array([0, 1, 2]))
* .setType(GLTF.AccessorType.SCALAR);
* .setType(Accessor.Type.SCALAR);
*

@@ -35,3 +36,3 @@ * // Create accessor containing output values, in local units.

* ]))
* .setType(GLTF.AccessorType.VEC3);
* .setType(Accessor.Type.VEC3);
*

@@ -42,3 +43,3 @@ * // Create sampler.

* .setOutput(output)
* .setInterpolation(GLTF.AnimationSamplerInterpolation.LINEAR);
* .setInterpolation('LINEAR');
* ```

@@ -55,2 +56,7 @@ *

copy(other: this, resolve?: <T extends Property>(t: T) => T): this;
/**********************************************************************************************
* Static.
*/
/** Interpolation method. */
static Interpolation: Record<string, GLTF.AnimationSamplerInterpolation>;
/** Interpolation mode: `STEP`, `LINEAR`, or `CUBICSPLINE`. */

@@ -61,5 +67,5 @@ getInterpolation(): GLTF.AnimationSamplerInterpolation;

/** Times for each keyframe, in seconds. */
getInput(): Accessor;
getInput(): Accessor | null;
/** Times for each keyframe, in seconds. */
setInput(input: Accessor): this;
setInput(input: Accessor | null): this;
/**

@@ -69,3 +75,3 @@ * Values for each keyframe. For `CUBICSPLINE` interpolation, output also contains in/out

*/
getOutput(): Accessor;
getOutput(): Accessor | null;
/**

@@ -75,3 +81,3 @@ * Values for each keyframe. For `CUBICSPLINE` interpolation, output also contains in/out

*/
setOutput(output: Accessor): this;
setOutput(output: Accessor | null): this;
}

@@ -43,2 +43,6 @@ import { PropertyType } from '../constants';

/**********************************************************************************************
* Static.
*/
static Type: Record<string, GLTF.CameraType>;
/**********************************************************************************************
* Common.

@@ -71,3 +75,3 @@ */

*/
getAspectRatio(): number;
getAspectRatio(): number | null;
/**

@@ -77,3 +81,3 @@ * Floating-point aspect ratio of the field of view. When undefined, the aspect ratio of the

*/
setAspectRatio(aspectRatio: number): this;
setAspectRatio(aspectRatio: number | null): this;
/** Floating-point vertical field of view in radians. */

@@ -80,0 +84,0 @@ getYFov(): number;

@@ -21,3 +21,3 @@ import { Link } from '../graph';

*/
getExtension<Prop extends ExtensionProperty>(name: string): Prop;
getExtension<Prop extends ExtensionProperty>(name: string): Prop | null;
/**

@@ -28,3 +28,3 @@ * Attaches the given {@link ExtensionProperty} to this Property. For a given extension, only

*/
setExtension<Prop extends ExtensionProperty>(name: string, extensionProperty: Prop): this;
setExtension<Prop extends ExtensionProperty>(name: string, extensionProperty: Prop | null): this;
/**

@@ -31,0 +31,0 @@ * Lists all {@link ExtensionProperty} instances attached to this Property. *Not available on

@@ -97,2 +97,6 @@ import { PropertyType, vec3, vec4 } from '../constants';

/**********************************************************************************************
* Static.
*/
static AlphaMode: Record<string, GLTF.MaterialAlphaMode>;
/**********************************************************************************************
* Double-sided / culling.

@@ -166,3 +170,3 @@ */

*/
getBaseColorTexture(): Texture;
getBaseColorTexture(): Texture | null;
/**

@@ -172,5 +176,5 @@ * Settings affecting the material's use of its base color texture. If no texture is attached,

*/
getBaseColorTextureInfo(): TextureInfo;
getBaseColorTextureInfo(): TextureInfo | null;
/** Sets base color / albedo texture. See {@link getBaseColorTexture}. */
setBaseColorTexture(texture: Texture): this;
setBaseColorTexture(texture: Texture | null): this;
/**********************************************************************************************

@@ -202,3 +206,3 @@ * Emissive.

*/
getEmissiveTexture(): Texture;
getEmissiveTexture(): Texture | null;
/**

@@ -208,5 +212,5 @@ * Settings affecting the material's use of its emissive texture. If no texture is attached,

*/
getEmissiveTextureInfo(): TextureInfo;
getEmissiveTextureInfo(): TextureInfo | null;
/** Sets emissive texture. See {@link getEmissiveTexture}. */
setEmissiveTexture(texture: Texture): this;
setEmissiveTexture(texture: Texture | null): this;
/**********************************************************************************************

@@ -231,3 +235,3 @@ * Normal.

*/
getNormalTexture(): Texture;
getNormalTexture(): Texture | null;
/**

@@ -237,5 +241,5 @@ * Settings affecting the material's use of its normal texture. If no texture is attached,

*/
getNormalTextureInfo(): TextureInfo;
getNormalTextureInfo(): TextureInfo | null;
/** Sets normal (surface detail) texture. See {@link getNormalTexture}. */
setNormalTexture(texture: Texture): this;
setNormalTexture(texture: Texture | null): this;
/**********************************************************************************************

@@ -260,3 +264,3 @@ * Occlusion.

*/
getOcclusionTexture(): Texture;
getOcclusionTexture(): Texture | null;
/**

@@ -266,5 +270,5 @@ * Settings affecting the material's use of its occlusion texture. If no texture is attached,

*/
getOcclusionTextureInfo(): TextureInfo;
getOcclusionTextureInfo(): TextureInfo | null;
/** Sets (ambient) occlusion texture. See {@link getOcclusionTexture}. */
setOcclusionTexture(texture: Texture): this;
setOcclusionTexture(texture: Texture | null): this;
/**********************************************************************************************

@@ -302,3 +306,3 @@ * Metallic / roughness.

*/
getMetallicRoughnessTexture(): Texture;
getMetallicRoughnessTexture(): Texture | null;
/**

@@ -308,5 +312,5 @@ * Settings affecting the material's use of its metallic/roughness texture. If no texture is

*/
getMetallicRoughnessTextureInfo(): TextureInfo;
getMetallicRoughnessTextureInfo(): TextureInfo | null;
/** Sets metallic/roughness texture. See {@link getMetallicRoughnessTexture}. */
setMetallicRoughnessTexture(texture: Texture): this;
setMetallicRoughnessTexture(texture: Texture | null): this;
}

@@ -41,3 +41,3 @@ import { PropertyType, mat4, vec3, vec4 } from '../constants';

/** @hidden Internal reference to node's parent, omitted from {@link Graph}. */
_parent: SceneNode;
_parent: SceneNode | null;
private camera;

@@ -89,3 +89,3 @@ private mesh;

*/
getParent(): SceneNode;
getParent(): SceneNode | null;
/**********************************************************************************************

@@ -95,3 +95,3 @@ * Attachments.

/** Returns the {@link Mesh}, if any, instantiated at this node. */
getMesh(): Mesh;
getMesh(): Mesh | null;
/**

@@ -101,11 +101,11 @@ * Sets a {@link Mesh} to be instantiated at this node. A single mesh may be instatiated by

*/
setMesh(mesh: Mesh): this;
setMesh(mesh: Mesh | null): this;
/** Returns the {@link Camera}, if any, instantiated at this node. */
getCamera(): Camera;
getCamera(): Camera | null;
/** Sets a {@link Camera} to be instantiated at this node. */
setCamera(camera: Camera): this;
setCamera(camera: Camera | null): this;
/** Returns the {@link Skin}, if any, instantiated at this node. */
getSkin(): Skin;
getSkin(): Skin | null;
/** Sets a {@link Skin} to be instantiated at this node. */
setSkin(skin: Skin): this;
setSkin(skin: Skin | null): this;
/**

@@ -128,3 +128,3 @@ * Initial weights of each {@link PrimitiveTarget} for the mesh instance at this node.

interface SceneNode {
_parent?: SceneNode;
_parent?: SceneNode | null;
addChild(node: Node): this;

@@ -131,0 +131,0 @@ removeChild(node: Node): this;

@@ -25,7 +25,7 @@ import { PropertyType } from '../constants';

/** Returns a morph target vertex attribute as an {@link Accessor}. */
getAttribute(semantic: string): Accessor;
getAttribute(semantic: string): Accessor | null;
/**
* Sets a morph target vertex attribute to an {@link Accessor}.
*/
setAttribute(semantic: string, accessor: Accessor): this;
setAttribute(semantic: string, accessor: Accessor | null): this;
/**

@@ -32,0 +32,0 @@ * Lists all morph target vertex attribute {@link Accessor}s associated. Order will be

@@ -50,4 +50,12 @@ import { PropertyType } from '../constants';

copy(other: this, resolve?: <T extends import("./property").Property>(t: T) => T): this;
/**********************************************************************************************
* Static.
*/
/** Type of primitives to render. All valid values correspond to WebGL enums. */
static Mode: Record<string, GLTF.MeshPrimitiveMode>;
/**********************************************************************************************
* Primitive data.
*/
/** Returns an {@link Accessor} with indices of vertices to be drawn. */
getIndices(): Accessor;
getIndices(): Accessor | null;
/**

@@ -58,5 +66,5 @@ * Sets an {@link Accessor} with indices of vertices to be drawn. In `TRIANGLES` draw mode,

*/
setIndices(indices: Accessor): this;
setIndices(indices: Accessor | null): this;
/** Returns a vertex attribute as an {@link Accessor}. */
getAttribute(semantic: string): Accessor;
getAttribute(semantic: string): Accessor | null;
/**

@@ -66,3 +74,3 @@ * Sets a vertex attribute to an {@link Accessor}. All attributes must have the same vertex

*/
setAttribute(semantic: string, accessor: Accessor): this;
setAttribute(semantic: string, accessor: Accessor | null): this;
/**

@@ -81,5 +89,8 @@ * Lists all vertex attribute {@link Accessor}s associated with the primitive, excluding any

/** Returns the material used to render the primitive. */
getMaterial(): Material;
getMaterial(): Material | null;
/** Sets the material used to render the primitive. */
setMaterial(material: Material): this;
setMaterial(material: Material | null): this;
/**********************************************************************************************
* Mode.
*/
/**

@@ -99,2 +110,5 @@ * Returns the GPU draw mode (`TRIANGLES`, `LINES`, `POINTS`...) as a WebGL enum value.

setMode(mode: GLTF.MeshPrimitiveMode): this;
/**********************************************************************************************
* Morph targets.
*/
/** Lists all morph targets associated with the primitive. */

@@ -101,0 +115,0 @@ listTargets(): PrimitiveTarget[];

import { Graph } from '../graph';
import { Accessor } from './accessor';
import { Primitive } from './primitive';
import { PrimitiveTarget } from './primitive-target';
import { Property } from './property';

@@ -9,4 +8,8 @@ import { AttributeLink, IndexLink } from './property-links';

export declare class PropertyGraph extends Graph<Property> {
linkAttribute(name: string, a: Primitive | PrimitiveTarget, b: Accessor): AttributeLink;
linkAttribute(name: string, a: Property, b: null): null;
linkAttribute(name: string, a: Property, b: Accessor): AttributeLink;
linkAttribute(name: string, a: Property, b: Accessor | null): AttributeLink | null;
linkIndex(name: string, a: Primitive, b: null): null;
linkIndex(name: string, a: Primitive, b: Accessor): IndexLink;
linkIndex(name: string, a: Primitive, b: Accessor | null): IndexLink | null;
}
import { Link } from '../graph';
import { Accessor } from './accessor';
import { Primitive } from './primitive';
import { PrimitiveTarget } from './primitive-target';
import { Property } from './property';
/** @hidden */
export declare class AttributeLink extends Link<Primitive | PrimitiveTarget, Accessor> {
export declare class AttributeLink extends Link<Property, Accessor> {
semantic: string;

@@ -12,3 +12,3 @@ copy(other: this): this;

export declare class IndexLink extends Link<Primitive, Accessor> {
copy(other: this): this;
copy(_other: this): this;
}

@@ -41,5 +41,5 @@ import { GraphNode } from '../graph';

export declare abstract class Property extends GraphNode {
protected readonly graph: PropertyGraph;
/** Property type. */
abstract readonly propertyType: string;
protected readonly graph: PropertyGraph;
private _extras;

@@ -71,3 +71,3 @@ private _name;

*/
getExtras(): object;
getExtras(): Record<string, unknown>;
/**

@@ -77,3 +77,3 @@ * Updates the Extras object, containing application-specific data for this Property. Extras

*/
setExtras(extras: object): this;
setExtras(extras: Record<string, unknown>): this;
/**********************************************************************************************

@@ -80,0 +80,0 @@ * Graph state.

@@ -26,3 +26,3 @@ import { PropertyType } from '../constants';

*/
getSkeleton(): Node;
getSkeleton(): Node | null;
/**

@@ -32,3 +32,3 @@ * {@link Node} used as a skeleton root. The node must be the closest common root of the joints

*/
setSkeleton(skeleton: Node): this;
setSkeleton(skeleton: Node | null): this;
/**

@@ -39,3 +39,3 @@ * {@link Accessor} containing the floating-point 4x4 inverse-bind matrices. The default is

*/
getInverseBindMatrices(): Accessor;
getInverseBindMatrices(): Accessor | null;
/**

@@ -46,3 +46,3 @@ * {@link Accessor} containing the floating-point 4x4 inverse-bind matrices. The default is

*/
setInverseBindMatrices(inverseBindMatrices: Accessor): this;
setInverseBindMatrices(inverseBindMatrices: Accessor | null): this;
/** Adds a joint {@link Node} to this {@link Skin}. */

@@ -49,0 +49,0 @@ addJoint(joint: Node): this;

@@ -30,23 +30,12 @@ import { PropertyType } from '../constants';

private _wrapT;
copy(other: this, resolve?: <T extends import("./property").Property>(t: T) => T): this;
/**********************************************************************************************
* Static.
*/
/** UV wrapping mode. Values correspond to WebGL enums. */
static TextureWrapMode: {
CLAMP_TO_EDGE: GLTF.TextureWrapMode;
MIRRORED_REPEAT: GLTF.TextureWrapMode;
REPEAT: GLTF.TextureWrapMode;
};
static WrapMode: Record<string, GLTF.TextureWrapMode>;
/** Magnification filter. Values correspond to WebGL enums. */
static TextureMagFilter: {
NEAREST: GLTF.TextureMagFilter;
LINEAR: GLTF.TextureMagFilter;
};
static MagFilter: Record<string, GLTF.TextureMagFilter>;
/** Minification filter. Values correspond to WebGL enums. */
static TextureMinFilter: {
NEAREST: GLTF.TextureMinFilter;
LINEAR: GLTF.TextureMinFilter;
NEAREST_MIPMAP_NEAREST: GLTF.TextureMinFilter;
LINEAR_MIPMAP_NEAREST: GLTF.TextureMinFilter;
NEAREST_MIPMAP_LINEAR: GLTF.TextureMinFilter;
LINEAR_MIPMAP_LINEAR: GLTF.TextureMinFilter;
};
copy(other: this, resolve?: <T extends import("./property").Property>(t: T) => T): this;
static MinFilter: Record<string, GLTF.TextureMinFilter>;
/**********************************************************************************************

@@ -63,9 +52,9 @@ * Texture coordinates.

/** Returns the magnification filter applied to the texture. */
getMagFilter(): GLTF.TextureMagFilter;
getMagFilter(): GLTF.TextureMagFilter | null;
/** Sets the magnification filter applied to the texture. */
setMagFilter(magFilter: GLTF.TextureMagFilter): this;
setMagFilter(magFilter: GLTF.TextureMagFilter | null): this;
/** Sets the minification filter applied to the texture. */
getMinFilter(): GLTF.TextureMinFilter;
getMinFilter(): GLTF.TextureMinFilter | null;
/** Returns the minification filter applied to the texture. */
setMinFilter(minFilter: GLTF.TextureMinFilter): this;
setMinFilter(minFilter: GLTF.TextureMinFilter | null): this;
/**********************************************************************************************

@@ -72,0 +61,0 @@ * UV wrapping.

@@ -56,7 +56,7 @@ import { PropertyType, vec2 } from '../constants';

/** Returns the raw image data for this texture. */
getImage(): ArrayBuffer;
getImage(): ArrayBuffer | null;
/** Sets the raw image data for this texture. */
setImage(image: ArrayBuffer): this;
/** Returns the size, in pixels, of this texture. */
getSize(): vec2;
getSize(): vec2 | null;
}
/**
* Module for glTF 2.0 Interface
*/
* Module for glTF 2.0 Interface
*/
export declare module GLTF {
/** Data type of the values composing each element in the accessor. */
type AccessorComponentType = 5120 | 5121 | 5122 | 5123 | 5125 | 5126;
/** Element type contained by the accessor (SCALAR, VEC2, ...). */
type AccessorType = 'SCALAR' | 'VEC2' | 'VEC3' | 'VEC4' | 'MAT2' | 'MAT3' | 'MAT4';
/** Name of the property to be modified by an animation channel. */
type AnimationChannelTargetPath = 'translation' | 'rotation' | 'scale' | 'weights';
/** Interpolation method. */
type AnimationSamplerInterpolation = 'LINEAR' | 'STEP' | 'CUBICSPLINE';
/** Projection type used by a camera. */
type CameraType = 'perspective' | 'orthographic';
/** The alpha rendering mode of the material. */
type MaterialAlphaMode = 'OPAQUE' | 'MASK' | 'BLEND';
/** The type of the GL primitives to render. */
type MeshPrimitiveMode = 0 | 1 | 2 | 3 | 4 | 5 | 6;
/** Magnification filter. Values match to WebGL enums: 9728 (NEAREST) and 9729 (LINEAR). */
type TextureMagFilter = 9728 | 9729;
/** Minification filter. All valid values correspond to WebGL enums. */
type TextureMinFilter = 9728 | 9729 | 9984 | 9985 | 9986 | 9987;
/** S (U) wrapping mode. All valid values correspond to WebGL enums. */
type TextureWrapMode = 33071 | 33648 | 10497;
/**
* The datatype of the components in the attribute
*/
const enum AccessorComponentType {
/**
* Byte
*/
BYTE = 5120,
/**
* Unsigned Byte
*/
UNSIGNED_BYTE = 5121,
/**
* Short
*/
SHORT = 5122,
/**
* Unsigned Short
*/
UNSIGNED_SHORT = 5123,
/**
* Unsigned Int
*/
UNSIGNED_INT = 5125,
/**
* Float
*/
FLOAT = 5126
}
/**
* Specifies if the attirbute is a scalar, vector, or matrix
*/
const enum AccessorType {
/**
* Scalar
*/
SCALAR = "SCALAR",
/**
* Vector2
*/
VEC2 = "VEC2",
/**
* Vector3
*/
VEC3 = "VEC3",
/**
* Vector4
*/
VEC4 = "VEC4",
/**
* Matrix2x2
*/
MAT2 = "MAT2",
/**
* Matrix3x3
*/
MAT3 = "MAT3",
/**
* Matrix4x4
*/
MAT4 = "MAT4"
}
/**
* The name of the node's TRS property to modify, or the weights of the Morph Targets it instantiates
*/
const enum AnimationChannelTargetPath {
/**
* Translation
*/
TRANSLATION = "translation",
/**
* Rotation
*/
ROTATION = "rotation",
/**
* Scale
*/
SCALE = "scale",
/**
* Weights
*/
WEIGHTS = "weights"
}
/**
* Interpolation algorithm
*/
const enum AnimationSamplerInterpolation {
/**
* The animated values are linearly interpolated between keyframes
*/
LINEAR = "LINEAR",
/**
* The animated values remain constant to the output of the first keyframe, until the next keyframe
*/
STEP = "STEP",
/**
* The animation's interpolation is computed using a cubic spline with specified tangents
*/
CUBICSPLINE = "CUBICSPLINE"
}
/**
* A camera's projection. A node can reference a camera to apply a transform to place the camera in the scene
*/
const enum CameraType {
/**
* A perspective camera containing properties to create a perspective projection matrix
*/
PERSPECTIVE = "perspective",
/**
* An orthographic camera containing properties to create an orthographic projection matrix
*/
ORTHOGRAPHIC = "orthographic"
}
/**
* The alpha rendering mode of the material
*/
const enum MaterialAlphaMode {
/**
* The alpha value is ignored and the rendered output is fully opaque
*/
OPAQUE = "OPAQUE",
/**
* The rendered output is either fully opaque or fully transparent depending on the alpha value and the specified alpha cutoff value
*/
MASK = "MASK",
/**
* The alpha value is used to composite the source and destination areas. The rendered output is combined with the background using the normal painting operation (i.e. the Porter and Duff over operator)
*/
BLEND = "BLEND"
}
/**
* The type of the primitives to render
*/
const enum MeshPrimitiveMode {
/**
* Points
*/
POINTS = 0,
/**
* Lines
*/
LINES = 1,
/**
* Line Loop
*/
LINE_LOOP = 2,
/**
* Line Strip
*/
LINE_STRIP = 3,
/**
* Triangles
*/
TRIANGLES = 4,
/**
* Triangle Strip
*/
TRIANGLE_STRIP = 5,
/**
* Triangle Fan
*/
TRIANGLE_FAN = 6
}
/**
* Magnification filter. Valid values correspond to WebGL enums: 9728 (NEAREST) and 9729 (LINEAR)
*/
const enum TextureMagFilter {
/**
* Nearest
*/
NEAREST = 9728,
/**
* Linear
*/
LINEAR = 9729
}
/**
* Minification filter. All valid values correspond to WebGL enums
*/
const enum TextureMinFilter {
/**
* Nearest
*/
NEAREST = 9728,
/**
* Linear
*/
LINEAR = 9729,
/**
* Nearest Mip-Map Nearest
*/
NEAREST_MIPMAP_NEAREST = 9984,
/**
* Linear Mipmap Nearest
*/
LINEAR_MIPMAP_NEAREST = 9985,
/**
* Nearest Mipmap Linear
*/
NEAREST_MIPMAP_LINEAR = 9986,
/**
* Linear Mipmap Linear
*/
LINEAR_MIPMAP_LINEAR = 9987
}
/**
* S (U) wrapping mode. All valid values correspond to WebGL enums
*/
const enum TextureWrapMode {
/**
* Clamp to Edge
*/
CLAMP_TO_EDGE = 33071,
/**
* Mirrored Repeat
*/
MIRRORED_REPEAT = 33648,
/**
* Repeat
*/
REPEAT = 10497
}
/**
* glTF Property
*/
* glTF Property
*/
interface IProperty {
/**
* Dictionary object with extension-specific objects
*/
extensions?: {
[key: string]: any;
};
* Dictionary object with extension-specific objects
*/
extensions?: Record<string, unknown>;
/**
* Application-Specific data
*/
extras?: any;
* Application-Specific data
*/
extras?: Record<string, unknown>;
}
/**
* glTF Child of Root Property
*/
* glTF Child of Root Property
*/
interface IChildRootProperty extends IProperty {
/**
* The user-defined name of this object
*/
* The user-defined name of this object
*/
name?: string;
}
/**
* Indices of those attributes that deviate from their initialization value
*/
* Indices of those attributes that deviate from their initialization value
*/
interface IAccessorSparseIndices extends IProperty {
/**
* The index of the bufferView with sparse indices. Referenced bufferView can't have ARRAY_BUFFER or ELEMENT_ARRAY_BUFFER target
*/
* The index of the bufferView with sparse indices. Referenced bufferView can't have
* ARRAY_BUFFER or ELEMENT_ARRAY_BUFFER target
*/
bufferView: number;
/**
* The offset relative to the start of the bufferView in bytes. Must be aligned
*/
* The offset relative to the start of the bufferView in bytes. Must be aligned
*/
byteOffset?: number;
/**
* The indices data type. Valid values correspond to WebGL enums: 5121 (UNSIGNED_BYTE), 5123 (UNSIGNED_SHORT), 5125 (UNSIGNED_INT)
*/
* The indices data type. Valid values correspond to WebGL enums: 5121 (UNSIGNED_BYTE),
* 5123 (UNSIGNED_SHORT), 5125 (UNSIGNED_INT)
*/
componentType: AccessorComponentType;
}
/**
* Array of size accessor.sparse.count times number of components storing the displaced accessor attributes pointed by accessor.sparse.indices
*/
* Array of size accessor.sparse.count times number of components storing the displaced accessor
* attributes pointed by accessor.sparse.indices
*/
interface IAccessorSparseValues extends IProperty {
/**
* The index of the bufferView with sparse values. Referenced bufferView can't have ARRAY_BUFFER or ELEMENT_ARRAY_BUFFER target
*/
* The index of the bufferView with sparse values. Referenced bufferView can't have
* ARRAY_BUFFER or ELEMENT_ARRAY_BUFFER target
*/
bufferView: number;
/**
* The offset relative to the start of the bufferView in bytes. Must be aligned
*/
* The offset relative to the start of the bufferView in bytes. Must be aligned
*/
byteOffset?: number;
}
/**
* Sparse storage of attributes that deviate from their initialization value
*/
* Sparse storage of attributes that deviate from their initialization value
*/
interface IAccessorSparse extends IProperty {
/**
* The number of attributes encoded in this sparse accessor
*/
* The number of attributes encoded in this sparse accessor
*/
count: number;
/**
* Index array of size count that points to those accessor attributes that deviate from their initialization value. Indices must strictly increase
*/
* Index array of size count that points to those accessor attributes that deviate from
* their initialization value. Indices must strictly increase
*/
indices: IAccessorSparseIndices;
/**
* Array of size count times number of components, storing the displaced accessor attributes pointed by indices. Substituted values must have the same componentType and number of components as the base accessor
*/
* Array of size count times number of components, storing the displaced accessor attributes
* pointed by indices. Substituted values must have the same componentType and number of
* components as the base accessor
*/
values: IAccessorSparseValues;
}
/**
* A typed view into a bufferView. A bufferView contains raw binary data. An accessor provides a typed view into a bufferView or a subset of a bufferView similar to how WebGL's vertexAttribPointer() defines an attribute in a buffer
*/
* A typed view into a bufferView. A bufferView contains raw binary data. An accessor provides
* a typed view into a bufferView or a subset of a bufferView similar to how WebGL's
* vertexAttribPointer() defines an attribute in a buffer
*/
interface IAccessor extends IChildRootProperty {
/**
* The index of the bufferview
*/
* The index of the bufferview
*/
bufferView?: number;
/**
* The offset relative to the start of the bufferView in bytes
*/
* The offset relative to the start of the bufferView in bytes
*/
byteOffset?: number;
/**
* The datatype of components in the attribute
*/
* The datatype of components in the attribute
*/
componentType: AccessorComponentType;
/**
* Specifies whether integer data values should be normalized
*/
* Specifies whether integer data values should be normalized
*/
normalized?: boolean;
/**
* The number of attributes referenced by this accessor
*/
* The number of attributes referenced by this accessor
*/
count: number;
/**
* Specifies if the attribute is a scalar, vector, or matrix
*/
* Specifies if the attribute is a scalar, vector, or matrix
*/
type: AccessorType;
/**
* Maximum value of each component in this attribute
*/
* Maximum value of each component in this attribute
*/
max?: number[];
/**
* Minimum value of each component in this attribute
*/
* Minimum value of each component in this attribute
*/
min?: number[];
/**
* Sparse storage of attributes that deviate from their initialization value
*/
* Sparse storage of attributes that deviate from their initialization value
*/
sparse?: IAccessorSparse;
}
/**
* Targets an animation's sampler at a node's property
*/
* Targets an animation's sampler at a node's property
*/
interface IAnimationChannel extends IProperty {
/**
* The index of a sampler in this animation used to compute the value for the target
*/
* The index of a sampler in this animation used to compute the value for the target
*/
sampler: number;
/**
* The index of the node and TRS property to target
*/
* The index of the node and TRS property to target
*/
target: IAnimationChannelTarget;
}
/**
* The index of the node and TRS property that an animation channel targets
*/
* The index of the node and TRS property that an animation channel targets
*/
interface IAnimationChannelTarget extends IProperty {
/**
* The index of the node to target
*/
* The index of the node to target
*/
node: number;
/**
* The name of the node's TRS property to modify, or the weights of the Morph Targets it instantiates
*/
* The name of the node's TRS property to modify, or the weights of the Morph Targets it
* instantiates
*/
path: AnimationChannelTargetPath;
}
/**
* Combines input and output accessors with an interpolation algorithm to define a keyframe graph (but not its target)
*/
* Combines input and output accessors with an interpolation algorithm to define a keyframe
* graph (but not its target)
*/
interface IAnimationSampler extends IProperty {
/**
* The index of an accessor containing keyframe input values, e.g., time
*/
* The index of an accessor containing keyframe input values, e.g., time
*/
input: number;
/**
* Interpolation algorithm
*/
* Interpolation algorithm
*/
interpolation?: AnimationSamplerInterpolation;
/**
* The index of an accessor, containing keyframe output values
*/
* The index of an accessor, containing keyframe output values
*/
output: number;
}
/**
* A keyframe animation
*/
* A keyframe animation
*/
interface IAnimation extends IChildRootProperty {
/**
* An array of channels, each of which targets an animation's sampler at a node's property
*/
* An array of channels, each of which targets an animation's sampler at a node's property
*/
channels: IAnimationChannel[];
/**
* An array of samplers that combines input and output accessors with an interpolation algorithm to define a keyframe graph (but not its target)
*/
* An array of samplers that combines input and output accessors with an interpolation
* algorithm to define a keyframe graph (but not its target)
*/
samplers: IAnimationSampler[];
}
/**
* Metadata about the glTF asset
*/
* Metadata about the glTF asset
*/
interface IAsset extends IChildRootProperty {
/**
* A copyright message suitable for display to credit the content creator
*/
* A copyright message suitable for display to credit the content creator
*/
copyright?: string;
/**
* Tool that generated this glTF model. Useful for debugging
*/
* Tool that generated this glTF model. Useful for debugging
*/
generator?: string;
/**
* The glTF version that this asset targets
*/
* The glTF version that this asset targets
*/
version: string;
/**
* The minimum glTF version that this asset targets
*/
* The minimum glTF version that this asset targets
*/
minVersion?: string;
}
/**
* A buffer points to binary geometry, animation, or skins
*/
* A buffer points to binary geometry, animation, or skins
*/
interface IBuffer extends IChildRootProperty {
/**
* The uri of the buffer. Relative paths are relative to the .gltf file. Instead of referencing an external file, the uri can also be a data-uri
*/
* The uri of the buffer. Relative paths are relative to the .gltf file. Instead of
* referencing an external file, the uri can also be a data-uri
*/
uri?: string;
/**
* The length of the buffer in bytes
*/
* The length of the buffer in bytes
*/
byteLength: number;
}
/**
* A view into a buffer generally representing a subset of the buffer
*/
* A view into a buffer generally representing a subset of the buffer
*/
interface IBufferView extends IChildRootProperty {
/**
* The index of the buffer
*/
* The index of the buffer
*/
buffer: number;
/**
* The offset into the buffer in bytes
*/
* The offset into the buffer in bytes
*/
byteOffset?: number;
/**
* The lenth of the bufferView in bytes
*/
* The lenth of the bufferView in bytes
*/
byteLength: number;
/**
* The stride, in bytes
*/
* The stride, in bytes
*/
byteStride?: number;
/**
* The target that the GPU buffer should be bound to
*/
* The target that the GPU buffer should be bound to
*/
target?: number;
}
/**
* An orthographic camera containing properties to create an orthographic projection matrix
*/
* An orthographic camera containing properties to create an orthographic projection matrix
*/
interface ICameraOrthographic extends IProperty {
/**
* The floating-point horizontal magnification of the view. Must not be zero
*/
* The floating-point horizontal magnification of the view. Must not be zero
*/
xmag: number;
/**
* The floating-point vertical magnification of the view. Must not be zero
*/
* The floating-point vertical magnification of the view. Must not be zero
*/
ymag: number;
/**
* The floating-point distance to the far clipping plane. zfar must be greater than znear
*/
* The floating-point distance to the far clipping plane. zfar must be greater than znear
*/
zfar: number;
/**
* The floating-point distance to the near clipping plane
*/
* The floating-point distance to the near clipping plane
*/
znear: number;
}
/**
* A perspective camera containing properties to create a perspective projection matrix
*/
* A perspective camera containing properties to create a perspective projection matrix
*/
interface ICameraPerspective extends IProperty {
/**
* The floating-point aspect ratio of the field of view
*/
* The floating-point aspect ratio of the field of view
*/
aspectRatio?: number;
/**
* The floating-point vertical field of view in radians
*/
* The floating-point vertical field of view in radians
*/
yfov: number;
/**
* The floating-point distance to the far clipping plane
*/
* The floating-point distance to the far clipping plane
*/
zfar?: number;
/**
* The floating-point distance to the near clipping plane
*/
* The floating-point distance to the near clipping plane
*/
znear: number;
}
/**
* A camera's projection. A node can reference a camera to apply a transform to place the camera in the scene
*/
* A camera's projection. A node can reference a camera to apply a transform to place the
* camera in the scene
*/
interface ICamera extends IChildRootProperty {
/**
* An orthographic camera containing properties to create an orthographic projection matrix
*/
* An orthographic camera containing properties to create an orthographic projection matrix
*/
orthographic?: ICameraOrthographic;
/**
* A perspective camera containing properties to create a perspective projection matrix
*/
* A perspective camera containing properties to create a perspective projection matrix
*/
perspective?: ICameraPerspective;
/**
* Specifies if the camera uses a perspective or orthographic projection
*/
* Specifies if the camera uses a perspective or orthographic projection
*/
type: CameraType;
}
/**
* Image data used to create a texture. Image can be referenced by URI or bufferView index. mimeType is required in the latter case
*/
* Image data used to create a texture. Image can be referenced by URI or bufferView index.
* mimeType is required in the latter case
*/
interface IImage extends IChildRootProperty {
/**
* The uri of the image. Relative paths are relative to the .gltf file. Instead of referencing an external file, the uri can also be a data-uri. The image format must be jpg or png
*/
* The uri of the image. Relative paths are relative to the .gltf file. Instead of
* referencing an external file, the uri can also be a data-uri. The image format must be
* jpg or png
*/
uri?: string;
/**
* The image's MIME type
*/
* The image's MIME type
*/
mimeType?: string;
/**
* The index of the bufferView that contains the image. Use this instead of the image's uri property
*/
* The index of the bufferView that contains the image. Use this instead of the image's uri
* property
*/
bufferView?: number;
}
/**
* Material Normal Texture Info
*/
* Material Normal Texture Info
*/
interface IMaterialNormalTextureInfo extends ITextureInfo {
/**
* The scalar multiplier applied to each normal vector of the normal texture
*/
* The scalar multiplier applied to each normal vector of the normal texture
*/
scale?: number;
}
/**
* Material Occlusion Texture Info
*/
* Material Occlusion Texture Info
*/
interface IMaterialOcclusionTextureInfo extends ITextureInfo {
/**
* A scalar multiplier controlling the amount of occlusion applied
*/
* A scalar multiplier controlling the amount of occlusion applied
*/
strength?: number;
}
/**
* A set of parameter values that are used to define the metallic-roughness material model from Physically-Based Rendering (PBR) methodology
*/
* A set of parameter values that are used to define the metallic-roughness material model from
* Physically-Based Rendering (PBR) methodology
*/
interface IMaterialPbrMetallicRoughness {
/**
* The material's base color factor
*/
* The material's base color factor
*/
baseColorFactor?: number[];
/**
* The base color texture
*/
* The base color texture
*/
baseColorTexture?: ITextureInfo;
/**
* The metalness of the material
*/
* The metalness of the material
*/
metallicFactor?: number;
/**
* The roughness of the material
*/
* The roughness of the material
*/
roughnessFactor?: number;
/**
* The metallic-roughness texture
*/
* The metallic-roughness texture
*/
metallicRoughnessTexture?: ITextureInfo;
}
/**
* The material appearance of a primitive
*/
* The material appearance of a primitive
*/
interface IMaterial extends IChildRootProperty {
/**
* A set of parameter values that are used to define the metallic-roughness material model from Physically-Based Rendering (PBR) methodology. When not specified, all the default values of pbrMetallicRoughness apply
*/
* A set of parameter values that are used to define the metallic-roughness material model
* from Physically-Based Rendering (PBR) methodology. When not specified, all the default
* values of pbrMetallicRoughness apply
*/
pbrMetallicRoughness?: IMaterialPbrMetallicRoughness;
/**
* The normal map texture
*/
* The normal map texture
*/
normalTexture?: IMaterialNormalTextureInfo;
/**
* The occlusion map texture
*/
* The occlusion map texture
*/
occlusionTexture?: IMaterialOcclusionTextureInfo;
/**
* The emissive map texture
*/
* The emissive map texture
*/
emissiveTexture?: ITextureInfo;
/**
* The RGB components of the emissive color of the material. These values are linear. If an emissiveTexture is specified, this value is multiplied with the texel values
*/
* The RGB components of the emissive color of the material. These values are linear. If
* an emissiveTexture is specified, this value is multiplied with the texel values
*/
emissiveFactor?: number[];
/**
* The alpha rendering mode of the material
*/
* The alpha rendering mode of the material
*/
alphaMode?: MaterialAlphaMode;
/**
* The alpha cutoff value of the material
*/
* The alpha cutoff value of the material
*/
alphaCutoff?: number;
/**
* Specifies whether the material is double sided
*/
* Specifies whether the material is double sided
*/
doubleSided?: boolean;
}
/**
* Geometry to be rendered with the given material
*/
* Geometry to be rendered with the given material
*/
interface IMeshPrimitive extends IProperty {
/**
* A dictionary object, where each key corresponds to mesh attribute semantic and each value is the index of the accessor containing attribute's data
*/
* A dictionary object, where each key corresponds to mesh attribute semantic and each
* value is the index of the accessor containing attribute's data
*/
attributes: {

@@ -621,16 +440,17 @@ [name: string]: number;

/**
* The index of the accessor that contains the indices
*/
* The index of the accessor that contains the indices
*/
indices?: number;
/**
* The index of the material to apply to this primitive when rendering
*/
* The index of the material to apply to this primitive when rendering
*/
material?: number;
/**
* The type of primitives to render. All valid values correspond to WebGL enums
*/
* The type of primitives to render. All valid values correspond to WebGL enums
*/
mode?: MeshPrimitiveMode;
/**
* An array of Morph Targets, each Morph Target is a dictionary mapping attributes (only POSITION, NORMAL, and TANGENT supported) to their deviations in the Morph Target
*/
* An array of Morph Targets, each Morph Target is a dictionary mapping attributes (only
* POSITION, NORMAL, and TANGENT supported) to their deviations in the Morph Target
*/
targets?: {

@@ -641,201 +461,211 @@ [name: string]: number;

/**
* A set of primitives to be rendered. A node can contain one mesh. A node's transform places the mesh in the scene
*/
* A set of primitives to be rendered. A node can contain one mesh. A node's transform
* places the mesh in the scene
*/
interface IMesh extends IChildRootProperty {
/**
* An array of primitives, each defining geometry to be rendered with a material
*/
* An array of primitives, each defining geometry to be rendered with a material
*/
primitives: IMeshPrimitive[];
/**
* Array of weights to be applied to the Morph Targets
*/
* Array of weights to be applied to the Morph Targets
*/
weights?: number[];
}
/**
* A node in the node hierarchy
*/
* A node in the node hierarchy
*/
interface INode extends IChildRootProperty {
/**
* The index of the camera referenced by this node
*/
* The index of the camera referenced by this node
*/
camera?: number;
/**
* The indices of this node's children
*/
* The indices of this node's children
*/
children?: number[];
/**
* The index of the skin referenced by this node
*/
* The index of the skin referenced by this node
*/
skin?: number;
/**
* A floating-point 4x4 transformation matrix stored in column-major order
*/
* A floating-point 4x4 transformation matrix stored in column-major order
*/
matrix?: number[];
/**
* The index of the mesh in this node
*/
* The index of the mesh in this node
*/
mesh?: number;
/**
* The node's unit quaternion rotation in the order (x, y, z, w), where w is the scalar
*/
* The node's unit quaternion rotation in the order (x, y, z, w), where w is the scalar
*/
rotation?: number[];
/**
* The node's non-uniform scale, given as the scaling factors along the x, y, and z axes
*/
* The node's non-uniform scale, given as the scaling factors along the x, y, and z axes
*/
scale?: number[];
/**
* The node's translation along the x, y, and z axes
*/
* The node's translation along the x, y, and z axes
*/
translation?: number[];
/**
* The weights of the instantiated Morph Target. Number of elements must match number of Morph Targets of used mesh
*/
* The weights of the instantiated Morph Target. Number of elements must match number of
* Morph Targets of used mesh
*/
weights?: number[];
}
/**
* Texture sampler properties for filtering and wrapping modes
*/
* Texture sampler properties for filtering and wrapping modes
*/
interface ISampler extends IChildRootProperty {
/**
* Magnification filter. Valid values correspond to WebGL enums: 9728 (NEAREST) and 9729 (LINEAR)
*/
* Magnification filter. Valid values correspond to WebGL enums: 9728 (NEAREST) and 9729
* (LINEAR)
*/
magFilter?: TextureMagFilter;
/**
* Minification filter. All valid values correspond to WebGL enums
*/
* Minification filter. All valid values correspond to WebGL enums
*/
minFilter?: TextureMinFilter;
/**
* S (U) wrapping mode. All valid values correspond to WebGL enums
*/
* S (U) wrapping mode. All valid values correspond to WebGL enums
*/
wrapS?: TextureWrapMode;
/**
* T (V) wrapping mode. All valid values correspond to WebGL enums
*/
* T (V) wrapping mode. All valid values correspond to WebGL enums
*/
wrapT?: TextureWrapMode;
}
/**
* The root nodes of a scene
*/
* The root nodes of a scene
*/
interface IScene extends IChildRootProperty {
/**
* The indices of each root node
*/
* The indices of each root node
*/
nodes: number[];
}
/**
* Joints and matrices defining a skin
*/
* Joints and matrices defining a skin
*/
interface ISkin extends IChildRootProperty {
/**
* The index of the accessor containing the floating-point 4x4 inverse-bind matrices. The default is that each matrix is a 4x4 identity matrix, which implies that inverse-bind matrices were pre-applied
*/
* The index of the accessor containing the floating-point 4x4 inverse-bind matrices. The
* default is that each matrix is a 4x4 identity matrix, which implies that inverse-bind
* matrices were pre-applied
*/
inverseBindMatrices?: number;
/**
* The index of the node used as a skeleton root. When undefined, joints transforms resolve to scene root
*/
* The index of the node used as a skeleton root. When undefined, joints transforms resolve
* to scene root
*/
skeleton?: number;
/**
* Indices of skeleton nodes, used as joints in this skin. The array length must be the same as the count property of the inverseBindMatrices accessor (when defined)
*/
* Indices of skeleton nodes, used as joints in this skin. The array length must be the
* same as the count property of the inverseBindMatrices accessor (when defined)
*/
joints: number[];
}
/**
* A texture and its sampler
*/
* A texture and its sampler
*/
interface ITexture extends IChildRootProperty {
/**
* The index of the sampler used by this texture. When undefined, a sampler with repeat wrapping and auto filtering should be used
*/
* The index of the sampler used by this texture. When undefined, a sampler with repeat
* wrapping and auto filtering should be used
*/
sampler?: number;
/**
* The index of the image used by this texture
*/
source: number;
* The index of the image used by this texture
*/
source?: number;
}
/**
* Reference to a texture
*/
* Reference to a texture
*/
interface ITextureInfo extends IProperty {
/**
* The index of the texture
*/
* The index of the texture
*/
index: number;
/**
* The set index of texture's TEXCOORD attribute used for texture coordinate mapping
*/
* The set index of texture's TEXCOORD attribute used for texture coordinate mapping
*/
texCoord?: number;
}
/**
* The root object for a glTF asset
*/
* The root object for a glTF asset
*/
interface IGLTF extends IProperty {
/**
* An array of accessors. An accessor is a typed view into a bufferView
*/
* An array of accessors. An accessor is a typed view into a bufferView
*/
accessors?: IAccessor[];
/**
* An array of keyframe animations
*/
* An array of keyframe animations
*/
animations?: IAnimation[];
/**
* Metadata about the glTF asset
*/
* Metadata about the glTF asset
*/
asset: IAsset;
/**
* An array of buffers. A buffer points to binary geometry, animation, or skins
*/
* An array of buffers. A buffer points to binary geometry, animation, or skins
*/
buffers?: IBuffer[];
/**
* An array of bufferViews. A bufferView is a view into a buffer generally representing a subset of the buffer
*/
* An array of bufferViews. A bufferView is a view into a buffer generally representing
* a subset of the buffer
*/
bufferViews?: IBufferView[];
/**
* An array of cameras
*/
* An array of cameras
*/
cameras?: ICamera[];
/**
* Names of glTF extensions used somewhere in this asset
*/
* Names of glTF extensions used somewhere in this asset
*/
extensionsUsed?: string[];
/**
* Names of glTF extensions required to properly load this asset
*/
* Names of glTF extensions required to properly load this asset
*/
extensionsRequired?: string[];
/**
* An array of images. An image defines data used to create a texture
*/
* An array of images. An image defines data used to create a texture
*/
images?: IImage[];
/**
* An array of materials. A material defines the appearance of a primitive
*/
* An array of materials. A material defines the appearance of a primitive
*/
materials?: IMaterial[];
/**
* An array of meshes. A mesh is a set of primitives to be rendered
*/
* An array of meshes. A mesh is a set of primitives to be rendered
*/
meshes?: IMesh[];
/**
* An array of nodes
*/
* An array of nodes
*/
nodes?: INode[];
/**
* An array of samplers. A sampler contains properties for texture filtering and wrapping modes
*/
* An array of samplers. A sampler contains properties for texture filtering and wrapping
* modes
*/
samplers?: ISampler[];
/**
* The index of the default scene
*/
* The index of the default scene
*/
scene?: number;
/**
* An array of scenes
*/
* An array of scenes
*/
scenes?: IScene[];
/**
* An array of skins. A skin is defined by joints and matrices
*/
* An array of skins. A skin is defined by joints and matrices
*/
skins?: ISkin[];
/**
* An array of textures
*/
* An array of textures
*/
textures?: ITexture[];
}
}

@@ -10,17 +10,25 @@ import { vec2 } from '../constants';

declare class ImageUtils {
/** Returns [conservative] estimate of the dimensions of the image. */
/** Returns the dimensions of the image. */
static getSize(buffer: ArrayBuffer, mimeType: string): vec2;
/** Returns [conservative] estimate of the number of channels in the image. */
/**
* Returns a conservative estimate of the number of channels in the image. For some image
* formats, the method may return 4 indicating the possibility of an alpha channel, without
* the ability to guarantee that an alpha channel is present.
*/
static getChannels(buffer: ArrayBuffer, mimeType: string): number;
/** Returns [conservative] estimate of the GPU memory required by this image. */
/** Returns a conservative estimate of the GPU memory required by this image. */
static getMemSize(buffer: ArrayBuffer, mimeType: string): number;
/** Returns the size of a JPEG image. */
/** @hidden Returns the size of a JPEG image. */
private static _getSizeJPEG;
/** Returns the size of a PNG image. */
/** @hidden Returns the size of a PNG image. */
private static _getSizePNG;
/** @hidden Returns the size of a WebP image. */
private static _getSizeWebP;
/** @hidden */
private static _getSizeKTX2;
/** Returns the preferred file extension for the given MIME type. */
static mimeTypeToExtension(mimeType: string): string;
/** Returns the MIME type for the given file extension. */
static extensionToMimeType(extension: string): string;
}
export { ImageUtils };

@@ -5,4 +5,5 @@ import { GLTF } from '../types/gltf';

static identity(v: number): number;
static eq(a: number[], b: number[]): boolean;
static denormalize(c: number, componentType: GLTF.AccessorComponentType): number;
static normalize(f: number, componentType: GLTF.AccessorComponentType): number;
}
{
"name": "@gltf-transform/core",
"version": "0.8.4",
"version": "0.9.0",
"repository": "github:donmccurdy/glTF-Transform",

@@ -42,3 +42,3 @@ "description": "glTF 2.0 SDK for JavaScript, TypeScript, and Node.js",

},
"gitHead": "c0f5e0e9983dfa3bda71dd3687d762422b71ac17"
"gitHead": "b518862852f07deddffc7b2ffa8bd6c8f4233149"
}

@@ -76,3 +76,3 @@ // Injected at compile time, from $npm_package_version.

/**
* Abstraction representing any one of the typed array constructors supported by glTF and JavaScript.
* Abstraction representing the typed array constructors supported by glTF and JavaScript.
* @hidden

@@ -79,0 +79,0 @@ */

@@ -0,4 +1,7 @@

/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-namespace */
export { Document, Transform } from './document';
export { JSONDocument } from './json-document';
export { Extension } from './extension';
export { Accessor, Animation, AnimationChannel, AnimationSampler, Buffer, Camera, ExtensionProperty, Property, Material, Mesh, Node, Primitive, PrimitiveTarget, Root, Scene, Skin, Texture, TextureInfo, COPY_IDENTITY } from './properties';
export { Accessor, Animation, AnimationChannel, AnimationSampler, Buffer, Camera, ExtensionProperty, Property, Material, Mesh, Node, Primitive, PrimitiveTarget, Root, Scene, Skin, Texture, TextureInfo, AttributeLink, IndexLink, COPY_IDENTITY } from './properties';
export { Graph, GraphChild, GraphChildList, Link } from './graph/';

@@ -11,12 +14,12 @@ export { NodeIO, WebIO, ReaderContext, WriterContext } from './io/';

/** [[include:CONCEPTS.md]] */
namespace Concepts {};
namespace Concepts {}
/** [[include:LIBRARY.md]] */
namespace Library {};
namespace Library {}
/** [[include:EXTENSIONS.md]] */
namespace Extensions {};
namespace Extensions {}
/** [[include:CONTRIBUTING.md]] */
namespace Contributing {};
namespace Contributing {}

@@ -42,2 +45,2 @@ /**

*/
namespace CLI {};
namespace CLI {}

@@ -132,3 +132,4 @@ import { PropertyType } from './constants';

// For other property types, create stub classes.
const PropertyClass = thisProp.constructor as new(g: PropertyGraph, e?: Extension) => Property;
const PropertyClass = thisProp.constructor as
new(g: PropertyGraph, e?: Extension) => Property;
otherProp = thisProp instanceof ExtensionProperty

@@ -145,5 +146,10 @@ ? new PropertyClass(this._graph, thisExtensions[thisProp.extensionName])

// 4. Assemble the links between Properties.
const resolve = (p: Property): Property => propertyMap.get(p);
const resolve = (p: Property): Property => {
const resolved = propertyMap.get(p);
if (!resolved) throw new Error('Could resolve property.');
return resolved;
};
for (const otherProp of visited) {
const thisProp = propertyMap.get(otherProp);
if (!thisProp) throw new Error('Could resolve property.');
thisProp.copy(otherProp, resolve);

@@ -285,3 +291,3 @@ }

/** Creates a new {@link Accessor} attached to this document's {@link Root}. */
createAccessor(name = '', buffer: Buffer = null): Accessor {
createAccessor(name = '', buffer: Buffer | null = null): Accessor {
if (!buffer) {

@@ -288,0 +294,0 @@ buffer = this.getRoot().listBuffers()[0];

@@ -116,4 +116,3 @@ import { PropertyType } from './constants';

*/
// eslint-disable-next-line @typescript-eslint/no-unused-vars
public preread(readerContext: ReaderContext, propertyType: PropertyType): this {
public preread(_readerContext: ReaderContext, _propertyType: PropertyType): this {
return this;

@@ -130,4 +129,3 @@ }

*/
// eslint-disable-next-line @typescript-eslint/no-unused-vars
public prewrite(writerContext: WriterContext, propertyType: PropertyType): this {
public prewrite(_writerContext: WriterContext, _propertyType: PropertyType): this {
return this;

@@ -134,0 +132,0 @@ }

@@ -1,3 +0,8 @@

/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/no-unused-vars */
/*
eslint-disable
@typescript-eslint/no-explicit-any,
@typescript-eslint/no-empty-function,
@typescript-eslint/no-unused-vars,
@typescript-eslint/explicit-module-boundary-types
*/

@@ -43,3 +48,2 @@ const DECORATOR_PREFIX = '__';

*/
// eslint-disable-next-line @typescript-eslint/no-empty-function
export function GraphChildList (target: any, propertyKey: string): void {}

@@ -11,5 +11,4 @@ import { Graph } from './graph';

export abstract class GraphNode {
protected readonly graph: Graph<GraphNode>;
private _disposed = false;
constructor(graph: Graph<GraphNode>) {
constructor(protected readonly graph: Graph<GraphNode>) {
this.graph = graph;

@@ -73,3 +72,5 @@ }

*/
protected addGraphChild(links: Link<GraphNode, GraphNode>[], link: Link<GraphNode, GraphNode>): this {
protected addGraphChild(
links: Link<GraphNode, GraphNode>[],
link: Link<GraphNode, GraphNode>): this {
links.push(link);

@@ -76,0 +77,0 @@ link.onDispose(() => {

@@ -65,7 +65,7 @@ import { Link } from './graph-links';

.forEach((link) => {
this._childRefs.get(prevChild).delete(link);
this._childRefs.get(prevChild)!.delete(link);
link.setChild(nextChild);
if (!this._childRefs.has(nextChild)) this._childRefs.set(nextChild, new Set());
this._childRefs.get(nextChild).add(link);
this._childRefs.get(nextChild)!.add(link);
});

@@ -81,3 +81,6 @@ return this;

*/
public link<A extends T, B extends T>(name: string, a: A, b: B): Link<A, B> {
public link<A extends T>(name: string, a: A, b: null): null;
public link<A extends T, B extends T>(name: string, a: A, b: B): Link<A, B>;
public link<A extends T, B extends T>(name: string, a: A, b: B | null): Link<A, B> | null;
public link<A extends T, B extends T>(name: string, a: A, b: B | null): Link<A, B> | null {
// If there's no resource, return a null link. Avoids a lot of boilerplate in node setters.

@@ -96,7 +99,7 @@ if (!b) return null;

if (!this._parentRefs.has(parent)) this._parentRefs.set(parent, new Set());
this._parentRefs.get(parent).add(link);
this._parentRefs.get(parent)!.add(link);
const child = link.getChild();
if (!this._childRefs.has(child)) this._childRefs.set(child, new Set());
this._childRefs.get(child).add(link);
this._childRefs.get(child)!.add(link);

@@ -115,6 +118,6 @@ link.onDispose(() => this.unlink(link));

this._links.delete(link);
this._parentRefs.get(link.getParent()).delete(link);
this._childRefs.get(link.getChild()).delete(link);
this._parentRefs.get(link.getParent())!.delete(link);
this._childRefs.get(link.getChild())!.delete(link);
return this;
}
}

@@ -127,3 +127,4 @@ import { GLB_BUFFER } from '../constants';

const binaryChunkData = BufferUtils.pad(Object.values(resources)[0] || new ArrayBuffer(0), 0x00);
const binaryChunkData
= BufferUtils.pad(Object.values(resources)[0] || new ArrayBuffer(0), 0x00);
const binaryChunkHeader = new Uint32Array([binaryChunkData.byteLength, 0x004E4942]).buffer;

@@ -130,0 +131,0 @@ const binaryChunk = BufferUtils.concat([binaryChunkHeader, binaryChunkData]);

@@ -1,3 +0,3 @@

import { determinant, getRotation } from 'gl-matrix/mat4'
import { length } from 'gl-matrix/vec3'
import { determinant, getRotation } from 'gl-matrix/mat4';
import { length } from 'gl-matrix/vec3';
import { GLB_BUFFER, PropertyType, TypedArray, mat4, vec3, vec4 } from '../constants';

@@ -7,3 +7,3 @@ import { Document } from '../document';

import { JSONDocument } from '../json-document';
import { Accessor } from '../properties';
import { Accessor, AnimationSampler, Camera } from '../properties';
import { GLTF } from '../types/gltf';

@@ -62,4 +62,5 @@ import { FileUtils, ImageUtils, Logger } from '../utils';

if (extensionsUsed.includes(Extension.EXTENSION_NAME)) {
const extension = doc.createExtension(Extension as unknown as new (doc: Document) => Extension)
.setRequired(extensionsRequired.includes(Extension.EXTENSION_NAME));
const extension = doc.createExtension(
Extension as unknown as new (doc: Document) => Extension
).setRequired(extensionsRequired.includes(Extension.EXTENSION_NAME));

@@ -306,3 +307,3 @@ for (const key of extension.dependencies) {

mesh.addPrimitive(primitive);
})
});

@@ -320,3 +321,3 @@ return mesh;

if (cameraDef.type === GLTF.CameraType.PERSPECTIVE) {
if (cameraDef.type === Camera.Type.PERSPECTIVE) {
camera

@@ -414,3 +415,3 @@ .setZNear(cameraDef.perspective.znear)

if (nodeDef.skin !== undefined) node.setSkin(context.skins[nodeDef.skin]);
})
});

@@ -430,3 +431,5 @@ /** Animations. */

.setOutput(context.accessors[samplerDef.output])
.setInterpolation(samplerDef.interpolation || GLTF.AnimationSamplerInterpolation.LINEAR);
.setInterpolation(
samplerDef.interpolation || AnimationSampler.Interpolation.LINEAR
);

@@ -437,3 +440,3 @@ if (samplerDef.extras) sampler.setExtras(samplerDef.extras);

return sampler;
})
});

@@ -517,3 +520,5 @@ const channels = animationDef.channels || [];

const bufferDef = jsonDoc.json.buffers[bufferViewDef.buffer];
const resource = bufferDef.uri ? jsonDoc.resources[bufferDef.uri] : jsonDoc.resources[GLB_BUFFER];
const resource = bufferDef.uri
? jsonDoc.resources[bufferDef.uri]
: jsonDoc.resources[GLB_BUFFER];

@@ -534,18 +539,18 @@ const TypedArray = ComponentTypeToTypedArray[accessorDef.componentType];

switch (accessorDef.componentType) {
case GLTF.AccessorComponentType.FLOAT:
case Accessor.ComponentType.FLOAT:
value = view.getFloat32(byteOffset, true);
break;
case GLTF.AccessorComponentType.UNSIGNED_INT:
case Accessor.ComponentType.UNSIGNED_INT:
value = view.getUint32(byteOffset, true);
break;
case GLTF.AccessorComponentType.UNSIGNED_SHORT:
case Accessor.ComponentType.UNSIGNED_SHORT:
value = view.getUint16(byteOffset, true);
break;
case GLTF.AccessorComponentType.UNSIGNED_BYTE:
case Accessor.ComponentType.UNSIGNED_BYTE:
value = view.getUint8(byteOffset);
break;
case GLTF.AccessorComponentType.SHORT:
case Accessor.ComponentType.SHORT:
value = view.getInt16(byteOffset, true);
break;
case GLTF.AccessorComponentType.BYTE:
case Accessor.ComponentType.BYTE:
value = view.getInt8(byteOffset);

@@ -570,3 +575,5 @@ break;

const bufferDef = jsonDoc.json.buffers[bufferViewDef.buffer];
const resource = bufferDef.uri ? jsonDoc.resources[bufferDef.uri] : jsonDoc.resources[GLB_BUFFER];
const resource = bufferDef.uri
? jsonDoc.resources[bufferDef.uri]
: jsonDoc.resources[GLB_BUFFER];

@@ -586,13 +593,13 @@ const TypedArray = ComponentTypeToTypedArray[accessorDef.componentType];

switch (accessorDef.componentType) {
case GLTF.AccessorComponentType.FLOAT:
case Accessor.ComponentType.FLOAT:
return new Float32Array(resource, start, accessorDef.count * elementSize);
case GLTF.AccessorComponentType.UNSIGNED_INT:
case Accessor.ComponentType.UNSIGNED_INT:
return new Uint32Array(resource, start, accessorDef.count * elementSize);
case GLTF.AccessorComponentType.UNSIGNED_SHORT:
case Accessor.ComponentType.UNSIGNED_SHORT:
return new Uint16Array(resource, start, accessorDef.count * elementSize);
case GLTF.AccessorComponentType.UNSIGNED_BYTE:
case Accessor.ComponentType.UNSIGNED_BYTE:
return new Uint8Array(resource, start, accessorDef.count * elementSize);
case GLTF.AccessorComponentType.SHORT:
case Accessor.ComponentType.SHORT:
return new Int16Array(resource, start, accessorDef.count * elementSize);
case GLTF.AccessorComponentType.BYTE:
case Accessor.ComponentType.BYTE:
return new Int8Array(resource, start, accessorDef.count * elementSize);

@@ -599,0 +606,0 @@ default:

@@ -36,2 +36,5 @@ import { JSONDocument } from '../json-document';

private readonly _accessorUsageMap = new Map<Accessor, string>();
public readonly accessorUsageGroupedByParent = new Set<string>(['ARRAY_BUFFER']);
constructor (public readonly jsonDoc: JSONDocument, public readonly options: WriterOptions) {}

@@ -115,2 +118,36 @@

}
/**
* Returns usage for the given accessor, if any. Some accessor types must be grouped into
* buffer views with like accessors. This includes the specified buffer view "targets", but
* also implicit usage like IBMs or instanced mesh attributes.
*/
getAccessorUsage(accessor: Accessor): string {
return this._accessorUsageMap.get(accessor);
}
/**
* Sets usage for the given accessor. Some accessor types must be grouped into
* buffer views with like accessors. This includes the specified buffer view "targets", but
* also implicit usage like IBMs or instanced mesh attributes. If unspecified, an accessor
* will be grouped with other accessors of unspecified usage.
*/
setAccessorUsage(accessor: Accessor, usage: string): this {
const prevUsage = this._accessorUsageMap.get(accessor);
if (prevUsage && prevUsage !== usage) {
throw new Error(`Accessor with usage "${prevUsage}" cannot be reused as "${usage}".`);
}
this._accessorUsageMap.set(accessor, usage);
return this;
}
/** Lists accessors grouped by usage. Accessors with unspecified usage are not included. */
listAccessorsByUsage(): {[key: string]: Accessor[]} {
const result = {};
for (const [accessor, usage] of Array.from(this._accessorUsageMap.entries())) {
result[usage] = result[usage] || [];
result[usage].push(accessor);
}
return result;
}
}

@@ -117,0 +154,0 @@

@@ -5,3 +5,3 @@ import { GLB_BUFFER, NAME, PropertyType, VERSION } from '../constants';

import { JSONDocument } from '../json-document';
import { Accessor, AnimationSampler, AttributeLink, IndexLink, Primitive, Property, Root } from '../properties';
import { Accessor, AnimationSampler, AttributeLink, Camera, IndexLink, Material, Property } from '../properties';
import { GLTF } from '../types/gltf';

@@ -16,2 +16,9 @@ import { BufferUtils, Logger } from '../utils';

const BufferViewUsage = {
ARRAY_BUFFER: 'ARRAY_BUFFER',
ELEMENT_ARRAY_BUFFER: 'ELEMENT_ARRAY_BUFFER',
INVERSE_BIND_MATRICES: 'INVERSE_BIND_MATRICES',
OTHER: 'OTHER',
};
export interface WriterOptions {

@@ -73,3 +80,7 @@ logger?: Logger;

*/
function concatAccessors(accessors: Accessor[], bufferIndex: number, bufferByteOffset: number, bufferViewTarget?: number): BufferViewResult {
function concatAccessors(
accessors: Accessor[],
bufferIndex: number,
bufferByteOffset: number,
bufferViewTarget?: number): BufferViewResult {
const buffers: ArrayBuffer[] = [];

@@ -102,18 +113,21 @@ let byteLength = 0;

return {buffers, byteLength}
return {buffers, byteLength};
}
/**
* Pack a group of accessors into an interleaved buffer view. Appends accessor and buffer view
* definitions to the root JSON lists. Buffer view target is implicitly attribute data.
*
* References:
* - [Apple • Best Practices for Working with Vertex Data](https://developer.apple.com/library/archive/documentation/3DDrawing/Conceptual/OpenGLES_ProgrammingGuide/TechniquesforWorkingwithVertexData/TechniquesforWorkingwithVertexData.html)
* - [Khronos • Vertex Specification Best Practices](https://www.khronos.org/opengl/wiki/Vertex_Specification_Best_Practices)
*
* @param accessors Accessors to be included.
* @param bufferIndex Buffer to write to.
* @param bufferByteOffset Current offset into the buffer, accounting for other buffer views.
*/
function interleaveAccessors(accessors: Accessor[], bufferIndex: number, bufferByteOffset: number): BufferViewResult {
* Pack a group of accessors into an interleaved buffer view. Appends accessor and buffer
* view definitions to the root JSON lists. Buffer view target is implicitly attribute data.
*
* References:
* - [Apple • Best Practices for Working with Vertex Data](https://developer.apple.com/library/archive/documentation/3DDrawing/Conceptual/OpenGLES_ProgrammingGuide/TechniquesforWorkingwithVertexData/TechniquesforWorkingwithVertexData.html)
* - [Khronos • Vertex Specification Best Practices](https://www.khronos.org/opengl/wiki/Vertex_Specification_Best_Practices)
*
* @param accessors Accessors to be included.
* @param bufferIndex Buffer to write to.
* @param bufferByteOffset Offset into the buffer, accounting for other buffer views.
*/
function interleaveAccessors(
accessors: Accessor[],
bufferIndex: number,
bufferByteOffset: number): BufferViewResult {
const vertexCount = accessors[0].getCount();

@@ -150,21 +164,22 @@ let byteStride = 0;

for (let j = 0; j < elementSize; j++) {
const viewByteOffset = i * byteStride + vertexByteOffset + j * componentSize;
const viewByteOffset =
i * byteStride + vertexByteOffset + j * componentSize;
const value = array[i * elementSize + j];
switch (componentType) {
case GLTF.AccessorComponentType.FLOAT:
case Accessor.ComponentType.FLOAT:
view.setFloat32(viewByteOffset, value, true);
break;
case GLTF.AccessorComponentType.BYTE:
case Accessor.ComponentType.BYTE:
view.setInt8(viewByteOffset, value);
break;
case GLTF.AccessorComponentType.SHORT:
case Accessor.ComponentType.SHORT:
view.setInt16(viewByteOffset, value, true);
break;
case GLTF.AccessorComponentType.UNSIGNED_BYTE:
case Accessor.ComponentType.UNSIGNED_BYTE:
view.setUint8(viewByteOffset, value);
break;
case GLTF.AccessorComponentType.UNSIGNED_SHORT:
case Accessor.ComponentType.UNSIGNED_SHORT:
view.setUint16(viewByteOffset, value, true);
break;
case GLTF.AccessorComponentType.UNSIGNED_INT:
case Accessor.ComponentType.UNSIGNED_INT:
view.setUint32(viewByteOffset, value, true);

@@ -245,57 +260,47 @@ break;

// Attributes are grouped and interleaved in one buffer view per mesh primitive. Indices for
// all primitives are grouped into a single buffer view. Everything else goes into a
// miscellaneous buffer view.
const attributeAccessors = new Map<Primitive, Set<Accessor>>();
const indexAccessors = new Set<Accessor>();
const ibmAccessors = new Set<Accessor>();
const otherAccessors = new Set<Accessor>();
// Attributes are grouped and interleaved in one buffer view per mesh primitive.
// Indices for all primitives are grouped into a single buffer view. IBMs are grouped
// into a single buffer view. Other usage (if specified by extensions) also goes into
// a dedicated buffer view. Everything else goes into a miscellaneous buffer view.
const bufferParents = buffer.listParents()
.filter((property) => !(property instanceof Root)) as Property[];
// Certain accessor usage should group data into buffer views by the accessor parent.
// The `accessorParents` map uses the first parent of each accessor for this purpose.
const groupByParent = context.accessorUsageGroupedByParent;
const accessorParents = new Map<Property, Set<Accessor>>();
const bufferAccessors = buffer.listParents()
.filter((property) => property instanceof Accessor) as Accessor[];
const bufferAccessorsSet = new Set(bufferAccessors);
// Categorize accessors by use.
for (const parent of bufferParents) {
if ((!(parent instanceof Accessor))) { // Not expected.
throw new Error('Unimplemented buffer reference: ' + parent);
}
for (const accessor of bufferAccessors) {
// Skip if already written by an extension.
if (context.accessorIndexMap.has(parent)) continue;
if (context.accessorIndexMap.has(accessor)) continue;
let isAttribute = false;
let isIndex = false;
let isIBM = false;
let isOther = false;
// Assign usage for core accessor usage types (explicit targets and implicit usage).
const accessorRefs = accessorLinks.get(accessor) || [];
for (const link of accessorRefs) {
if (context.getAccessorUsage(accessor)) break;
const accessorRefs = accessorLinks.get(parent) || [];
for (const link of accessorRefs) {
if (link instanceof AttributeLink) {
isAttribute = true;
context.setAccessorUsage(accessor, BufferViewUsage.ARRAY_BUFFER);
} else if (link instanceof IndexLink) {
isIndex = true;
context.setAccessorUsage(accessor, BufferViewUsage.ELEMENT_ARRAY_BUFFER);
} else if (link.getName() === 'inverseBindMatrices') {
isIBM = true;
} else {
isOther = true;
context.setAccessorUsage(accessor, BufferViewUsage.INVERSE_BIND_MATRICES);
}
}
// If the Accessor isn't used at all, treat it as "other".
if (!isAttribute && !isIndex && !isIBM && !isOther) isOther = true;
// Group accessors with no specified usage into a miscellaneous buffer view.
if (!context.getAccessorUsage(accessor)) {
context.setAccessorUsage(accessor, BufferViewUsage.OTHER);
}
if (isAttribute && !isIndex && !isIBM && !isOther) {
const primitive = accessorRefs[0].getParent() as Primitive;
const primitiveAccessors = attributeAccessors.get(primitive) || new Set<Accessor>();
primitiveAccessors.add(parent);
attributeAccessors.set(primitive, primitiveAccessors);
} else if (isIndex && !isAttribute && !isIBM && !isOther) {
indexAccessors.add(parent);
} else if (isIBM && !isAttribute && !isIndex && !isOther) {
ibmAccessors.add(parent);
} else if (isOther && !isAttribute && !isIndex && !isIBM) {
otherAccessors.add(parent);
} else {
throw new Error('Attribute, index, or IBM accessors must be used only for that purpose.');
// For accessor usage that requires grouping by parent (vertex and instance
// attributes) organize buffer views accordingly.
if (groupByParent.has(context.getAccessorUsage(accessor))) {
const parent = accessorRefs[0].getParent();
const parentAccessors = accessorParents.get(parent) || new Set<Accessor>();
parentAccessors.add(accessor);
accessorParents.set(parent, parentAccessors);
}

@@ -310,26 +315,35 @@ }

if (indexAccessors.size) {
const indexResult = concatAccessors(Array.from(indexAccessors), bufferIndex, bufferByteLength, BufferViewTarget.ELEMENT_ARRAY_BUFFER);
bufferByteLength += indexResult.byteLength;
buffers.push(...indexResult.buffers);
}
const usageGroups = context.listAccessorsByUsage();
for (const primitiveAccessors of Array.from(attributeAccessors.values())) {
if (primitiveAccessors.size) {
const primitiveResult = interleaveAccessors(Array.from(primitiveAccessors), bufferIndex, bufferByteLength);
bufferByteLength += primitiveResult.byteLength;
buffers.push(...primitiveResult.buffers);
}
}
for (const usage in usageGroups) {
if (groupByParent.has(usage)) {
// Accessors grouped by (first) parent, including vertex and instance
// attributes. Instanced data is not interleaved, see:
// https://github.com/KhronosGroup/glTF/pull/1888
for (const parentAccessors of Array.from(accessorParents.values())) {
const accessors = Array.from(parentAccessors)
.filter((a) => bufferAccessorsSet.has(a))
.filter((a) => context.getAccessorUsage(a) === usage);
if (!accessors.length) continue;
if (ibmAccessors.size) {
const ibmResult = concatAccessors(Array.from(ibmAccessors), bufferIndex, bufferByteLength);
bufferByteLength += ibmResult.byteLength;
buffers.push(...ibmResult.buffers);
}
const result = usage === BufferViewUsage.ARRAY_BUFFER
? interleaveAccessors(accessors, bufferIndex, bufferByteLength)
: concatAccessors(accessors, bufferIndex, bufferByteLength);
bufferByteLength += result.byteLength;
buffers.push(...result.buffers);
}
} else {
// Accessors concatenated end-to-end, including indices, IBMs, and other data.
const accessors = usageGroups[usage].filter((a) => bufferAccessorsSet.has(a));
if (!accessors.length) continue;
if (otherAccessors.size) {
const otherResult = concatAccessors(Array.from(otherAccessors), bufferIndex, bufferByteLength);
bufferByteLength += otherResult.byteLength;
buffers.push(...otherResult.buffers);
const target = usage === BufferViewUsage.ELEMENT_ARRAY_BUFFER
? BufferViewTarget.ELEMENT_ARRAY_BUFFER
: null;
const result = concatAccessors(
accessors, bufferIndex, bufferByteLength, target
);
bufferByteLength += result.byteLength;
buffers.push(...result.buffers);
}
}

@@ -343,2 +357,9 @@

buffers.push(context.imageBufferViews[i]);
if (bufferByteLength % 4) {
// See: https://github.com/KhronosGroup/glTF/issues/1935
const imagePadding = 4 - (bufferByteLength % 4);
bufferByteLength += imagePadding;
buffers.push(new ArrayBuffer(imagePadding));
}
}

@@ -384,3 +405,3 @@ }

if (root.listAccessors().find((a) => !a.getBuffer())) {
logger.warn('Skipped writing one or more Accessors: no Buffer assigned.')
logger.warn('Skipped writing one or more Accessors: no Buffer assigned.');
}

@@ -396,3 +417,3 @@

materialDef.alphaMode = material.getAlphaMode();
if (material.getAlphaMode() === GLTF.MaterialAlphaMode.MASK) {
if (material.getAlphaMode() === Material.AlphaMode.MASK) {
materialDef.alphaCutoff = material.getAlphaCutoff();

@@ -415,3 +436,4 @@ }

const textureInfo = material.getBaseColorTextureInfo();
materialDef.pbrMetallicRoughness.baseColorTexture = context.createTextureInfoDef(texture, textureInfo);
materialDef.pbrMetallicRoughness.baseColorTexture
= context.createTextureInfoDef(texture, textureInfo);
}

@@ -428,3 +450,4 @@

const textureInfo = material.getNormalTextureInfo();
const textureInfoDef = context.createTextureInfoDef(texture, textureInfo) as GLTF.IMaterialNormalTextureInfo;
const textureInfoDef = context.createTextureInfoDef(texture, textureInfo) as
GLTF.IMaterialNormalTextureInfo;
if (material.getNormalScale() !== 1) {

@@ -439,3 +462,4 @@ textureInfoDef.scale = material.getNormalScale();

const textureInfo = material.getOcclusionTextureInfo();
const textureInfoDef = context.createTextureInfoDef(texture, textureInfo) as GLTF.IMaterialOcclusionTextureInfo;
const textureInfoDef = context.createTextureInfoDef(texture, textureInfo) as
GLTF.IMaterialOcclusionTextureInfo;
if (material.getOcclusionStrength() !== 1) {

@@ -450,3 +474,4 @@ textureInfoDef.strength = material.getOcclusionStrength();

const textureInfo = material.getMetallicRoughnessTextureInfo();
materialDef.pbrMetallicRoughness.metallicRoughnessTexture = context.createTextureInfoDef(texture, textureInfo);
materialDef.pbrMetallicRoughness.metallicRoughnessTexture
= context.createTextureInfoDef(texture, textureInfo);
}

@@ -483,3 +508,4 @@

for (const semantic of primitive.listSemantics()) {
primitiveDef.attributes[semantic] = context.accessorIndexMap.get(primitive.getAttribute(semantic));
primitiveDef.attributes[semantic]
= context.accessorIndexMap.get(primitive.getAttribute(semantic));
}

@@ -491,3 +517,4 @@

for (const semantic of target.listSemantics()) {
targetDef[semantic] = context.accessorIndexMap.get(target.getAttribute(semantic));
targetDef[semantic]
= context.accessorIndexMap.get(target.getAttribute(semantic));
}

@@ -512,3 +539,3 @@

meshDef.extras = meshDef.extras || {};
meshDef.extras.targetNames = targetNames;
meshDef.extras['targetNames'] = targetNames;
}

@@ -525,3 +552,3 @@

cameraDef.type = camera.getType();
if (cameraDef.type === GLTF.CameraType.PERSPECTIVE) {
if (cameraDef.type === Camera.Type.PERSPECTIVE) {
cameraDef.perspective = {

@@ -570,3 +597,4 @@ znear: camera.getZNear(),

if (skin.getInverseBindMatrices()) {
skinDef.inverseBindMatrices = context.accessorIndexMap.get(skin.getInverseBindMatrices());
skinDef.inverseBindMatrices
= context.accessorIndexMap.get(skin.getInverseBindMatrices());
}

@@ -602,3 +630,4 @@

if (node.listChildren().length > 0) {
nodeDef.children = node.listChildren().map((node) => context.nodeIndexMap.get(node));
nodeDef.children = node.listChildren()
.map((node) => context.nodeIndexMap.get(node));
}

@@ -622,3 +651,3 @@ });

return samplerDef;
})
});

@@ -634,3 +663,3 @@ animationDef.channels = animation.listChannels()

return channelDef;
})
});

@@ -637,0 +666,0 @@ return animationDef;

@@ -22,14 +22,4 @@ import { PropertyType, TypedArray } from '../constants';

* {@link getCount}(). The number of components in an element — e.g. 9 for `"MAT3"` — are its
* {@link getElementSize}().
* {@link getElementSize}(). See {@link Accessor.Type}.
*
* | `type` | Components |
* |:----------:|:----------:|
* | `"SCALAR"` | 1 |
* | `"VEC2"` | 2 |
* | `"VEC3"` | 3 |
* | `"VEC4"` | 4 |
* | `"MAT2"` | 4 |
* | `"MAT3"` | 9 |
* | `"MAT4"` | 16 |
*
* *Components* are the numeric values within an element — e.g. `.x` and `.y` for `"VEC2"`. Various

@@ -39,13 +29,4 @@ * component types are available: `BYTE`, `UNSIGNED_BYTE`, `SHORT`, `UNSIGNED_SHORT`,

* {@link getComponentType} method, and the number of bytes in each component determine its
* {@link getComponentSize}. Component types are identified by WebGL enum values, below.
* {@link getComponentSize}. See {@link Accessor.ComponentType}.
*
* | `componentType` | Bytes |
* |:-----------------------:|:-----:|
* | `5120` (BYTE) | 1 |
* | `5121` (UNSIGNED_BYTE) | 1 |
* | `5122` (SHORT) | 2 |
* | `5123` (UNSIGNED_SHORT) | 2 |
* | `5125` (UNSIGNED_INT) | 4 |
* | `5126` (FLOAT) | 4 |
*
* Usage:

@@ -56,3 +37,3 @@ *

* .setArray(new Float32Array([1,2,3,4,5,6,7,8,9,10,11,12]))
* .setType(GLTF.AccessorType.VEC3)
* .setType(Accessor.Type.VEC3)
* .setBuffer(doc.listBuffers()[0]);

@@ -91,9 +72,9 @@ *

/** @hidden Raw data of the accessor. */
private _array: TypedArray = null;
private _array: TypedArray | null = null;
/** @hidden Type of element represented. */
private _type: GLTF.AccessorType = GLTF.AccessorType.SCALAR;
private _type: GLTF.AccessorType = Accessor.Type.SCALAR;
/** @hidden Numeric type of each component in an element. */
private _componentType: GLTF.AccessorComponentType = null;
private _componentType: GLTF.AccessorComponentType = Accessor.ComponentType.FLOAT;

@@ -110,3 +91,3 @@ /** @hidden Whether data in the raw array should be considered normalized. */

/** @hidden The {@link Buffer} to which this accessor's data will be written. */
@GraphChild private buffer: Link<Accessor, Buffer> = null;
@GraphChild private buffer: Link<Accessor, Buffer> | null = null;

@@ -132,20 +113,52 @@ public copy(other: this, resolve = COPY_IDENTITY): this {

/** Supported element types. */
public static Type = {
SCALAR: GLTF.AccessorType.SCALAR,
VEC2: GLTF.AccessorType.VEC2,
VEC3: GLTF.AccessorType.VEC3,
VEC4: GLTF.AccessorType.VEC4,
MAT3: GLTF.AccessorType.MAT3,
MAT4: GLTF.AccessorType.MAT4,
/** Element type contained by the accessor (SCALAR, VEC2, ...). */
public static Type: Record<string, GLTF.AccessorType> = {
/** Scalar, having 1 value per element. */
SCALAR: 'SCALAR',
/** 2-component vector, having 2 components per element. */
VEC2: 'VEC2',
/** 3-component vector, having 3 components per element. */
VEC3: 'VEC3',
/** 4-component vector, having 4 components per element. */
VEC4: 'VEC4',
/** 2x2 matrix, having 4 components per element. */
MAT2: 'MAT2',
/** 3x3 matrix, having 9 components per element. */
MAT3: 'MAT3',
/** 4x3 matrix, having 16 components per element. */
MAT4: 'MAT4',
}
/** Supported component types. */
public static ComponentType = {
BYTE: GLTF.AccessorComponentType.BYTE,
UNSIGNED_BYTE: GLTF.AccessorComponentType.UNSIGNED_BYTE,
SHORT: GLTF.AccessorComponentType.SHORT,
UNSIGNED_SHORT: GLTF.AccessorComponentType.UNSIGNED_SHORT,
UNSIGNED_INT: GLTF.AccessorComponentType.UNSIGNED_INT,
FLOAT: GLTF.AccessorComponentType.FLOAT,
/** Data type of the values composing each element in the accessor. */
public static ComponentType: Record<string, GLTF.AccessorComponentType> = {
/**
* 1-byte signed integer, stored as
* {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Int8Array Int8Array}.
*/
BYTE: 5120,
/**
* 1-byte unsigned integer, stored as
* {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array Uint8Array}.
*/
UNSIGNED_BYTE: 5121,
/**
* 2-byte signed integer, stored as
* {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint16Array Uint16Array}.
*/
SHORT: 5122,
/**
* 2-byte unsigned integer, stored as
* {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint16Array Uint16Array}.
*/
UNSIGNED_SHORT: 5123,
/**
* 4-byte unsigned integer, stored as
* {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint32Array Uint32Array}.
*/
UNSIGNED_INT: 5125,
/**
* 4-byte floating point number, stored as
* {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float32Array Float32Array}.
*/
FLOAT: 5126,
}

@@ -156,9 +169,9 @@

switch (type) {
case GLTF.AccessorType.SCALAR: return 1;
case GLTF.AccessorType.VEC2: return 2;
case GLTF.AccessorType.VEC3: return 3;
case GLTF.AccessorType.VEC4: return 4;
case GLTF.AccessorType.MAT2: return 4;
case GLTF.AccessorType.MAT3: return 9;
case GLTF.AccessorType.MAT4: return 16;
case Accessor.Type.SCALAR: return 1;
case Accessor.Type.VEC2: return 2;
case Accessor.Type.VEC3: return 3;
case Accessor.Type.VEC4: return 4;
case Accessor.Type.MAT2: return 4;
case Accessor.Type.MAT3: return 9;
case Accessor.Type.MAT4: return 16;
default:

@@ -172,8 +185,8 @@ throw new Error('Unexpected type: ' + type);

switch (componentType) {
case GLTF.AccessorComponentType.BYTE: return 1;
case GLTF.AccessorComponentType.UNSIGNED_BYTE: return 1;
case GLTF.AccessorComponentType.SHORT: return 2;
case GLTF.AccessorComponentType.UNSIGNED_SHORT: return 2;
case GLTF.AccessorComponentType.UNSIGNED_INT: return 4;
case GLTF.AccessorComponentType.FLOAT: return 4;
case Accessor.ComponentType.BYTE: return 1;
case Accessor.ComponentType.UNSIGNED_BYTE: return 1;
case Accessor.ComponentType.SHORT: return 2;
case Accessor.ComponentType.UNSIGNED_SHORT: return 2;
case Accessor.ComponentType.UNSIGNED_INT: return 4;
case Accessor.ComponentType.FLOAT: return 4;
default:

@@ -215,3 +228,3 @@ throw new Error('Unexpected component type: ' + componentType);

for (let j = 0; j < elementSize; j++) {
const value = this._array[i + j];
const value = this._array![i + j];
if (Number.isFinite(value)) {

@@ -253,3 +266,3 @@ target[j] = Math.min(target[j], value);

for (let j = 0; j < elementSize; j++) {
const value = this._array[i + j];
const value = this._array![i + j];
if (Number.isFinite(value)) {

@@ -273,3 +286,3 @@ target[j] = Math.max(target[j], value);

public getCount(): number {
return this._array.length / this.getElementSize();
return this._array ? this._array.length / this.getElementSize() : 0;
}

@@ -303,3 +316,3 @@

public getComponentSize(): number {
return this._array.BYTES_PER_ELEMENT;
return this._array!.BYTES_PER_ELEMENT;
}

@@ -357,3 +370,3 @@

const elementSize = this.getElementSize();
return this._out(this._array[index * elementSize]);
return this._out(this._array![index * elementSize]);
}

@@ -366,3 +379,3 @@

public setScalar(index: number, x: number): this {
this._array[index * this.getElementSize()] = this._in(x);
this._array![index * this.getElementSize()] = this._in(x);
return this;

@@ -378,3 +391,3 @@ }

for (let i = 0; i < elementSize; i++) {
target[i] = this._out(this._array[index * elementSize + i]);
target[i] = this._out(this._array![index * elementSize + i]);
}

@@ -391,3 +404,3 @@ return target;

for (let i = 0; i < elementSize; i++) {
this._array[index * elementSize + i] = this._in(value[i]);
this._array![index * elementSize + i] = this._in(value[i]);
}

@@ -402,3 +415,3 @@ return this;

/** Returns the {@link Buffer} into which this accessor will be organized. */
public getBuffer(): Buffer { return this.buffer ? this.buffer.getChild() : null; }
public getBuffer(): Buffer | null { return this.buffer ? this.buffer.getChild() : null; }

@@ -412,7 +425,7 @@ /** Assigns the {@link Buffer} into which this accessor will be organized. */

/** Returns the raw typed array underlying this accessor. */
public getArray(): TypedArray { return this._array; }
public getArray(): TypedArray | null { return this._array; }
/** Assigns the raw typed array underlying this accessor. */
public setArray(array: TypedArray): this {
this._componentType = arrayToComponentType(array);
this._componentType = array ? arrayToComponentType(array) : Accessor.ComponentType.FLOAT;
this._array = array;

@@ -424,3 +437,3 @@ return this;

public getByteLength(): number {
return this._array.byteLength;
return this._array ? this._array.byteLength : 0;
}

@@ -430,3 +443,3 @@ }

/**************************************************************************************************
* Array utilities.
* Accessor utilities.
*/

@@ -438,13 +451,13 @@

case Float32Array:
return GLTF.AccessorComponentType.FLOAT;
return Accessor.ComponentType.FLOAT;
case Uint32Array:
return GLTF.AccessorComponentType.UNSIGNED_INT;
return Accessor.ComponentType.UNSIGNED_INT;
case Uint16Array:
return GLTF.AccessorComponentType.UNSIGNED_SHORT;
return Accessor.ComponentType.UNSIGNED_SHORT;
case Uint8Array:
return GLTF.AccessorComponentType.UNSIGNED_BYTE;
return Accessor.ComponentType.UNSIGNED_BYTE;
case Int16Array:
return GLTF.AccessorComponentType.SHORT;
return Accessor.ComponentType.SHORT;
case Int8Array:
return GLTF.AccessorComponentType.BYTE;
return Accessor.ComponentType.BYTE;
default:

@@ -451,0 +464,0 @@ throw new Error('Unknown accessor componentType.');

@@ -16,5 +16,6 @@ import { PropertyType } from '../constants';

* Node that can be affected by animation: `translation`, `rotation`, `scale`, or `weights`. An
* {@link Animation} affecting the positions and rotations of several {@link Node}s would contain one
* channel for each Node-position or Node-rotation pair. The keyframe data for an AnimationChannel
* is stored in an {@link AnimationSampler}, which must be attached to the same {@link Animation}.
* {@link Animation} affecting the positions and rotations of several {@link Node}s would contain
* one channel for each Node-position or Node-rotation pair. The keyframe data for an
* AnimationChannel is stored in an {@link AnimationSampler}, which must be attached to the same
* {@link Animation}.
*

@@ -29,3 +30,3 @@ * Usage:

* const channel = doc.createAnimationChannel('cogRotation')
* .setTargetPath(GLTF.AnimationChannelTargetPath.ROTATION)
* .setTargetPath('rotation')
* .setTargetNode(node)

@@ -40,5 +41,5 @@ * .setSampler(rotateSampler);

public readonly propertyType = PropertyType.ANIMATION_CHANNEL;
private _targetPath: GLTF.AnimationChannelTargetPath = null;
@GraphChild private targetNode: Link<AnimationChannel, Node> = null;
@GraphChild private sampler: Link<AnimationChannel, AnimationSampler> = null;
private _targetPath: GLTF.AnimationChannelTargetPath | null = null;
@GraphChild private targetNode: Link<AnimationChannel, Node> | null = null;
@GraphChild private sampler: Link<AnimationChannel, AnimationSampler> | null = null;

@@ -56,2 +57,22 @@ public copy(other: this, resolve = COPY_IDENTITY): this {

/**********************************************************************************************
* Static.
*/
/** Name of the property to be modified by an animation channel. */
public static TargetPath: Record<string, GLTF.AnimationChannelTargetPath> = {
/** Channel targets {@link Node.setTranslation}. */
TRANSLATION: 'translation',
/** Channel targets {@link Node.setRotation}. */
ROTATION: 'rotation',
/** Channel targets {@link Node.setScale}. */
SCALE: 'scale',
/** Channel targets {@link Node.setWeights}, affecting {@link PrimitiveTarget} weights. */
WEIGHTS: 'weights',
}
/**********************************************************************************************
* Properties.
*/
/**

@@ -61,3 +82,3 @@ * Path (property) animated on the target {@link Node}. Supported values include:

*/
public getTargetPath(): GLTF.AnimationChannelTargetPath {
public getTargetPath(): GLTF.AnimationChannelTargetPath | null {
return this._targetPath;

@@ -76,3 +97,3 @@ }

/** Target {@link Node} animated by the channel. */
public getTargetNode(): Node {
public getTargetNode(): Node | null {
return this.targetNode ? this.targetNode.getChild() : null;

@@ -91,3 +112,3 @@ }

*/
public getSampler(): AnimationSampler {
public getSampler(): AnimationSampler | null {
return this.sampler ? this.sampler.getChild() : null;

@@ -94,0 +115,0 @@ }

@@ -17,3 +17,4 @@ import { PropertyType } from '../constants';

*
* in<sub>1</sub>, value<sub>1</sub>, out<sub>1</sub>, in<sub>2</sub>, value<sub>2</sub>, out<sub>2</sub>,
* in<sub>1</sub>, value<sub>1</sub>, out<sub>1</sub>,
* in<sub>2</sub>, value<sub>2</sub>, out<sub>2</sub>,
* in<sub>3</sub>, value<sub>3</sub>, out<sub>3</sub>, ...

@@ -27,3 +28,3 @@ *

* .setArray(new Float32Array([0, 1, 2]))
* .setType(GLTF.AccessorType.SCALAR);
* .setType(Accessor.Type.SCALAR);
*

@@ -37,3 +38,3 @@ * // Create accessor containing output values, in local units.

* ]))
* .setType(GLTF.AccessorType.VEC3);
* .setType(Accessor.Type.VEC3);
*

@@ -44,3 +45,3 @@ * // Create sampler.

* .setOutput(output)
* .setInterpolation(GLTF.AnimationSamplerInterpolation.LINEAR);
* .setInterpolation('LINEAR');
* ```

@@ -54,6 +55,7 @@ *

private _interpolation: GLTF.AnimationSamplerInterpolation = GLTF.AnimationSamplerInterpolation.LINEAR;
private _interpolation: GLTF.AnimationSamplerInterpolation
= AnimationSampler.Interpolation.LINEAR;
@GraphChild private input: Link<AnimationSampler, Accessor> = null;
@GraphChild private output: Link<AnimationSampler, Accessor> = null;
@GraphChild private input: Link<AnimationSampler, Accessor> | null = null;
@GraphChild private output: Link<AnimationSampler, Accessor> | null = null;

@@ -71,2 +73,16 @@ public copy(other: this, resolve = COPY_IDENTITY): this {

/**********************************************************************************************
* Static.
*/
/** Interpolation method. */
public static Interpolation: Record<string, GLTF.AnimationSamplerInterpolation> = {
/** Animated values are linearly interpolated between keyframes. */
LINEAR: 'LINEAR',
/** Animated values remain constant from one keyframe until the next keyframe. */
STEP: 'STEP',
/** Animated values are interpolated according to given cubic spline tangents. */
CUBICSPLINE: 'CUBICSPLINE',
}
/** Interpolation mode: `STEP`, `LINEAR`, or `CUBICSPLINE`. */

@@ -84,3 +100,3 @@ public getInterpolation(): GLTF.AnimationSamplerInterpolation {

/** Times for each keyframe, in seconds. */
public getInput(): Accessor {
public getInput(): Accessor | null {
return this.input ? this.input.getChild() : null;

@@ -90,3 +106,3 @@ }

/** Times for each keyframe, in seconds. */
public setInput(input: Accessor): this {
public setInput(input: Accessor | null): this {
this.input = this.graph.link('input', this, input);

@@ -100,3 +116,3 @@ return this;

*/
public getOutput(): Accessor {
public getOutput(): Accessor | null {
return this.output ? this.output.getChild() : null;

@@ -109,3 +125,3 @@ }

*/
public setOutput(output: Accessor): this {
public setOutput(output: Accessor | null): this {
this.output = this.graph.link('output', this, output);

@@ -112,0 +128,0 @@ return this;

@@ -64,3 +64,3 @@ import { PropertyType } from '../constants';

/** @hidden URI (or filename) of the buffer. */
private _uri: string;
private _uri = '';

@@ -67,0 +67,0 @@ public copy(other: this, resolve = COPY_IDENTITY): this {

@@ -39,15 +39,15 @@ import { PropertyType } from '../constants';

private _type: GLTF.CameraType = GLTF.CameraType.PERSPECTIVE;
private _znear: number;
private _zfar: number;
private _type: GLTF.CameraType = Camera.Type.PERSPECTIVE;
private _znear = 0.1;
private _zfar = 100;
// Perspective.
private _aspectRatio: number;
private _yfov: number;
private _aspectRatio: number | null = null;
private _yfov: number = Math.PI * 2 * 50 / 360; // 50º
// Orthographic.
private _xmag: number;
private _ymag: number;
private _xmag = 1;
private _ymag = 1;

@@ -69,2 +69,13 @@ public copy(other: this, resolve = COPY_IDENTITY): this {

/**********************************************************************************************
* Static.
*/
public static Type: Record<string, GLTF.CameraType> = {
/** A perspective camera representing a perspective projection matrix. */
PERSPECTIVE: 'perspective',
/** An orthographic camera representing an orthographic projection matrix. */
ORTHOGRAPHIC: 'orthographic',
}
/**********************************************************************************************
* Common.

@@ -114,3 +125,3 @@ */

*/
public getAspectRatio(): number { return this._aspectRatio; }
public getAspectRatio(): number | null { return this._aspectRatio; }

@@ -121,3 +132,3 @@ /**

*/
public setAspectRatio(aspectRatio: number): this {
public setAspectRatio(aspectRatio: number | null): this {
this._aspectRatio = aspectRatio;

@@ -124,0 +135,0 @@ return this;

@@ -28,3 +28,3 @@ import { GraphChildList, Link } from '../graph';

this.setExtension(extension.extensionName, resolve(extension));
})
});

@@ -38,3 +38,3 @@ return this;

*/
public getExtension<Prop extends ExtensionProperty>(name: string): Prop {
public getExtension<Prop extends ExtensionProperty>(name: string): Prop | null {
if (typeof name !== 'string') throw new Error(TOKEN_WARNING);

@@ -50,3 +50,4 @@ const link = this.extensions.find((link) => link.getChild().extensionName === name);

*/
public setExtension<Prop extends ExtensionProperty>(name: string, extensionProperty: Prop): this {
public setExtension<Prop extends ExtensionProperty>(
name: string, extensionProperty: Prop | null): this {
if (typeof name !== 'string') throw new Error(TOKEN_WARNING);

@@ -53,0 +54,0 @@

@@ -47,5 +47,7 @@ import { ExtensibleProperty } from './extensible-property';

if (!this.parentTypes.includes(parent.propertyType)) {
throw new Error(`Parent "${parent.propertyType}" invalid for child "${this.propertyType}".`);
throw new Error(
`Parent "${parent.propertyType}" invalid for child "${this.propertyType}".`
);
}
}
}

@@ -46,3 +46,3 @@ import { PropertyType, vec3, vec4 } from '../constants';

/** @hidden Mode of the material's alpha channels. (`OPAQUE`, `BLEND`, or `MASK`) */
private _alphaMode: GLTF.MaterialAlphaMode = GLTF.MaterialAlphaMode.OPAQUE;
private _alphaMode: GLTF.MaterialAlphaMode = Material.AlphaMode.OPAQUE;

@@ -82,3 +82,3 @@ /** @hidden Visibility threshold. Applied only when `.alphaMode='MASK'`. */

/** @hidden Base color / albedo texture. */
@GraphChild private baseColorTexture: Link<this, Texture> = null;
@GraphChild private baseColorTexture: Link<this, Texture> | null = null;
@GraphChild private baseColorTextureInfo: Link<this, TextureInfo> =

@@ -88,3 +88,3 @@ this.graph.link('baseColorTextureInfo', this, new TextureInfo(this.graph));

/** @hidden Emissive texture. */
@GraphChild private emissiveTexture: Link<this, Texture> = null;
@GraphChild private emissiveTexture: Link<this, Texture> | null = null;
@GraphChild private emissiveTextureInfo: Link<this, TextureInfo> =

@@ -98,3 +98,3 @@ this.graph.link('emissiveTextureInfo', this, new TextureInfo(this.graph));

*/
@GraphChild private normalTexture: Link<this, Texture> = null;
@GraphChild private normalTexture: Link<this, Texture> | null = null;
@GraphChild private normalTextureInfo: Link<this, TextureInfo> =

@@ -108,3 +108,3 @@ this.graph.link('normalTextureInfo', this, new TextureInfo(this.graph));

*/
@GraphChild private occlusionTexture: Link<this, Texture> = null;
@GraphChild private occlusionTexture: Link<this, Texture> | null = null;
@GraphChild private occlusionTextureInfo: Link<this, TextureInfo> =

@@ -119,3 +119,3 @@ this.graph.link('occlusionTextureInfo', this, new TextureInfo(this.graph));

*/
@GraphChild private metallicRoughnessTexture: Link<this, Texture> = null;
@GraphChild private metallicRoughnessTexture: Link<this, Texture> | null = null;
@GraphChild private metallicRoughnessTextureInfo: Link<this, TextureInfo> =

@@ -139,19 +139,24 @@ this.graph.link('metallicRoughnessTextureInfo', this, new TextureInfo(this.graph));

this.setBaseColorTexture(resolve(other.baseColorTexture.getChild()));
this.getBaseColorTextureInfo().copy(resolve(other.baseColorTextureInfo.getChild()), resolve);
this.getBaseColorTextureInfo()
.copy(resolve(other.baseColorTextureInfo.getChild()), resolve);
}
if (other.emissiveTexture) {
this.setEmissiveTexture(resolve(other.emissiveTexture.getChild()));
this.getEmissiveTextureInfo().copy(resolve(other.emissiveTextureInfo.getChild()), resolve);
this.getEmissiveTextureInfo()
.copy(resolve(other.emissiveTextureInfo.getChild()), resolve);
}
if (other.normalTexture) {
this.setNormalTexture(resolve(other.normalTexture.getChild()));
this.getNormalTextureInfo().copy(resolve(other.normalTextureInfo.getChild()), resolve);
this.getNormalTextureInfo()
.copy(resolve(other.normalTextureInfo.getChild()), resolve);
}
if (other.occlusionTexture) {
this.setOcclusionTexture(resolve(other.occlusionTexture.getChild()));
this.getOcclusionTextureInfo().copy(resolve(other.occlusionTextureInfo.getChild()), resolve);
this.getOcclusionTextureInfo()
.copy(resolve(other.occlusionTextureInfo.getChild()), resolve);
}
if (other.metallicRoughnessTexture) {
this.setMetallicRoughnessTexture(resolve(other.metallicRoughnessTexture.getChild()));
this.getMetallicRoughnessTextureInfo().copy(resolve(other.metallicRoughnessTextureInfo.getChild()), resolve);
this.getMetallicRoughnessTextureInfo()
.copy(resolve(other.metallicRoughnessTextureInfo.getChild()), resolve);
}

@@ -173,2 +178,24 @@

/**********************************************************************************************
* Static.
*/
public static AlphaMode: Record<string, GLTF.MaterialAlphaMode> = {
/**
* The alpha value is ignored and the rendered output is fully opaque
*/
OPAQUE: 'OPAQUE',
/**
* The rendered output is either fully opaque or fully transparent depending on the alpha
* value and the specified alpha cutoff value
*/
MASK: 'MASK',
/**
* The alpha value is used to composite the source and destination areas. The rendered
* output is combined with the background using the normal painting operation (i.e. the
* Porter and Duff over operator)
*/
BLEND: 'BLEND',
}
/**********************************************************************************************
* Double-sided / culling.

@@ -277,3 +304,3 @@ */

*/
public getBaseColorTexture(): Texture {
public getBaseColorTexture(): Texture | null {
return this.baseColorTexture ? this.baseColorTexture.getChild() : null;

@@ -286,3 +313,3 @@ }

*/
public getBaseColorTextureInfo(): TextureInfo {
public getBaseColorTextureInfo(): TextureInfo | null {
return this.baseColorTexture ? this.baseColorTextureInfo.getChild() : null;

@@ -292,3 +319,3 @@ }

/** Sets base color / albedo texture. See {@link getBaseColorTexture}. */
public setBaseColorTexture(texture: Texture): this {
public setBaseColorTexture(texture: Texture | null): this {
this.baseColorTexture = this.graph.link('baseColorTexture', this, texture);

@@ -337,3 +364,3 @@ return this;

*/
public getEmissiveTexture(): Texture {
public getEmissiveTexture(): Texture | null {
return this.emissiveTexture ? this.emissiveTexture.getChild() : null;

@@ -346,3 +373,3 @@ }

*/
public getEmissiveTextureInfo(): TextureInfo {
public getEmissiveTextureInfo(): TextureInfo | null {
return this.emissiveTexture ? this.emissiveTextureInfo.getChild() : null;

@@ -352,3 +379,3 @@ }

/** Sets emissive texture. See {@link getEmissiveTexture}. */
public setEmissiveTexture(texture: Texture): this {
public setEmissiveTexture(texture: Texture | null): this {
this.emissiveTexture = this.graph.link('emissiveTexture', this, texture);

@@ -383,3 +410,3 @@ return this;

*/
public getNormalTexture(): Texture {
public getNormalTexture(): Texture | null {
return this.normalTexture ? this.normalTexture.getChild() : null;

@@ -392,3 +419,3 @@ }

*/
public getNormalTextureInfo(): TextureInfo {
public getNormalTextureInfo(): TextureInfo | null {
return this.normalTexture ? this.normalTextureInfo.getChild() : null;

@@ -398,3 +425,3 @@ }

/** Sets normal (surface detail) texture. See {@link getNormalTexture}. */
public setNormalTexture(texture: Texture): this {
public setNormalTexture(texture: Texture | null): this {
this.normalTexture = this.graph.link('normalTexture', this, texture);

@@ -429,3 +456,3 @@ return this;

*/
public getOcclusionTexture(): Texture {
public getOcclusionTexture(): Texture | null {
return this.occlusionTexture ? this.occlusionTexture.getChild() : null;

@@ -438,3 +465,3 @@ }

*/
public getOcclusionTextureInfo(): TextureInfo {
public getOcclusionTextureInfo(): TextureInfo | null {
return this.occlusionTexture ? this.occlusionTextureInfo.getChild() : null;

@@ -444,3 +471,3 @@ }

/** Sets (ambient) occlusion texture. See {@link getOcclusionTexture}. */
public setOcclusionTexture(texture: Texture): this {
public setOcclusionTexture(texture: Texture | null): this {
this.occlusionTexture = this.graph.link('occlusionTexture', this, texture);

@@ -493,3 +520,3 @@ return this;

*/
public getMetallicRoughnessTexture(): Texture {
public getMetallicRoughnessTexture(): Texture | null {
return this.metallicRoughnessTexture ? this.metallicRoughnessTexture.getChild() : null;

@@ -502,3 +529,3 @@ }

*/
public getMetallicRoughnessTextureInfo(): TextureInfo {
public getMetallicRoughnessTextureInfo(): TextureInfo | null {
return this.metallicRoughnessTexture ? this.metallicRoughnessTextureInfo.getChild() : null;

@@ -508,3 +535,3 @@ }

/** Sets metallic/roughness texture. See {@link getMetallicRoughnessTexture}. */
public setMetallicRoughnessTexture(texture: Texture): this {
public setMetallicRoughnessTexture(texture: Texture | null): this {
this.metallicRoughnessTexture = this.graph.link('metallicRoughnessTexture', this, texture);

@@ -511,0 +538,0 @@ return this;

@@ -1,2 +0,2 @@

import { fromRotationTranslationScale, getRotation, getScaling, getTranslation, multiply } from 'gl-matrix/mat4'
import { fromRotationTranslationScale, getRotation, getScaling, getTranslation, multiply } from 'gl-matrix/mat4';
import { PropertyType, mat4, vec3, vec4 } from '../constants';

@@ -47,7 +47,7 @@ import { GraphChild, GraphChildList } from '../graph/graph-decorators';

/** @hidden Internal reference to node's parent, omitted from {@link Graph}. */
public _parent: SceneNode = null;
public _parent: SceneNode | null = null;
@GraphChild private camera: Link<Node, Camera> = null;
@GraphChild private mesh: Link<Node, Mesh> = null;
@GraphChild private skin: Link<Node, Skin> = null;
@GraphChild private camera: Link<Node, Camera> | null = null;
@GraphChild private mesh: Link<Node, Mesh> | null = null;
@GraphChild private skin: Link<Node, Skin> | null = null;
@GraphChildList private children: Link<Node, Node>[] = [];

@@ -135,3 +135,3 @@

// eslint-disable-next-line @typescript-eslint/no-this-alias
for (let node: SceneNode = this; node instanceof Node; node = node._parent) {
for (let node: SceneNode | null = this; node instanceof Node; node = node._parent) {
ancestors.push(node);

@@ -141,4 +141,4 @@ }

// Compute world matrix.
let ancestor: Node;
const worldMatrix = ancestors.pop().getMatrix();
let ancestor: Node | undefined;
const worldMatrix = ancestors.pop()!.getMatrix();
while ((ancestor = ancestors.pop())) {

@@ -172,3 +172,3 @@ multiply(worldMatrix, worldMatrix, ancestor.getMatrix());

public removeChild(child: Node): this {
return this.removeGraphChild(this.children, child)
return this.removeGraphChild(this.children, child);
}

@@ -185,3 +185,3 @@

*/
public getParent(): SceneNode {
public getParent(): SceneNode | null {
return this._parent;

@@ -195,3 +195,3 @@ }

/** Returns the {@link Mesh}, if any, instantiated at this node. */
public getMesh(): Mesh { return this.mesh ? this.mesh.getChild() : null; }
public getMesh(): Mesh | null { return this.mesh ? this.mesh.getChild() : null; }

@@ -202,3 +202,3 @@ /**

*/
public setMesh(mesh: Mesh): this {
public setMesh(mesh: Mesh | null): this {
this.mesh = this.graph.link('mesh', this, mesh);

@@ -209,6 +209,6 @@ return this;

/** Returns the {@link Camera}, if any, instantiated at this node. */
public getCamera(): Camera { return this.camera ? this.camera.getChild() : null; }
public getCamera(): Camera | null { return this.camera ? this.camera.getChild() : null; }
/** Sets a {@link Camera} to be instantiated at this node. */
public setCamera(camera: Camera): this {
public setCamera(camera: Camera | null): this {
this.camera = this.graph.link('camera', this, camera);

@@ -219,6 +219,6 @@ return this;

/** Returns the {@link Skin}, if any, instantiated at this node. */
public getSkin(): Skin { return this.skin ? this.skin.getChild() : null; }
public getSkin(): Skin | null { return this.skin ? this.skin.getChild() : null; }
/** Sets a {@link Skin} to be instantiated at this node. */
public setSkin(skin: Skin): this {
public setSkin(skin: Skin | null): this {
this.skin = this.graph.link('skin', this, skin);

@@ -258,5 +258,5 @@ return this;

interface SceneNode {
_parent?: SceneNode;
_parent?: SceneNode | null;
addChild(node: Node): this;
removeChild(node: Node): this;
}

@@ -33,3 +33,3 @@ import { PropertyType } from '../constants';

other.listSemantics().forEach((semantic) => {
this.setAttribute(semantic, resolve(other.getAttribute(semantic)));
this.setAttribute(semantic, resolve(other.getAttribute(semantic)!));
});

@@ -41,3 +41,3 @@

/** Returns a morph target vertex attribute as an {@link Accessor}. */
public getAttribute(semantic: string): Accessor {
public getAttribute(semantic: string): Accessor | null {
const link = this.attributes.find((link) => link.semantic === semantic);

@@ -50,3 +50,3 @@ return link ? link.getChild() : null;

*/
public setAttribute(semantic: string, accessor: Accessor): this {
public setAttribute(semantic: string, accessor: Accessor | null): this {
// Remove previous attribute.

@@ -60,3 +60,3 @@ const prevAccessor = this.getAttribute(semantic);

// Add next attribute.
const link = this.graph.linkAttribute(semantic.toLowerCase(), this, accessor) as AttributeLink;
const link = this.graph.linkAttribute(semantic.toLowerCase(), this, accessor);
link.semantic = semantic;

@@ -63,0 +63,0 @@ return this.addGraphChild(this.attributes, link);

@@ -50,6 +50,6 @@ import { PropertyType } from '../constants';

/** @hidden GPU draw mode. */
private _mode: GLTF.MeshPrimitiveMode = GLTF.MeshPrimitiveMode.TRIANGLES;
private _mode: GLTF.MeshPrimitiveMode = Primitive.Mode.TRIANGLES;
@GraphChild private material: Link<Primitive, Material> = null;
@GraphChild private indices: Link<Primitive, Accessor> = null;
@GraphChild private material: Link<Primitive, Material> | null = null;
@GraphChild private indices: Link<Primitive, Accessor> | null = null;
@GraphChildList private attributes: AttributeLink[] = [];

@@ -68,3 +68,3 @@ @GraphChildList private targets: Link<Primitive, PrimitiveTarget>[] = [];

other.listSemantics().forEach((semantic) => {
this.setAttribute(semantic, resolve(other.getAttribute(semantic)));
this.setAttribute(semantic, resolve(other.getAttribute(semantic)!));
});

@@ -78,4 +78,37 @@

/**********************************************************************************************
* Static.
*/
/** Type of primitives to render. All valid values correspond to WebGL enums. */
public static Mode: Record<string, GLTF.MeshPrimitiveMode> = {
/** Draw single points. */
POINTS: 0,
/** Draw lines. Each vertex connects to the one after it. */
LINES: 1,
/**
* Draw lines. Each set of two vertices is treated as a separate line segment.
* @deprecated See {@link https://github.com/KhronosGroup/glTF/issues/1883 KhronosGroup/glTF#1883}.
*/
LINE_LOOP: 2,
/** Draw a connected group of line segments from the first vertex to the last, */
LINE_STRIP: 3,
/** Draw triangles. Each set of three vertices creates a separate triangle. */
TRIANGLES: 4,
/** Draw a connected strip of triangles. */
TRIANGLE_STRIP: 5,
/**
* Draw a connected group of triangles. Each vertex connects to the previous and the first
* vertex in the fan.
* @deprecated See {@link https://github.com/KhronosGroup/glTF/issues/1883 KhronosGroup/glTF#1883}.
*/
TRIANGLE_FAN: 6,
}
/**********************************************************************************************
* Primitive data.
*/
/** Returns an {@link Accessor} with indices of vertices to be drawn. */
public getIndices(): Accessor {
public getIndices(): Accessor | null {
return this.indices ? this.indices.getChild() : null;

@@ -89,3 +122,3 @@ }

*/
public setIndices(indices: Accessor): this {
public setIndices(indices: Accessor | null): this {
this.indices = this.graph.linkIndex('index', this, indices);

@@ -96,3 +129,3 @@ return this;

/** Returns a vertex attribute as an {@link Accessor}. */
public getAttribute(semantic: string): Accessor {
public getAttribute(semantic: string): Accessor | null {
const link = this.attributes.find((link) => link.semantic === semantic);

@@ -106,3 +139,3 @@ return link ? link.getChild() : null;

*/
public setAttribute(semantic: string, accessor: Accessor): this {
public setAttribute(semantic: string, accessor: Accessor | null): this {
// Remove previous attribute.

@@ -116,3 +149,3 @@ const prevAccessor = this.getAttribute(semantic);

// Add next attribute.
const link = this.graph.linkAttribute(semantic.toLowerCase(), this, accessor) as AttributeLink;
const link = this.graph.linkAttribute(semantic.toLowerCase(), this, accessor);
link.semantic = semantic;

@@ -141,6 +174,8 @@ return this.addGraphChild(this.attributes, link);

/** Returns the material used to render the primitive. */
public getMaterial(): Material { return this.material ? this.material.getChild() : null; }
public getMaterial(): Material | null {
return this.material ? this.material.getChild() : null;
}
/** Sets the material used to render the primitive. */
public setMaterial(material: Material): this {
public setMaterial(material: Material | null): this {
this.material = this.graph.link('material', this, material);

@@ -150,2 +185,6 @@ return this;

/**********************************************************************************************
* Mode.
*/
/**

@@ -170,2 +209,6 @@ * Returns the GPU draw mode (`TRIANGLES`, `LINES`, `POINTS`...) as a WebGL enum value.

/**********************************************************************************************
* Morph targets.
*/
/** Lists all morph targets associated with the primitive. */

@@ -172,0 +215,0 @@ public listTargets(): PrimitiveTarget[] {

import { Graph } from '../graph';
import { Accessor } from './accessor';
import { Primitive } from './primitive';
import { PrimitiveTarget } from './primitive-target';
import { Property } from './property';

@@ -10,3 +9,6 @@ import { AttributeLink, IndexLink } from './property-links';

export class PropertyGraph extends Graph<Property> {
public linkAttribute(name: string, a: Primitive|PrimitiveTarget, b: Accessor): AttributeLink {
public linkAttribute(name: string, a: Property, b: null): null;
public linkAttribute(name: string, a: Property, b: Accessor): AttributeLink;
public linkAttribute(name: string, a: Property, b: Accessor | null): AttributeLink | null;
public linkAttribute(name: string, a: Property, b: Accessor | null): AttributeLink | null {
if (!b) return null;

@@ -18,3 +20,6 @@ const link = new AttributeLink(name, a, b);

public linkIndex(name: string, a: Primitive, b: Accessor): IndexLink {
public linkIndex(name: string, a: Primitive, b: null): null;
public linkIndex(name: string, a: Primitive, b: Accessor): IndexLink;
public linkIndex(name: string, a: Primitive, b: Accessor | null): IndexLink | null;
public linkIndex(name: string, a: Primitive, b: Accessor | null): IndexLink | null {
if (!b) return null;

@@ -21,0 +26,0 @@ const link = new IndexLink(name, a, b);

import { Link } from '../graph';
import { Accessor } from './accessor';
import { Primitive } from './primitive';
import { PrimitiveTarget } from './primitive-target';
import { Property } from './property';
/** @hidden */
export class AttributeLink extends Link<Primitive|PrimitiveTarget, Accessor> {
export class AttributeLink extends Link<Property, Accessor> {
public semantic = '';

@@ -17,3 +17,3 @@ public copy (other: this): this {

export class IndexLink extends Link<Primitive, Accessor> {
public copy (other: this): this { return this; }
public copy (_other: this): this { return this; }
}

@@ -46,9 +46,7 @@ import { GraphNode } from '../graph';

protected readonly graph: PropertyGraph;
private _extras: object = {};
private _extras: Record<string, unknown> = {};
private _name = '';
/** @hidden */
constructor(graph: PropertyGraph, name = '') {
constructor(protected readonly graph: PropertyGraph, name = '') {
super(graph);

@@ -87,3 +85,3 @@ this._name = name;

*/
public getExtras(): object { return this._extras; }
public getExtras(): Record<string, unknown> { return this._extras; }

@@ -94,3 +92,3 @@ /**

*/
public setExtras(extras: object): this {
public setExtras(extras: Record<string, unknown>): this {
this._extras = extras;

@@ -97,0 +95,0 @@ return this;

@@ -22,4 +22,4 @@ import { PropertyType } from '../constants';

@GraphChild private skeleton: Link<Skin, Node> = null;
@GraphChild private inverseBindMatrices: Link<Skin, Accessor> = null;
@GraphChild private skeleton: Link<Skin, Node> | null = null;
@GraphChild private inverseBindMatrices: Link<Skin, Accessor> | null = null;
@GraphChildList private joints: Link<Skin, Node>[] = [];

@@ -31,3 +31,5 @@

if (other.skeleton) this.setSkeleton(resolve(other.skeleton.getChild()));
if (other.inverseBindMatrices) this.setInverseBindMatrices(resolve(other.inverseBindMatrices.getChild()));
if (other.inverseBindMatrices) {
this.setInverseBindMatrices(resolve(other.inverseBindMatrices.getChild()));
}

@@ -44,3 +46,3 @@ this.clearGraphChildList(this.joints);

*/
public getSkeleton(): Node {
public getSkeleton(): Node | null {
return this.skeleton ? this.skeleton.getChild() : null;

@@ -53,3 +55,3 @@ }

*/
public setSkeleton(skeleton: Node): this {
public setSkeleton(skeleton: Node | null): this {
this.skeleton = this.graph.link('skeleton', this, skeleton);

@@ -64,3 +66,3 @@ return this;

*/
public getInverseBindMatrices(): Accessor {
public getInverseBindMatrices(): Accessor | null {
return this.inverseBindMatrices ? this.inverseBindMatrices.getChild() : null;

@@ -74,4 +76,5 @@ }

*/
public setInverseBindMatrices(inverseBindMatrices: Accessor): this {
this.inverseBindMatrices = this.graph.link('inverseBindMatrices', this, inverseBindMatrices);
public setInverseBindMatrices(inverseBindMatrices: Accessor | null): this {
this.inverseBindMatrices
= this.graph.link('inverseBindMatrices', this, inverseBindMatrices);
return this;

@@ -78,0 +81,0 @@ }

@@ -31,30 +31,7 @@ import { PropertyType } from '../constants';

// Sampler properties are also attached to TextureInfo, for simplicity.
private _magFilter: GLTF.TextureMagFilter = null;
private _minFilter: GLTF.TextureMinFilter = null;
private _wrapS: GLTF.TextureWrapMode = GLTF.TextureWrapMode.REPEAT;
private _wrapT: GLTF.TextureWrapMode = GLTF.TextureWrapMode.REPEAT;
private _magFilter: GLTF.TextureMagFilter | null = null;
private _minFilter: GLTF.TextureMinFilter | null = null;
private _wrapS: GLTF.TextureWrapMode = TextureInfo.WrapMode.REPEAT;
private _wrapT: GLTF.TextureWrapMode = TextureInfo.WrapMode.REPEAT;
/** UV wrapping mode. Values correspond to WebGL enums. */
public static TextureWrapMode = {
CLAMP_TO_EDGE: GLTF.TextureWrapMode.CLAMP_TO_EDGE,
MIRRORED_REPEAT: GLTF.TextureWrapMode.MIRRORED_REPEAT,
REPEAT: GLTF.TextureWrapMode.REPEAT,
}
/** Magnification filter. Values correspond to WebGL enums. */
public static TextureMagFilter = {
NEAREST: GLTF.TextureMagFilter.NEAREST,
LINEAR: GLTF.TextureMagFilter.LINEAR,
}
/** Minification filter. Values correspond to WebGL enums. */
public static TextureMinFilter = {
NEAREST: GLTF.TextureMinFilter.NEAREST,
LINEAR: GLTF.TextureMinFilter.LINEAR,
NEAREST_MIPMAP_NEAREST: GLTF.TextureMinFilter.NEAREST_MIPMAP_NEAREST,
LINEAR_MIPMAP_NEAREST: GLTF.TextureMinFilter.LINEAR_MIPMAP_NEAREST,
NEAREST_MIPMAP_LINEAR: GLTF.TextureMinFilter.NEAREST_MIPMAP_LINEAR,
LINEAR_MIPMAP_LINEAR: GLTF.TextureMinFilter.LINEAR_MIPMAP_LINEAR,
}
public copy(other: this, resolve = COPY_IDENTITY): this {

@@ -73,2 +50,40 @@ super.copy(other, resolve);

/**********************************************************************************************
* Static.
*/
/** UV wrapping mode. Values correspond to WebGL enums. */
public static WrapMode: Record<string, GLTF.TextureWrapMode> = {
/** */
CLAMP_TO_EDGE: 33071,
/** */
MIRRORED_REPEAT: 33648,
/** */
REPEAT: 10497,
}
/** Magnification filter. Values correspond to WebGL enums. */
public static MagFilter: Record<string, GLTF.TextureMagFilter> = {
/** */
NEAREST: 9728,
/** */
LINEAR: 9729,
}
/** Minification filter. Values correspond to WebGL enums. */
public static MinFilter: Record<string, GLTF.TextureMinFilter> = {
/** */
NEAREST: 9728,
/** */
LINEAR: 9729,
/** */
NEAREST_MIPMAP_NEAREST: 9984,
/** */
LINEAR_MIPMAP_NEAREST: 9985,
/** */
NEAREST_MIPMAP_LINEAR: 9986,
/** */
LINEAR_MIPMAP_LINEAR: 9987,
}
/**********************************************************************************************
* Texture coordinates.

@@ -91,6 +106,6 @@ */

/** Returns the magnification filter applied to the texture. */
public getMagFilter(): GLTF.TextureMagFilter { return this._magFilter; }
public getMagFilter(): GLTF.TextureMagFilter | null { return this._magFilter; }
/** Sets the magnification filter applied to the texture. */
public setMagFilter(magFilter: GLTF.TextureMagFilter): this {
public setMagFilter(magFilter: GLTF.TextureMagFilter | null): this {
this._magFilter = magFilter;

@@ -101,6 +116,6 @@ return this;

/** Sets the minification filter applied to the texture. */
public getMinFilter(): GLTF.TextureMinFilter { return this._minFilter; }
public getMinFilter(): GLTF.TextureMinFilter | null { return this._minFilter; }
/** Returns the minification filter applied to the texture. */
public setMinFilter(minFilter: GLTF.TextureMinFilter): this {
public setMinFilter(minFilter: GLTF.TextureMinFilter | null): this {
this._minFilter = minFilter;

@@ -107,0 +122,0 @@ return this;

@@ -30,3 +30,3 @@ import { PropertyType, vec2 } from '../constants';

/** @hidden Raw image data for this texture. */
private _image: ArrayBuffer = null;
private _image: ArrayBuffer | null = null;

@@ -92,3 +92,3 @@ /** @hidden Image MIME type. Required if URI is not set. */

/** Returns the raw image data for this texture. */
public getImage(): ArrayBuffer { return this._image; }
public getImage(): ArrayBuffer | null { return this._image; }

@@ -102,5 +102,6 @@ /** Sets the raw image data for this texture. */

/** Returns the size, in pixels, of this texture. */
public getSize(): vec2 {
public getSize(): vec2 | null {
if (!this._image) return null;
return ImageUtils.getSize(this._image, this.getMimeType());
}
}
/* eslint-disable @typescript-eslint/no-namespace */
/* eslint-disable @typescript-eslint/interface-name-prefix */
/* eslint-disable @typescript-eslint/prefer-namespace-keyword */
/**
* Module for glTF 2.0 Interface
*/
* Module for glTF 2.0 Interface
*/
export declare module GLTF {
/** Data type of the values composing each element in the accessor. */
type AccessorComponentType = 5120 | 5121 | 5122 | 5123 | 5125 | 5126;
/** Element type contained by the accessor (SCALAR, VEC2, ...). */
type AccessorType = 'SCALAR' | 'VEC2' | 'VEC3' | 'VEC4' | 'MAT2' | 'MAT3' | 'MAT4';
/** Name of the property to be modified by an animation channel. */
type AnimationChannelTargetPath = 'translation' | 'rotation' | 'scale' | 'weights';
/** Interpolation method. */
type AnimationSamplerInterpolation = 'LINEAR' | 'STEP' | 'CUBICSPLINE';
/** Projection type used by a camera. */
type CameraType = 'perspective' | 'orthographic';
/** The alpha rendering mode of the material. */
type MaterialAlphaMode = 'OPAQUE' | 'MASK' | 'BLEND';
/** The type of the GL primitives to render. */
type MeshPrimitiveMode = | 0 | 1 | 2 | 3 | 4 | 5 | 6;
/** Magnification filter. Values match to WebGL enums: 9728 (NEAREST) and 9729 (LINEAR). */
type TextureMagFilter = 9728 | 9729;
/** Minification filter. All valid values correspond to WebGL enums. */
type TextureMinFilter = 9728 | 9729 | 9984 | 9985 | 9986 | 9987;
/** S (U) wrapping mode. All valid values correspond to WebGL enums. */
type TextureWrapMode = 33071 | 33648 | 10497;
/**
* The datatype of the components in the attribute
*/
const enum AccessorComponentType {
/**
* Byte
*/
BYTE = 5120,
/**
* Unsigned Byte
*/
UNSIGNED_BYTE = 5121,
/**
* Short
*/
SHORT = 5122,
/**
* Unsigned Short
*/
UNSIGNED_SHORT = 5123,
/**
* Unsigned Int
*/
UNSIGNED_INT = 5125,
/**
* Float
*/
FLOAT = 5126,
}
/**
* Specifies if the attirbute is a scalar, vector, or matrix
*/
const enum AccessorType {
/**
* Scalar
*/
SCALAR = "SCALAR",
/**
* Vector2
*/
VEC2 = "VEC2",
/**
* Vector3
*/
VEC3 = "VEC3",
/**
* Vector4
*/
VEC4 = "VEC4",
/**
* Matrix2x2
*/
MAT2 = "MAT2",
/**
* Matrix3x3
*/
MAT3 = "MAT3",
/**
* Matrix4x4
*/
MAT4 = "MAT4",
}
/**
* The name of the node's TRS property to modify, or the weights of the Morph Targets it instantiates
*/
const enum AnimationChannelTargetPath {
/**
* Translation
*/
TRANSLATION = "translation",
/**
* Rotation
*/
ROTATION = "rotation",
/**
* Scale
*/
SCALE = "scale",
/**
* Weights
*/
WEIGHTS = "weights",
}
/**
* Interpolation algorithm
*/
const enum AnimationSamplerInterpolation {
/**
* The animated values are linearly interpolated between keyframes
*/
LINEAR = "LINEAR",
/**
* The animated values remain constant to the output of the first keyframe, until the next keyframe
*/
STEP = "STEP",
/**
* The animation's interpolation is computed using a cubic spline with specified tangents
*/
CUBICSPLINE = "CUBICSPLINE",
}
/**
* A camera's projection. A node can reference a camera to apply a transform to place the camera in the scene
*/
const enum CameraType {
/**
* A perspective camera containing properties to create a perspective projection matrix
*/
PERSPECTIVE = "perspective",
/**
* An orthographic camera containing properties to create an orthographic projection matrix
*/
ORTHOGRAPHIC = "orthographic",
}
/**
* The alpha rendering mode of the material
*/
const enum MaterialAlphaMode {
/**
* The alpha value is ignored and the rendered output is fully opaque
*/
OPAQUE = "OPAQUE",
/**
* The rendered output is either fully opaque or fully transparent depending on the alpha value and the specified alpha cutoff value
*/
MASK = "MASK",
/**
* The alpha value is used to composite the source and destination areas. The rendered output is combined with the background using the normal painting operation (i.e. the Porter and Duff over operator)
*/
BLEND = "BLEND",
}
/**
* The type of the primitives to render
*/
const enum MeshPrimitiveMode {
/**
* Points
*/
POINTS = 0,
/**
* Lines
*/
LINES = 1,
/**
* Line Loop
*/
LINE_LOOP = 2,
/**
* Line Strip
*/
LINE_STRIP = 3,
/**
* Triangles
*/
TRIANGLES = 4,
/**
* Triangle Strip
*/
TRIANGLE_STRIP = 5,
/**
* Triangle Fan
*/
TRIANGLE_FAN = 6,
}
/**
* Magnification filter. Valid values correspond to WebGL enums: 9728 (NEAREST) and 9729 (LINEAR)
*/
const enum TextureMagFilter {
/**
* Nearest
*/
NEAREST = 9728,
/**
* Linear
*/
LINEAR = 9729,
}
/**
* Minification filter. All valid values correspond to WebGL enums
*/
const enum TextureMinFilter {
/**
* Nearest
*/
NEAREST = 9728,
/**
* Linear
*/
LINEAR = 9729,
/**
* Nearest Mip-Map Nearest
*/
NEAREST_MIPMAP_NEAREST = 9984,
/**
* Linear Mipmap Nearest
*/
LINEAR_MIPMAP_NEAREST = 9985,
/**
* Nearest Mipmap Linear
*/
NEAREST_MIPMAP_LINEAR = 9986,
/**
* Linear Mipmap Linear
*/
LINEAR_MIPMAP_LINEAR = 9987,
}
/**
* S (U) wrapping mode. All valid values correspond to WebGL enums
*/
const enum TextureWrapMode {
/**
* Clamp to Edge
*/
CLAMP_TO_EDGE = 33071,
/**
* Mirrored Repeat
*/
MIRRORED_REPEAT = 33648,
/**
* Repeat
*/
REPEAT = 10497,
}
/**
* glTF Property
*/
* glTF Property
*/
interface IProperty {
/**
* Dictionary object with extension-specific objects
*/
extensions?: {
[key: string]: any;
};
* Dictionary object with extension-specific objects
*/
extensions?: Record<string, unknown>;
/**
* Application-Specific data
*/
extras?: any;
* Application-Specific data
*/
extras?: Record<string, unknown>;
}
/**
* glTF Child of Root Property
*/
* glTF Child of Root Property
*/
interface IChildRootProperty extends IProperty {
/**
* The user-defined name of this object
*/
* The user-defined name of this object
*/
name?: string;
}
/**
* Indices of those attributes that deviate from their initialization value
*/
* Indices of those attributes that deviate from their initialization value
*/
interface IAccessorSparseIndices extends IProperty {
/**
* The index of the bufferView with sparse indices. Referenced bufferView can't have ARRAY_BUFFER or ELEMENT_ARRAY_BUFFER target
*/
* The index of the bufferView with sparse indices. Referenced bufferView can't have
* ARRAY_BUFFER or ELEMENT_ARRAY_BUFFER target
*/
bufferView: number;
/**
* The offset relative to the start of the bufferView in bytes. Must be aligned
*/
* The offset relative to the start of the bufferView in bytes. Must be aligned
*/
byteOffset?: number;
/**
* The indices data type. Valid values correspond to WebGL enums: 5121 (UNSIGNED_BYTE), 5123 (UNSIGNED_SHORT), 5125 (UNSIGNED_INT)
*/
* The indices data type. Valid values correspond to WebGL enums: 5121 (UNSIGNED_BYTE),
* 5123 (UNSIGNED_SHORT), 5125 (UNSIGNED_INT)
*/
componentType: AccessorComponentType;
}
/**
* Array of size accessor.sparse.count times number of components storing the displaced accessor attributes pointed by accessor.sparse.indices
*/
* Array of size accessor.sparse.count times number of components storing the displaced accessor
* attributes pointed by accessor.sparse.indices
*/
interface IAccessorSparseValues extends IProperty {
/**
* The index of the bufferView with sparse values. Referenced bufferView can't have ARRAY_BUFFER or ELEMENT_ARRAY_BUFFER target
*/
* The index of the bufferView with sparse values. Referenced bufferView can't have
* ARRAY_BUFFER or ELEMENT_ARRAY_BUFFER target
*/
bufferView: number;
/**
* The offset relative to the start of the bufferView in bytes. Must be aligned
*/
* The offset relative to the start of the bufferView in bytes. Must be aligned
*/
byteOffset?: number;
}
/**
* Sparse storage of attributes that deviate from their initialization value
*/
* Sparse storage of attributes that deviate from their initialization value
*/
interface IAccessorSparse extends IProperty {
/**
* The number of attributes encoded in this sparse accessor
*/
* The number of attributes encoded in this sparse accessor
*/
count: number;
/**
* Index array of size count that points to those accessor attributes that deviate from their initialization value. Indices must strictly increase
*/
* Index array of size count that points to those accessor attributes that deviate from
* their initialization value. Indices must strictly increase
*/
indices: IAccessorSparseIndices;
/**
* Array of size count times number of components, storing the displaced accessor attributes pointed by indices. Substituted values must have the same componentType and number of components as the base accessor
*/
* Array of size count times number of components, storing the displaced accessor attributes
* pointed by indices. Substituted values must have the same componentType and number of
* components as the base accessor
*/
values: IAccessorSparseValues;
}
/**
* A typed view into a bufferView. A bufferView contains raw binary data. An accessor provides a typed view into a bufferView or a subset of a bufferView similar to how WebGL's vertexAttribPointer() defines an attribute in a buffer
*/
* A typed view into a bufferView. A bufferView contains raw binary data. An accessor provides
* a typed view into a bufferView or a subset of a bufferView similar to how WebGL's
* vertexAttribPointer() defines an attribute in a buffer
*/
interface IAccessor extends IChildRootProperty {
/**
* The index of the bufferview
*/
* The index of the bufferview
*/
bufferView?: number;
/**
* The offset relative to the start of the bufferView in bytes
*/
* The offset relative to the start of the bufferView in bytes
*/
byteOffset?: number;
/**
* The datatype of components in the attribute
*/
* The datatype of components in the attribute
*/
componentType: AccessorComponentType;
/**
* Specifies whether integer data values should be normalized
*/
* Specifies whether integer data values should be normalized
*/
normalized?: boolean;
/**
* The number of attributes referenced by this accessor
*/
* The number of attributes referenced by this accessor
*/
count: number;
/**
* Specifies if the attribute is a scalar, vector, or matrix
*/
* Specifies if the attribute is a scalar, vector, or matrix
*/
type: AccessorType;
/**
* Maximum value of each component in this attribute
*/
* Maximum value of each component in this attribute
*/
max?: number[];
/**
* Minimum value of each component in this attribute
*/
* Minimum value of each component in this attribute
*/
min?: number[];
/**
* Sparse storage of attributes that deviate from their initialization value
*/
* Sparse storage of attributes that deviate from their initialization value
*/
sparse?: IAccessorSparse;
}
/**
* Targets an animation's sampler at a node's property
*/
* Targets an animation's sampler at a node's property
*/
interface IAnimationChannel extends IProperty {
/**
* The index of a sampler in this animation used to compute the value for the target
*/
* The index of a sampler in this animation used to compute the value for the target
*/
sampler: number;
/**
* The index of the node and TRS property to target
*/
* The index of the node and TRS property to target
*/
target: IAnimationChannelTarget;
}
/**
* The index of the node and TRS property that an animation channel targets
*/
* The index of the node and TRS property that an animation channel targets
*/
interface IAnimationChannelTarget extends IProperty {
/**
* The index of the node to target
*/
* The index of the node to target
*/
node: number;
/**
* The name of the node's TRS property to modify, or the weights of the Morph Targets it instantiates
*/
* The name of the node's TRS property to modify, or the weights of the Morph Targets it
* instantiates
*/
path: AnimationChannelTargetPath;
}
/**
* Combines input and output accessors with an interpolation algorithm to define a keyframe graph (but not its target)
*/
* Combines input and output accessors with an interpolation algorithm to define a keyframe
* graph (but not its target)
*/
interface IAnimationSampler extends IProperty {
/**
* The index of an accessor containing keyframe input values, e.g., time
*/
* The index of an accessor containing keyframe input values, e.g., time
*/
input: number;
/**
* Interpolation algorithm
*/
* Interpolation algorithm
*/
interpolation?: AnimationSamplerInterpolation;
/**
* The index of an accessor, containing keyframe output values
*/
* The index of an accessor, containing keyframe output values
*/
output: number;
}
/**
* A keyframe animation
*/
* A keyframe animation
*/
interface IAnimation extends IChildRootProperty {
/**
* An array of channels, each of which targets an animation's sampler at a node's property
*/
* An array of channels, each of which targets an animation's sampler at a node's property
*/
channels: IAnimationChannel[];
/**
* An array of samplers that combines input and output accessors with an interpolation algorithm to define a keyframe graph (but not its target)
*/
* An array of samplers that combines input and output accessors with an interpolation
* algorithm to define a keyframe graph (but not its target)
*/
samplers: IAnimationSampler[];
}
/**
* Metadata about the glTF asset
*/
* Metadata about the glTF asset
*/
interface IAsset extends IChildRootProperty {
/**
* A copyright message suitable for display to credit the content creator
*/
* A copyright message suitable for display to credit the content creator
*/
copyright?: string;
/**
* Tool that generated this glTF model. Useful for debugging
*/
* Tool that generated this glTF model. Useful for debugging
*/
generator?: string;
/**
* The glTF version that this asset targets
*/
* The glTF version that this asset targets
*/
version: string;
/**
* The minimum glTF version that this asset targets
*/
* The minimum glTF version that this asset targets
*/
minVersion?: string;
}
/**
* A buffer points to binary geometry, animation, or skins
*/
* A buffer points to binary geometry, animation, or skins
*/
interface IBuffer extends IChildRootProperty {
/**
* The uri of the buffer. Relative paths are relative to the .gltf file. Instead of referencing an external file, the uri can also be a data-uri
*/
* The uri of the buffer. Relative paths are relative to the .gltf file. Instead of
* referencing an external file, the uri can also be a data-uri
*/
uri?: string;
/**
* The length of the buffer in bytes
*/
* The length of the buffer in bytes
*/
byteLength: number;
}
/**
* A view into a buffer generally representing a subset of the buffer
*/
* A view into a buffer generally representing a subset of the buffer
*/
interface IBufferView extends IChildRootProperty {
/**
* The index of the buffer
*/
* The index of the buffer
*/
buffer: number;
/**
* The offset into the buffer in bytes
*/
* The offset into the buffer in bytes
*/
byteOffset?: number;
/**
* The lenth of the bufferView in bytes
*/
* The lenth of the bufferView in bytes
*/
byteLength: number;
/**
* The stride, in bytes
*/
* The stride, in bytes
*/
byteStride?: number;
/**
* The target that the GPU buffer should be bound to
*/
* The target that the GPU buffer should be bound to
*/
target?: number;
}
/**
* An orthographic camera containing properties to create an orthographic projection matrix
*/
* An orthographic camera containing properties to create an orthographic projection matrix
*/
interface ICameraOrthographic extends IProperty {
/**
* The floating-point horizontal magnification of the view. Must not be zero
*/
* The floating-point horizontal magnification of the view. Must not be zero
*/
xmag: number;
/**
* The floating-point vertical magnification of the view. Must not be zero
*/
* The floating-point vertical magnification of the view. Must not be zero
*/
ymag: number;
/**
* The floating-point distance to the far clipping plane. zfar must be greater than znear
*/
* The floating-point distance to the far clipping plane. zfar must be greater than znear
*/
zfar: number;
/**
* The floating-point distance to the near clipping plane
*/
* The floating-point distance to the near clipping plane
*/
znear: number;
}
/**
* A perspective camera containing properties to create a perspective projection matrix
*/
* A perspective camera containing properties to create a perspective projection matrix
*/
interface ICameraPerspective extends IProperty {
/**
* The floating-point aspect ratio of the field of view
*/
* The floating-point aspect ratio of the field of view
*/
aspectRatio?: number;
/**
* The floating-point vertical field of view in radians
*/
* The floating-point vertical field of view in radians
*/
yfov: number;
/**
* The floating-point distance to the far clipping plane
*/
* The floating-point distance to the far clipping plane
*/
zfar?: number;
/**
* The floating-point distance to the near clipping plane
*/
* The floating-point distance to the near clipping plane
*/
znear: number;
}
/**
* A camera's projection. A node can reference a camera to apply a transform to place the camera in the scene
*/
* A camera's projection. A node can reference a camera to apply a transform to place the
* camera in the scene
*/
interface ICamera extends IChildRootProperty {
/**
* An orthographic camera containing properties to create an orthographic projection matrix
*/
* An orthographic camera containing properties to create an orthographic projection matrix
*/
orthographic?: ICameraOrthographic;
/**
* A perspective camera containing properties to create a perspective projection matrix
*/
* A perspective camera containing properties to create a perspective projection matrix
*/
perspective?: ICameraPerspective;
/**
* Specifies if the camera uses a perspective or orthographic projection
*/
* Specifies if the camera uses a perspective or orthographic projection
*/
type: CameraType;
}
/**
* Image data used to create a texture. Image can be referenced by URI or bufferView index. mimeType is required in the latter case
*/
* Image data used to create a texture. Image can be referenced by URI or bufferView index.
* mimeType is required in the latter case
*/
interface IImage extends IChildRootProperty {
/**
* The uri of the image. Relative paths are relative to the .gltf file. Instead of referencing an external file, the uri can also be a data-uri. The image format must be jpg or png
*/
* The uri of the image. Relative paths are relative to the .gltf file. Instead of
* referencing an external file, the uri can also be a data-uri. The image format must be
* jpg or png
*/
uri?: string;
/**
* The image's MIME type
*/
* The image's MIME type
*/
mimeType?: string;
/**
* The index of the bufferView that contains the image. Use this instead of the image's uri property
*/
* The index of the bufferView that contains the image. Use this instead of the image's uri
* property
*/
bufferView?: number;
}
/**
* Material Normal Texture Info
*/
* Material Normal Texture Info
*/
interface IMaterialNormalTextureInfo extends ITextureInfo {
/**
* The scalar multiplier applied to each normal vector of the normal texture
*/
* The scalar multiplier applied to each normal vector of the normal texture
*/
scale?: number;
}
/**
* Material Occlusion Texture Info
*/
* Material Occlusion Texture Info
*/
interface IMaterialOcclusionTextureInfo extends ITextureInfo {
/**
* A scalar multiplier controlling the amount of occlusion applied
*/
* A scalar multiplier controlling the amount of occlusion applied
*/
strength?: number;
}
/**
* A set of parameter values that are used to define the metallic-roughness material model from Physically-Based Rendering (PBR) methodology
*/
* A set of parameter values that are used to define the metallic-roughness material model from
* Physically-Based Rendering (PBR) methodology
*/
interface IMaterialPbrMetallicRoughness {
/**
* The material's base color factor
*/
* The material's base color factor
*/
baseColorFactor?: number[];
/**
* The base color texture
*/
* The base color texture
*/
baseColorTexture?: ITextureInfo;
/**
* The metalness of the material
*/
* The metalness of the material
*/
metallicFactor?: number;
/**
* The roughness of the material
*/
* The roughness of the material
*/
roughnessFactor?: number;
/**
* The metallic-roughness texture
*/
* The metallic-roughness texture
*/
metallicRoughnessTexture?: ITextureInfo;
}
/**
* The material appearance of a primitive
*/
* The material appearance of a primitive
*/
interface IMaterial extends IChildRootProperty {
/**
* A set of parameter values that are used to define the metallic-roughness material model from Physically-Based Rendering (PBR) methodology. When not specified, all the default values of pbrMetallicRoughness apply
*/
* A set of parameter values that are used to define the metallic-roughness material model
* from Physically-Based Rendering (PBR) methodology. When not specified, all the default
* values of pbrMetallicRoughness apply
*/
pbrMetallicRoughness?: IMaterialPbrMetallicRoughness;
/**
* The normal map texture
*/
* The normal map texture
*/
normalTexture?: IMaterialNormalTextureInfo;
/**
* The occlusion map texture
*/
* The occlusion map texture
*/
occlusionTexture?: IMaterialOcclusionTextureInfo;
/**
* The emissive map texture
*/
* The emissive map texture
*/
emissiveTexture?: ITextureInfo;
/**
* The RGB components of the emissive color of the material. These values are linear. If an emissiveTexture is specified, this value is multiplied with the texel values
*/
* The RGB components of the emissive color of the material. These values are linear. If
* an emissiveTexture is specified, this value is multiplied with the texel values
*/
emissiveFactor?: number[];
/**
* The alpha rendering mode of the material
*/
* The alpha rendering mode of the material
*/
alphaMode?: MaterialAlphaMode;
/**
* The alpha cutoff value of the material
*/
* The alpha cutoff value of the material
*/
alphaCutoff?: number;
/**
* Specifies whether the material is double sided
*/
* Specifies whether the material is double sided
*/
doubleSided?: boolean;
}
/**
* Geometry to be rendered with the given material
*/
* Geometry to be rendered with the given material
*/
interface IMeshPrimitive extends IProperty {
/**
* A dictionary object, where each key corresponds to mesh attribute semantic and each value is the index of the accessor containing attribute's data
*/
* A dictionary object, where each key corresponds to mesh attribute semantic and each
* value is the index of the accessor containing attribute's data
*/
attributes: {

@@ -624,16 +442,17 @@ [name: string]: number;

/**
* The index of the accessor that contains the indices
*/
* The index of the accessor that contains the indices
*/
indices?: number;
/**
* The index of the material to apply to this primitive when rendering
*/
* The index of the material to apply to this primitive when rendering
*/
material?: number;
/**
* The type of primitives to render. All valid values correspond to WebGL enums
*/
* The type of primitives to render. All valid values correspond to WebGL enums
*/
mode?: MeshPrimitiveMode;
/**
* An array of Morph Targets, each Morph Target is a dictionary mapping attributes (only POSITION, NORMAL, and TANGENT supported) to their deviations in the Morph Target
*/
* An array of Morph Targets, each Morph Target is a dictionary mapping attributes (only
* POSITION, NORMAL, and TANGENT supported) to their deviations in the Morph Target
*/
targets?: {

@@ -644,201 +463,211 @@ [name: string]: number;

/**
* A set of primitives to be rendered. A node can contain one mesh. A node's transform places the mesh in the scene
*/
* A set of primitives to be rendered. A node can contain one mesh. A node's transform
* places the mesh in the scene
*/
interface IMesh extends IChildRootProperty {
/**
* An array of primitives, each defining geometry to be rendered with a material
*/
* An array of primitives, each defining geometry to be rendered with a material
*/
primitives: IMeshPrimitive[];
/**
* Array of weights to be applied to the Morph Targets
*/
* Array of weights to be applied to the Morph Targets
*/
weights?: number[];
}
/**
* A node in the node hierarchy
*/
* A node in the node hierarchy
*/
interface INode extends IChildRootProperty {
/**
* The index of the camera referenced by this node
*/
* The index of the camera referenced by this node
*/
camera?: number;
/**
* The indices of this node's children
*/
* The indices of this node's children
*/
children?: number[];
/**
* The index of the skin referenced by this node
*/
* The index of the skin referenced by this node
*/
skin?: number;
/**
* A floating-point 4x4 transformation matrix stored in column-major order
*/
* A floating-point 4x4 transformation matrix stored in column-major order
*/
matrix?: number[];
/**
* The index of the mesh in this node
*/
* The index of the mesh in this node
*/
mesh?: number;
/**
* The node's unit quaternion rotation in the order (x, y, z, w), where w is the scalar
*/
* The node's unit quaternion rotation in the order (x, y, z, w), where w is the scalar
*/
rotation?: number[];
/**
* The node's non-uniform scale, given as the scaling factors along the x, y, and z axes
*/
* The node's non-uniform scale, given as the scaling factors along the x, y, and z axes
*/
scale?: number[];
/**
* The node's translation along the x, y, and z axes
*/
* The node's translation along the x, y, and z axes
*/
translation?: number[];
/**
* The weights of the instantiated Morph Target. Number of elements must match number of Morph Targets of used mesh
*/
* The weights of the instantiated Morph Target. Number of elements must match number of
* Morph Targets of used mesh
*/
weights?: number[];
}
/**
* Texture sampler properties for filtering and wrapping modes
*/
* Texture sampler properties for filtering and wrapping modes
*/
interface ISampler extends IChildRootProperty {
/**
* Magnification filter. Valid values correspond to WebGL enums: 9728 (NEAREST) and 9729 (LINEAR)
*/
* Magnification filter. Valid values correspond to WebGL enums: 9728 (NEAREST) and 9729
* (LINEAR)
*/
magFilter?: TextureMagFilter;
/**
* Minification filter. All valid values correspond to WebGL enums
*/
* Minification filter. All valid values correspond to WebGL enums
*/
minFilter?: TextureMinFilter;
/**
* S (U) wrapping mode. All valid values correspond to WebGL enums
*/
* S (U) wrapping mode. All valid values correspond to WebGL enums
*/
wrapS?: TextureWrapMode;
/**
* T (V) wrapping mode. All valid values correspond to WebGL enums
*/
* T (V) wrapping mode. All valid values correspond to WebGL enums
*/
wrapT?: TextureWrapMode;
}
/**
* The root nodes of a scene
*/
* The root nodes of a scene
*/
interface IScene extends IChildRootProperty {
/**
* The indices of each root node
*/
* The indices of each root node
*/
nodes: number[];
}
/**
* Joints and matrices defining a skin
*/
* Joints and matrices defining a skin
*/
interface ISkin extends IChildRootProperty {
/**
* The index of the accessor containing the floating-point 4x4 inverse-bind matrices. The default is that each matrix is a 4x4 identity matrix, which implies that inverse-bind matrices were pre-applied
*/
* The index of the accessor containing the floating-point 4x4 inverse-bind matrices. The
* default is that each matrix is a 4x4 identity matrix, which implies that inverse-bind
* matrices were pre-applied
*/
inverseBindMatrices?: number;
/**
* The index of the node used as a skeleton root. When undefined, joints transforms resolve to scene root
*/
* The index of the node used as a skeleton root. When undefined, joints transforms resolve
* to scene root
*/
skeleton?: number;
/**
* Indices of skeleton nodes, used as joints in this skin. The array length must be the same as the count property of the inverseBindMatrices accessor (when defined)
*/
* Indices of skeleton nodes, used as joints in this skin. The array length must be the
* same as the count property of the inverseBindMatrices accessor (when defined)
*/
joints: number[];
}
/**
* A texture and its sampler
*/
* A texture and its sampler
*/
interface ITexture extends IChildRootProperty {
/**
* The index of the sampler used by this texture. When undefined, a sampler with repeat wrapping and auto filtering should be used
*/
* The index of the sampler used by this texture. When undefined, a sampler with repeat
* wrapping and auto filtering should be used
*/
sampler?: number;
/**
* The index of the image used by this texture
*/
source: number;
* The index of the image used by this texture
*/
source?: number;
}
/**
* Reference to a texture
*/
* Reference to a texture
*/
interface ITextureInfo extends IProperty {
/**
* The index of the texture
*/
* The index of the texture
*/
index: number;
/**
* The set index of texture's TEXCOORD attribute used for texture coordinate mapping
*/
* The set index of texture's TEXCOORD attribute used for texture coordinate mapping
*/
texCoord?: number;
}
/**
* The root object for a glTF asset
*/
* The root object for a glTF asset
*/
interface IGLTF extends IProperty {
/**
* An array of accessors. An accessor is a typed view into a bufferView
*/
* An array of accessors. An accessor is a typed view into a bufferView
*/
accessors?: IAccessor[];
/**
* An array of keyframe animations
*/
* An array of keyframe animations
*/
animations?: IAnimation[];
/**
* Metadata about the glTF asset
*/
* Metadata about the glTF asset
*/
asset: IAsset;
/**
* An array of buffers. A buffer points to binary geometry, animation, or skins
*/
* An array of buffers. A buffer points to binary geometry, animation, or skins
*/
buffers?: IBuffer[];
/**
* An array of bufferViews. A bufferView is a view into a buffer generally representing a subset of the buffer
*/
* An array of bufferViews. A bufferView is a view into a buffer generally representing
* a subset of the buffer
*/
bufferViews?: IBufferView[];
/**
* An array of cameras
*/
* An array of cameras
*/
cameras?: ICamera[];
/**
* Names of glTF extensions used somewhere in this asset
*/
* Names of glTF extensions used somewhere in this asset
*/
extensionsUsed?: string[];
/**
* Names of glTF extensions required to properly load this asset
*/
* Names of glTF extensions required to properly load this asset
*/
extensionsRequired?: string[];
/**
* An array of images. An image defines data used to create a texture
*/
* An array of images. An image defines data used to create a texture
*/
images?: IImage[];
/**
* An array of materials. A material defines the appearance of a primitive
*/
* An array of materials. A material defines the appearance of a primitive
*/
materials?: IMaterial[];
/**
* An array of meshes. A mesh is a set of primitives to be rendered
*/
* An array of meshes. A mesh is a set of primitives to be rendered
*/
meshes?: IMesh[];
/**
* An array of nodes
*/
* An array of nodes
*/
nodes?: INode[];
/**
* An array of samplers. A sampler contains properties for texture filtering and wrapping modes
*/
* An array of samplers. A sampler contains properties for texture filtering and wrapping
* modes
*/
samplers?: ISampler[];
/**
* The index of the default scene
*/
* The index of the default scene
*/
scene?: number;
/**
* An array of scenes
*/
* An array of scenes
*/
scenes?: IScene[];
/**
* An array of skins. A skin is defined by joints and matrices
*/
* An array of skins. A skin is defined by joints and matrices
*/
skins?: ISkin[];
/**
* An array of textures
*/
* An array of textures
*/
textures?: ITexture[];
}
}

@@ -20,3 +20,3 @@ import { vec2 } from '../constants';

class ImageUtils {
/** Returns [conservative] estimate of the dimensions of the image. */
/** Returns the dimensions of the image. */
public static getSize (buffer: ArrayBuffer, mimeType: string): vec2 {

@@ -32,3 +32,7 @@ switch (mimeType) {

/** Returns [conservative] estimate of the number of channels in the image. */
/**
* Returns a conservative estimate of the number of channels in the image. For some image
* formats, the method may return 4 indicating the possibility of an alpha channel, without
* the ability to guarantee that an alpha channel is present.
*/
public static getChannels (buffer: ArrayBuffer, mimeType: string): number {

@@ -44,3 +48,3 @@ switch (mimeType) {

/** Returns [conservative] estimate of the GPU memory required by this image. */
/** Returns a conservative estimate of the GPU memory required by this image. */
public static getMemSize (buffer: ArrayBuffer, mimeType: string): number {

@@ -64,7 +68,7 @@ if (mimeType === 'image/ktx2') {

const resolution = this.getSize(buffer, mimeType);
const channels = this.getChannels(buffer, mimeType);
const channels = 4; // See https://github.com/donmccurdy/glTF-Transform/issues/151.
return resolution ? resolution[0] * resolution[1] * channels : null;
}
/** Returns the size of a JPEG image. */
/** @hidden Returns the size of a JPEG image. */
private static _getSizeJPEG (buffer: ArrayBuffer): vec2 {

@@ -88,3 +92,3 @@ // Skip 4 chars, they are for signature

if (next === 0xC0 || next === 0xC1 || next === 0xC2) {
return [view.getUint16(i + 7, false), view.getUint16(i + 5, false)]
return [view.getUint16(i + 7, false), view.getUint16(i + 5, false)];
}

@@ -99,3 +103,3 @@

/** Returns the size of a PNG image. */
/** @hidden Returns the size of a PNG image. */
private static _getSizePNG (buffer: ArrayBuffer): vec2 {

@@ -110,2 +114,3 @@ const view = new DataView(buffer);

/** @hidden Returns the size of a WebP image. */
private static _getSizeWebP (buffer: ArrayBuffer): vec2 {

@@ -143,2 +148,3 @@ // Reference: http://tools.ietf.org/html/rfc6386

/** @hidden */
private static _getSizeKTX2 (buffer: ArrayBuffer): vec2 {

@@ -150,2 +156,3 @@ validateKTX2Buffer(new DataView(buffer));

/** Returns the preferred file extension for the given MIME type. */
public static mimeTypeToExtension(mimeType: string): string {

@@ -156,2 +163,3 @@ if (mimeType === 'image/jpeg') return 'jpg';

/** Returns the MIME type for the given file extension. */
public static extensionToMimeType(extension: string): string {

@@ -158,0 +166,0 @@ if (extension === 'jpg') return 'image/jpeg';

@@ -9,14 +9,28 @@ import { GLTF } from '../types/gltf';

public static eq(a: number[], b: number[]): boolean {
if (a.length !== b.length) return false;
const eps = 10e-6;
for (let i = 0; i < a.length; i++) {
if (Math.abs(a[i] - b[i]) > eps) return false;
}
return true;
}
public static denormalize(c: number, componentType: GLTF.AccessorComponentType): number {
// Hardcode enums from accessor.ts to avoid a circular dependency.
switch (componentType) {
case GLTF.AccessorComponentType.FLOAT:
case 5126:
return c;
case GLTF.AccessorComponentType.UNSIGNED_SHORT:
case 5123:
return c / 65535.0;
case GLTF.AccessorComponentType.UNSIGNED_BYTE:
case 5121:
return c / 255.0;
case GLTF.AccessorComponentType.SHORT:
case 5122:
return Math.max(c / 32767.0, -1.0);
case GLTF.AccessorComponentType.BYTE:
case 5120:
return Math.max(c / 127.0, -1.0);
default:
throw new Error('Invalid component type.');
}

@@ -27,15 +41,18 @@

public static normalize(f: number, componentType: GLTF.AccessorComponentType): number {
// Hardcode enums from accessor.ts to avoid a circular dependency.
switch (componentType) {
case GLTF.AccessorComponentType.FLOAT:
case 5126:
return f;
case GLTF.AccessorComponentType.UNSIGNED_SHORT:
case 5123:
return Math.round(f * 65535.0);
case GLTF.AccessorComponentType.UNSIGNED_BYTE:
case 5121:
return Math.round(f * 255.0);
case GLTF.AccessorComponentType.SHORT:
case 5122:
return Math.round(f * 32767.0);
case GLTF.AccessorComponentType.BYTE:
case 5120:
return Math.round(f * 127.0);
default:
throw new Error('Invalid component type.');
}
}
}

@@ -13,3 +13,3 @@ const ALPHABET = '23456789abdegjkmnpqrvwxyzABDEGJKMNPQRVWXYZ';

return rtn;
}
};

@@ -35,2 +35,3 @@ /**

}
return '';
};

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc