diff --git a/Apps/SampleData/EnvironmentMap/kiara_6_afternoon_2k_ibl.ktx b/Apps/SampleData/EnvironmentMap/kiara_6_afternoon_2k_ibl.ktx deleted file mode 100644 index 7a8880d04115..000000000000 Binary files a/Apps/SampleData/EnvironmentMap/kiara_6_afternoon_2k_ibl.ktx and /dev/null differ diff --git a/Apps/SampleData/models/CesiumBalloonKTX2/CesiumBalloonKTX2.glb b/Apps/SampleData/models/CesiumBalloonKTX2/CesiumBalloonKTX2.glb new file mode 100644 index 000000000000..4b7580f05979 Binary files /dev/null and b/Apps/SampleData/models/CesiumBalloonKTX2/CesiumBalloonKTX2.glb differ diff --git a/Apps/Sandcastle/gallery/3D Models.html b/Apps/Sandcastle/gallery/3D Models.html index 3172c1023b00..deed91a406ce 100644 --- a/Apps/Sandcastle/gallery/3D Models.html +++ b/Apps/Sandcastle/gallery/3D Models.html @@ -133,6 +133,20 @@ ); }, }, + { + text: "KTX2 Compressed Balloon", + onselect: function () { + if (!Cesium.FeatureDetection.supportsBasis(viewer.scene)) { + window.alert( + "This browser does not support Basis Universal compressed textures" + ); + } + createModel( + "../../SampleData/models/CesiumBalloonKTX2/CesiumBalloonKTX2.glb", + 1000.0 + ); + }, + }, ]; Sandcastle.addToolbarMenu(options); diff --git a/Apps/Sandcastle/gallery/Image-Based Lighting.html b/Apps/Sandcastle/gallery/Image-Based Lighting.html index f689badbd417..8155119d9201 100644 --- a/Apps/Sandcastle/gallery/Image-Based Lighting.html +++ b/Apps/Sandcastle/gallery/Image-Based Lighting.html @@ -66,58 +66,62 @@ } var environmentMapURL = - "https://cesium.com/public/SandcastleSampleData/kiara_6_afternoon_2k_ibl.ktx"; + "https://cesium.com/public/SandcastleSampleData/kiara_6_afternoon_2k_ibl.ktx2"; var modelURL = "../../SampleData/models/Pawns/Pawns.glb"; - // This environment map was processed using Google's Filament project. To process your own: + // This environment map was processed using Khronos's glTF IBL Sampler. To process your own: + // 1 - Download and build the Khronos glTF IBL Sampler (https://github.com/KhronosGroup/glTF-IBL-Sampler). + // 2 - Run `cli -inputPath /path/to/image.hdr -outCubeMap /path/to/output.ktx2`. Run `cli -h` for all options. + + // To generate the spherical harmonic coefficients below, use Google's Filament project: // 1 - Download the Filament release (https://github.com/google/filament/releases). // 2 - Run `cmgen --type=ktx --deploy=/path/to/output /path/to/image.hdr`. Other formats are also supported. Run `cmgen --help` for all options. - // 3 - Take the generated coefficients and the KTX file and load them in CesiumJS as shown below. + // 3 - Take the generated coefficients and load them in CesiumJS as shown below. var L00 = new Cesium.Cartesian3( - 0.170455150831422, - 0.163151083190219, - 0.196966760289763 + 1.234709620475769, + 1.221461296081543, + 1.273156881332397 ); var L1_1 = new Cesium.Cartesian3( - -0.066550267689383, - -0.022088055746048, - 0.078835009246127 + 1.135921120643616, + 1.171217799186707, + 1.287644743919373 ); var L10 = new Cesium.Cartesian3( - 0.038364097478591, - 0.045714300098753, - 0.063498904606215 + 1.245193719863892, + 1.245591878890991, + 1.282818794250488 ); var L11 = new Cesium.Cartesian3( - -0.01436536331281, - -0.026490613715151, - -0.05018940406602 + -1.106930732727051, + -1.112522482872009, + -1.153198838233948 ); var L2_2 = new Cesium.Cartesian3( - -0.05153278691789, - -0.050777795729986, - -0.056449044453032 + -1.086226940155029, + -1.079731941223145, + -1.101912498474121 ); var L2_1 = new Cesium.Cartesian3( - 0.043454596136534, - 0.046672590104157, - 0.05753010764661 + 1.189834713935852, + 1.185906887054443, + 1.214385271072388 ); var L20 = new Cesium.Cartesian3( - -0.00164046627411, - 0.001286638231156, - 0.007228908989616 + 0.01778045296669, + 0.02013735473156, + 0.025313569232821 ); var L21 = new Cesium.Cartesian3( - -0.042260855700641, - -0.046394335094707, - -0.057562936365585 + -1.086826920509338, + -1.084611177444458, + -1.111204028129578 ); var L22 = new Cesium.Cartesian3( - -0.004953478914091, - -0.000479681664876, - 0.008508150106928 + -0.05241484940052, + -0.048303380608559, + -0.041960217058659 ); var coefficients = [L00, L1_1, L10, L11, L2_2, L2_1, L20, L21, L22]; diff --git a/Apps/Sandcastle/gallery/Materials.html b/Apps/Sandcastle/gallery/Materials.html index ff2071f62b6f..90c6d5ca053c 100644 --- a/Apps/Sandcastle/gallery/Materials.html +++ b/Apps/Sandcastle/gallery/Materials.html @@ -218,17 +218,25 @@ }); } - function applyCompressedTextureMaterial(primitive, scene) { - Sandcastle.declare(applyCompressedTextureMaterial); // For highlighting in Sandcastle. - - var compressedImageUrl; - if (scene.getCompressedTextureFormatSupported("s3tc")) { - compressedImageUrl = "../images/LogoDXT1.ktx"; - } else if (scene.getCompressedTextureFormatSupported("etc1")) { - compressedImageUrl = "../images/LogoETC1.ktx"; - } else if (scene.getCompressedTextureFormatSupported("pvrtc")) { - compressedImageUrl = "../images/LogoPVR.ktx"; - } + function applyETC1SCompressedTextureMaterial(primitive, scene) { + Sandcastle.declare(applyETC1SCompressedTextureMaterial); // For highlighting in Sandcastle. + + var compressedImageUrl = "../images/Cesium_Logo_ETC1S.ktx2"; + + primitive.appearance.material = new Cesium.Material({ + fabric: { + type: "Image", + uniforms: { + image: compressedImageUrl, + }, + }, + }); + } + + function applyUASTCCompressedTextureMaterial(primitive, scene) { + Sandcastle.declare(applyUASTCCompressedTextureMaterial); // For highlighting in Sandcastle. + + var compressedImageUrl = "../images/Cesium_Logo_UASTC.ktx2"; primitive.appearance.material = new Cesium.Material({ fabric: { @@ -357,11 +365,29 @@ }, }, { - text: "Compressed Image", + text: "ETC1S Compressed Image", + onselect: function () { + if (!Cesium.FeatureDetection.supportsBasis(scene)) { + window.alert( + "This browser does not support Basis Universal compressed textures" + ); + } + toggleRectangleVisibility(); + applyETC1SCompressedTextureMaterial(rectangle, scene); + Sandcastle.highlight(applyETC1SCompressedTextureMaterial); + }, + }, + { + text: "UASTC Compressed Image", onselect: function () { + if (!Cesium.FeatureDetection.supportsBasis(scene)) { + window.alert( + "This browser does not support Basis Universal compressed textures" + ); + } toggleRectangleVisibility(); - applyCompressedTextureMaterial(rectangle, scene); - Sandcastle.highlight(applyCompressedTextureMaterial); + applyUASTCCompressedTextureMaterial(rectangle, scene); + Sandcastle.highlight(applyUASTCCompressedTextureMaterial); }, }, ]); diff --git a/Apps/Sandcastle/images/Cesium_Logo_ETC1S.ktx2 b/Apps/Sandcastle/images/Cesium_Logo_ETC1S.ktx2 new file mode 100644 index 000000000000..1c44a7e3925b Binary files /dev/null and b/Apps/Sandcastle/images/Cesium_Logo_ETC1S.ktx2 differ diff --git a/Apps/Sandcastle/images/Cesium_Logo_UASTC.ktx2 b/Apps/Sandcastle/images/Cesium_Logo_UASTC.ktx2 new file mode 100644 index 000000000000..53ccb13613e1 Binary files /dev/null and b/Apps/Sandcastle/images/Cesium_Logo_UASTC.ktx2 differ diff --git a/Apps/Sandcastle/images/LogoDXT1.ktx b/Apps/Sandcastle/images/LogoDXT1.ktx deleted file mode 100644 index 73598d1c8d30..000000000000 Binary files a/Apps/Sandcastle/images/LogoDXT1.ktx and /dev/null differ diff --git a/Apps/Sandcastle/images/LogoETC1.ktx b/Apps/Sandcastle/images/LogoETC1.ktx deleted file mode 100644 index 9d8b88d7f541..000000000000 Binary files a/Apps/Sandcastle/images/LogoETC1.ktx and /dev/null differ diff --git a/Apps/Sandcastle/images/LogoPVR.ktx b/Apps/Sandcastle/images/LogoPVR.ktx deleted file mode 100644 index fd3461c7bbbb..000000000000 Binary files a/Apps/Sandcastle/images/LogoPVR.ktx and /dev/null differ diff --git a/CHANGES.md b/CHANGES.md index a10a23460c42..b260f8299184 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,6 +2,10 @@ ### 1.83 - 2021-07-01 +##### Breaking Changes :mega: + +- Dropped support for KTX1 and Crunch textures; use the [`ktx2ktx2`](https://github.com/KhronosGroup/KTX-Software) converter tool to update existing KTX1 files. + ##### Additions :tada: - Added dynamic terrain exaggeration with `Globe.terrainExaggeration` and `Globe.terrainExaggerationRelativeHeight`. [#9603](https://github.com/CesiumGS/cesium/pull/9603) @@ -10,6 +14,11 @@ - Added checks for supported 3D Tiles extensions. [#9552](https://github.com/CesiumGS/cesium/issues/9552) - Added documentation clarifying that the `outlineWidth` property will be ignored on all major browsers on Windows platforms. [#9600](https://github.com/CesiumGS/cesium/pull/9600) - Added documentation for `KmlTour`, `KmlTourFlyTo`, and `KmlTourWait`. Added documentation and a `kmlTours` getter to `KmlDataSource`. Removed references to `KmlTourSoundCues`. [#8073](https://github.com/CesiumGS/cesium/issues/8073) +- Added support for KTX2 and Basis Universal compressed textures. [#9513](https://github.com/CesiumGS/cesium/issues/9513) + - Added support for glTF models with the [`KHR_texture_basisu`](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_texture_basisu/README.md) extension. + - Added support for 8-bit, 16-bit float, and 32-bit float KTX2 specular environment maps. + - Added support for KTX2 images in `Material`. + - Added new `PixelFormat` and `WebGLConstants` enums from WebGL extensions `WEBGL_compressed_texture_etc`, `WEBGL_compressed_texture_astc`, and `EXT_texture_compression_bptc`. - Added the ability to hide outlines on OSM Buildings and other tilesets and glTF models using the CESIUM_primitive_outline extension. [#8959](https://github.com/CesiumGS/cesium/issues/8959) - Added option to ignore extraneous colorspace information in glTF textures and `ImageBitmap`. [#9624](https://github.com/CesiumGS/cesium/pull/9624) diff --git a/LICENSE.md b/LICENSE.md index f12698a068b7..1041d7c1bd95 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -556,58 +556,47 @@ https://github.com/mourner/quickselect > TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF > THIS SOFTWARE. -### crunch +### basis_universal -https://github.com/BinomialLLC/crunch +https://github.com/BinomialLLC/basis_universal -> crunch/crnlib uses the ZLIB license: -> http://opensource.org/licenses/Zlib -> -> Copyright (c) 2010-2016 Richard Geldreich, Jr. and Binomial LLC -> -> This software is provided 'as-is', without any express or implied -> warranty. In no event will the authors be held liable for any damages -> arising from the use of this software. -> -> Permission is granted to anyone to use this software for any purpose, -> including commercial applications, and to alter it and redistribute it -> freely, subject to the following restrictions: -> -> 1. The origin of this software must not be misrepresented; you must not -> claim that you wrote the original software. If you use this software -> in a product, an acknowledgment in the product documentation would be -> appreciated but is not required. +> Licensed under the Apache License, Version 2.0 (the "License"); you may not +> use this file except in compliance with the License. You may obtain a copy of +> the License at > -> 2. Altered source versions must be plainly marked as such, and must not be -> misrepresented as being the original software. +> > -> 3. This notice may not be removed or altered from any source distribution. +> Unless required by applicable law or agreed to in writing, software +> distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +> WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +> License for the specific language governing permissions and limitations under +> the License. -### crunch_lib.cpp +### KTX-Parse -https://github.com/Apress/html5-game-dev-insights/blob/master/jones_ch21/crunch_webgl/crunch_js/crunch_lib.cpp +https://github.com/donmccurdy/KTX-Parse/ -> Copyright (c) 2013, Evan Parker, Brandon Jones. All rights reserved. +> (The MIT License) > -> Redistribution and use in source and binary forms, with or without modification, -> are permitted provided that the following conditions are met: +> Copyright (c) 2020 Don McCurdy > -> - Redistributions of source code must retain the above copyright notice, this -> list of conditions and the following disclaimer. -> - Redistributions in binary form must reproduce the above copyright notice, -> this list of conditions and the following disclaimer in the documentation -> and/or other materials provided with the distribution. +> Permission is hereby granted, free of charge, to any person obtaining a copy +> of this software and associated documentation files (the "Software"), to deal +> in the Software without restriction, including without limitation the rights +> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +> copies of the Software, and to permit persons to whom the Software is +> furnished to do so, subject to the following conditions: > -> THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -> ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -> WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -> DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -> ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -> (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -> LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -> ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -> (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -> SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \*/ +> The above copyright notice and this permission notice shall be included in +> all copies or substantial portions of the Software. +> +> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +> THE SOFTWARE. ### texture-tester diff --git a/Source/Core/CompressedTextureBuffer.js b/Source/Core/CompressedTextureBuffer.js index 8263e9e0adef..be19eb346779 100644 --- a/Source/Core/CompressedTextureBuffer.js +++ b/Source/Core/CompressedTextureBuffer.js @@ -6,12 +6,20 @@ import defined from "./defined.js"; * @constructor * * @param {PixelFormat} internalFormat The pixel format of the compressed texture. + * @param {PixelDatatype} pixelDatatype The pixel datatype of the compressed texture. * @param {Number} width The width of the texture. * @param {Number} height The height of the texture. * @param {Uint8Array} buffer The compressed texture buffer. */ -function CompressedTextureBuffer(internalFormat, width, height, buffer) { +function CompressedTextureBuffer( + internalFormat, + pixelDatatype, + width, + height, + buffer +) { this._format = internalFormat; + this._datatype = pixelDatatype; this._width = width; this._height = height; this._buffer = buffer; @@ -29,6 +37,17 @@ Object.defineProperties(CompressedTextureBuffer.prototype, { return this._format; }, }, + /** + * The datatype of the compressed texture. + * @type PixelDatatype + * @readonly + * @memberof CompressedTextureBuffer.prototype + */ + pixelDatatype: { + get: function () { + return this._datatype; + }, + }, /** * The width of the texture. * @type Number @@ -77,6 +96,7 @@ CompressedTextureBuffer.clone = function (object) { return new CompressedTextureBuffer( object._format, + object._datatype, object._width, object._height, object._buffer diff --git a/Source/Core/FeatureDetection.js b/Source/Core/FeatureDetection.js index b54ca06c0ae6..6adf52dfd22e 100644 --- a/Source/Core/FeatureDetection.js +++ b/Source/Core/FeatureDetection.js @@ -318,6 +318,16 @@ var FeatureDetection = { typedArrayTypes: typedArrayTypes, }; +/** + * Detects whether the current browser supports Basis Universal textures and the web assembly modules needed to transcode them. + * + * @param {Scene} scene + * @returns {Boolean} true if the browser supports web assembly modules and the scene supports Basis Universal textures, false if not. + */ +FeatureDetection.supportsBasis = function (scene) { + return FeatureDetection.supportsWebAssembly() && scene.context.supportsBasis; +}; + /** * Detects whether the current browser supports the full screen standard. * diff --git a/Source/Core/KTX2Transcoder.js b/Source/Core/KTX2Transcoder.js new file mode 100644 index 000000000000..890f7bfa38d5 --- /dev/null +++ b/Source/Core/KTX2Transcoder.js @@ -0,0 +1,95 @@ +import Check from "./Check.js"; +import CompressedTextureBuffer from "./CompressedTextureBuffer.js"; +import defined from "./defined.js"; +import TaskProcessor from "./TaskProcessor.js"; + +/** + * Transcodes KTX2 textures using web workers. + * + * @private + */ +function KTX2Transcoder() {} + +KTX2Transcoder._transcodeTaskProcessor = new TaskProcessor( + "transcodeKTX2", + Number.POSITIVE_INFINITY // KTX2 transcoding is used in place of Resource.fetchImage, so it can't reject as "just soooo busy right now" +); + +KTX2Transcoder._readyPromise = undefined; + +function makeReadyPromise() { + var readyPromise = KTX2Transcoder._transcodeTaskProcessor + .initWebAssemblyModule({ + modulePath: "ThirdParty/Workers/basis_transcoder.js", + wasmBinaryFile: "ThirdParty/basis_transcoder.wasm", + }) + .then(function () { + return KTX2Transcoder._transcodeTaskProcessor; + }); + KTX2Transcoder._readyPromise = readyPromise; +} + +KTX2Transcoder.transcode = function (ktx2Buffer, supportedTargetFormats) { + //>>includeStart('debug', pragmas.debug); + Check.defined("supportedTargetFormats", supportedTargetFormats); + //>>includeEnd('debug'); + + if (!defined(KTX2Transcoder._readyPromise)) { + makeReadyPromise(); + } + + return KTX2Transcoder._readyPromise + .then(function (taskProcessor) { + var parameters; + if (ktx2Buffer instanceof ArrayBuffer) { + var view = new Uint8Array(ktx2Buffer); + parameters = { + supportedTargetFormats: supportedTargetFormats, + ktx2Buffer: view, + }; + return taskProcessor.scheduleTask(parameters, [ktx2Buffer]); + } + parameters = { + supportedTargetFormats: supportedTargetFormats, + ktx2Buffer: ktx2Buffer, + }; + return taskProcessor.scheduleTask(parameters, [ktx2Buffer.buffer]); + }) + .then(function (result) { + var levelsLength = result.length; + var faceKeys = Object.keys(result[0]); + var faceKeysLength = faceKeys.length; + + var i; + for (i = 0; i < levelsLength; i++) { + var faces = result[i]; + for (var j = 0; j < faceKeysLength; j++) { + var face = faces[faceKeys[j]]; + faces[faceKeys[j]] = new CompressedTextureBuffer( + face.internalFormat, + face.datatype, + face.width, + face.height, + face.levelBuffer + ); + } + } + + // Cleaning up parsed result if it's a single image + if (faceKeysLength === 1) { + for (i = 0; i < levelsLength; ++i) { + result[i] = result[i][faceKeys[0]]; + } + + if (levelsLength === 1) { + result = result[0]; + } + } + return result; + }) + .otherwise(function (error) { + throw error; + }); +}; + +export default KTX2Transcoder; diff --git a/Source/Core/PixelFormat.js b/Source/Core/PixelFormat.js index 781fffa2c2ac..7efa64665202 100644 --- a/Source/Core/PixelFormat.js +++ b/Source/Core/PixelFormat.js @@ -127,6 +127,14 @@ var PixelFormat = { */ RGBA_PVRTC_2BPPV1: WebGLConstants.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG, + /** + * A pixel format containing red, green, blue, and alpha channels that is ASTC compressed. + * + * @type {Number} + * @constant + */ + RGBA_ASTC: WebGLConstants.COMPRESSED_RGBA_ASTC_4x4_WEBGL, + /** * A pixel format containing red, green, and blue channels that is ETC1 compressed. * @@ -134,6 +142,30 @@ var PixelFormat = { * @constant */ RGB_ETC1: WebGLConstants.COMPRESSED_RGB_ETC1_WEBGL, + + /** + * A pixel format containing red, green, and blue channels that is ETC2 compressed. + * + * @type {Number} + * @constant + */ + RGB8_ETC2: WebGLConstants.COMPRESSED_RGB8_ETC2, + + /** + * A pixel format containing red, green, blue, and alpha channels that is ETC2 compressed. + * + * @type {Number} + * @constant + */ + RGBA8_ETC2_EAC: WebGLConstants.COMPRESSED_RGBA8_ETC2_EAC, + + /** + * A pixel format containing red, green, blue, and alpha channels that is BC7 compressed. + * + * @type {Number} + * @constant + */ + RGBA_BC7: WebGLConstants.COMPRESSED_RGBA_BPTC_UNORM, }; /** @@ -175,7 +207,11 @@ PixelFormat.validate = function (pixelFormat) { pixelFormat === PixelFormat.RGB_PVRTC_2BPPV1 || pixelFormat === PixelFormat.RGBA_PVRTC_4BPPV1 || pixelFormat === PixelFormat.RGBA_PVRTC_2BPPV1 || - pixelFormat === PixelFormat.RGB_ETC1 + pixelFormat === PixelFormat.RGBA_ASTC || + pixelFormat === PixelFormat.RGB_ETC1 || + pixelFormat === PixelFormat.RGB8_ETC2 || + pixelFormat === PixelFormat.RGBA8_ETC2_EAC || + pixelFormat === PixelFormat.RGBA_BC7 ); }; @@ -215,7 +251,11 @@ PixelFormat.isCompressedFormat = function (pixelFormat) { pixelFormat === PixelFormat.RGB_PVRTC_2BPPV1 || pixelFormat === PixelFormat.RGBA_PVRTC_4BPPV1 || pixelFormat === PixelFormat.RGBA_PVRTC_2BPPV1 || - pixelFormat === PixelFormat.RGB_ETC1 + pixelFormat === PixelFormat.RGBA_ASTC || + pixelFormat === PixelFormat.RGB_ETC1 || + pixelFormat === PixelFormat.RGB8_ETC2 || + pixelFormat === PixelFormat.RGBA8_ETC2_EAC || + pixelFormat === PixelFormat.RGBA_BC7 ); }; @@ -243,6 +283,13 @@ PixelFormat.isPVRTCFormat = function (pixelFormat) { ); }; +/** + * @private + */ +PixelFormat.isASTCFormat = function (pixelFormat) { + return pixelFormat === PixelFormat.RGBA_ASTC; +}; + /** * @private */ @@ -250,6 +297,23 @@ PixelFormat.isETC1Format = function (pixelFormat) { return pixelFormat === PixelFormat.RGB_ETC1; }; +/** + * @private + */ +PixelFormat.isETC2Format = function (pixelFormat) { + return ( + pixelFormat === PixelFormat.RGB8_ETC2 || + pixelFormat === PixelFormat.RGBA8_ETC2_EAC + ); +}; + +/** + * @private + */ +PixelFormat.isBC7Format = function (pixelFormat) { + return pixelFormat === PixelFormat.RGBA_BC7; +}; + /** * @private */ @@ -262,10 +326,13 @@ PixelFormat.compressedTextureSizeInBytes = function ( case PixelFormat.RGB_DXT1: case PixelFormat.RGBA_DXT1: case PixelFormat.RGB_ETC1: + case PixelFormat.RGB8_ETC2: return Math.floor((width + 3) / 4) * Math.floor((height + 3) / 4) * 8; case PixelFormat.RGBA_DXT3: case PixelFormat.RGBA_DXT5: + case PixelFormat.RGBA_ASTC: + case PixelFormat.RGBA8_ETC2_EAC: return Math.floor((width + 3) / 4) * Math.floor((height + 3) / 4) * 16; case PixelFormat.RGB_PVRTC_4BPPV1: @@ -278,6 +345,9 @@ PixelFormat.compressedTextureSizeInBytes = function ( (Math.max(width, 16) * Math.max(height, 8) * 2 + 7) / 8 ); + case PixelFormat.RGBA_BC7: + return Math.ceil(width / 4) * Math.ceil(height / 4) * 16; + default: return 0; } diff --git a/Source/Core/VulkanConstants.js b/Source/Core/VulkanConstants.js new file mode 100644 index 000000000000..14f45708ca4d --- /dev/null +++ b/Source/Core/VulkanConstants.js @@ -0,0 +1,286 @@ +/** + * Enum containing Vulkan Constant values by name. + * + * These match the constants from the {@link https://www.khronos.org/registry/vulkan/specs/1.2-extensions/html/vkspec.html#formats-definition|Vulkan 1.2 specification}. + * + * @enum {Number} + * @private + */ +var VulkanConstants = { + VK_FORMAT_UNDEFINED: 0, + VK_FORMAT_R4G4_UNORM_PACK8: 1, + VK_FORMAT_R4G4B4A4_UNORM_PACK16: 2, + VK_FORMAT_B4G4R4A4_UNORM_PACK16: 3, + VK_FORMAT_R5G6B5_UNORM_PACK16: 4, + VK_FORMAT_B5G6R5_UNORM_PACK16: 5, + VK_FORMAT_R5G5B5A1_UNORM_PACK16: 6, + VK_FORMAT_B5G5R5A1_UNORM_PACK16: 7, + VK_FORMAT_A1R5G5B5_UNORM_PACK16: 8, + VK_FORMAT_R8_UNORM: 9, + VK_FORMAT_R8_SNORM: 10, + VK_FORMAT_R8_USCALED: 11, + VK_FORMAT_R8_SSCALED: 12, + VK_FORMAT_R8_UINT: 13, + VK_FORMAT_R8_SINT: 14, + VK_FORMAT_R8_SRGB: 15, + VK_FORMAT_R8G8_UNORM: 16, + VK_FORMAT_R8G8_SNORM: 17, + VK_FORMAT_R8G8_USCALED: 18, + VK_FORMAT_R8G8_SSCALED: 19, + VK_FORMAT_R8G8_UINT: 20, + VK_FORMAT_R8G8_SINT: 21, + VK_FORMAT_R8G8_SRGB: 22, + VK_FORMAT_R8G8B8_UNORM: 23, + VK_FORMAT_R8G8B8_SNORM: 24, + VK_FORMAT_R8G8B8_USCALED: 25, + VK_FORMAT_R8G8B8_SSCALED: 26, + VK_FORMAT_R8G8B8_UINT: 27, + VK_FORMAT_R8G8B8_SINT: 28, + VK_FORMAT_R8G8B8_SRGB: 29, + VK_FORMAT_B8G8R8_UNORM: 30, + VK_FORMAT_B8G8R8_SNORM: 31, + VK_FORMAT_B8G8R8_USCALED: 32, + VK_FORMAT_B8G8R8_SSCALED: 33, + VK_FORMAT_B8G8R8_UINT: 34, + VK_FORMAT_B8G8R8_SINT: 35, + VK_FORMAT_B8G8R8_SRGB: 36, + VK_FORMAT_R8G8B8A8_UNORM: 37, + VK_FORMAT_R8G8B8A8_SNORM: 38, + VK_FORMAT_R8G8B8A8_USCALED: 39, + VK_FORMAT_R8G8B8A8_SSCALED: 40, + VK_FORMAT_R8G8B8A8_UINT: 41, + VK_FORMAT_R8G8B8A8_SINT: 42, + VK_FORMAT_R8G8B8A8_SRGB: 43, + VK_FORMAT_B8G8R8A8_UNORM: 44, + VK_FORMAT_B8G8R8A8_SNORM: 45, + VK_FORMAT_B8G8R8A8_USCALED: 46, + VK_FORMAT_B8G8R8A8_SSCALED: 47, + VK_FORMAT_B8G8R8A8_UINT: 48, + VK_FORMAT_B8G8R8A8_SINT: 49, + VK_FORMAT_B8G8R8A8_SRGB: 50, + VK_FORMAT_A8B8G8R8_UNORM_PACK32: 51, + VK_FORMAT_A8B8G8R8_SNORM_PACK32: 52, + VK_FORMAT_A8B8G8R8_USCALED_PACK32: 53, + VK_FORMAT_A8B8G8R8_SSCALED_PACK32: 54, + VK_FORMAT_A8B8G8R8_UINT_PACK32: 55, + VK_FORMAT_A8B8G8R8_SINT_PACK32: 56, + VK_FORMAT_A8B8G8R8_SRGB_PACK32: 57, + VK_FORMAT_A2R10G10B10_UNORM_PACK32: 58, + VK_FORMAT_A2R10G10B10_SNORM_PACK32: 59, + VK_FORMAT_A2R10G10B10_USCALED_PACK32: 60, + VK_FORMAT_A2R10G10B10_SSCALED_PACK32: 61, + VK_FORMAT_A2R10G10B10_UINT_PACK32: 62, + VK_FORMAT_A2R10G10B10_SINT_PACK32: 63, + VK_FORMAT_A2B10G10R10_UNORM_PACK32: 64, + VK_FORMAT_A2B10G10R10_SNORM_PACK32: 65, + VK_FORMAT_A2B10G10R10_USCALED_PACK32: 66, + VK_FORMAT_A2B10G10R10_SSCALED_PACK32: 67, + VK_FORMAT_A2B10G10R10_UINT_PACK32: 68, + VK_FORMAT_A2B10G10R10_SINT_PACK32: 69, + VK_FORMAT_R16_UNORM: 70, + VK_FORMAT_R16_SNORM: 71, + VK_FORMAT_R16_USCALED: 72, + VK_FORMAT_R16_SSCALED: 73, + VK_FORMAT_R16_UINT: 74, + VK_FORMAT_R16_SINT: 75, + VK_FORMAT_R16_SFLOAT: 76, + VK_FORMAT_R16G16_UNORM: 77, + VK_FORMAT_R16G16_SNORM: 78, + VK_FORMAT_R16G16_USCALED: 79, + VK_FORMAT_R16G16_SSCALED: 80, + VK_FORMAT_R16G16_UINT: 81, + VK_FORMAT_R16G16_SINT: 82, + VK_FORMAT_R16G16_SFLOAT: 83, + VK_FORMAT_R16G16B16_UNORM: 84, + VK_FORMAT_R16G16B16_SNORM: 85, + VK_FORMAT_R16G16B16_USCALED: 86, + VK_FORMAT_R16G16B16_SSCALED: 87, + VK_FORMAT_R16G16B16_UINT: 88, + VK_FORMAT_R16G16B16_SINT: 89, + VK_FORMAT_R16G16B16_SFLOAT: 90, + VK_FORMAT_R16G16B16A16_UNORM: 91, + VK_FORMAT_R16G16B16A16_SNORM: 92, + VK_FORMAT_R16G16B16A16_USCALED: 93, + VK_FORMAT_R16G16B16A16_SSCALED: 94, + VK_FORMAT_R16G16B16A16_UINT: 95, + VK_FORMAT_R16G16B16A16_SINT: 96, + VK_FORMAT_R16G16B16A16_SFLOAT: 97, + VK_FORMAT_R32_UINT: 98, + VK_FORMAT_R32_SINT: 99, + VK_FORMAT_R32_SFLOAT: 100, + VK_FORMAT_R32G32_UINT: 101, + VK_FORMAT_R32G32_SINT: 102, + VK_FORMAT_R32G32_SFLOAT: 103, + VK_FORMAT_R32G32B32_UINT: 104, + VK_FORMAT_R32G32B32_SINT: 105, + VK_FORMAT_R32G32B32_SFLOAT: 106, + VK_FORMAT_R32G32B32A32_UINT: 107, + VK_FORMAT_R32G32B32A32_SINT: 108, + VK_FORMAT_R32G32B32A32_SFLOAT: 109, + VK_FORMAT_R64_UINT: 110, + VK_FORMAT_R64_SINT: 111, + VK_FORMAT_R64_SFLOAT: 112, + VK_FORMAT_R64G64_UINT: 113, + VK_FORMAT_R64G64_SINT: 114, + VK_FORMAT_R64G64_SFLOAT: 115, + VK_FORMAT_R64G64B64_UINT: 116, + VK_FORMAT_R64G64B64_SINT: 117, + VK_FORMAT_R64G64B64_SFLOAT: 118, + VK_FORMAT_R64G64B64A64_UINT: 119, + VK_FORMAT_R64G64B64A64_SINT: 120, + VK_FORMAT_R64G64B64A64_SFLOAT: 121, + VK_FORMAT_B10G11R11_UFLOAT_PACK32: 122, + VK_FORMAT_E5B9G9R9_UFLOAT_PACK32: 123, + VK_FORMAT_D16_UNORM: 124, + VK_FORMAT_X8_D24_UNORM_PACK32: 125, + VK_FORMAT_D32_SFLOAT: 126, + VK_FORMAT_S8_UINT: 127, + VK_FORMAT_D16_UNORM_S8_UINT: 128, + VK_FORMAT_D24_UNORM_S8_UINT: 129, + VK_FORMAT_D32_SFLOAT_S8_UINT: 130, + VK_FORMAT_BC1_RGB_UNORM_BLOCK: 131, + VK_FORMAT_BC1_RGB_SRGB_BLOCK: 132, + VK_FORMAT_BC1_RGBA_UNORM_BLOCK: 133, + VK_FORMAT_BC1_RGBA_SRGB_BLOCK: 134, + VK_FORMAT_BC2_UNORM_BLOCK: 135, + VK_FORMAT_BC2_SRGB_BLOCK: 136, + VK_FORMAT_BC3_UNORM_BLOCK: 137, + VK_FORMAT_BC3_SRGB_BLOCK: 138, + VK_FORMAT_BC4_UNORM_BLOCK: 139, + VK_FORMAT_BC4_SNORM_BLOCK: 140, + VK_FORMAT_BC5_UNORM_BLOCK: 141, + VK_FORMAT_BC5_SNORM_BLOCK: 142, + VK_FORMAT_BC6H_UFLOAT_BLOCK: 143, + VK_FORMAT_BC6H_SFLOAT_BLOCK: 144, + VK_FORMAT_BC7_UNORM_BLOCK: 145, + VK_FORMAT_BC7_SRGB_BLOCK: 146, + VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK: 147, + VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK: 148, + VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK: 149, + VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK: 150, + VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK: 151, + VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK: 152, + VK_FORMAT_EAC_R11_UNORM_BLOCK: 153, + VK_FORMAT_EAC_R11_SNORM_BLOCK: 154, + VK_FORMAT_EAC_R11G11_UNORM_BLOCK: 155, + VK_FORMAT_EAC_R11G11_SNORM_BLOCK: 156, + VK_FORMAT_ASTC_4x4_UNORM_BLOCK: 157, + VK_FORMAT_ASTC_4x4_SRGB_BLOCK: 158, + VK_FORMAT_ASTC_5x4_UNORM_BLOCK: 159, + VK_FORMAT_ASTC_5x4_SRGB_BLOCK: 160, + VK_FORMAT_ASTC_5x5_UNORM_BLOCK: 161, + VK_FORMAT_ASTC_5x5_SRGB_BLOCK: 162, + VK_FORMAT_ASTC_6x5_UNORM_BLOCK: 163, + VK_FORMAT_ASTC_6x5_SRGB_BLOCK: 164, + VK_FORMAT_ASTC_6x6_UNORM_BLOCK: 165, + VK_FORMAT_ASTC_6x6_SRGB_BLOCK: 166, + VK_FORMAT_ASTC_8x5_UNORM_BLOCK: 167, + VK_FORMAT_ASTC_8x5_SRGB_BLOCK: 168, + VK_FORMAT_ASTC_8x6_UNORM_BLOCK: 169, + VK_FORMAT_ASTC_8x6_SRGB_BLOCK: 170, + VK_FORMAT_ASTC_8x8_UNORM_BLOCK: 171, + VK_FORMAT_ASTC_8x8_SRGB_BLOCK: 172, + VK_FORMAT_ASTC_10x5_UNORM_BLOCK: 173, + VK_FORMAT_ASTC_10x5_SRGB_BLOCK: 174, + VK_FORMAT_ASTC_10x6_UNORM_BLOCK: 175, + VK_FORMAT_ASTC_10x6_SRGB_BLOCK: 176, + VK_FORMAT_ASTC_10x8_UNORM_BLOCK: 177, + VK_FORMAT_ASTC_10x8_SRGB_BLOCK: 178, + VK_FORMAT_ASTC_10x10_UNORM_BLOCK: 179, + VK_FORMAT_ASTC_10x10_SRGB_BLOCK: 180, + VK_FORMAT_ASTC_12x10_UNORM_BLOCK: 181, + VK_FORMAT_ASTC_12x10_SRGB_BLOCK: 182, + VK_FORMAT_ASTC_12x12_UNORM_BLOCK: 183, + VK_FORMAT_ASTC_12x12_SRGB_BLOCK: 184, + VK_FORMAT_G8B8G8R8_422_UNORM: 1000156000, + VK_FORMAT_B8G8R8G8_422_UNORM: 1000156001, + VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM: 1000156002, + VK_FORMAT_G8_B8R8_2PLANE_420_UNORM: 1000156003, + VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM: 1000156004, + VK_FORMAT_G8_B8R8_2PLANE_422_UNORM: 1000156005, + VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM: 1000156006, + VK_FORMAT_R10X6_UNORM_PACK16: 1000156007, + VK_FORMAT_R10X6G10X6_UNORM_2PACK16: 1000156008, + VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16: 1000156009, + VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16: 1000156010, + VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16: 1000156011, + VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16: 1000156012, + VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16: 1000156013, + VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16: 1000156014, + VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16: 1000156015, + VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16: 1000156016, + VK_FORMAT_R12X4_UNORM_PACK16: 1000156017, + VK_FORMAT_R12X4G12X4_UNORM_2PACK16: 1000156018, + VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16: 1000156019, + VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16: 1000156020, + VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16: 1000156021, + VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16: 1000156022, + VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16: 1000156023, + VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16: 1000156024, + VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16: 1000156025, + VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16: 1000156026, + VK_FORMAT_G16B16G16R16_422_UNORM: 1000156027, + VK_FORMAT_B16G16R16G16_422_UNORM: 1000156028, + VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM: 1000156029, + VK_FORMAT_G16_B16R16_2PLANE_420_UNORM: 1000156030, + VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM: 1000156031, + VK_FORMAT_G16_B16R16_2PLANE_422_UNORM: 1000156032, + VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM: 1000156033, + VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG: 1000054000, + VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG: 1000054001, + VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG: 1000054002, + VK_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG: 1000054003, + VK_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG: 1000054004, + VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG: 1000054005, + VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG: 1000054006, + VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG: 1000054007, + VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK_EXT: 1000066000, + VK_FORMAT_ASTC_5x4_SFLOAT_BLOCK_EXT: 1000066001, + VK_FORMAT_ASTC_5x5_SFLOAT_BLOCK_EXT: 1000066002, + VK_FORMAT_ASTC_6x5_SFLOAT_BLOCK_EXT: 1000066003, + VK_FORMAT_ASTC_6x6_SFLOAT_BLOCK_EXT: 1000066004, + VK_FORMAT_ASTC_8x5_SFLOAT_BLOCK_EXT: 1000066005, + VK_FORMAT_ASTC_8x6_SFLOAT_BLOCK_EXT: 1000066006, + VK_FORMAT_ASTC_8x8_SFLOAT_BLOCK_EXT: 1000066007, + VK_FORMAT_ASTC_10x5_SFLOAT_BLOCK_EXT: 1000066008, + VK_FORMAT_ASTC_10x6_SFLOAT_BLOCK_EXT: 1000066009, + VK_FORMAT_ASTC_10x8_SFLOAT_BLOCK_EXT: 1000066010, + VK_FORMAT_ASTC_10x10_SFLOAT_BLOCK_EXT: 1000066011, + VK_FORMAT_ASTC_12x10_SFLOAT_BLOCK_EXT: 1000066012, + VK_FORMAT_ASTC_12x12_SFLOAT_BLOCK_EXT: 1000066013, + VK_FORMAT_G8B8G8R8_422_UNORM_KHR: 1000156000, + VK_FORMAT_B8G8R8G8_422_UNORM_KHR: 1000156001, + VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM_KHR: 1000156002, + VK_FORMAT_G8_B8R8_2PLANE_420_UNORM_KHR: 1000156003, + VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM_KHR: 1000156004, + VK_FORMAT_G8_B8R8_2PLANE_422_UNORM_KHR: 1000156005, + VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM_KHR: 1000156006, + VK_FORMAT_R10X6_UNORM_PACK16_KHR: 1000156007, + VK_FORMAT_R10X6G10X6_UNORM_2PACK16_KHR: 1000156008, + VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16_KHR: 1000156009, + VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16_KHR: 1000156010, + VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16_KHR: 1000156011, + VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16_KHR: 1000156012, + VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16_KHR: 1000156013, + VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16_KHR: 1000156014, + VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16_KHR: 1000156015, + VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16_KHR: 1000156016, + VK_FORMAT_R12X4_UNORM_PACK16_KHR: 1000156017, + VK_FORMAT_R12X4G12X4_UNORM_2PACK16_KHR: 1000156018, + VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16_KHR: 1000156019, + VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16_KHR: 1000156020, + VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16_KHR: 1000156021, + VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16_KHR: 1000156022, + VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16_KHR: 1000156023, + VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16_KHR: 1000156024, + VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16_KHR: 1000156025, + VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16_KHR: 1000156026, + VK_FORMAT_G16B16G16R16_422_UNORM_KHR: 1000156027, + VK_FORMAT_B16G16R16G16_422_UNORM_KHR: 1000156028, + VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM_KHR: 1000156029, + VK_FORMAT_G16_B16R16_2PLANE_420_UNORM_KHR: 1000156030, + VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM_KHR: 1000156031, + VK_FORMAT_G16_B16R16_2PLANE_422_UNORM_KHR: 1000156032, + VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM_KHR: 1000156033, +}; +export default Object.freeze(VulkanConstants); diff --git a/Source/Core/WebGLConstants.js b/Source/Core/WebGLConstants.js index 32b63443cd2a..b3d2706e924f 100644 --- a/Source/Core/WebGLConstants.js +++ b/Source/Core/WebGLConstants.js @@ -320,9 +320,15 @@ var WebGLConstants = { COMPRESSED_RGBA_PVRTC_4BPPV1_IMG: 0x8c02, COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: 0x8c03, + // WEBGL_compressed_texture_astc + COMPRESSED_RGBA_ASTC_4x4_WEBGL: 0x93b0, + // WEBGL_compressed_texture_etc1 COMPRESSED_RGB_ETC1_WEBGL: 0x8d64, + // EXT_texture_compression_bptc + COMPRESSED_RGBA_BPTC_UNORM: 0x8e8c, + // EXT_color_buffer_half_float HALF_FLOAT_OES: 0x8d61, diff --git a/Source/Core/loadCRN.js b/Source/Core/loadCRN.js deleted file mode 100644 index 0bd835c33030..000000000000 --- a/Source/Core/loadCRN.js +++ /dev/null @@ -1,93 +0,0 @@ -import when from "../ThirdParty/when.js"; -import CompressedTextureBuffer from "./CompressedTextureBuffer.js"; -import defined from "./defined.js"; -import DeveloperError from "./DeveloperError.js"; -import Resource from "./Resource.js"; -import TaskProcessor from "./TaskProcessor.js"; -import deprecationWarning from "./deprecationWarning.js"; - -var transcodeTaskProcessor = new TaskProcessor("transcodeCRNToDXT"); - -/** - * Asynchronously loads and parses the given URL to a CRN file or parses the raw binary data of a CRN file. - * Returns a promise that will resolve to an object containing the image buffer, width, height and format once loaded, - * or reject if the URL failed to load or failed to parse the data. The data is loaded - * using XMLHttpRequest, which means that in order to make requests to another origin, - * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. - * - * @function loadCRN - * - * @param {Resource|String|ArrayBuffer} resourceOrUrlOrBuffer The URL of the binary data or an ArrayBuffer. - * @returns {Promise.|undefined} A promise that will resolve to the requested data when loaded. Returns undefined if request.throttle is true and the request does not have high enough priority. - * - * @exception {RuntimeError} Unsupported compressed format. - * - * @example - * // load a single URL asynchronously - * Cesium.loadCRN('some/url').then(function(textureData) { - * var width = textureData.width; - * var height = textureData.height; - * var format = textureData.internalFormat; - * var arrayBufferView = textureData.bufferView; - * // use the data to create a texture - * }).otherwise(function(error) { - * // an error occurred - * }); - * - * @see {@link https://github.com/BinomialLLC/crunch|crunch DXTc texture compression and transcoding library} - * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} - * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} - * @deprecated This function has been deprecated and will be removed in CesiumJS 1.83. - */ -function loadCRN(resourceOrUrlOrBuffer) { - deprecationWarning( - "loadCRN", - "loadCRN is deprecated and will be removed in CesiumJS 1.83." - ); - //>>includeStart('debug', pragmas.debug); - if (!defined(resourceOrUrlOrBuffer)) { - throw new DeveloperError("resourceOrUrlOrBuffer is required."); - } - //>>includeEnd('debug'); - - var loadPromise; - if ( - resourceOrUrlOrBuffer instanceof ArrayBuffer || - ArrayBuffer.isView(resourceOrUrlOrBuffer) - ) { - loadPromise = when.resolve(resourceOrUrlOrBuffer); - } else { - var resource = Resource.createIfNeeded(resourceOrUrlOrBuffer); - loadPromise = resource.fetchArrayBuffer(); - } - - if (!defined(loadPromise)) { - return undefined; - } - - return loadPromise - .then(function (data) { - if (!defined(data)) { - return; - } - var transferrableObjects = []; - if (data instanceof ArrayBuffer) { - transferrableObjects.push(data); - } else if ( - data.byteOffset === 0 && - data.byteLength === data.buffer.byteLength - ) { - transferrableObjects.push(data.buffer); - } else { - // data is a view of an array buffer. need to copy so it is transferrable to web worker - data = data.slice(0, data.length); - transferrableObjects.push(data.buffer); - } - - return transcodeTaskProcessor.scheduleTask(data, transferrableObjects); - }) - .then(function (compressedTextureBuffer) { - return CompressedTextureBuffer.clone(compressedTextureBuffer); - }); -} -export default loadCRN; diff --git a/Source/Core/loadKTX.js b/Source/Core/loadKTX.js deleted file mode 100644 index e3905f01573f..000000000000 --- a/Source/Core/loadKTX.js +++ /dev/null @@ -1,280 +0,0 @@ -import when from "../ThirdParty/when.js"; -import Check from "./Check.js"; -import CompressedTextureBuffer from "./CompressedTextureBuffer.js"; -import defined from "./defined.js"; -import PixelFormat from "./PixelFormat.js"; -import Resource from "./Resource.js"; -import RuntimeError from "./RuntimeError.js"; -import WebGLConstants from "./WebGLConstants.js"; -import deprecationWarning from "./deprecationWarning.js"; - -/** - * Asynchronously loads and parses the given URL to a KTX file or parses the raw binary data of a KTX file. - * Returns a promise that will resolve to an object containing the image buffer, width, height and format once loaded, - * or reject if the URL failed to load or failed to parse the data. The data is loaded - * using XMLHttpRequest, which means that in order to make requests to another origin, - * the server must have Cross-Origin Resource Sharing (CORS) headers enabled. - *

- * The following are part of the KTX format specification but are not supported: - *

- *

- * - * @function loadKTX - * - * @param {Resource|String|ArrayBuffer} resourceOrUrlOrBuffer The URL of the binary data or an ArrayBuffer. - * @returns {Promise.|undefined} A promise that will resolve to the requested data when loaded. Returns undefined if request.throttle is true and the request does not have high enough priority. - * - * @exception {RuntimeError} Invalid KTX file. - * @exception {RuntimeError} File is the wrong endianness. - * @exception {RuntimeError} glInternalFormat is not a valid format. - * @exception {RuntimeError} glType must be zero when the texture is compressed. - * @exception {RuntimeError} The type size for compressed textures must be 1. - * @exception {RuntimeError} glFormat must be zero when the texture is compressed. - * @exception {RuntimeError} Generating mipmaps for a compressed texture is unsupported. - * @exception {RuntimeError} The base internal format must be the same as the format for uncompressed textures. - * @exception {RuntimeError} 3D textures are not supported. - * @exception {RuntimeError} Texture arrays are not supported. - * @exception {RuntimeError} Cubemaps are not supported. - * - * @example - * // load a single URL asynchronously - * Cesium.loadKTX('some/url').then(function(ktxData) { - * var width = ktxData.width; - * var height = ktxData.height; - * var format = ktxData.internalFormat; - * var arrayBufferView = ktxData.bufferView; - * // use the data to create a texture - * }).otherwise(function(error) { - * // an error occurred - * }); - * - * @see {@link https://www.khronos.org/opengles/sdk/tools/KTX/file_format_spec/|KTX file format} - * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} - * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} - * @deprecated This function has been deprecated and will be removed in CesiumJS 1.83. - */ -function loadKTX(resourceOrUrlOrBuffer) { - deprecationWarning( - "loadKTX", - "loadKTX is deprecated and will be removed in CesiumJS 1.83." - ); - //>>includeStart('debug', pragmas.debug); - Check.defined("resourceOrUrlOrBuffer", resourceOrUrlOrBuffer); - //>>includeEnd('debug'); - - var loadPromise; - if ( - resourceOrUrlOrBuffer instanceof ArrayBuffer || - ArrayBuffer.isView(resourceOrUrlOrBuffer) - ) { - loadPromise = when.resolve(resourceOrUrlOrBuffer); - } else { - var resource = Resource.createIfNeeded(resourceOrUrlOrBuffer); - loadPromise = resource.fetchArrayBuffer(); - } - - if (!defined(loadPromise)) { - return undefined; - } - - return loadPromise.then(function (data) { - if (defined(data)) { - return parseKTX(data); - } - }); -} - -var fileIdentifier = [ - 0xab, - 0x4b, - 0x54, - 0x58, - 0x20, - 0x31, - 0x31, - 0xbb, - 0x0d, - 0x0a, - 0x1a, - 0x0a, -]; -var endiannessTest = 0x04030201; -var faceOrder = [ - "positiveX", - "negativeX", - "positiveY", - "negativeY", - "positiveZ", - "negativeZ", -]; - -var sizeOfUint32 = 4; - -function parseKTX(data) { - var byteBuffer = new Uint8Array(data); - - var isKTX = true; - var i; - for (i = 0; i < fileIdentifier.length; ++i) { - if (fileIdentifier[i] !== byteBuffer[i]) { - isKTX = false; - break; - } - } - - if (!isKTX) { - throw new RuntimeError("Invalid KTX file."); - } - - var view; - var byteOffset; - - if (defined(data.buffer)) { - view = new DataView(data.buffer); - byteOffset = data.byteOffset; - } else { - view = new DataView(data); - byteOffset = 0; - } - - byteOffset += 12; // skip identifier - - var endianness = view.getUint32(byteOffset, true); - byteOffset += sizeOfUint32; - if (endianness !== endiannessTest) { - throw new RuntimeError("File is the wrong endianness."); - } - - var glType = view.getUint32(byteOffset, true); - byteOffset += sizeOfUint32; - var glTypeSize = view.getUint32(byteOffset, true); - byteOffset += sizeOfUint32; - var glFormat = view.getUint32(byteOffset, true); - byteOffset += sizeOfUint32; - var glInternalFormat = view.getUint32(byteOffset, true); - byteOffset += sizeOfUint32; - var glBaseInternalFormat = view.getUint32(byteOffset, true); - byteOffset += sizeOfUint32; - var pixelWidth = view.getUint32(byteOffset, true); - byteOffset += sizeOfUint32; - var pixelHeight = view.getUint32(byteOffset, true); - byteOffset += sizeOfUint32; - var pixelDepth = view.getUint32(byteOffset, true); - byteOffset += sizeOfUint32; - var numberOfArrayElements = view.getUint32(byteOffset, true); - byteOffset += sizeOfUint32; - var numberOfFaces = view.getUint32(byteOffset, true); - byteOffset += sizeOfUint32; - var numberOfMipmapLevels = view.getUint32(byteOffset, true); - byteOffset += sizeOfUint32; - var bytesOfKeyValueByteSize = view.getUint32(byteOffset, true); - byteOffset += sizeOfUint32; - - // skip metadata - byteOffset += bytesOfKeyValueByteSize; - - var imageSize = view.getUint32(byteOffset, true); - byteOffset += sizeOfUint32; - - var texture; - if (defined(data.buffer)) { - texture = new Uint8Array(data.buffer, byteOffset, imageSize); - } else { - texture = new Uint8Array(data, byteOffset, imageSize); - } - - // Some tools use a sized internal format. - // See table 2: https://www.opengl.org/sdk/docs/man/html/glTexImage2D.xhtml - if (glInternalFormat === WebGLConstants.RGB8) { - glInternalFormat = PixelFormat.RGB; - } else if (glInternalFormat === WebGLConstants.RGBA8) { - glInternalFormat = PixelFormat.RGBA; - } - - if (!PixelFormat.validate(glInternalFormat)) { - throw new RuntimeError("glInternalFormat is not a valid format."); - } - - if (PixelFormat.isCompressedFormat(glInternalFormat)) { - if (glType !== 0) { - throw new RuntimeError( - "glType must be zero when the texture is compressed." - ); - } - if (glTypeSize !== 1) { - throw new RuntimeError( - "The type size for compressed textures must be 1." - ); - } - if (glFormat !== 0) { - throw new RuntimeError( - "glFormat must be zero when the texture is compressed." - ); - } - } else if (glType !== WebGLConstants.UNSIGNED_BYTE) { - throw new RuntimeError("Only unsigned byte buffers are supported."); - } else if (glBaseInternalFormat !== glFormat) { - throw new RuntimeError( - "The base internal format must be the same as the format for uncompressed textures." - ); - } - - if (pixelDepth !== 0) { - throw new RuntimeError("3D textures are unsupported."); - } - - if (numberOfArrayElements !== 0) { - throw new RuntimeError("Texture arrays are unsupported."); - } - - var offset = texture.byteOffset; - var mipmaps = new Array(numberOfMipmapLevels); - for (i = 0; i < numberOfMipmapLevels; ++i) { - var level = (mipmaps[i] = {}); - for (var j = 0; j < numberOfFaces; ++j) { - var width = pixelWidth >> i; - var height = pixelHeight >> i; - var levelSize = PixelFormat.isCompressedFormat(glInternalFormat) - ? PixelFormat.compressedTextureSizeInBytes( - glInternalFormat, - width, - height - ) - : PixelFormat.textureSizeInBytes( - glInternalFormat, - glType, - width, - height - ); - var levelBuffer = new Uint8Array(texture.buffer, offset, levelSize); - level[faceOrder[j]] = new CompressedTextureBuffer( - glInternalFormat, - width, - height, - levelBuffer - ); - offset += levelSize; - } - offset += 3 - ((offset + 3) % 4) + 4; - } - - var result = mipmaps; - if (numberOfFaces === 1) { - for (i = 0; i < numberOfMipmapLevels; ++i) { - result[i] = result[i][faceOrder[0]]; - } - } - if (numberOfMipmapLevels === 1) { - result = result[0]; - } - - return result; -} -export default loadKTX; diff --git a/Source/Core/loadKTX2.js b/Source/Core/loadKTX2.js new file mode 100644 index 000000000000..9c0f67379787 --- /dev/null +++ b/Source/Core/loadKTX2.js @@ -0,0 +1,105 @@ +import Check from "./Check.js"; +import Resource from "./Resource.js"; +import KTX2Transcoder from "./KTX2Transcoder.js"; +import when from "../ThirdParty/when.js"; + +/** + * Stores the supported formats that KTX2 can transcode to. Called during context creation. + * + * @param {Boolean} s3tc Whether or not S3TC is supported + * @param {Boolean} pvrtc Whether or not PVRTC is supported + * @param {Boolean} astc Whether or not ASTC is supported + * @param {Boolean} etc Whether or not ETC is supported + * @param {Boolean} etc1 Whether or not ETC1 is supported + * @param {Boolean} bc7 Whether or not BC7 is supported + * @private + */ +var supportedTranscoderFormats; + +loadKTX2.setKTX2SupportedFormats = function ( + s3tc, + pvrtc, + astc, + etc, + etc1, + bc7 +) { + supportedTranscoderFormats = { + s3tc: s3tc, + pvrtc: pvrtc, + astc: astc, + etc: etc, + etc1: etc1, + bc7: bc7, + }; +}; + +/** + * Asynchronously loads and parses the given URL to a KTX2 file or parses the raw binary data of a KTX2 file. + * Returns a promise that will resolve to an object containing the image buffer, width, height, and format once loaded, + * or reject if the URL failed to load or failed to parse the data. The data is loaded + * using XMLHttpRequest, which means that in order to make requests to another origin, + * the server must have Cross-Origin Resource sharing (CORS) headers enabled. + *

+ * The following are part of the KTX2 format specification but are not supported: + *

    + *
  • Metadata
  • + *
  • 3D textures
  • + *
  • Texture Arrays
  • + *
  • Video
  • + *
+ *

+ * + * @function loadKTX2 + * + * @param {Resource|String|ArrayBuffer} resourceOrUrlOrBuffer The URL of the binary data or an ArrayBuffer. + * @returns {Promise.|undefined} A promise that will resolve to the requested data when loaded. Returns undefined if request.throttle is true and the request does not have high enough priority. + * + * @exception {RuntimeError} Invalid KTX2 file. + * @exception {RuntimeError} KTX2 texture arrays are not supported. + * @exception {RuntimeError} KTX2 3D textures are unsupported. + * @exception {RuntimeError} No transcoding format target available for ETC1S compressed ktx2s. + * @exception {RuntimeError} No transcoding format target available for UASTC compressed ktx2s. + * @exception {RuntimeError} startTranscoding() failed. + * @exception {RuntimeError} transcodeImage() failed. + * + * @example + * // load a single URL asynchronously + * Cesium.loadKTX2('some/url').then(function (ktx2Data) { + * var width = ktx2Data.width; + * var height = ktx2Data.height; + * var format = ktx2Data.internalFormat; + * var arrayBufferView = ktx2Data.bufferView; + * // use the data to create a texture + * }).otherwise(function (error) { + * // an error occurred. + * }); + * + * @see {@link https://github.com/KhronosGroup/KTX-Specification|KTX file format} + * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing} + * @see {@link http://wiki.commonjs.org/wiki/Promises/A|CommonJS Promises/A} + * @private + */ +function loadKTX2(resourceOrUrlOrBuffer) { + //>>includeStart('debug', pragmas.debug); + Check.defined("resourceOrUrlOrBuffer", resourceOrUrlOrBuffer); + //>>includeEnd('debug'); + + var loadPromise; + if ( + resourceOrUrlOrBuffer instanceof ArrayBuffer || + ArrayBuffer.isView(resourceOrUrlOrBuffer) + ) { + loadPromise = when.resolve(resourceOrUrlOrBuffer); + } else { + var resource = Resource.createIfNeeded(resourceOrUrlOrBuffer); + loadPromise = resource.fetchArrayBuffer(); + } + + // load module then return + return loadPromise.then(function (data) { + return KTX2Transcoder.transcode(data, supportedTranscoderFormats); + }); +} + +export default loadKTX2; diff --git a/Source/Core/parseKTX2.js b/Source/Core/parseKTX2.js new file mode 100644 index 000000000000..6ee2eff26fe5 --- /dev/null +++ b/Source/Core/parseKTX2.js @@ -0,0 +1,293 @@ +import Check from "./Check.js"; +import defined from "./defined.js"; +import PixelFormat from "./PixelFormat.js"; +import RuntimeError from "./RuntimeError.js"; +import VulkanConstants from "./VulkanConstants.js"; +import PixelDatatype from "../Renderer/PixelDatatype.js"; +import { read } from "../ThirdParty/Workers/ktx-parse.modern.js"; + +var faceOrder = [ + "positiveX", + "negativeX", + "positiveY", + "negativeY", + "positiveZ", + "negativeZ", +]; + +// Flags +var colorModelETC1S = 163; +var colorModelUASTC = 166; + +/** + * Parses and transcodes KTX2 buffers to an appropriate target format. + * + * @param {Uint8Array} data Data representing one KTX2 texture. + * @param {Object} supportedTargetFormats Target formats available on the current system. + * @param {Object} transcoderModule basis_transcoder object. + * + * @private + */ +function parseKTX2( + data, + supportedTargetFormats, + transcoderModule, + transferableObjects +) { + //>>includeStart('debug', pragmas.debug); + Check.typeOf.object("transcoderModule", transcoderModule); + //>>includeEnd('debug'); + + var header; + try { + header = read(data); + } catch (e) { + throw new RuntimeError("Invalid KTX2 file."); + } + + if (header.layerCount !== 0) { + throw new RuntimeError("KTX2 texture arrays are not supported."); + } + + if (header.pixelDepth !== 0) { + throw new RuntimeError("KTX2 3D textures are unsupported."); + } + + var dfd = header.dataFormatDescriptor[0]; + var result = new Array(header.levelCount); + + if ( + header.vkFormat === 0x0 && + (dfd.colorModel === colorModelETC1S || dfd.colorModel === colorModelUASTC) + ) { + // Compressed, initialize transcoder module + transcodeCompressed( + data, + header, + supportedTargetFormats, + transcoderModule, + transferableObjects, + result + ); + } else { + transferableObjects.push(data.buffer); + parseUncompressed(header, result); + } + + return result; +} + +// Parser for uncompressed +function parseUncompressed(header, result) { + var internalFormat = + header.vkFormat === VulkanConstants.VK_FORMAT_R8G8B8_SRGB + ? PixelFormat.RGB + : PixelFormat.RGBA; + var datatype; + if (header.vkFormat === VulkanConstants.VK_FORMAT_R8G8B8A8_UNORM) { + datatype = PixelDatatype.UNSIGNED_BYTE; + } else if ( + header.vkFormat === VulkanConstants.VK_FORMAT_R16G16B16A16_SFLOAT + ) { + datatype = PixelDatatype.HALF_FLOAT; + } else if ( + header.vkFormat === VulkanConstants.VK_FORMAT_R32G32B32A32_SFLOAT + ) { + datatype = PixelDatatype.FLOAT; + } + + for (var i = 0; i < header.levels.length; ++i) { + var level = {}; + result[i] = level; + var levelBuffer = header.levels[i].levelData; + + var width = header.pixelWidth >> i; + var height = header.pixelHeight >> i; + var faceLength = + width * height * PixelFormat.componentsLength(internalFormat); + + for (var j = 0; j < header.faceCount; ++j) { + // multiply levelBuffer.byteOffset by the size in bytes of the pixel data type + var faceByteOffset = + levelBuffer.byteOffset + faceLength * header.typeSize * j; + var faceView; + if (!defined(datatype) || PixelDatatype.sizeInBytes(datatype) === 1) { + faceView = new Uint8Array( + levelBuffer.buffer, + faceByteOffset, + faceLength + ); + } else if (PixelDatatype.sizeInBytes(datatype) === 2) { + faceView = new Uint16Array( + levelBuffer.buffer, + faceByteOffset, + faceLength + ); + } else { + faceView = new Float32Array( + levelBuffer.buffer, + faceByteOffset, + faceLength + ); + } + + level[faceOrder[j]] = { + internalFormat: internalFormat, + datatype: datatype, + width: width, + height: height, + levelBuffer: faceView, + }; + } + } +} + +function transcodeCompressed( + data, + header, + supportedTargetFormats, + transcoderModule, + transferableObjects, + result +) { + var ktx2File = new transcoderModule.KTX2File(data); + var width = ktx2File.getWidth(); + var height = ktx2File.getHeight(); + var levels = ktx2File.getLevels(); + var hasAlpha = ktx2File.getHasAlpha(); + + if (!(width > 0) || !(height > 0) || !(levels > 0)) { + ktx2File.close(); + ktx2File.delete(); + throw new RuntimeError("Invalid KTX2 file"); + } + + var internalFormat, transcoderFormat; + var dfd = header.dataFormatDescriptor[0]; + var BasisFormat = transcoderModule.transcoder_texture_format; + + // Determine target format based on platform support + if (dfd.colorModel === colorModelETC1S) { + if (supportedTargetFormats.etc) { + internalFormat = hasAlpha + ? PixelFormat.RGBA8_ETC2_EAC + : PixelFormat.RGB8_ETC2; + transcoderFormat = hasAlpha + ? BasisFormat.cTFETC2_RGBA + : BasisFormat.cTFETC1_RGB; + } else if (supportedTargetFormats.etc1 && !hasAlpha) { + internalFormat = PixelFormat.RGB_ETC1; + transcoderFormat = BasisFormat.cTFETC1_RGB; + } else if (supportedTargetFormats.s3tc) { + internalFormat = hasAlpha ? PixelFormat.RGBA_DXT5 : PixelFormat.RGB_DXT1; + transcoderFormat = hasAlpha + ? BasisFormat.cTFBC3_RGBA + : BasisFormat.cTFBC1_RGB; + } else if (supportedTargetFormats.pvrtc) { + internalFormat = hasAlpha + ? PixelFormat.RGBA_PVRTC_4BPPV1 + : PixelFormat.RGB_PVRTC_4BPPV1; + transcoderFormat = hasAlpha + ? BasisFormat.cTFPVRTC1_4_RGBA + : BasisFormat.cTFPVRTC1_4_RGB; + } else if (supportedTargetFormats.astc) { + internalFormat = PixelFormat.RGBA_ASTC; + transcoderFormat = BasisFormat.cTFASTC_4x4_RGBA; + } else if (supportedTargetFormats.bc7) { + internalFormat = PixelFormat.RGBA_BC7; + transcoderFormat = BasisFormat.cTFBC7_RGBA; + } else { + throw new RuntimeError( + "No transcoding format target available for ETC1S compressed ktx2." + ); + } + } else if (dfd.colorModel === colorModelUASTC) { + if (supportedTargetFormats.astc) { + internalFormat = PixelFormat.RGBA_ASTC; + transcoderFormat = BasisFormat.cTFASTC_4x4_RGBA; + } else if (supportedTargetFormats.bc7) { + internalFormat = PixelFormat.RGBA_BC7; + transcoderFormat = BasisFormat.cTFBC7_RGBA; + } else if (supportedTargetFormats.s3tc) { + internalFormat = hasAlpha ? PixelFormat.RGBA_DXT5 : PixelFormat.RGB_DXT1; + transcoderFormat = hasAlpha + ? BasisFormat.cTFBC3_RGBA + : BasisFormat.cTFBC1_RGB; + } else if (supportedTargetFormats.etc) { + internalFormat = hasAlpha + ? PixelFormat.RGBA8_ETC2_EAC + : PixelFormat.RGB8_ETC2; + transcoderFormat = hasAlpha + ? BasisFormat.cTFETC2_RGBA + : BasisFormat.cTFETC1_RGB; + } else if (supportedTargetFormats.etc1 && !hasAlpha) { + internalFormat = PixelFormat.RGB_ETC1; + transcoderFormat = BasisFormat.cTFETC1_RGB; + } else if (supportedTargetFormats.pvrtc) { + internalFormat = hasAlpha + ? PixelFormat.RGBA_PVRTC_4BPPV1 + : PixelFormat.RGB_PVRTC_4BPPV1; + transcoderFormat = hasAlpha + ? BasisFormat.cTFPVRTC1_4_RGBA + : BasisFormat.cTFPVRTC1_4_RGB; + } else { + throw new RuntimeError( + "No transcoding format target available for UASTC compressed ktx2." + ); + } + } + + if (!ktx2File.startTranscoding()) { + ktx2File.close(); + ktx2File.delete(); + throw new RuntimeError("startTranscoding() failed"); + } + + for (var i = 0; i < header.levels.length; ++i) { + var level = {}; + result[i] = level; + width = header.pixelWidth >> i; + height = header.pixelHeight >> i; + + // Since supercompressed cubemaps are unsupported, this function + // does not iterate over KTX2 faces and assumes faceCount = 1. + + var dstSize = ktx2File.getImageTranscodedSizeInBytes( + i, // level index + 0, // layer index + 0, // face index + transcoderFormat.value + ); + var dst = new Uint8Array(dstSize); + + var transcoded = ktx2File.transcodeImage( + dst, + i, // level index + 0, // layer index + 0, // face index + transcoderFormat.value, + 0, // get_alpha_for_opaque_formats + -1, // channel0 + -1 // channel1 + ); + + if (!defined(transcoded)) { + throw new RuntimeError("transcodeImage() failed."); + } + + transferableObjects.push(dst.buffer); + + level[faceOrder[0]] = { + internalFormat: internalFormat, + width: width, + height: height, + levelBuffer: dst, + }; + } + + ktx2File.close(); + ktx2File.delete(); + return result; +} + +export default parseKTX2; diff --git a/Source/Renderer/Context.js b/Source/Renderer/Context.js index cc8d5c326ef4..8f427707c232 100644 --- a/Source/Renderer/Context.js +++ b/Source/Renderer/Context.js @@ -9,6 +9,7 @@ import destroyObject from "../Core/destroyObject.js"; import DeveloperError from "../Core/DeveloperError.js"; import Geometry from "../Core/Geometry.js"; import GeometryAttribute from "../Core/GeometryAttribute.js"; +import loadKTX2 from "../Core/loadKTX2.js"; import Matrix4 from "../Core/Matrix4.js"; import PixelFormat from "../Core/PixelFormat.js"; import PrimitiveType from "../Core/PrimitiveType.js"; @@ -314,7 +315,21 @@ function Context(canvas, options) { "WEBGL_compressed_texture_pvrtc", "WEBKIT_WEBGL_compressed_texture_pvrtc", ]); + this._astc = !!getExtension(gl, ["WEBGL_compressed_texture_astc"]); + this._etc = !!getExtension(gl, ["WEBG_compressed_texture_etc"]); this._etc1 = !!getExtension(gl, ["WEBGL_compressed_texture_etc1"]); + this._bc7 = !!getExtension(gl, ["EXT_texture_compression_bptc"]); + + // It is necessary to pass supported formats to loadKTX2 + // because imagery layers don't have access to the context. + loadKTX2.setKTX2SupportedFormats( + this._s3tc, + this._pvrtc, + this._astc, + this._etc, + this._etc1, + this._bc7 + ); var textureFilterAnisotropic = options.allowTextureFilterAnisotropic ? getExtension(gl, [ @@ -665,7 +680,7 @@ Object.defineProperties(Context.prototype, { * access to floating point textures that, for example, can be attached to framebuffers for high dynamic range. * @memberof Context.prototype * @type {Boolean} - * @see {@link https://www.khronos.org/registry/webgl/extensions/OES_texture_float/} + * @see {@link https://www.khronos.org/registry/webgl/extensions/OES_texture_half_float/} */ halfFloatingPointTexture: { get: function () { @@ -716,7 +731,7 @@ Object.defineProperties(Context.prototype, { }, /** - * true if WEBGL_texture_compression_s3tc is supported. This extension provides + * true if WEBGL_compressed_texture_s3tc is supported. This extension provides * access to DXT compressed textures. * @memberof Context.prototype * @type {Boolean} @@ -729,7 +744,7 @@ Object.defineProperties(Context.prototype, { }, /** - * true if WEBGL_texture_compression_pvrtc is supported. This extension provides + * true if WEBGL_compressed_texture_pvrtc is supported. This extension provides * access to PVR compressed textures. * @memberof Context.prototype * @type {Boolean} @@ -742,7 +757,33 @@ Object.defineProperties(Context.prototype, { }, /** - * true if WEBGL_texture_compression_etc1 is supported. This extension provides + * true if WEBGL_compressed_texture_astc is supported. This extension provides + * access to ASTC compressed textures. + * @memberof Context.prototype + * @type {Boolean} + * @see {@link https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_astc/} + */ + astc: { + get: function () { + return this._astc; + }, + }, + + /** + * true if WEBGL_compressed_texture_etc is supported. This extension provides + * access to ETC compressed textures. + * @memberof Context.prototype + * @type {Boolean} + * @see {@link https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_etc/} + */ + etc: { + get: function () { + return this._etc; + }, + }, + + /** + * true if WEBGL_compressed_texture_etc1 is supported. This extension provides * access to ETC1 compressed textures. * @memberof Context.prototype * @type {Boolean} @@ -754,6 +795,37 @@ Object.defineProperties(Context.prototype, { }, }, + /** + * true if EXT_texture_compression_bptc is supported. This extension provides + * access to BC7 compressed textures. + * @memberof Context.prototype + * @type {Boolean} + * @see {@link https://www.khronos.org/registry/webgl/extensions/EXT_texture_compression_bptc/} + */ + bc7: { + get: function () { + return this._bc7; + }, + }, + + /** + * true if S3TC, PVRTC, ASTC, ETC, ETC1, or BC7 compression is supported. + * @memberof Context.prototype + * @type {Boolean} + */ + supportsBasis: { + get: function () { + return ( + this._s3tc || + this._pvrtc || + this._astc || + this._etc || + this._etc1 || + this._bc7 + ); + }, + }, + /** * true if the OES_vertex_array_object extension is supported. This * extension can improve performance by reducing the overhead of switching vertex arrays. diff --git a/Source/Renderer/Texture.js b/Source/Renderer/Texture.js index 58894466acbc..3340e1b61b8c 100644 --- a/Source/Renderer/Texture.js +++ b/Source/Renderer/Texture.js @@ -143,15 +143,27 @@ function Texture(options) { if (PixelFormat.isDXTFormat(internalFormat) && !context.s3tc) { throw new DeveloperError( - "When options.pixelFormat is S3TC compressed, this WebGL implementation must support the WEBGL_texture_compression_s3tc extension. Check context.s3tc." + "When options.pixelFormat is S3TC compressed, this WebGL implementation must support the WEBGL_compressed_texture_s3tc extension. Check context.s3tc." ); } else if (PixelFormat.isPVRTCFormat(internalFormat) && !context.pvrtc) { throw new DeveloperError( - "When options.pixelFormat is PVRTC compressed, this WebGL implementation must support the WEBGL_texture_compression_pvrtc extension. Check context.pvrtc." + "When options.pixelFormat is PVRTC compressed, this WebGL implementation must support the WEBGL_compressed_texture_pvrtc extension. Check context.pvrtc." + ); + } else if (PixelFormat.isASTCFormat(internalFormat) && !context.astc) { + throw new DeveloperError( + "When options.pixelFormat is ASTC compressed, this WebGL implementation must support the WEBGL_compressed_texture_astc extension. Check context.astc." + ); + } else if (PixelFormat.isETC2Format(internalFormat) && !context.etc) { + throw new DeveloperError( + "When options.pixelFormat is ETC2 compressed, this WebGL implementation must support the WEBGL_compressed_texture_etc extension. Check context.etc." ); } else if (PixelFormat.isETC1Format(internalFormat) && !context.etc1) { throw new DeveloperError( - "When options.pixelFormat is ETC1 compressed, this WebGL implementation must support the WEBGL_texture_compression_etc1 extension. Check context.etc1." + "When options.pixelFormat is ETC1 compressed, this WebGL implementation must support the WEBGL_compressed_texture_etc1 extension. Check context.etc1." + ); + } else if (PixelFormat.isBC7Format(internalFormat) && !context.bc7) { + throw new DeveloperError( + "When options.pixelFormat is BC7 compressed, this WebGL implementation must support the EXT_texture_compression_bptc extension. Check context.bc7." ); } @@ -217,6 +229,7 @@ function Texture(options) { // Source: typed array var arrayBufferView = source.arrayBufferView; + var i, mipWidth, mipHeight; if (isCompressed) { gl.compressedTexImage2D( textureTarget, @@ -227,6 +240,29 @@ function Texture(options) { 0, arrayBufferView ); + if (defined(source.mipLevels)) { + mipWidth = width; + mipHeight = height; + for (i = 0; i < source.mipLevels.length; ++i) { + mipWidth = Math.floor(mipWidth / 2) | 0; + if (mipWidth < 1) { + mipWidth = 1; + } + mipHeight = Math.floor(mipHeight / 2) | 0; + if (mipHeight < 1) { + mipHeight = 1; + } + gl.compressedTexImage2D( + textureTarget, + i + 1, + internalFormat, + mipWidth, + mipHeight, + 0, + source.mipLevels[i] + ); + } + } } else { if (flipY) { arrayBufferView = PixelFormat.flipY( @@ -250,9 +286,9 @@ function Texture(options) { ); if (defined(source.mipLevels)) { - var mipWidth = width; - var mipHeight = height; - for (var i = 0; i < source.mipLevels.length; ++i) { + mipWidth = width; + mipHeight = height; + for (i = 0; i < source.mipLevels.length; ++i) { mipWidth = Math.floor(mipWidth / 2) | 0; if (mipWidth < 1) { mipWidth = 1; diff --git a/Source/Scene/BufferLoader.js b/Source/Scene/BufferLoader.js index 63ee39af5b1d..613649c56fe7 100644 --- a/Source/Scene/BufferLoader.js +++ b/Source/Scene/BufferLoader.js @@ -108,8 +108,7 @@ BufferLoader.prototype.load = function () { function loadExternalBuffer(bufferLoader) { var resource = bufferLoader._resource; bufferLoader._state = ResourceLoaderState.LOADING; - resource - .fetchArrayBuffer() + BufferLoader._fetchArrayBuffer(resource) .then(function (arrayBuffer) { if (bufferLoader.isDestroyed()) { return; @@ -128,6 +127,14 @@ function loadExternalBuffer(bufferLoader) { }); } +/** + * Exposed for testing + * @private + */ +BufferLoader._fetchArrayBuffer = function (resource) { + return resource.fetchArrayBuffer(); +}; + /** * Unloads the resource. * @private diff --git a/Source/Scene/Cesium3DTileset.js b/Source/Scene/Cesium3DTileset.js index 3ea01f7ead08..82dcb932e1d4 100644 --- a/Source/Scene/Cesium3DTileset.js +++ b/Source/Scene/Cesium3DTileset.js @@ -94,7 +94,7 @@ import TileOrientedBoundingBox from "./TileOrientedBoundingBox.js"; * @param {Cartesian3} [options.lightColor] The light color when shading models. When undefined the scene's light color is used instead. * @param {Number} [options.luminanceAtZenith=0.2] The sun's luminance at the zenith in kilo candela per meter squared to use for this model's procedural environment map. * @param {Cartesian3[]} [options.sphericalHarmonicCoefficients] The third order spherical harmonic coefficients used for the diffuse color of image-based lighting. - * @param {String} [options.specularEnvironmentMaps] A URL to a KTX file that contains a cube map of the specular lighting and the convoluted specular mipmaps. + * @param {String} [options.specularEnvironmentMaps] A URL to a KTX2 file that contains a cube map of the specular lighting and the convoluted specular mipmaps. * @param {Boolean} [options.backFaceCulling=true] Whether to cull back-facing geometry. When true, back face culling is determined by the glTF material's doubleSided property; when false, back face culling is disabled. * @param {Boolean} [options.showOutline=true] Whether to display the outline for models using the {@link https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/CESIUM_primitive_outline|CESIUM_primitive_outline} extension. When true, outlines are displayed. When false, outlines are not displayed. * @param {Boolean} [options.vectorClassificationOnly=false] Indicates that only the tileset's vector tiles should be used for classification. diff --git a/Source/Scene/GltfImageLoader.js b/Source/Scene/GltfImageLoader.js index 7fd4c70079f4..712975bd811e 100644 --- a/Source/Scene/GltfImageLoader.js +++ b/Source/Scene/GltfImageLoader.js @@ -1,12 +1,10 @@ import Check from "../Core/Check.js"; import defaultValue from "../Core/defaultValue.js"; import defined from "../Core/defined.js"; -import loadCRN from "../Core/loadCRN.js"; import loadImageFromTypedArray from "../Core/loadImageFromTypedArray.js"; -import loadKTX from "../Core/loadKTX.js"; +import loadKTX2 from "../Core/loadKTX2.js"; import RuntimeError from "../Core/RuntimeError.js"; import when from "../ThirdParty/when.js"; -import GltfLoaderUtil from "./GltfLoaderUtil.js"; import ResourceLoader from "./ResourceLoader.js"; import ResourceLoaderState from "./ResourceLoaderState.js"; @@ -26,7 +24,6 @@ import ResourceLoaderState from "./ResourceLoaderState.js"; * @param {Number} options.imageId The image ID. * @param {Resource} options.gltfResource The {@link Resource} containing the glTF. * @param {Resource} options.baseResource The {@link Resource} that paths in the glTF JSON are relative to. - * @param {SupportedImageFormats} options.supportedImageFormats The supported image formats. * @param {String} [options.cacheKey] The cache key of the resource. * * @private @@ -38,7 +35,6 @@ export default function GltfImageLoader(options) { var imageId = options.imageId; var gltfResource = options.gltfResource; var baseResource = options.baseResource; - var supportedImageFormats = options.supportedImageFormats; var cacheKey = options.cacheKey; //>>includeStart('debug', pragmas.debug); @@ -47,17 +43,11 @@ export default function GltfImageLoader(options) { Check.typeOf.number("options.imageId", imageId); Check.typeOf.object("options.gltfResource", gltfResource); Check.typeOf.object("options.baseResource", baseResource); - Check.typeOf.object("options.supportedImageFormats", supportedImageFormats); //>>includeEnd('debug'); - var results = GltfLoaderUtil.getImageUriOrBufferView({ - gltf: gltf, - imageId: imageId, - supportedImageFormats: supportedImageFormats, - }); - - var bufferViewId = results.bufferViewId; - var uri = results.uri; + var image = gltf.images[imageId]; + var bufferViewId = image.bufferView; + var uri = image.uri; this._resourceCache = resourceCache; this._gltfResource = gltfResource; @@ -68,6 +58,7 @@ export default function GltfImageLoader(options) { this._cacheKey = cacheKey; this._bufferViewLoader = undefined; this._image = undefined; + this._mipLevels = undefined; this._state = ResourceLoaderState.UNLOADED; this._promise = when.defer(); } @@ -120,6 +111,20 @@ Object.defineProperties(GltfImageLoader.prototype, { return this._image; }, }, + /** + * The mip levels. Only defined for KTX2 files containing mip levels. + * + * @memberof GltfImageLoader.prototype + * + * @type {Uint8Array[]} + * @readonly + * @private + */ + mipLevels: { + get: function () { + return this._mipLevels; + }, + }, }); /** @@ -134,6 +139,23 @@ GltfImageLoader.prototype.load = function () { } }; +function getImageAndMipLevels(image) { + // Images transcoded from KTX2 can contain multiple mip levels: + // https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_texture_basisu + var mipLevels; + if (Array.isArray(image)) { + // highest detail mip should be level 0 + mipLevels = image.slice(1, image.length).map(function (mipLevel) { + return mipLevel.bufferView; + }); + image = image[0]; + } + return { + image: image, + mipLevels: mipLevels, + }; +} + function loadFromBufferView(imageLoader) { var resourceCache = imageLoader._resourceCache; var bufferViewLoader = resourceCache.loadBufferView({ @@ -158,10 +180,13 @@ function loadFromBufferView(imageLoader) { return; } + var imageAndMipLevels = getImageAndMipLevels(image); + // Unload everything except the image imageLoader.unload(); - imageLoader._image = image; + imageLoader._image = imageAndMipLevels.image; + imageLoader._mipLevels = imageAndMipLevels.mipLevels; imageLoader._state = ResourceLoaderState.READY; imageLoader._promise.resolve(imageLoader); }); @@ -187,10 +212,13 @@ function loadFromUri(imageLoader) { return; } + var imageAndMipLevels = getImageAndMipLevels(image); + // Unload everything except the image imageLoader.unload(); - imageLoader._image = image; + imageLoader._image = imageAndMipLevels.image; + imageLoader._mipLevels = imageAndMipLevels.mipLevels; imageLoader._state = ResourceLoaderState.READY; imageLoader._promise.resolve(imageLoader); }) @@ -221,13 +249,7 @@ function getMimeTypeFromTypedArray(typedArray) { return "image/png"; } else if (header[0] === 0xab && header[1] === 0x4b) { // See http://github.khronos.org/KTX-Specification/#_identifier - return "image/ktx"; - } else if (header[0] === 0x48 && header[1] === 0x78) { - // See https://github.com/BinomialLLC/crunch/blob/671a0648c8a440b4397f1d96ea5cf5700f830417/inc/crn_decomp.h#L268 - return "image/crn"; - } else if (header[0] === 0x73 && header[1] === 0x42) { - // See https://github.com/BinomialLLC/basis_universal/blob/ed135f03a05de315dd7ec7c1b8ef0589099b3e52/spec/basis_spec.txt#L125 - return "image/basis"; + return "image/ktx2"; } else if ( // See https://developers.google.com/speed/webp/docs/riff_container#webp_file_header webpHeaderRIFFChars[0] === 0x52 && @@ -247,12 +269,15 @@ function getMimeTypeFromTypedArray(typedArray) { function loadImageFromBufferTypedArray(typedArray) { var mimeType = getMimeTypeFromTypedArray(typedArray); - if (mimeType === "image/ktx") { - // Resolves to a CompressedTextureBuffer - return loadKTX(typedArray); - } else if (mimeType === "image/crn") { + if (mimeType === "image/ktx2") { + // Need to make a copy of the embedded KTX2 buffer otherwise the underlying + // ArrayBuffer may be accessed on both the worker and the main thread and + // throw an error like "Cannot perform Construct on a detached ArrayBuffer". + // Look into SharedArrayBuffer at some point to get around this. + var ktxBuffer = new Uint8Array(typedArray); + // Resolves to a CompressedTextureBuffer - return loadCRN(typedArray); + return loadKTX2(ktxBuffer); } // Resolves to an Image or ImageBitmap return GltfImageLoader._loadImageFromTypedArray({ @@ -263,17 +288,13 @@ function loadImageFromBufferTypedArray(typedArray) { }); } -var ktxRegex = /(^data:image\/ktx)|(\.ktx$)/i; -var crnRegex = /(^data:image\/crn)|(\.crn$)/i; +var ktx2Regex = /(^data:image\/ktx2)|(\.ktx2$)/i; function loadImageFromUri(resource) { var uri = resource.url; - if (ktxRegex.test(uri)) { - // Resolves to a CompressedTextureBuffer - return loadKTX(resource); - } else if (crnRegex.test(uri)) { + if (ktx2Regex.test(uri)) { // Resolves to a CompressedTextureBuffer - return loadCRN(resource); + return loadKTX2(resource); } // Resolves to an ImageBitmap or Image return resource.fetchImage({ @@ -294,8 +315,9 @@ GltfImageLoader.prototype.unload = function () { this._bufferViewLoader = undefined; this._uri = undefined; // Free in case the uri is a data uri this._image = undefined; + this._mipLevels = undefined; this._gltf = undefined; }; -//Exposed for testing +// Exposed for testing GltfImageLoader._loadImageFromTypedArray = loadImageFromTypedArray; diff --git a/Source/Scene/GltfLoader.js b/Source/Scene/GltfLoader.js index a4b17d7041dd..95939ab7cdce 100644 --- a/Source/Scene/GltfLoader.js +++ b/Source/Scene/GltfLoader.js @@ -263,9 +263,7 @@ GltfLoader.prototype.process = function (frameState) { var supportedImageFormats = new SupportedImageFormats({ webp: FeatureDetection.supportsWebP(), - s3tc: frameState.context.s3tc, - pvrtc: frameState.context.pvrtc, - etc1: frameState.context.etc1, + basis: frameState.context.supportsBasis, }); var gltf = this._gltfJsonLoader.gltf; diff --git a/Source/Scene/GltfLoaderUtil.js b/Source/Scene/GltfLoaderUtil.js index c6f5d35a1f4e..7f6fabf5c0e3 100644 --- a/Source/Scene/GltfLoaderUtil.js +++ b/Source/Scene/GltfLoaderUtil.js @@ -18,75 +18,6 @@ import ModelComponents from "./ModelComponents.js"; */ var GltfLoaderUtil = {}; -/** - * Get the uri or buffer view for an image. - * - * @param {Object} options Object with the following properties: - * @param {Object} options.gltf The glTF JSON. - * @param {Number} options.imageId The image ID. - * @param {SupportedImageFormats} options.supportedImageFormats The supported image formats. - * - * @returns {Object} An object containing a uri and bufferView property. - * @private - */ -GltfLoaderUtil.getImageUriOrBufferView = function (options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - var gltf = options.gltf; - var imageId = options.imageId; - var supportedImageFormats = options.supportedImageFormats; - - //>>includeStart('debug', pragmas.debug); - Check.typeOf.object("options.gltf", gltf); - Check.typeOf.number("options.imageId", imageId); - Check.typeOf.object("options.supportedImageFormats", supportedImageFormats); - //>>includeEnd('debug'); - - var image = gltf.images[imageId]; - var extras = image.extras; - - var bufferViewId = image.bufferView; - var uri = image.uri; - - // First check for a compressed texture - if (defined(extras) && defined(extras.compressedImage3DTiles)) { - var crunch = extras.compressedImage3DTiles.crunch; - var s3tc = extras.compressedImage3DTiles.s3tc; - var pvrtc = extras.compressedImage3DTiles.pvrtc1; - var etc1 = extras.compressedImage3DTiles.etc1; - - if (supportedImageFormats.s3tc && defined(crunch)) { - if (defined(crunch.bufferView)) { - bufferViewId = crunch.bufferView; - } else { - uri = crunch.uri; - } - } else if (supportedImageFormats.s3tc && defined(s3tc)) { - if (defined(s3tc.bufferView)) { - bufferViewId = s3tc.bufferView; - } else { - uri = s3tc.uri; - } - } else if (supportedImageFormats.pvrtc && defined(pvrtc)) { - if (defined(pvrtc.bufferView)) { - bufferViewId = pvrtc.bufferView; - } else { - uri = pvrtc.uri; - } - } else if (supportedImageFormats.etc1 && defined(etc1)) { - if (defined(etc1.bufferView)) { - bufferViewId = etc1.bufferView; - } else { - uri = etc1.uri; - } - } - } - - return { - bufferViewId: bufferViewId, - uri: uri, - }; -}; - /** * Get the image ID referenced by a texture. *

@@ -119,6 +50,11 @@ GltfLoaderUtil.getImageIdFromTexture = function (options) { if (defined(extensions)) { if (supportedImageFormats.webp && defined(extensions.EXT_texture_webp)) { return extensions.EXT_texture_webp.source; + } else if ( + supportedImageFormats.basis && + defined(extensions.KHR_texture_basisu) + ) { + return extensions.KHR_texture_basisu.source; } } return texture.source; @@ -130,6 +66,7 @@ GltfLoaderUtil.getImageIdFromTexture = function (options) { * @param {Object} options Object with the following properties: * @param {Object} options.gltf The glTF JSON. * @param {Object} options.textureInfo The texture info object. + * @param {Boolean} [options.compressedTextureNoMipmap=false] True when the texture is compressed and does not have an embedded mipmap. * * @returns {Sampler} The sampler. * @private @@ -138,6 +75,10 @@ GltfLoaderUtil.createSampler = function (options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); var gltf = options.gltf; var textureInfo = options.textureInfo; + var compressedTextureNoMipmap = defaultValue( + options.compressedTextureNoMipmap, + false + ); //>>includeStart('debug', pragmas.debug); Check.typeOf.object("options.gltf", gltf); @@ -169,7 +110,7 @@ GltfLoaderUtil.createSampler = function (options) { } if ( - usesTextureTransform && + (compressedTextureNoMipmap || usesTextureTransform) && minFilter !== TextureMinificationFilter.LINEAR && minFilter !== TextureMinificationFilter.NEAREST ) { diff --git a/Source/Scene/GltfTextureLoader.js b/Source/Scene/GltfTextureLoader.js index 6a6594729069..8017767a9ca0 100644 --- a/Source/Scene/GltfTextureLoader.js +++ b/Source/Scene/GltfTextureLoader.js @@ -2,6 +2,7 @@ import Check from "../Core/Check.js"; import CesiumMath from "../Core/Math.js"; import defaultValue from "../Core/defaultValue.js"; import defined from "../Core/defined.js"; +import PixelFormat from "../Core/PixelFormat.js"; import Texture from "../Renderer/Texture.js"; import TextureMinificationFilter from "../Renderer/TextureMinificationFilter.js"; import TextureWrap from "../Renderer/TextureWrap.js"; @@ -69,11 +70,11 @@ export default function GltfTextureLoader(options) { this._imageId = imageId; this._gltfResource = gltfResource; this._baseResource = baseResource; - this._supportedImageFormats = supportedImageFormats; this._cacheKey = cacheKey; this._asynchronous = asynchronous; this._imageLoader = undefined; this._image = undefined; + this._mipLevels = undefined; this._texture = undefined; this._state = ResourceLoaderState.UNLOADED; this._promise = when.defer(); @@ -140,7 +141,6 @@ GltfTextureLoader.prototype.load = function () { imageId: this._imageId, gltfResource: this._gltfResource, baseResource: this._baseResource, - supportedImageFormats: this._supportedImageFormats, }); this._imageLoader = imageLoader; @@ -155,6 +155,7 @@ GltfTextureLoader.prototype.load = function () { } // Now wait for process() to run to finish loading that._image = imageLoader.image; + that._mipLevels = imageLoader.mipLevels; that._state = ResourceLoaderState.PROCESSING; }) .otherwise(function (error) { @@ -176,10 +177,17 @@ function CreateTextureJob() { this.texture = undefined; } -CreateTextureJob.prototype.set = function (gltf, textureInfo, image, context) { +CreateTextureJob.prototype.set = function ( + gltf, + textureInfo, + image, + mipLevels, + context +) { this.gltf = gltf; this.textureInfo = textureInfo; this.image = image; + this.mipLevels = mipLevels; this.context = context; }; @@ -188,6 +196,7 @@ CreateTextureJob.prototype.execute = function () { this.gltf, this.textureInfo, this.image, + this.mipLevels, this.context ); }; @@ -211,19 +220,25 @@ function resizeImageToNextPowerOfTwo(image) { return canvas; } -function createTexture(gltf, textureInfo, image, context) { +function createTexture(gltf, textureInfo, image, mipLevels, context) { + // internalFormat is only defined for CompressedTextureBuffer + var internalFormat = image.internalFormat; + + var compressedTextureNoMipmap = false; + if (PixelFormat.isCompressedFormat(internalFormat) && !defined(mipLevels)) { + compressedTextureNoMipmap = true; + } + var sampler = GltfLoaderUtil.createSampler({ gltf: gltf, textureInfo: textureInfo, + compressedTextureNoMipmap: compressedTextureNoMipmap, }); var minFilter = sampler.minificationFilter; var wrapS = sampler.wrapS; var wrapT = sampler.wrapT; - // internalFormat is only defined for CompressedTextureBuffer - var internalFormat = image.internalFormat; - var samplerRequiresMipmap = minFilter === TextureMinificationFilter.NEAREST_MIPMAP_NEAREST || minFilter === TextureMinificationFilter.NEAREST_MIPMAP_LINEAR || @@ -235,7 +250,7 @@ function createTexture(gltf, textureInfo, image, context) { // WebGL. Also note from the KHR_texture_basisu spec: // // When a texture refers to a sampler with mipmap minification or when the - // sampler is undefined, the KTX image SHOULD contain a full mip pyramid. + // sampler is undefined, the KTX2 image SHOULD contain a full mip pyramid. // var generateMipmap = !defined(internalFormat) && samplerRequiresMipmap; @@ -255,10 +270,22 @@ function createTexture(gltf, textureInfo, image, context) { var texture; if (defined(internalFormat)) { + if ( + !context.webgl2 && + PixelFormat.isCompressedFormat(internalFormat) && + nonPowerOfTwo && + requiresPowerOfTwo + ) { + console.warn( + "Compressed texture uses REPEAT or MIRRORED_REPEAT texture wrap mode and dimensions are not powers of two. The texture may be rendered incorrectly." + ); + } + texture = Texture.create({ context: context, source: { arrayBufferView: image.bufferView, // Only defined for CompressedTextureBuffer + mipLevels: mipLevels, }, width: image.width, height: image.height, @@ -316,6 +343,7 @@ GltfTextureLoader.prototype.process = function (frameState) { this._gltf, this._textureInfo, this._image, + this._mipLevels, frameState.context ); var jobScheduler = frameState.jobScheduler; @@ -329,6 +357,7 @@ GltfTextureLoader.prototype.process = function (frameState) { this._gltf, this._textureInfo, this._image, + this._mipLevels, frameState.context ); } @@ -356,6 +385,7 @@ GltfTextureLoader.prototype.unload = function () { this._imageLoader = undefined; this._image = undefined; + this._mipLevels = undefined; this._texture = undefined; this._gltf = undefined; }; diff --git a/Source/Scene/ImageryProvider.js b/Source/Scene/ImageryProvider.js index 297ce3044137..35dfd0abe51b 100644 --- a/Source/Scene/ImageryProvider.js +++ b/Source/Scene/ImageryProvider.js @@ -1,8 +1,7 @@ import Check from "../Core/Check.js"; import defined from "../Core/defined.js"; import DeveloperError from "../Core/DeveloperError.js"; -import loadCRN from "../Core/loadCRN.js"; -import loadKTX from "../Core/loadKTX.js"; +import loadKTX2 from "../Core/loadKTX2.js"; import Resource from "../Core/Resource.js"; /** @@ -337,8 +336,7 @@ ImageryProvider.prototype.pickFeatures = function ( DeveloperError.throwInstantiationError(); }; -var ktxRegex = /\.ktx$/i; -var crnRegex = /\.crn$/i; +var ktx2Regex = /\.ktx2$/i; /** * Loads an image from a given URL. If the server referenced by the URL already has @@ -359,10 +357,8 @@ ImageryProvider.loadImage = function (imageryProvider, url) { var resource = Resource.createIfNeeded(url); - if (ktxRegex.test(resource.url)) { - return loadKTX(resource); - } else if (crnRegex.test(resource.url)) { - return loadCRN(resource); + if (ktx2Regex.test(resource.url)) { + return loadKTX2(resource); } else if ( defined(imageryProvider) && defined(imageryProvider.tileDiscardPolicy) diff --git a/Source/Scene/Material.js b/Source/Scene/Material.js index 8b4212fa39d1..bb681110d593 100644 --- a/Source/Scene/Material.js +++ b/Source/Scene/Material.js @@ -7,8 +7,7 @@ import defaultValue from "../Core/defaultValue.js"; import defined from "../Core/defined.js"; import destroyObject from "../Core/destroyObject.js"; import DeveloperError from "../Core/DeveloperError.js"; -import loadCRN from "../Core/loadCRN.js"; -import loadKTX from "../Core/loadKTX.js"; +import loadKTX2 from "../Core/loadKTX2.js"; import Matrix2 from "../Core/Matrix2.js"; import Matrix3 from "../Core/Matrix3.js"; import Matrix4 from "../Core/Matrix4.js"; @@ -434,6 +433,17 @@ Material.prototype.update = function (context) { uniformId = loadedImage.id; var image = loadedImage.image; + // Images transcoded from KTX2 can contain multiple mip levels: + // https://github.khronos.org/KTX-Specification/#_mip_level_array + var mipLevels; + if (Array.isArray(image)) { + // highest detail mip should be level 0 + mipLevels = image.slice(1, image.length).map(function (mipLevel) { + return mipLevel.bufferView; + }); + image = image[0]; + } + var sampler = new Sampler({ minificationFilter: this._minificationFilter, magnificationFilter: this._magnificationFilter, @@ -448,6 +458,7 @@ Material.prototype.update = function (context) { height: image.height, source: { arrayBufferView: image.bufferView, + mipLevels: mipLevels, }, sampler: sampler, }); @@ -776,8 +787,7 @@ var matrixMap = { mat4: Matrix4, }; -var ktxRegex = /\.ktx$/i; -var crnRegex = /\.crn$/i; +var ktx2Regex = /\.ktx2$/i; function createTexture2DUpdateFunction(uniformId) { var oldUniformValue; @@ -879,13 +889,12 @@ function createTexture2DUpdateFunction(uniformId) { : Resource.createIfNeeded(uniformValue); var promise; - if (ktxRegex.test(resource.url)) { - promise = loadKTX(resource); - } else if (crnRegex.test(resource.url)) { - promise = loadCRN(resource); + if (ktx2Regex.test(resource.url)) { + promise = loadKTX2(resource.url); } else { promise = resource.fetchImage(); } + when(promise, function (image) { material._loadedImages.push({ id: uniformId, diff --git a/Source/Scene/Model.js b/Source/Scene/Model.js index 098b121cf750..30cfb090481c 100644 --- a/Source/Scene/Model.js +++ b/Source/Scene/Model.js @@ -20,9 +20,8 @@ import getJsonFromTypedArray from "../Core/getJsonFromTypedArray.js"; import getMagic from "../Core/getMagic.js"; import getStringFromTypedArray from "../Core/getStringFromTypedArray.js"; import IndexDatatype from "../Core/IndexDatatype.js"; -import loadCRN from "../Core/loadCRN.js"; import loadImageFromTypedArray from "../Core/loadImageFromTypedArray.js"; -import loadKTX from "../Core/loadKTX.js"; +import loadKTX2 from "../Core/loadKTX2.js"; import CesiumMath from "../Core/Math.js"; import Matrix3 from "../Core/Matrix3.js"; import Matrix4 from "../Core/Matrix4.js"; @@ -175,10 +174,17 @@ var uriToGuid = {}; * {@link https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_techniques_webgl/README.md|KHR_techniques_webgl} *

  • * {@link https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_texture_transform/README.md|KHR_texture_transform} + *
  • + * {@link https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_texture_basisu|KHR_texture_basisu} *
  • * *

    *

    + * Note: for models with compressed textures using the KHR_texture_basisu extension, we recommend power of 2 textures in both dimensions + * for maximum compatibility. This is because some samplers require power of 2 textures ({@link https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Tutorial/Using_textures_in_WebGL|Using textures in WebGL}) + * and KHR_texture_basisu requires multiple of 4 dimensions ({@link https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_texture_basisu/README.md#additional-requirements|KHR_texture_basisu additional requirements}). + *

    + *

    * For high-precision rendering, Cesium supports the {@link https://github.com/KhronosGroup/glTF/blob/master/extensions/1.0/Vendor/CESIUM_RTC/README.md|CESIUM_RTC} extension, which introduces the * CESIUM_RTC_MODELVIEW parameter semantic that says the node is in WGS84 coordinates translated * relative to a local origin. @@ -217,7 +223,7 @@ var uriToGuid = {}; * @param {Cartesian3} [options.lightColor] The light color when shading the model. When undefined the scene's light color is used instead. * @param {Number} [options.luminanceAtZenith=0.2] The sun's luminance at the zenith in kilo candela per meter squared to use for this model's procedural environment map. * @param {Cartesian3[]} [options.sphericalHarmonicCoefficients] The third order spherical harmonic coefficients used for the diffuse color of image-based lighting. - * @param {String} [options.specularEnvironmentMaps] A URL to a KTX file that contains a cube map of the specular lighting and the convoluted specular mipmaps. + * @param {String} [options.specularEnvironmentMaps] A URL to a KTX2 file that contains a cube map of the specular lighting and the convoluted specular mipmaps. * @param {Credit|String} [options.credit] A credit for the data source, which is displayed on the canvas. * @param {Boolean} [options.backFaceCulling=true] Whether to cull back-facing geometry. When true, back face culling is determined by the material's doubleSided property; when false, back face culling is disabled. Back faces are not culled if {@link Model#color} is translucent or {@link Model#silhouetteSize} is greater than 0.0. * @param {Boolean} [options.showOutline=true] Whether to display the outline for models using the {@link https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/CESIUM_primitive_outline|CESIUM_primitive_outline} extension. When true, outlines are displayed. When false, outlines are not displayed. @@ -1282,7 +1288,7 @@ Object.defineProperties(Model.prototype, { }, /** - * A URL to a KTX file that contains a cube map of the specular lighting and the convoluted specular mipmaps. + * A URL to a KTX2 file that contains a cube map of the specular lighting and the convoluted specular mipmaps. * * @memberof Model.prototype * @demo {@link https://sandcastle.cesium.com/index.html?src=Image-Based Lighting.html|Sandcastle Image Based Lighting Demo} @@ -1378,6 +1384,8 @@ function containsGltfMagic(uint8Array) { * {@link https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_techniques_webgl/README.md|KHR_techniques_webgl} *

  • * {@link https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_texture_transform/README.md|KHR_texture_transform} + *
  • + * {@link https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_texture_basisu/README.md|KHR_texture_basisu} *
  • * *

    @@ -1950,6 +1958,18 @@ function imageLoad(model, textureId) { return function (image) { var loadResources = model._loadResources; --loadResources.pendingTextureLoads; + + // Images transcoded from KTX2 can contain multiple mip levels: + // https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_texture_basisu + var mipLevels; + if (Array.isArray(image)) { + // highest detail mip should be level 0 + mipLevels = image.slice(1, image.length).map(function (mipLevel) { + return mipLevel.bufferView; + }); + image = image[0]; + } + loadResources.texturesToCreate.enqueue({ id: textureId, image: image, @@ -1957,12 +1977,12 @@ function imageLoad(model, textureId) { width: image.width, height: image.height, internalFormat: image.internalFormat, + mipLevels: mipLevels, }); }; } -var ktxRegex = /(^data:image\/ktx)|(\.ktx$)/i; -var crnRegex = /(^data:image\/crn)|(\.crn$)/i; +var ktx2Regex = /(^data:image\/ktx2)|(\.ktx2$)/i; function parseTextures(model, context, supportsWebP) { var gltf = model.gltf; @@ -1977,53 +1997,20 @@ function parseTextures(model, context, supportsWebP) { supportsWebP ) { imageId = texture.extensions.EXT_texture_webp.source; + } else if ( + defined(texture.extensions) && + defined(texture.extensions.KHR_texture_basisu) && + context.supportsBasis + ) { + imageId = texture.extensions.KHR_texture_basisu.source; } var gltfImage = images[imageId]; - var extras = gltfImage.extras; var bufferViewId = gltfImage.bufferView; var mimeType = gltfImage.mimeType; uri = gltfImage.uri; - // First check for a compressed texture - if (defined(extras) && defined(extras.compressedImage3DTiles)) { - var crunch = extras.compressedImage3DTiles.crunch; - var s3tc = extras.compressedImage3DTiles.s3tc; - var pvrtc = extras.compressedImage3DTiles.pvrtc1; - var etc1 = extras.compressedImage3DTiles.etc1; - - if (context.s3tc && defined(crunch)) { - mimeType = crunch.mimeType; - if (defined(crunch.bufferView)) { - bufferViewId = crunch.bufferView; - } else { - uri = crunch.uri; - } - } else if (context.s3tc && defined(s3tc)) { - mimeType = s3tc.mimeType; - if (defined(s3tc.bufferView)) { - bufferViewId = s3tc.bufferView; - } else { - uri = s3tc.uri; - } - } else if (context.pvrtc && defined(pvrtc)) { - mimeType = pvrtc.mimeType; - if (defined(pvrtc.bufferView)) { - bufferViewId = pvrtc.bufferView; - } else { - uri = pvrtc.uri; - } - } else if (context.etc1 && defined(etc1)) { - mimeType = etc1.mimeType; - if (defined(etc1.bufferView)) { - bufferViewId = etc1.bufferView; - } else { - uri = etc1.uri; - } - } - } - // Image references either uri (external or base64-encoded) or bufferView if (defined(bufferViewId)) { model._loadResources.texturesToCreateFromBufferView.enqueue({ @@ -2040,10 +2027,8 @@ function parseTextures(model, context, supportsWebP) { }); var promise; - if (ktxRegex.test(uri)) { - promise = loadKTX(imageResource); - } else if (crnRegex.test(uri)) { - promise = loadCRN(imageResource); + if (ktx2Regex.test(uri)) { + promise = loadKTX2(imageResource); } else { promise = imageResource.fetchImage({ skipColorSpaceConversion: true, @@ -2779,13 +2764,13 @@ function loadTexturesFromBufferViews(model) { "id: " + gltfTexture.id + ", bufferView: " + gltfTexture.bufferView ); - if (gltfTexture.mimeType === "image/ktx") { - loadKTX(loadResources.getBuffer(bufferView)) - .then(imageLoad(model, gltfTexture.id, imageId)) - .otherwise(onerror); - ++model._loadResources.pendingTextureLoads; - } else if (gltfTexture.mimeType === "image/crn") { - loadCRN(loadResources.getBuffer(bufferView)) + if (gltfTexture.mimeType === "image/ktx2") { + // Need to make a copy of the embedded KTX2 buffer otherwise the underlying + // ArrayBuffer may be accessed on both the worker and the main thread and + // throw an error like "Cannot perform Construct on a detached ArrayBuffer". + // Look into SharedArrayBuffer at some point to get around this. + var ktxBuffer = new Uint8Array(loadResources.getBuffer(bufferView)); + loadKTX2(ktxBuffer) .then(imageLoad(model, gltfTexture.id, imageId)) .otherwise(onerror); ++model._loadResources.pendingTextureLoads; @@ -2907,8 +2892,8 @@ function createTexture(gltfTexture, model, context) { sampler = new Sampler({ wrapS: sampler.wrapS, wrapT: sampler.wrapT, - textureMinificationFilter: minFilter, - textureMagnificationFilter: sampler.magnificationFilter, + minificationFilter: minFilter, + magnificationFilter: sampler.magnificationFilter, }); } @@ -2928,15 +2913,53 @@ function createTexture(gltfTexture, model, context) { wrapS === TextureWrap.MIRRORED_REPEAT || wrapT === TextureWrap.REPEAT || wrapT === TextureWrap.MIRRORED_REPEAT; - + var npot; var tx; var source = gltfTexture.image; if (defined(internalFormat)) { + npot = + !CesiumMath.isPowerOfTwo(gltfTexture.width) || + !CesiumMath.isPowerOfTwo(gltfTexture.height); + + // Warning to encourage power of 2 texture dimensions with KHR_texture_basisu + if ( + !context.webgl2 && + PixelFormat.isCompressedFormat(internalFormat) && + npot && + requiresNpot + ) { + console.warn( + "Compressed texture uses REPEAT or MIRRORED_REPEAT texture wrap mode and dimensions are not powers of two. The texture may be rendered incorrectly. See the Model.js constructor documentation for more information." + ); + } + + var minificationFilter; + if ( + !defined(gltfTexture.mipLevels) && + (minFilter === TextureMinificationFilter.NEAREST_MIPMAP_NEAREST || + minFilter === TextureMinificationFilter.NEAREST_MIPMAP_LINEAR) + ) { + minificationFilter = TextureMinificationFilter.NEAREST; + } else if ( + !defined(gltfTexture.mipLevels) && + (minFilter === TextureMinificationFilter.LINEAR_MIPMAP_NEAREST || + minFilter === TextureMinificationFilter.LINEAR_MIPMAP_LINEAR) + ) { + minificationFilter = TextureMinificationFilter.LINEAR; + } + sampler = new Sampler({ + wrapS: sampler.wrapS, + wrapT: sampler.wrapT, + minificationFilter: minificationFilter, + magnificationFilter: sampler.magnificationFilter, + }); + tx = new Texture({ context: context, source: { arrayBufferView: gltfTexture.bufferView, + mipLevels: gltfTexture.mipLevels, }, width: gltfTexture.width, height: gltfTexture.height, @@ -2944,10 +2967,9 @@ function createTexture(gltfTexture, model, context) { sampler: sampler, }); } else if (defined(source)) { - var npot = + npot = !CesiumMath.isPowerOfTwo(source.width) || !CesiumMath.isPowerOfTwo(source.height); - if (requiresNpot && npot) { // WebGL requires power-of-two texture dimensions for mipmapping and REPEAT/MIRRORED_REPEAT wrap modes. var canvas = document.createElement("canvas"); @@ -5167,11 +5189,12 @@ Model.prototype.update = function (frameState) { FeatureDetection.supportsWebP.initialize(); return; } - var supportsWebP = FeatureDetection.supportsWebP(); var context = frameState.context; this._defaultTexture = context.defaultTexture; + var supportsWebP = FeatureDetection.supportsWebP(); + if (this._state === ModelState.NEEDS_LOAD && defined(this.gltf)) { // Use renderer resources from cache instead of loading/creating them? var cachedRendererResources; diff --git a/Source/Scene/ModelInstanceCollection.js b/Source/Scene/ModelInstanceCollection.js index d48931153d10..a84a53becbfa 100644 --- a/Source/Scene/ModelInstanceCollection.js +++ b/Source/Scene/ModelInstanceCollection.js @@ -62,7 +62,7 @@ var LoadState = { * @param {Cartesian3} [options.lightColor] The light color when shading models. When undefined the scene's light color is used instead. * @param {Number} [options.luminanceAtZenith=0.2] The sun's luminance at the zenith in kilo candela per meter squared to use for this model's procedural environment map. * @param {Cartesian3[]} [options.sphericalHarmonicCoefficients] The third order spherical harmonic coefficients used for the diffuse color of image-based lighting. - * @param {String} [options.specularEnvironmentMaps] A URL to a KTX file that contains a cube map of the specular lighting and the convoluted specular mipmaps. + * @param {String} [options.specularEnvironmentMaps] A URL to a KTX2 file that contains a cube map of the specular lighting and the convoluted specular mipmaps. * @param {Boolean} [options.backFaceCulling=true] Whether to cull back-facing geometry. When true, back face culling is determined by the glTF material's doubleSided property; when false, back face culling is disabled. * @param {Boolean} [options.debugShowBoundingVolume=false] For debugging only. Draws the bounding sphere for the collection. * @param {Boolean} [options.debugWireframe=false] For debugging only. Draws the instances in wireframe. diff --git a/Source/Scene/ModelUtility.js b/Source/Scene/ModelUtility.js index e2948c84b26d..6822468d584a 100644 --- a/Source/Scene/ModelUtility.js +++ b/Source/Scene/ModelUtility.js @@ -564,6 +564,7 @@ ModelUtility.supportedExtensions = { EXT_texture_webp: true, KHR_blend: true, KHR_binary_glTF: true, + KHR_texture_basisu: true, KHR_draco_mesh_compression: true, KHR_materials_common: true, KHR_techniques_webgl: true, diff --git a/Source/Scene/OctahedralProjectedCubeMap.js b/Source/Scene/OctahedralProjectedCubeMap.js index 1de61027cc73..fc721c3ab71c 100644 --- a/Source/Scene/OctahedralProjectedCubeMap.js +++ b/Source/Scene/OctahedralProjectedCubeMap.js @@ -3,7 +3,7 @@ import ComponentDatatype from "../Core/ComponentDatatype.js"; import defined from "../Core/defined.js"; import destroyObject from "../Core/destroyObject.js"; import IndexDatatype from "../Core/IndexDatatype.js"; -import loadKTX from "../Core/loadKTX.js"; +import loadKTX2 from "../Core/loadKTX2.js"; import PixelFormat from "../Core/PixelFormat.js"; import Buffer from "../Renderer/Buffer.js"; import BufferUsage from "../Renderer/BufferUsage.js"; @@ -11,6 +11,7 @@ import ComputeCommand from "../Renderer/ComputeCommand.js"; import CubeMap from "../Renderer/CubeMap.js"; import PixelDatatype from "../Renderer/PixelDatatype.js"; import ShaderProgram from "../Renderer/ShaderProgram.js"; +import ShaderSource from "../Renderer/ShaderSource.js"; import Texture from "../Renderer/Texture.js"; import VertexArray from "../Renderer/VertexArray.js"; import OctahedralProjectionAtlasFS from "../Shaders/OctahedralProjectionAtlasFS.js"; @@ -47,7 +48,7 @@ function OctahedralProjectedCubeMap(url) { Object.defineProperties(OctahedralProjectedCubeMap.prototype, { /** - * The url to the KTX file containing the specular environment map and convoluted mipmaps. + * The url to the KTX2 file containing the specular environment map and convoluted mipmaps. * @memberof OctahedralProjectedCubeMap.prototype * @type {String} * @readonly @@ -290,7 +291,7 @@ OctahedralProjectedCubeMap.prototype.update = function (frameState) { var cubeMapBuffers = this._cubeMapBuffers; if (!defined(cubeMapBuffers) && !this._loading) { var that = this; - loadKTX(this._url) + loadKTX2(this._url) .then(function (buffers) { that._cubeMapBuffers = buffers; that._loading = false; @@ -302,11 +303,28 @@ OctahedralProjectedCubeMap.prototype.update = function (frameState) { return; } + var defines = []; + // Datatype is defined if it is a normalized type (i.e. ..._UNORM, ..._SFLOAT) + var pixelDatatype = cubeMapBuffers[0].positiveX.pixelDatatype; + if (!defined(pixelDatatype)) { + pixelDatatype = context.halfFloatingPointTexture + ? PixelDatatype.HALF_FLOAT + : PixelDatatype.FLOAT; + } else { + defines.push("RGBA_NORMALIZED"); + } + var pixelFormat = PixelFormat.RGBA; + + var fs = new ShaderSource({ + defines: defines, + sources: [OctahedralProjectionFS], + }); + this._va = createVertexArray(context); this._sp = ShaderProgram.fromCache({ context: context, vertexShaderSource: OctahedralProjectionVS, - fragmentShaderSource: OctahedralProjectionFS, + fragmentShaderSource: fs, attributeLocations: { position: 0, cubeMapCoordinates: 1, @@ -325,11 +343,6 @@ OctahedralProjectedCubeMap.prototype.update = function (frameState) { }, }; - var pixelDatatype = context.halfFloatingPointTexture - ? PixelDatatype.HALF_FLOAT - : PixelDatatype.FLOAT; - var pixelFormat = PixelFormat.RGBA; - // First we project each cubemap onto a flat octahedron, and write that to a texture. for (var i = 0; i < length; ++i) { // Swap +Y/-Y faces since the octahedral projection expects this order. @@ -340,6 +353,7 @@ OctahedralProjectedCubeMap.prototype.update = function (frameState) { var cubeMap = (cubeMaps[i] = new CubeMap({ context: context, source: cubeMapBuffers[i], + pixelDatatype: pixelDatatype, })); var size = cubeMaps[i].width * 2; diff --git a/Source/Scene/ResourceCache.js b/Source/Scene/ResourceCache.js index e5301bf6f4ad..848f3938ee76 100644 --- a/Source/Scene/ResourceCache.js +++ b/Source/Scene/ResourceCache.js @@ -587,7 +587,6 @@ ResourceCache.loadIndexBuffer = function (options) { * @param {Number} options.imageId The image ID. * @param {Resource} options.gltfResource The {@link Resource} containing the glTF. * @param {Resource} options.baseResource The {@link Resource} that paths in the glTF JSON are relative to. - * @param {SupportedImageFormats} options.supportedImageFormats The supported image formats. * * @returns {GltfImageLoader} The image loader. * @private @@ -598,14 +597,12 @@ ResourceCache.loadImage = function (options) { var imageId = options.imageId; var gltfResource = options.gltfResource; var baseResource = options.baseResource; - var supportedImageFormats = options.supportedImageFormats; //>>includeStart('debug', pragmas.debug); Check.typeOf.object("options.gltf", gltf); Check.typeOf.number("options.imageId", imageId); Check.typeOf.object("options.gltfResource", gltfResource); Check.typeOf.object("options.baseResource", baseResource); - Check.typeOf.object("options.supportedImageFormats", supportedImageFormats); //>>includeEnd('debug'); var cacheKey = ResourceCacheKey.getImageCacheKey({ @@ -613,7 +610,6 @@ ResourceCache.loadImage = function (options) { imageId: imageId, gltfResource: gltfResource, baseResource: baseResource, - supportedImageFormats: supportedImageFormats, }); var imageLoader = ResourceCache.get(cacheKey); @@ -627,7 +623,6 @@ ResourceCache.loadImage = function (options) { imageId: imageId, gltfResource: gltfResource, baseResource: baseResource, - supportedImageFormats: supportedImageFormats, cacheKey: cacheKey, }); diff --git a/Source/Scene/ResourceCacheKey.js b/Source/Scene/ResourceCacheKey.js index 0af7bf75a66f..deaa8fc8290f 100644 --- a/Source/Scene/ResourceCacheKey.js +++ b/Source/Scene/ResourceCacheKey.js @@ -70,21 +70,10 @@ function getDracoCacheKey(gltf, draco, gltfResource, baseResource) { return bufferCacheKey + "-range-" + bufferViewCacheKey; } -function getImageCacheKey( - gltf, - imageId, - gltfResource, - baseResource, - supportedImageFormats -) { - var results = GltfLoaderUtil.getImageUriOrBufferView({ - gltf: gltf, - imageId: imageId, - supportedImageFormats: supportedImageFormats, - }); - - var bufferViewId = results.bufferViewId; - var uri = results.uri; +function getImageCacheKey(gltf, imageId, gltfResource, baseResource) { + var image = gltf.images[imageId]; + var bufferViewId = image.bufferView; + var uri = image.uri; if (defined(uri)) { var resource = baseResource.getDerivedResource({ @@ -441,7 +430,6 @@ ResourceCacheKey.getIndexBufferCacheKey = function (options) { * @param {Number} options.imageId The image ID. * @param {Resource} options.gltfResource The {@link Resource} containing the glTF. * @param {Resource} options.baseResource The {@link Resource} that paths in the glTF JSON are relative to. - * @param {SupportedImageFormats} options.supportedImageFormats The supported image formats. * * @returns {String} The image cache key. * @private @@ -452,22 +440,19 @@ ResourceCacheKey.getImageCacheKey = function (options) { var imageId = options.imageId; var gltfResource = options.gltfResource; var baseResource = options.baseResource; - var supportedImageFormats = options.supportedImageFormats; //>>includeStart('debug', pragmas.debug); Check.typeOf.object("options.gltf", gltf); Check.typeOf.number("options.imageId", imageId); Check.typeOf.object("options.gltfResource", gltfResource); Check.typeOf.object("options.baseResource", baseResource); - Check.typeOf.object("options.supportedImageFormats", supportedImageFormats); //>>includeEnd('debug'); var imageCacheKey = getImageCacheKey( gltf, imageId, gltfResource, - baseResource, - supportedImageFormats + baseResource ); return "image:" + imageCacheKey; @@ -514,8 +499,7 @@ ResourceCacheKey.getTextureCacheKey = function (options) { gltf, imageId, gltfResource, - baseResource, - supportedImageFormats + baseResource ); // Include the sampler cache key in the texture cache key since textures and diff --git a/Source/Scene/Scene.js b/Source/Scene/Scene.js index 4bb114c62c9c..eed0e095698f 100644 --- a/Source/Scene/Scene.js +++ b/Source/Scene/Scene.js @@ -750,7 +750,7 @@ function Scene(options) { this.sphericalHarmonicCoefficients = undefined; /** - * The url to the KTX file containing the specular environment map and convoluted mipmaps for image-based lighting of PBR models. + * The url to the KTX2 file containing the specular environment map and convoluted mipmaps for image-based lighting of PBR models. * @type {String} */ this.specularEnvironmentMaps = undefined; @@ -1695,8 +1695,14 @@ Scene.prototype.getCompressedTextureFormatSupported = function (format) { context.s3tc) || ((format === "WEBGL_compressed_texture_pvrtc" || format === "pvrtc") && context.pvrtc) || + ((format === "WEBGL_compressed_texture_etc" || format === "etc") && + context.etc) || ((format === "WEBGL_compressed_texture_etc1" || format === "etc1") && - context.etc1) + context.etc1) || + ((format === "WEBGL_compressed_texture_astc" || format === "astc") && + context.astc) || + ((format === "EXT_texture_compression_bptc" || format === "bc7") && + context.bc7) ); }; diff --git a/Source/Scene/SupportedImageFormats.js b/Source/Scene/SupportedImageFormats.js index ed090851448b..ce95038bea1d 100644 --- a/Source/Scene/SupportedImageFormats.js +++ b/Source/Scene/SupportedImageFormats.js @@ -5,16 +5,12 @@ import defaultValue from "../Core/defaultValue.js"; * * @param {Object} [options] Object with the following properties: * @param {Boolean} [options.webp=false] Whether the browser supports WebP images. - * @param {Boolean} [options.s3tc=false] Whether the browser supports s3tc compressed images. - * @param {Boolean} [options.pvrtc=false] Whether the browser supports pvrtc compressed images. - * @param {Boolean} [options.etc1=false] Whether the browser supports etc1 compressed images. + * @param {Boolean} [options.basis=false] Whether the browser supports compressed textures required to view KTX2 + Basis Universal images. * * @private */ export default function SupportedImageFormats(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); this.webp = defaultValue(options.webp, false); - this.s3tc = defaultValue(options.s3tc, false); - this.pvrtc = defaultValue(options.pvrtc, false); - this.etc1 = defaultValue(options.etc1, false); + this.basis = defaultValue(options.basis, false); } diff --git a/Source/Shaders/Builtin/Functions/sphericalHarmonics.glsl b/Source/Shaders/Builtin/Functions/sphericalHarmonics.glsl index 21a2cf67b57b..71a240ebf352 100644 --- a/Source/Shaders/Builtin/Functions/sphericalHarmonics.glsl +++ b/Source/Shaders/Builtin/Functions/sphericalHarmonics.glsl @@ -15,12 +15,6 @@ */ vec3 czm_sphericalHarmonics(vec3 normal, vec3 coefficients[9]) { - const float c1 = 0.429043; - const float c2 = 0.511664; - const float c3 = 0.743125; - const float c4 = 0.886227; - const float c5 = 0.247708; - vec3 L00 = coefficients[0]; vec3 L1_1 = coefficients[1]; vec3 L10 = coefficients[2]; @@ -35,7 +29,14 @@ vec3 czm_sphericalHarmonics(vec3 normal, vec3 coefficients[9]) float y = normal.y; float z = normal.z; - return c1 * L22 * (x * x - y * y) + c3 * L20 * z * z + c4 * L00 - c5 * L20 + - 2.0 * c1 * (L2_2 * x * y + L21 * x * z + L2_1 * y * z) + - 2.0 * c2 * (L11 * x + L1_1 * y + L10 * z); + return + L00 + + L1_1 * y + + L10 * z + + L11 * x + + L2_2 * (y * x) + + L2_1 * (y * z) + + L20 * (3.0 * z * z - 1.0) + + L21 * (z * x) + + L22 * (x * x - y * y); } diff --git a/Source/Shaders/OctahedralProjectionFS.glsl b/Source/Shaders/OctahedralProjectionFS.glsl index 4b75a2ec45e9..dca8b7d8236a 100644 --- a/Source/Shaders/OctahedralProjectionFS.glsl +++ b/Source/Shaders/OctahedralProjectionFS.glsl @@ -3,8 +3,12 @@ uniform samplerCube cubeMap; void main() { - vec4 rgbm = textureCube(cubeMap, v_cubeMapCoordinates); - float m = rgbm.a * 16.0; - vec3 r = rgbm.rgb * m; - gl_FragColor = vec4(r * r, 1.0); + vec4 rgba = textureCube(cubeMap, v_cubeMapCoordinates); + #ifdef RGBA_NORMALIZED + gl_FragColor = vec4(rgba.rgb, 1.0); + #else + float m = rgba.a * 16.0; + vec3 r = rgba.rgb * m; + gl_FragColor = vec4(r * r, 1.0); + #endif } diff --git a/Source/ThirdParty/GltfPipeline/ForEach.js b/Source/ThirdParty/GltfPipeline/ForEach.js index f899c88c4ad4..4ddb3e959516 100644 --- a/Source/ThirdParty/GltfPipeline/ForEach.js +++ b/Source/ThirdParty/GltfPipeline/ForEach.js @@ -1,73 +1,89 @@ -import usesExtension from './usesExtension.js' -import defined from '../../Core/defined.js' - - /** - * Contains traversal functions for processing elements of the glTF hierarchy. - * @constructor - * - * @private - */ - function ForEach() { - } - - /** - * Fallback for glTF 1.0 - * @private - */ - ForEach.objectLegacy = function(objects, handler) { - if (defined(objects)) { - for (var objectId in objects) { - if (Object.prototype.hasOwnProperty.call(objects, objectId)) { - var object = objects[objectId]; - var value = handler(object, objectId); - - if (defined(value)) { - return value; - } - } - } - } - }; - - /** - * @private - */ - ForEach.object = function(arrayOfObjects, handler) { - if (defined(arrayOfObjects)) { - var length = arrayOfObjects.length; - for (var i = 0; i < length; i++) { - var object = arrayOfObjects[i]; - var value = handler(object, i); +import usesExtension from "./usesExtension.js" +import defined from "../../Core/defined.js" + +/** + * Contains traversal functions for processing elements of the glTF hierarchy. + * @constructor + * + * @private + */ +function ForEach() { +} + +/** + * Fallback for glTF 1.0 + * @private + */ +ForEach.objectLegacy = function(objects, handler) { + if (defined(objects)) { + for (var objectId in objects) { + if (Object.prototype.hasOwnProperty.call(objects, objectId)) { + var object = objects[objectId]; + var value = handler(object, objectId); if (defined(value)) { return value; } } } - }; - - /** - * Supports glTF 1.0 and 2.0 - * @private - */ - ForEach.topLevel = function(gltf, name, handler) { - var gltfProperty = gltf[name]; - if (defined(gltfProperty) && !Array.isArray(gltfProperty)) { - return ForEach.objectLegacy(gltfProperty, handler); + } +}; + +/** + * @private + */ +ForEach.object = function(arrayOfObjects, handler) { + if (defined(arrayOfObjects)) { + var length = arrayOfObjects.length; + for (var i = 0; i < length; i++) { + var object = arrayOfObjects[i]; + var value = handler(object, i); + + if (defined(value)) { + return value; + } } + } +}; + +/** + * Supports glTF 1.0 and 2.0 + * @private + */ +ForEach.topLevel = function(gltf, name, handler) { + var gltfProperty = gltf[name]; + if (defined(gltfProperty) && !Array.isArray(gltfProperty)) { + return ForEach.objectLegacy(gltfProperty, handler); + } + + return ForEach.object(gltfProperty, handler); +}; - return ForEach.object(gltfProperty, handler); - }; +ForEach.accessor = function(gltf, handler) { + return ForEach.topLevel(gltf, 'accessors', handler); +}; - ForEach.accessor = function(gltf, handler) { - return ForEach.topLevel(gltf, 'accessors', handler); - }; +ForEach.accessorWithSemantic = function(gltf, semantic, handler) { + var visited = {}; + return ForEach.mesh(gltf, function(mesh) { + return ForEach.meshPrimitive(mesh, function(primitive) { + var valueForEach = ForEach.meshPrimitiveAttribute(primitive, function(accessorId, attributeSemantic) { + if (attributeSemantic.indexOf(semantic) === 0 && !defined(visited[accessorId])) { + visited[accessorId] = true; + var value = handler(accessorId); - ForEach.accessorWithSemantic = function(gltf, semantic, handler) { - var visited = {}; - return ForEach.mesh(gltf, function(mesh) { - return ForEach.meshPrimitive(mesh, function(primitive) { - var valueForEach = ForEach.meshPrimitiveAttribute(primitive, function(accessorId, attributeSemantic) { + if (defined(value)) { + return value; + } + } + }); + + if (defined(valueForEach)) { + return valueForEach; + } + + return ForEach.meshPrimitiveTarget(primitive, function(target) { + return ForEach.meshPrimitiveTargetAttribute(target, function(accessorId, attributeSemantic) { if (attributeSemantic.indexOf(semantic) === 0 && !defined(visited[accessorId])) { visited[accessorId] = true; var value = handler(accessorId); @@ -77,32 +93,32 @@ import defined from '../../Core/defined.js' } } }); + }); + }); + }); +}; + +ForEach.accessorContainingVertexAttributeData = function(gltf, handler) { + var visited = {}; + return ForEach.mesh(gltf, function(mesh) { + return ForEach.meshPrimitive(mesh, function(primitive) { + var valueForEach = ForEach.meshPrimitiveAttribute(primitive, function(accessorId) { + if (!defined(visited[accessorId])) { + visited[accessorId] = true; + var value = handler(accessorId); - if (defined(valueForEach)) { - return valueForEach; + if (defined(value)) { + return value; + } } - - return ForEach.meshPrimitiveTarget(primitive, function(target) { - return ForEach.meshPrimitiveTargetAttribute(target, function(accessorId, attributeSemantic) { - if (attributeSemantic.indexOf(semantic) === 0 && !defined(visited[accessorId])) { - visited[accessorId] = true; - var value = handler(accessorId); - - if (defined(value)) { - return value; - } - } - }); - }); }); - }); - }; - ForEach.accessorContainingVertexAttributeData = function(gltf, handler) { - var visited = {}; - return ForEach.mesh(gltf, function(mesh) { - return ForEach.meshPrimitive(mesh, function(primitive) { - var valueForEach = ForEach.meshPrimitiveAttribute(primitive, function(accessorId) { + if (defined(valueForEach)) { + return valueForEach; + } + + return ForEach.meshPrimitiveTarget(primitive, function(target) { + return ForEach.meshPrimitiveTargetAttribute(target, function(accessorId) { if (!defined(visited[accessorId])) { visited[accessorId] = true; var value = handler(accessorId); @@ -112,300 +128,268 @@ import defined from '../../Core/defined.js' } } }); - - if (defined(valueForEach)) { - return valueForEach; - } - - return ForEach.meshPrimitiveTarget(primitive, function(target) { - return ForEach.meshPrimitiveTargetAttribute(target, function(accessorId) { - if (!defined(visited[accessorId])) { - visited[accessorId] = true; - var value = handler(accessorId); - - if (defined(value)) { - return value; - } - } - }); - }); - }); - }); - }; - - ForEach.accessorContainingIndexData = function(gltf, handler) { - var visited = {}; - return ForEach.mesh(gltf, function(mesh) { - return ForEach.meshPrimitive(mesh, function(primitive) { - var indices = primitive.indices; - if (defined(indices) && !defined(visited[indices])) { - visited[indices] = true; - var value = handler(indices); - - if (defined(value)) { - return value; - } - } }); }); - }; - - ForEach.animation = function(gltf, handler) { - return ForEach.topLevel(gltf, 'animations', handler); - }; - - ForEach.animationChannel = function(animation, handler) { - var channels = animation.channels; - return ForEach.object(channels, handler); - }; - - ForEach.animationSampler = function(animation, handler) { - var samplers = animation.samplers; - return ForEach.object(samplers, handler); - }; - - ForEach.buffer = function(gltf, handler) { - return ForEach.topLevel(gltf, 'buffers', handler); - }; - - ForEach.bufferView = function(gltf, handler) { - return ForEach.topLevel(gltf, 'bufferViews', handler); - }; - - ForEach.camera = function(gltf, handler) { - return ForEach.topLevel(gltf, 'cameras', handler); - }; - - ForEach.image = function(gltf, handler) { - return ForEach.topLevel(gltf, 'images', handler); - }; - - ForEach.compressedImage = function(image, handler) { - if (defined(image.extras)) { - var compressedImages = image.extras.compressedImage3DTiles; - for (var type in compressedImages) { - if (Object.prototype.hasOwnProperty.call(compressedImages, type)) { - var compressedImage = compressedImages[type]; - var value = handler(compressedImage, type); + }); +}; + +ForEach.accessorContainingIndexData = function(gltf, handler) { + var visited = {}; + return ForEach.mesh(gltf, function(mesh) { + return ForEach.meshPrimitive(mesh, function(primitive) { + var indices = primitive.indices; + if (defined(indices) && !defined(visited[indices])) { + visited[indices] = true; + var value = handler(indices); - if (defined(value)) { - return value; - } + if (defined(value)) { + return value; } } - } - }; + }); + }); +}; + +ForEach.animation = function(gltf, handler) { + return ForEach.topLevel(gltf, 'animations', handler); +}; + +ForEach.animationChannel = function(animation, handler) { + var channels = animation.channels; + return ForEach.object(channels, handler); +}; + +ForEach.animationSampler = function(animation, handler) { + var samplers = animation.samplers; + return ForEach.object(samplers, handler); +}; + +ForEach.buffer = function(gltf, handler) { + return ForEach.topLevel(gltf, 'buffers', handler); +}; + +ForEach.bufferView = function(gltf, handler) { + return ForEach.topLevel(gltf, 'bufferViews', handler); +}; + +ForEach.camera = function(gltf, handler) { + return ForEach.topLevel(gltf, 'cameras', handler); +}; + +ForEach.image = function(gltf, handler) { + return ForEach.topLevel(gltf, 'images', handler); +}; + +ForEach.material = function(gltf, handler) { + return ForEach.topLevel(gltf, 'materials', handler); +}; + +ForEach.materialValue = function(material, handler) { + var values = material.values; + if (defined(material.extensions) && defined(material.extensions.KHR_techniques_webgl)) { + values = material.extensions.KHR_techniques_webgl.values; + } - ForEach.material = function(gltf, handler) { - return ForEach.topLevel(gltf, 'materials', handler); - }; + for (var name in values) { + if (Object.prototype.hasOwnProperty.call(values, name)) { + var value = handler(values[name], name); - ForEach.materialValue = function(material, handler) { - var values = material.values; - if (defined(material.extensions) && defined(material.extensions.KHR_techniques_webgl)) { - values = material.extensions.KHR_techniques_webgl.values; + if (defined(value)) { + return value; + } } - - for (var name in values) { - if (Object.prototype.hasOwnProperty.call(values, name)) { - var value = handler(values[name], name); - - if (defined(value)) { - return value; - } + } +}; + +ForEach.mesh = function(gltf, handler) { + return ForEach.topLevel(gltf, 'meshes', handler); +}; + +ForEach.meshPrimitive = function(mesh, handler) { + var primitives = mesh.primitives; + if (defined(primitives)) { + var primitivesLength = primitives.length; + for (var i = 0; i < primitivesLength; i++) { + var primitive = primitives[i]; + var value = handler(primitive, i); + + if (defined(value)) { + return value; } } - }; - - ForEach.mesh = function(gltf, handler) { - return ForEach.topLevel(gltf, 'meshes', handler); - }; + } +}; - ForEach.meshPrimitive = function(mesh, handler) { - var primitives = mesh.primitives; - if (defined(primitives)) { - var primitivesLength = primitives.length; - for (var i = 0; i < primitivesLength; i++) { - var primitive = primitives[i]; - var value = handler(primitive, i); +ForEach.meshPrimitiveAttribute = function(primitive, handler) { + var attributes = primitive.attributes; + for (var semantic in attributes) { + if (Object.prototype.hasOwnProperty.call(attributes, semantic)) { + var value = handler(attributes[semantic], semantic); - if (defined(value)) { - return value; - } + if (defined(value)) { + return value; } } - }; + } +}; - ForEach.meshPrimitiveAttribute = function(primitive, handler) { - var attributes = primitive.attributes; - for (var semantic in attributes) { - if (Object.prototype.hasOwnProperty.call(attributes, semantic)) { - var value = handler(attributes[semantic], semantic); +ForEach.meshPrimitiveTarget = function(primitive, handler) { + var targets = primitive.targets; + if (defined(targets)) { + var length = targets.length; + for (var i = 0; i < length; ++i) { + var value = handler(targets[i], i); - if (defined(value)) { - return value; - } + if (defined(value)) { + return value; } } - }; + } +}; - ForEach.meshPrimitiveTarget = function(primitive, handler) { - var targets = primitive.targets; - if (defined(targets)) { - var length = targets.length; - for (var i = 0; i < length; ++i) { - var value = handler(targets[i], i); +ForEach.meshPrimitiveTargetAttribute = function(target, handler) { + for (var semantic in target) { + if (Object.prototype.hasOwnProperty.call(target, semantic)) { + var accessorId = target[semantic]; + var value = handler(accessorId, semantic); - if (defined(value)) { - return value; - } + if (defined(value)) { + return value; } } - }; - - ForEach.meshPrimitiveTargetAttribute = function(target, handler) { - for (var semantic in target) { - if (Object.prototype.hasOwnProperty.call(target, semantic)) { - var accessorId = target[semantic]; - var value = handler(accessorId, semantic); + } +}; + +ForEach.node = function(gltf, handler) { + return ForEach.topLevel(gltf, 'nodes', handler); +}; + +ForEach.nodeInTree = function(gltf, nodeIds, handler) { + var nodes = gltf.nodes; + if (defined(nodes)) { + var length = nodeIds.length; + for (var i = 0; i < length; i++) { + var nodeId = nodeIds[i]; + var node = nodes[nodeId]; + if (defined(node)) { + var value = handler(node, nodeId); if (defined(value)) { return value; } - } - } - }; - - ForEach.node = function(gltf, handler) { - return ForEach.topLevel(gltf, 'nodes', handler); - }; - - ForEach.nodeInTree = function(gltf, nodeIds, handler) { - var nodes = gltf.nodes; - if (defined(nodes)) { - var length = nodeIds.length; - for (var i = 0; i < length; i++) { - var nodeId = nodeIds[i]; - var node = nodes[nodeId]; - if (defined(node)) { - var value = handler(node, nodeId); + + var children = node.children; + if (defined(children)) { + value = ForEach.nodeInTree(gltf, children, handler); if (defined(value)) { return value; } - - var children = node.children; - if (defined(children)) { - value = ForEach.nodeInTree(gltf, children, handler); - - if (defined(value)) { - return value; - } - } } } } - }; + } +}; - ForEach.nodeInScene = function(gltf, scene, handler) { - var sceneNodeIds = scene.nodes; - if (defined(sceneNodeIds)) { - return ForEach.nodeInTree(gltf, sceneNodeIds, handler); - } - }; +ForEach.nodeInScene = function(gltf, scene, handler) { + var sceneNodeIds = scene.nodes; + if (defined(sceneNodeIds)) { + return ForEach.nodeInTree(gltf, sceneNodeIds, handler); + } +}; - ForEach.program = function(gltf, handler) { - if (usesExtension(gltf, 'KHR_techniques_webgl')) { - return ForEach.object(gltf.extensions.KHR_techniques_webgl.programs, handler); - } +ForEach.program = function(gltf, handler) { + if (usesExtension(gltf, 'KHR_techniques_webgl')) { + return ForEach.object(gltf.extensions.KHR_techniques_webgl.programs, handler); + } - return ForEach.topLevel(gltf, 'programs', handler); - }; + return ForEach.topLevel(gltf, 'programs', handler); +}; - ForEach.sampler = function(gltf, handler) { - return ForEach.topLevel(gltf, 'samplers', handler); - }; +ForEach.sampler = function(gltf, handler) { + return ForEach.topLevel(gltf, 'samplers', handler); +}; - ForEach.scene = function(gltf, handler) { - return ForEach.topLevel(gltf, 'scenes', handler); - }; +ForEach.scene = function(gltf, handler) { + return ForEach.topLevel(gltf, 'scenes', handler); +}; - ForEach.shader = function(gltf, handler) { - if (usesExtension(gltf, 'KHR_techniques_webgl')) { - return ForEach.object(gltf.extensions.KHR_techniques_webgl.shaders, handler); - } +ForEach.shader = function(gltf, handler) { + if (usesExtension(gltf, 'KHR_techniques_webgl')) { + return ForEach.object(gltf.extensions.KHR_techniques_webgl.shaders, handler); + } - return ForEach.topLevel(gltf, 'shaders', handler); - }; + return ForEach.topLevel(gltf, 'shaders', handler); +}; - ForEach.skin = function(gltf, handler) { - return ForEach.topLevel(gltf, 'skins', handler); - }; +ForEach.skin = function(gltf, handler) { + return ForEach.topLevel(gltf, 'skins', handler); +}; - ForEach.skinJoint = function(skin, handler) { - var joints = skin.joints; - if (defined(joints)) { - var jointsLength = joints.length; - for (var i = 0; i < jointsLength; i++) { - var joint = joints[i]; - var value = handler(joint); +ForEach.skinJoint = function(skin, handler) { + var joints = skin.joints; + if (defined(joints)) { + var jointsLength = joints.length; + for (var i = 0; i < jointsLength; i++) { + var joint = joints[i]; + var value = handler(joint); - if (defined(value)) { - return value; - } + if (defined(value)) { + return value; } } - }; + } +}; - ForEach.techniqueAttribute = function(technique, handler) { - var attributes = technique.attributes; - for (var attributeName in attributes) { - if (Object.prototype.hasOwnProperty.call(attributes, attributeName)) { - var value = handler(attributes[attributeName], attributeName); +ForEach.techniqueAttribute = function(technique, handler) { + var attributes = technique.attributes; + for (var attributeName in attributes) { + if (Object.prototype.hasOwnProperty.call(attributes, attributeName)) { + var value = handler(attributes[attributeName], attributeName); - if (defined(value)) { - return value; - } + if (defined(value)) { + return value; } } - }; + } +}; - ForEach.techniqueUniform = function(technique, handler) { - var uniforms = technique.uniforms; - for (var uniformName in uniforms) { - if (Object.prototype.hasOwnProperty.call(uniforms, uniformName)) { - var value = handler(uniforms[uniformName], uniformName); +ForEach.techniqueUniform = function(technique, handler) { + var uniforms = technique.uniforms; + for (var uniformName in uniforms) { + if (Object.prototype.hasOwnProperty.call(uniforms, uniformName)) { + var value = handler(uniforms[uniformName], uniformName); - if (defined(value)) { - return value; - } + if (defined(value)) { + return value; } } - }; + } +}; - ForEach.techniqueParameter = function(technique, handler) { - var parameters = technique.parameters; - for (var parameterName in parameters) { - if (Object.prototype.hasOwnProperty.call(parameters, parameterName)) { - var value = handler(parameters[parameterName], parameterName); +ForEach.techniqueParameter = function(technique, handler) { + var parameters = technique.parameters; + for (var parameterName in parameters) { + if (Object.prototype.hasOwnProperty.call(parameters, parameterName)) { + var value = handler(parameters[parameterName], parameterName); - if (defined(value)) { - return value; - } + if (defined(value)) { + return value; } } - }; + } +}; - ForEach.technique = function(gltf, handler) { - if (usesExtension(gltf, 'KHR_techniques_webgl')) { - return ForEach.object(gltf.extensions.KHR_techniques_webgl.techniques, handler); - } +ForEach.technique = function(gltf, handler) { + if (usesExtension(gltf, 'KHR_techniques_webgl')) { + return ForEach.object(gltf.extensions.KHR_techniques_webgl.techniques, handler); + } - return ForEach.topLevel(gltf, 'techniques', handler); - }; + return ForEach.topLevel(gltf, 'techniques', handler); +}; - ForEach.texture = function(gltf, handler) { - return ForEach.topLevel(gltf, 'textures', handler); - }; +ForEach.texture = function(gltf, handler) { + return ForEach.topLevel(gltf, 'textures', handler); +}; - export default ForEach; +export default ForEach; diff --git a/Source/ThirdParty/GltfPipeline/addBuffer.js b/Source/ThirdParty/GltfPipeline/addBuffer.js index 1f4041327164..3db4b61acc8b 100644 --- a/Source/ThirdParty/GltfPipeline/addBuffer.js +++ b/Source/ThirdParty/GltfPipeline/addBuffer.js @@ -1,30 +1,30 @@ -import addToArray from './addToArray.js' +import addToArray from "./addToArray.js" - /** - * Adds buffer to gltf. - * - * @param {Object} gltf A javascript object containing a glTF asset. - * @param {Buffer} buffer A Buffer object which will be added to gltf.buffers. - * @returns {Number} The bufferView id of the newly added bufferView. - * - * @private - */ - function addBuffer(gltf, buffer) { - var newBuffer = { - byteLength: buffer.length, - extras: { - _pipeline: { - source: buffer - } +/** + * Adds buffer to gltf. + * + * @param {Object} gltf A javascript object containing a glTF asset. + * @param {Buffer} buffer A Buffer object which will be added to gltf.buffers. + * @returns {Number} The bufferView id of the newly added bufferView. + * + * @private + */ +function addBuffer(gltf, buffer) { + var newBuffer = { + byteLength: buffer.length, + extras: { + _pipeline: { + source: buffer } - }; - var bufferId = addToArray(gltf.buffers, newBuffer); - var bufferView = { - buffer: bufferId, - byteOffset: 0, - byteLength: buffer.length - }; - return addToArray(gltf.bufferViews, bufferView); - } + } + }; + var bufferId = addToArray(gltf.buffers, newBuffer); + var bufferView = { + buffer: bufferId, + byteOffset: 0, + byteLength: buffer.length + }; + return addToArray(gltf.bufferViews, bufferView); +} - export default addBuffer; +export default addBuffer; diff --git a/Source/ThirdParty/GltfPipeline/addDefaults.js b/Source/ThirdParty/GltfPipeline/addDefaults.js index 231d955836c5..43b95a3d7dcb 100644 --- a/Source/ThirdParty/GltfPipeline/addDefaults.js +++ b/Source/ThirdParty/GltfPipeline/addDefaults.js @@ -1,181 +1,181 @@ -import addToArray from './addToArray.js' -import ForEach from './ForEach.js' -import getAccessorByteStride from './getAccessorByteStride.js' -import defaultValue from '../../Core/defaultValue.js' -import defined from '../../Core/defined.js' -import WebGLConstants from '../../Core/WebGLConstants.js' - - /** - * Adds default glTF values if they don't exist. - * - * @param {Object} gltf A javascript object containing a glTF asset. - * @returns {Object} The modified glTF. - * - * @private - */ - function addDefaults(gltf) { - ForEach.accessor(gltf, function(accessor) { - if (defined(accessor.bufferView)) { - accessor.byteOffset = defaultValue(accessor.byteOffset, 0); - } - }); - - ForEach.bufferView(gltf, function(bufferView) { - if (defined(bufferView.buffer)) { - bufferView.byteOffset = defaultValue(bufferView.byteOffset, 0); - } - }); +import addToArray from "./addToArray.js" +import ForEach from "./ForEach.js" +import getAccessorByteStride from "./getAccessorByteStride.js" +import defaultValue from "../../Core/defaultValue.js" +import defined from "../../Core/defined.js" +import WebGLConstants from "../../Core/WebGLConstants.js" + +/** + * Adds default glTF values if they don't exist. + * + * @param {Object} gltf A javascript object containing a glTF asset. + * @returns {Object} The modified glTF. + * + * @private + */ +function addDefaults(gltf) { + ForEach.accessor(gltf, function(accessor) { + if (defined(accessor.bufferView)) { + accessor.byteOffset = defaultValue(accessor.byteOffset, 0); + } + }); - ForEach.mesh(gltf, function(mesh) { - ForEach.meshPrimitive(mesh, function(primitive) { - primitive.mode = defaultValue(primitive.mode, WebGLConstants.TRIANGLES); - if (!defined(primitive.material)) { - if (!defined(gltf.materials)) { - gltf.materials = []; - } - var defaultMaterial = { - name: 'default' - }; - primitive.material = addToArray(gltf.materials, defaultMaterial); + ForEach.bufferView(gltf, function(bufferView) { + if (defined(bufferView.buffer)) { + bufferView.byteOffset = defaultValue(bufferView.byteOffset, 0); + } + }); + + ForEach.mesh(gltf, function(mesh) { + ForEach.meshPrimitive(mesh, function(primitive) { + primitive.mode = defaultValue(primitive.mode, WebGLConstants.TRIANGLES); + if (!defined(primitive.material)) { + if (!defined(gltf.materials)) { + gltf.materials = []; } - }); - }); - - ForEach.accessorContainingVertexAttributeData(gltf, function(accessorId) { - var accessor = gltf.accessors[accessorId]; - var bufferViewId = accessor.bufferView; - accessor.normalized = defaultValue(accessor.normalized, false); - if (defined(bufferViewId)) { - var bufferView = gltf.bufferViews[bufferViewId]; - bufferView.byteStride = getAccessorByteStride(gltf, accessor); - bufferView.target = WebGLConstants.ARRAY_BUFFER; + var defaultMaterial = { + name: 'default' + }; + primitive.material = addToArray(gltf.materials, defaultMaterial); } }); - - ForEach.accessorContainingIndexData(gltf, function(accessorId) { - var accessor = gltf.accessors[accessorId]; - var bufferViewId = accessor.bufferView; - if (defined(bufferViewId)) { - var bufferView = gltf.bufferViews[bufferViewId]; - bufferView.target = WebGLConstants.ELEMENT_ARRAY_BUFFER; - } - }); - - ForEach.material(gltf, function(material) { - var extensions = defaultValue(material.extensions, defaultValue.EMPTY_OBJECT); - var materialsCommon = extensions.KHR_materials_common; - if (defined(materialsCommon)) { - var technique = materialsCommon.technique; - var values = defined(materialsCommon.values) ? materialsCommon.values : {}; - materialsCommon.values = values; - - values.ambient = defined(values.ambient) ? values.ambient : [0.0, 0.0, 0.0, 1.0]; - values.emission = defined(values.emission) ? values.emission : [0.0, 0.0, 0.0, 1.0]; - - values.transparency = defaultValue(values.transparency, 1.0); - values.transparent = defaultValue(values.transparent, false); - values.doubleSided = defaultValue(values.doubleSided, false); - - if (technique !== 'CONSTANT') { - values.diffuse = defined(values.diffuse) ? values.diffuse : [0.0, 0.0, 0.0, 1.0]; - if (technique !== 'LAMBERT') { - values.specular = defined(values.specular) ? values.specular : [0.0, 0.0, 0.0, 1.0]; - values.shininess = defaultValue(values.shininess, 0.0); - } + }); + + ForEach.accessorContainingVertexAttributeData(gltf, function(accessorId) { + var accessor = gltf.accessors[accessorId]; + var bufferViewId = accessor.bufferView; + accessor.normalized = defaultValue(accessor.normalized, false); + if (defined(bufferViewId)) { + var bufferView = gltf.bufferViews[bufferViewId]; + bufferView.byteStride = getAccessorByteStride(gltf, accessor); + bufferView.target = WebGLConstants.ARRAY_BUFFER; + } + }); + + ForEach.accessorContainingIndexData(gltf, function(accessorId) { + var accessor = gltf.accessors[accessorId]; + var bufferViewId = accessor.bufferView; + if (defined(bufferViewId)) { + var bufferView = gltf.bufferViews[bufferViewId]; + bufferView.target = WebGLConstants.ELEMENT_ARRAY_BUFFER; + } + }); + + ForEach.material(gltf, function(material) { + var extensions = defaultValue(material.extensions, defaultValue.EMPTY_OBJECT); + var materialsCommon = extensions.KHR_materials_common; + if (defined(materialsCommon)) { + var technique = materialsCommon.technique; + var values = defined(materialsCommon.values) ? materialsCommon.values : {}; + materialsCommon.values = values; + + values.ambient = defined(values.ambient) ? values.ambient : [0.0, 0.0, 0.0, 1.0]; + values.emission = defined(values.emission) ? values.emission : [0.0, 0.0, 0.0, 1.0]; + + values.transparency = defaultValue(values.transparency, 1.0); + values.transparent = defaultValue(values.transparent, false); + values.doubleSided = defaultValue(values.doubleSided, false); + + if (technique !== 'CONSTANT') { + values.diffuse = defined(values.diffuse) ? values.diffuse : [0.0, 0.0, 0.0, 1.0]; + if (technique !== 'LAMBERT') { + values.specular = defined(values.specular) ? values.specular : [0.0, 0.0, 0.0, 1.0]; + values.shininess = defaultValue(values.shininess, 0.0); } - return; - } - - material.emissiveFactor = defaultValue(material.emissiveFactor, [0.0, 0.0, 0.0]); - material.alphaMode = defaultValue(material.alphaMode, 'OPAQUE'); - material.doubleSided = defaultValue(material.doubleSided, false); - - if (material.alphaMode === 'MASK') { - material.alphaCutoff = defaultValue(material.alphaCutoff, 0.5); - } - - var techniquesExtension = extensions.KHR_techniques_webgl; - if (defined(techniquesExtension)) { - ForEach.materialValue(material, function (materialValue) { - // Check if material value is a TextureInfo object - if (defined(materialValue.index)) { - addTextureDefaults(materialValue); - } - }); } + return; + } - addTextureDefaults(material.emissiveTexture); - addTextureDefaults(material.normalTexture); - addTextureDefaults(material.occlusionTexture); - - var pbrMetallicRoughness = material.pbrMetallicRoughness; - if (defined(pbrMetallicRoughness)) { - pbrMetallicRoughness.baseColorFactor = defaultValue(pbrMetallicRoughness.baseColorFactor, [1.0, 1.0, 1.0, 1.0]); - pbrMetallicRoughness.metallicFactor = defaultValue(pbrMetallicRoughness.metallicFactor, 1.0); - pbrMetallicRoughness.roughnessFactor = defaultValue(pbrMetallicRoughness.roughnessFactor, 1.0); - addTextureDefaults(pbrMetallicRoughness.baseColorTexture); - addTextureDefaults(pbrMetallicRoughness.metallicRoughnessTexture); - } + material.emissiveFactor = defaultValue(material.emissiveFactor, [0.0, 0.0, 0.0]); + material.alphaMode = defaultValue(material.alphaMode, 'OPAQUE'); + material.doubleSided = defaultValue(material.doubleSided, false); - var pbrSpecularGlossiness = extensions.KHR_materials_pbrSpecularGlossiness; - if (defined(pbrSpecularGlossiness)) { - pbrSpecularGlossiness.diffuseFactor = defaultValue(pbrSpecularGlossiness.diffuseFactor, [1.0, 1.0, 1.0, 1.0]); - pbrSpecularGlossiness.specularFactor = defaultValue(pbrSpecularGlossiness.specularFactor, [1.0, 1.0, 1.0]); - pbrSpecularGlossiness.glossinessFactor = defaultValue(pbrSpecularGlossiness.glossinessFactor, 1.0); - addTextureDefaults(pbrSpecularGlossiness.specularGlossinessTexture); - } - }); + if (material.alphaMode === 'MASK') { + material.alphaCutoff = defaultValue(material.alphaCutoff, 0.5); + } - ForEach.animation(gltf, function(animation) { - ForEach.animationSampler(animation, function(sampler) { - sampler.interpolation = defaultValue(sampler.interpolation, 'LINEAR'); + var techniquesExtension = extensions.KHR_techniques_webgl; + if (defined(techniquesExtension)) { + ForEach.materialValue(material, function (materialValue) { + // Check if material value is a TextureInfo object + if (defined(materialValue.index)) { + addTextureDefaults(materialValue); + } }); - }); + } - var animatedNodes = getAnimatedNodes(gltf); - ForEach.node(gltf, function(node, id) { - var animated = defined(animatedNodes[id]); - if (animated || defined(node.translation) || defined(node.rotation) || defined(node.scale)) { - node.translation = defaultValue(node.translation, [0.0, 0.0, 0.0]); - node.rotation = defaultValue(node.rotation, [0.0, 0.0, 0.0, 1.0]); - node.scale = defaultValue(node.scale, [1.0, 1.0, 1.0]); - } else { - node.matrix = defaultValue(node.matrix, [1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0]); - } - }); + addTextureDefaults(material.emissiveTexture); + addTextureDefaults(material.normalTexture); + addTextureDefaults(material.occlusionTexture); + + var pbrMetallicRoughness = material.pbrMetallicRoughness; + if (defined(pbrMetallicRoughness)) { + pbrMetallicRoughness.baseColorFactor = defaultValue(pbrMetallicRoughness.baseColorFactor, [1.0, 1.0, 1.0, 1.0]); + pbrMetallicRoughness.metallicFactor = defaultValue(pbrMetallicRoughness.metallicFactor, 1.0); + pbrMetallicRoughness.roughnessFactor = defaultValue(pbrMetallicRoughness.roughnessFactor, 1.0); + addTextureDefaults(pbrMetallicRoughness.baseColorTexture); + addTextureDefaults(pbrMetallicRoughness.metallicRoughnessTexture); + } - ForEach.sampler(gltf, function(sampler) { - sampler.wrapS = defaultValue(sampler.wrapS, WebGLConstants.REPEAT); - sampler.wrapT = defaultValue(sampler.wrapT, WebGLConstants.REPEAT); - }); + var pbrSpecularGlossiness = extensions.KHR_materials_pbrSpecularGlossiness; + if (defined(pbrSpecularGlossiness)) { + pbrSpecularGlossiness.diffuseFactor = defaultValue(pbrSpecularGlossiness.diffuseFactor, [1.0, 1.0, 1.0, 1.0]); + pbrSpecularGlossiness.specularFactor = defaultValue(pbrSpecularGlossiness.specularFactor, [1.0, 1.0, 1.0]); + pbrSpecularGlossiness.glossinessFactor = defaultValue(pbrSpecularGlossiness.glossinessFactor, 1.0); + addTextureDefaults(pbrSpecularGlossiness.specularGlossinessTexture); + } + }); - if (defined(gltf.scenes) && !defined(gltf.scene)) { - gltf.scene = 0; + ForEach.animation(gltf, function(animation) { + ForEach.animationSampler(animation, function(sampler) { + sampler.interpolation = defaultValue(sampler.interpolation, 'LINEAR'); + }); + }); + + var animatedNodes = getAnimatedNodes(gltf); + ForEach.node(gltf, function(node, id) { + var animated = defined(animatedNodes[id]); + if (animated || defined(node.translation) || defined(node.rotation) || defined(node.scale)) { + node.translation = defaultValue(node.translation, [0.0, 0.0, 0.0]); + node.rotation = defaultValue(node.rotation, [0.0, 0.0, 0.0, 1.0]); + node.scale = defaultValue(node.scale, [1.0, 1.0, 1.0]); + } else { + node.matrix = defaultValue(node.matrix, [1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0]); } + }); + + ForEach.sampler(gltf, function(sampler) { + sampler.wrapS = defaultValue(sampler.wrapS, WebGLConstants.REPEAT); + sampler.wrapT = defaultValue(sampler.wrapT, WebGLConstants.REPEAT); + }); - return gltf; + if (defined(gltf.scenes) && !defined(gltf.scene)) { + gltf.scene = 0; } - function getAnimatedNodes(gltf) { - var nodes = {}; - ForEach.animation(gltf, function(animation) { - ForEach.animationChannel(animation, function(channel) { - var target = channel.target; - var nodeId = target.node; - var path = target.path; - // Ignore animations that target 'weights' - if (path === 'translation' || path === 'rotation' || path === 'scale') { - nodes[nodeId] = true; - } - }); + return gltf; +} + +function getAnimatedNodes(gltf) { + var nodes = {}; + ForEach.animation(gltf, function(animation) { + ForEach.animationChannel(animation, function(channel) { + var target = channel.target; + var nodeId = target.node; + var path = target.path; + // Ignore animations that target 'weights' + if (path === 'translation' || path === 'rotation' || path === 'scale') { + nodes[nodeId] = true; + } }); - return nodes; - } + }); + return nodes; +} - function addTextureDefaults(texture) { - if (defined(texture)) { - texture.texCoord = defaultValue(texture.texCoord, 0); - } +function addTextureDefaults(texture) { + if (defined(texture)) { + texture.texCoord = defaultValue(texture.texCoord, 0); } +} - export default addDefaults; +export default addDefaults; diff --git a/Source/ThirdParty/GltfPipeline/addExtensionsRequired.js b/Source/ThirdParty/GltfPipeline/addExtensionsRequired.js index c830658845e8..a0c605a92240 100644 --- a/Source/ThirdParty/GltfPipeline/addExtensionsRequired.js +++ b/Source/ThirdParty/GltfPipeline/addExtensionsRequired.js @@ -1,24 +1,24 @@ -import addExtensionsUsed from './addExtensionsUsed.js' -import addToArray from './addToArray.js' -import defined from '../../Core/defined.js' +import addExtensionsUsed from "./addExtensionsUsed.js" +import addToArray from "./addToArray.js" +import defined from "../../Core/defined.js" - /** - * Adds an extension to gltf.extensionsRequired if it does not already exist. - * Initializes extensionsRequired if it is not defined. - * - * @param {Object} gltf A javascript object containing a glTF asset. - * @param {String} extension The extension to add. - * - * @private - */ - function addExtensionsRequired(gltf, extension) { - var extensionsRequired = gltf.extensionsRequired; - if (!defined(extensionsRequired)) { - extensionsRequired = []; - gltf.extensionsRequired = extensionsRequired; - } - addToArray(extensionsRequired, extension, true); - addExtensionsUsed(gltf, extension); +/** + * Adds an extension to gltf.extensionsRequired if it does not already exist. + * Initializes extensionsRequired if it is not defined. + * + * @param {Object} gltf A javascript object containing a glTF asset. + * @param {String} extension The extension to add. + * + * @private + */ +function addExtensionsRequired(gltf, extension) { + var extensionsRequired = gltf.extensionsRequired; + if (!defined(extensionsRequired)) { + extensionsRequired = []; + gltf.extensionsRequired = extensionsRequired; } + addToArray(extensionsRequired, extension, true); + addExtensionsUsed(gltf, extension); +} - export default addExtensionsRequired; +export default addExtensionsRequired; diff --git a/Source/ThirdParty/GltfPipeline/addExtensionsUsed.js b/Source/ThirdParty/GltfPipeline/addExtensionsUsed.js index 9c3d53db788b..d035ace73996 100644 --- a/Source/ThirdParty/GltfPipeline/addExtensionsUsed.js +++ b/Source/ThirdParty/GltfPipeline/addExtensionsUsed.js @@ -1,22 +1,22 @@ -import addToArray from './addToArray.js' -import defined from '../../Core/defined.js' +import addToArray from "./addToArray.js" +import defined from "../../Core/defined.js" - /** - * Adds an extension to gltf.extensionsUsed if it does not already exist. - * Initializes extensionsUsed if it is not defined. - * - * @param {Object} gltf A javascript object containing a glTF asset. - * @param {String} extension The extension to add. - * - * @private - */ - function addExtensionsUsed(gltf, extension) { - var extensionsUsed = gltf.extensionsUsed; - if (!defined(extensionsUsed)) { - extensionsUsed = []; - gltf.extensionsUsed = extensionsUsed; - } - addToArray(extensionsUsed, extension, true); +/** + * Adds an extension to gltf.extensionsUsed if it does not already exist. + * Initializes extensionsUsed if it is not defined. + * + * @param {Object} gltf A javascript object containing a glTF asset. + * @param {String} extension The extension to add. + * + * @private + */ +function addExtensionsUsed(gltf, extension) { + var extensionsUsed = gltf.extensionsUsed; + if (!defined(extensionsUsed)) { + extensionsUsed = []; + gltf.extensionsUsed = extensionsUsed; } + addToArray(extensionsUsed, extension, true); +} - export default addExtensionsUsed; +export default addExtensionsUsed; diff --git a/Source/ThirdParty/GltfPipeline/addPipelineExtras.js b/Source/ThirdParty/GltfPipeline/addPipelineExtras.js index 2fb06c36bf41..91eb2df1e4aa 100644 --- a/Source/ThirdParty/GltfPipeline/addPipelineExtras.js +++ b/Source/ThirdParty/GltfPipeline/addPipelineExtras.js @@ -1,37 +1,34 @@ -import ForEach from './ForEach.js' -import defined from '../../Core/defined.js' +import ForEach from "./ForEach.js" +import defined from "../../Core/defined.js" - /** - * Adds extras._pipeline to each object that can have extras in the glTF asset. - * This stage runs before updateVersion and handles both glTF 1.0 and glTF 2.0 assets. - * - * @param {Object} gltf A javascript object containing a glTF asset. - * @returns {Object} The glTF asset with the added pipeline extras. - * - * @private - */ - function addPipelineExtras(gltf) { - ForEach.shader(gltf, function(shader) { - addExtras(shader); - }); - ForEach.buffer(gltf, function(buffer) { - addExtras(buffer); - }); - ForEach.image(gltf, function (image) { - addExtras(image); - ForEach.compressedImage(image, function(compressedImage) { - addExtras(compressedImage); - }); - }); +/** + * Adds extras._pipeline to each object that can have extras in the glTF asset. + * This stage runs before updateVersion and handles both glTF 1.0 and glTF 2.0 assets. + * + * @param {Object} gltf A javascript object containing a glTF asset. + * @returns {Object} The glTF asset with the added pipeline extras. + * + * @private + */ +function addPipelineExtras(gltf) { + ForEach.shader(gltf, function(shader) { + addExtras(shader); + }); + ForEach.buffer(gltf, function(buffer) { + addExtras(buffer); + }); + ForEach.image(gltf, function (image) { + addExtras(image); + }); - addExtras(gltf); + addExtras(gltf); - return gltf; - } + return gltf; +} - function addExtras(object) { - object.extras = defined(object.extras) ? object.extras : {}; - object.extras._pipeline = defined(object.extras._pipeline) ? object.extras._pipeline : {}; - } +function addExtras(object) { + object.extras = defined(object.extras) ? object.extras : {}; + object.extras._pipeline = defined(object.extras._pipeline) ? object.extras._pipeline : {}; +} - export default addPipelineExtras; +export default addPipelineExtras; diff --git a/Source/ThirdParty/GltfPipeline/addToArray.js b/Source/ThirdParty/GltfPipeline/addToArray.js index 7e102eeba7ae..8f487e825598 100644 --- a/Source/ThirdParty/GltfPipeline/addToArray.js +++ b/Source/ThirdParty/GltfPipeline/addToArray.js @@ -1,25 +1,25 @@ -import defaultValue from '../../Core/defaultValue.js' +import defaultValue from "../../Core/defaultValue.js" - /** - * Adds an element to an array and returns the element's index. - * - * @param {Array} array The array to add to. - * @param {Object} element The element to add. - * @param {Boolean} [checkDuplicates=false] When true, if a duplicate element is found its index is returned and element is not added to the array. - * - * @private - */ - function addToArray(array, element, checkDuplicates) { - checkDuplicates = defaultValue(checkDuplicates, false); - if (checkDuplicates) { - var index = array.indexOf(element); - if (index > -1) { - return index; - } +/** + * Adds an element to an array and returns the element's index. + * + * @param {Array} array The array to add to. + * @param {Object} element The element to add. + * @param {Boolean} [checkDuplicates=false] When true, if a duplicate element is found its index is returned and element is not added to the array. + * + * @private + */ +function addToArray(array, element, checkDuplicates) { + checkDuplicates = defaultValue(checkDuplicates, false); + if (checkDuplicates) { + var index = array.indexOf(element); + if (index > -1) { + return index; } - - array.push(element); - return array.length - 1; } - export default addToArray; + array.push(element); + return array.length - 1; +} + +export default addToArray; diff --git a/Source/ThirdParty/GltfPipeline/findAccessorMinMax.js b/Source/ThirdParty/GltfPipeline/findAccessorMinMax.js index 721415f37240..ecf17b706171 100644 --- a/Source/ThirdParty/GltfPipeline/findAccessorMinMax.js +++ b/Source/ThirdParty/GltfPipeline/findAccessorMinMax.js @@ -1,64 +1,64 @@ -import getAccessorByteStride from './getAccessorByteStride.js' -import getComponentReader from './getComponentReader.js' -import numberOfComponentsForType from './numberOfComponentsForType.js' -import arrayFill from '../../Core/arrayFill.js' -import ComponentDatatype from '../../Core/ComponentDatatype.js' -import defined from '../../Core/defined.js' +import getAccessorByteStride from "./getAccessorByteStride.js" +import getComponentReader from "./getComponentReader.js" +import numberOfComponentsForType from "./numberOfComponentsForType.js" +import arrayFill from "../../Core/arrayFill.js" +import ComponentDatatype from "../../Core/ComponentDatatype.js" +import defined from "../../Core/defined.js" - /** - * Finds the min and max values of the accessor. - * - * @param {Object} gltf A javascript object containing a glTF asset. - * @param {Object} accessor The accessor object from the glTF asset to read. - * @returns {{min: Array, max: Array}} min holding the array of minimum values and max holding the array of maximum values. - * - * @private - */ - function findAccessorMinMax(gltf, accessor) { - var bufferViews = gltf.bufferViews; - var buffers = gltf.buffers; - var bufferViewId = accessor.bufferView; - var numberOfComponents = numberOfComponentsForType(accessor.type); +/** + * Finds the min and max values of the accessor. + * + * @param {Object} gltf A javascript object containing a glTF asset. + * @param {Object} accessor The accessor object from the glTF asset to read. + * @returns {{min: Array, max: Array}} min holding the array of minimum values and max holding the array of maximum values. + * + * @private + */ +function findAccessorMinMax(gltf, accessor) { + var bufferViews = gltf.bufferViews; + var buffers = gltf.buffers; + var bufferViewId = accessor.bufferView; + var numberOfComponents = numberOfComponentsForType(accessor.type); - // According to the spec, when bufferView is not defined, accessor must be initialized with zeros - if (!defined(accessor.bufferView)) { - return { - min: arrayFill(new Array(numberOfComponents), 0.0), - max: arrayFill(new Array(numberOfComponents), 0.0) - }; - } + // According to the spec, when bufferView is not defined, accessor must be initialized with zeros + if (!defined(accessor.bufferView)) { + return { + min: arrayFill(new Array(numberOfComponents), 0.0), + max: arrayFill(new Array(numberOfComponents), 0.0) + }; + } - var min = arrayFill(new Array(numberOfComponents), Number.POSITIVE_INFINITY); - var max = arrayFill(new Array(numberOfComponents), Number.NEGATIVE_INFINITY); + var min = arrayFill(new Array(numberOfComponents), Number.POSITIVE_INFINITY); + var max = arrayFill(new Array(numberOfComponents), Number.NEGATIVE_INFINITY); - var bufferView = bufferViews[bufferViewId]; - var bufferId = bufferView.buffer; - var buffer = buffers[bufferId]; - var source = buffer.extras._pipeline.source; + var bufferView = bufferViews[bufferViewId]; + var bufferId = bufferView.buffer; + var buffer = buffers[bufferId]; + var source = buffer.extras._pipeline.source; - var count = accessor.count; - var byteStride = getAccessorByteStride(gltf, accessor); - var byteOffset = accessor.byteOffset + bufferView.byteOffset + source.byteOffset; - var componentType = accessor.componentType; - var componentTypeByteLength = ComponentDatatype.getSizeInBytes(componentType); - var dataView = new DataView(source.buffer); - var components = new Array(numberOfComponents); - var componentReader = getComponentReader(componentType); + var count = accessor.count; + var byteStride = getAccessorByteStride(gltf, accessor); + var byteOffset = accessor.byteOffset + bufferView.byteOffset + source.byteOffset; + var componentType = accessor.componentType; + var componentTypeByteLength = ComponentDatatype.getSizeInBytes(componentType); + var dataView = new DataView(source.buffer); + var components = new Array(numberOfComponents); + var componentReader = getComponentReader(componentType); - for (var i = 0; i < count; i++) { - componentReader(dataView, byteOffset, numberOfComponents, componentTypeByteLength, components); - for (var j = 0; j < numberOfComponents; j++) { - var value = components[j]; - min[j] = Math.min(min[j], value); - max[j] = Math.max(max[j], value); - } - byteOffset += byteStride; + for (var i = 0; i < count; i++) { + componentReader(dataView, byteOffset, numberOfComponents, componentTypeByteLength, components); + for (var j = 0; j < numberOfComponents; j++) { + var value = components[j]; + min[j] = Math.min(min[j], value); + max[j] = Math.max(max[j], value); } - - return { - min: min, - max: max - }; + byteOffset += byteStride; } - export default findAccessorMinMax; + return { + min: min, + max: max + }; +} + +export default findAccessorMinMax; diff --git a/Source/ThirdParty/GltfPipeline/forEachTextureInMaterial.js b/Source/ThirdParty/GltfPipeline/forEachTextureInMaterial.js new file mode 100644 index 000000000000..3e9bcc775eaf --- /dev/null +++ b/Source/ThirdParty/GltfPipeline/forEachTextureInMaterial.js @@ -0,0 +1,134 @@ +import ForEach from "./ForEach.js" +import Check from "../../Core/Check.js" +import defined from "../../Core/defined.js" + +/** + * Calls the provider handler function on each texture used by the material. + * Mimics the behavior of functions in gltf-pipeline ForEach. + * @param {Object} material The glTF material. + * @param {forEachTextureInMaterial~handler} handler Function that is called for each texture in the material. + */ +function forEachTextureInMaterial(material, handler) { + Check.typeOf.object('material', material); + Check.defined('handler', handler); + + // Metallic roughness + var pbrMetallicRoughness = material.pbrMetallicRoughness; + if (defined(pbrMetallicRoughness)) { + if (defined(pbrMetallicRoughness.baseColorTexture)) { + var textureInfo = pbrMetallicRoughness.baseColorTexture; + var value = handler(textureInfo.index, textureInfo); + if (defined(value)) { + return value; + } + } + if (defined(pbrMetallicRoughness.metallicRoughnessTexture)) { + var textureInfo = pbrMetallicRoughness.metallicRoughnessTexture; + var value = handler(textureInfo.index, textureInfo); + if (defined(value)) { + return value; + } + } + } + + if (defined(material.extensions)) { + // Spec gloss extension + var pbrSpecularGlossiness = material.extensions.KHR_materials_pbrSpecularGlossiness; + if (defined(pbrSpecularGlossiness)) { + if (defined(pbrSpecularGlossiness.diffuseTexture)) { + var textureInfo = pbrSpecularGlossiness.diffuseTexture; + var value = handler(textureInfo.index, textureInfo); + if (defined(value)) { + return value; + } + } + if (defined(pbrSpecularGlossiness.specularGlossinessTexture)) { + var textureInfo = pbrSpecularGlossiness.specularGlossinessTexture; + var value = handler(textureInfo.index, textureInfo); + if (defined(value)) { + return value; + } + } + } + + // Materials common extension (may be present in models converted from glTF 1.0) + var materialsCommon = material.extensions.KHR_materials_common; + if (defined(materialsCommon)) { + var diffuse = materialsCommon.values.diffuse; + var ambient = materialsCommon.values.ambient; + var emission = materialsCommon.values.emission; + var specular = materialsCommon.values.specular; + if (defined(diffuse) && defined(diffuse.index)) { + var value = handler(diffuse.index, diffuse); + if (defined(value)) { + return value; + } + } + if (defined(ambient) && defined(ambient.index)) { + var value = handler(ambient.index, ambient); + if (defined(value)) { + return value; + } + } + if (defined(emission) && defined(emission.index)) { + var value = handler(emission.index, emission); + if (defined(value)) { + return value; + } + } + if (defined(specular) && defined(specular.index)) { + var value = handler(specular.index, specular); + if (defined(value)) { + return value; + } + } + } + } + + // KHR_techniques_webgl extension + var value = ForEach.materialValue(material, function (materialValue) { + if (defined(materialValue.index)) { + var value = handler(materialValue.index, materialValue); + if (defined(value)) { + return value; + } + } + }); + if (defined(value)) { + return value; + } + + // Top level textures + if (defined(material.emissiveTexture)) { + var textureInfo = material.emissiveTexture; + var value = handler(textureInfo.index, textureInfo); + if (defined(value)) { + return value; + } + } + + if (defined(material.normalTexture)) { + var textureInfo = material.normalTexture; + var value = handler(textureInfo.index, textureInfo); + if (defined(value)) { + return value; + } + } + + if (defined(material.occlusionTexture)) { + var textureInfo = material.occlusionTexture; + var value = handler(textureInfo.index, textureInfo); + if (defined(value)) { + return value; + } + } +} + +/** + * Function that is called for each texture in the material. If this function returns a value the for each stops and returns that value. + * @callback forEachTextureInMaterial~handler + * @param {Number} The texture index. + * @param {Object} The texture info object. + */ + +export default forEachTextureInMaterial; diff --git a/Source/ThirdParty/GltfPipeline/getAccessorByteStride.js b/Source/ThirdParty/GltfPipeline/getAccessorByteStride.js index c0bbecb2249a..a6923e32dffe 100644 --- a/Source/ThirdParty/GltfPipeline/getAccessorByteStride.js +++ b/Source/ThirdParty/GltfPipeline/getAccessorByteStride.js @@ -1,26 +1,26 @@ -import numberOfComponentsForType from './numberOfComponentsForType.js' -import ComponentDatatype from '../../Core/ComponentDatatype.js' -import defined from '../../Core/defined.js' +import numberOfComponentsForType from "./numberOfComponentsForType.js" +import ComponentDatatype from "../../Core/ComponentDatatype.js" +import defined from "../../Core/defined.js" - /** - * Returns the byte stride of the provided accessor. - * If the byteStride is 0, it is calculated based on type and componentType - * - * @param {Object} gltf A javascript object containing a glTF asset. - * @param {Object} accessor The accessor. - * @returns {Number} The byte stride of the accessor. - * - * @private - */ - function getAccessorByteStride(gltf, accessor) { - var bufferViewId = accessor.bufferView; - if (defined(bufferViewId)) { - var bufferView = gltf.bufferViews[bufferViewId]; - if (defined(bufferView.byteStride) && bufferView.byteStride > 0) { - return bufferView.byteStride; - } +/** + * Returns the byte stride of the provided accessor. + * If the byteStride is 0, it is calculated based on type and componentType + * + * @param {Object} gltf A javascript object containing a glTF asset. + * @param {Object} accessor The accessor. + * @returns {Number} The byte stride of the accessor. + * + * @private + */ +function getAccessorByteStride(gltf, accessor) { + var bufferViewId = accessor.bufferView; + if (defined(bufferViewId)) { + var bufferView = gltf.bufferViews[bufferViewId]; + if (defined(bufferView.byteStride) && bufferView.byteStride > 0) { + return bufferView.byteStride; } - return ComponentDatatype.getSizeInBytes(accessor.componentType) * numberOfComponentsForType(accessor.type); } + return ComponentDatatype.getSizeInBytes(accessor.componentType) * numberOfComponentsForType(accessor.type); +} - export default getAccessorByteStride; +export default getAccessorByteStride; diff --git a/Source/ThirdParty/GltfPipeline/getComponentReader.js b/Source/ThirdParty/GltfPipeline/getComponentReader.js index ff406b46d391..c7ad4d9edca6 100644 --- a/Source/ThirdParty/GltfPipeline/getComponentReader.js +++ b/Source/ThirdParty/GltfPipeline/getComponentReader.js @@ -1,75 +1,75 @@ -import ComponentDatatype from '../../Core/ComponentDatatype.js' +import ComponentDatatype from "../../Core/ComponentDatatype.js" - /** - * Returns a function to read and convert data from a DataView into an array. - * - * @param {Number} componentType Type to convert the data to. - * @returns {ComponentReader} Function that reads and converts data. - * - * @private - */ - function getComponentReader(componentType) { - switch (componentType) { - case ComponentDatatype.BYTE: - return function (dataView, byteOffset, numberOfComponents, componentTypeByteLength, result) { - for (var i = 0; i < numberOfComponents; ++i) { - result[i] = dataView.getInt8(byteOffset + i * componentTypeByteLength); - } - }; - case ComponentDatatype.UNSIGNED_BYTE: - return function (dataView, byteOffset, numberOfComponents, componentTypeByteLength, result) { - for (var i = 0; i < numberOfComponents; ++i) { - result[i] = dataView.getUint8(byteOffset + i * componentTypeByteLength); - } - }; - case ComponentDatatype.SHORT: - return function (dataView, byteOffset, numberOfComponents, componentTypeByteLength, result) { - for (var i = 0; i < numberOfComponents; ++i) { - result[i] = dataView.getInt16(byteOffset + i * componentTypeByteLength, true); - } - }; - case ComponentDatatype.UNSIGNED_SHORT: - return function (dataView, byteOffset, numberOfComponents, componentTypeByteLength, result) { - for (var i = 0; i < numberOfComponents; ++i) { - result[i] = dataView.getUint16(byteOffset + i * componentTypeByteLength, true); - } - }; - case ComponentDatatype.INT: - return function (dataView, byteOffset, numberOfComponents, componentTypeByteLength, result) { - for (var i = 0; i < numberOfComponents; ++i) { - result[i] = dataView.getInt32(byteOffset + i * componentTypeByteLength, true); - } - }; - case ComponentDatatype.UNSIGNED_INT: - return function (dataView, byteOffset, numberOfComponents, componentTypeByteLength, result) { - for (var i = 0; i < numberOfComponents; ++i) { - result[i] = dataView.getUint32(byteOffset + i * componentTypeByteLength, true); - } - }; - case ComponentDatatype.FLOAT: - return function (dataView, byteOffset, numberOfComponents, componentTypeByteLength, result) { - for (var i = 0; i < numberOfComponents; ++i) { - result[i] = dataView.getFloat32(byteOffset + i * componentTypeByteLength, true); - } - }; - case ComponentDatatype.DOUBLE: - return function (dataView, byteOffset, numberOfComponents, componentTypeByteLength, result) { - for (var i = 0; i < numberOfComponents; ++i) { - result[i] = dataView.getFloat64(byteOffset + i * componentTypeByteLength, true); - } - }; - } +/** + * Returns a function to read and convert data from a DataView into an array. + * + * @param {Number} componentType Type to convert the data to. + * @returns {ComponentReader} Function that reads and converts data. + * + * @private + */ +function getComponentReader(componentType) { + switch (componentType) { + case ComponentDatatype.BYTE: + return function (dataView, byteOffset, numberOfComponents, componentTypeByteLength, result) { + for (var i = 0; i < numberOfComponents; ++i) { + result[i] = dataView.getInt8(byteOffset + i * componentTypeByteLength); + } + }; + case ComponentDatatype.UNSIGNED_BYTE: + return function (dataView, byteOffset, numberOfComponents, componentTypeByteLength, result) { + for (var i = 0; i < numberOfComponents; ++i) { + result[i] = dataView.getUint8(byteOffset + i * componentTypeByteLength); + } + }; + case ComponentDatatype.SHORT: + return function (dataView, byteOffset, numberOfComponents, componentTypeByteLength, result) { + for (var i = 0; i < numberOfComponents; ++i) { + result[i] = dataView.getInt16(byteOffset + i * componentTypeByteLength, true); + } + }; + case ComponentDatatype.UNSIGNED_SHORT: + return function (dataView, byteOffset, numberOfComponents, componentTypeByteLength, result) { + for (var i = 0; i < numberOfComponents; ++i) { + result[i] = dataView.getUint16(byteOffset + i * componentTypeByteLength, true); + } + }; + case ComponentDatatype.INT: + return function (dataView, byteOffset, numberOfComponents, componentTypeByteLength, result) { + for (var i = 0; i < numberOfComponents; ++i) { + result[i] = dataView.getInt32(byteOffset + i * componentTypeByteLength, true); + } + }; + case ComponentDatatype.UNSIGNED_INT: + return function (dataView, byteOffset, numberOfComponents, componentTypeByteLength, result) { + for (var i = 0; i < numberOfComponents; ++i) { + result[i] = dataView.getUint32(byteOffset + i * componentTypeByteLength, true); + } + }; + case ComponentDatatype.FLOAT: + return function (dataView, byteOffset, numberOfComponents, componentTypeByteLength, result) { + for (var i = 0; i < numberOfComponents; ++i) { + result[i] = dataView.getFloat32(byteOffset + i * componentTypeByteLength, true); + } + }; + case ComponentDatatype.DOUBLE: + return function (dataView, byteOffset, numberOfComponents, componentTypeByteLength, result) { + for (var i = 0; i < numberOfComponents; ++i) { + result[i] = dataView.getFloat64(byteOffset + i * componentTypeByteLength, true); + } + }; } +} - /** - * A callback function that logs messages. - * @callback ComponentReader - * - * @param {DataView} dataView The data view to read from. - * @param {Number} byteOffset The byte offset applied when reading from the data view. - * @param {Number} numberOfComponents The number of components to read. - * @param {Number} componentTypeByteLength The byte length of each component. - * @param {Number} result An array storing the components that are read. - */ +/** + * A callback function that logs messages. + * @callback ComponentReader + * + * @param {DataView} dataView The data view to read from. + * @param {Number} byteOffset The byte offset applied when reading from the data view. + * @param {Number} numberOfComponents The number of components to read. + * @param {Number} componentTypeByteLength The byte length of each component. + * @param {Number} result An array storing the components that are read. + */ - export default getComponentReader; +export default getComponentReader; diff --git a/Source/ThirdParty/GltfPipeline/moveTechniqueRenderStates.js b/Source/ThirdParty/GltfPipeline/moveTechniqueRenderStates.js index c6f9847c9932..24bf5dd6b941 100644 --- a/Source/ThirdParty/GltfPipeline/moveTechniqueRenderStates.js +++ b/Source/ThirdParty/GltfPipeline/moveTechniqueRenderStates.js @@ -1,129 +1,129 @@ -import addExtensionsUsed from './addExtensionsUsed.js' -import ForEach from './ForEach.js' -import defaultValue from '../../Core/defaultValue.js' -import defined from '../../Core/defined.js' -import WebGLConstants from '../../Core/WebGLConstants.js' - - var defaultBlendEquation = [ - WebGLConstants.FUNC_ADD, - WebGLConstants.FUNC_ADD - ]; - - var defaultBlendFactors = [ - WebGLConstants.ONE, - WebGLConstants.ZERO, - WebGLConstants.ONE, - WebGLConstants.ZERO - ]; - - function isStateEnabled(renderStates, state) { - var enabled = renderStates.enable; - if (!defined(enabled)) { - return false; - } +import addExtensionsUsed from "./addExtensionsUsed.js" +import ForEach from "./ForEach.js" +import defaultValue from "../../Core/defaultValue.js" +import defined from "../../Core/defined.js" +import WebGLConstants from "../../Core/WebGLConstants.js" + +var defaultBlendEquation = [ + WebGLConstants.FUNC_ADD, + WebGLConstants.FUNC_ADD +]; + +var defaultBlendFactors = [ + WebGLConstants.ONE, + WebGLConstants.ZERO, + WebGLConstants.ONE, + WebGLConstants.ZERO +]; + +function isStateEnabled(renderStates, state) { + var enabled = renderStates.enable; + if (!defined(enabled)) { + return false; + } - return (enabled.indexOf(state) > -1); + return (enabled.indexOf(state) > -1); +} + +var supportedBlendFactors = [ + WebGLConstants.ZERO, + WebGLConstants.ONE, + WebGLConstants.SRC_COLOR, + WebGLConstants.ONE_MINUS_SRC_COLOR, + WebGLConstants.SRC_ALPHA, + WebGLConstants.ONE_MINUS_SRC_ALPHA, + WebGLConstants.DST_ALPHA, + WebGLConstants.ONE_MINUS_DST_ALPHA, + WebGLConstants.DST_COLOR, + WebGLConstants.ONE_MINUS_DST_COLOR +]; + +// If any of the blend factors are not supported, return the default +function getSupportedBlendFactors(value, defaultValue) { + if (!defined(value)) { + return defaultValue; } - var supportedBlendFactors = [ - WebGLConstants.ZERO, - WebGLConstants.ONE, - WebGLConstants.SRC_COLOR, - WebGLConstants.ONE_MINUS_SRC_COLOR, - WebGLConstants.SRC_ALPHA, - WebGLConstants.ONE_MINUS_SRC_ALPHA, - WebGLConstants.DST_ALPHA, - WebGLConstants.ONE_MINUS_DST_ALPHA, - WebGLConstants.DST_COLOR, - WebGLConstants.ONE_MINUS_DST_COLOR - ]; - - // If any of the blend factors are not supported, return the default - function getSupportedBlendFactors(value, defaultValue) { - if (!defined(value)) { + for (var i = 0; i < 4; i++) { + if (supportedBlendFactors.indexOf(value[i]) === -1) { return defaultValue; } - - for (var i = 0; i < 4; i++) { - if (supportedBlendFactors.indexOf(value[i]) === -1) { - return defaultValue; - } - } - - return value; } - /** - * Move glTF 1.0 technique render states to glTF 2.0 materials properties and KHR_blend extension. - * - * @param {Object} gltf A javascript object containing a glTF asset. - * @returns {Object} The updated glTF asset. - * - * @private - */ - function moveTechniqueRenderStates(gltf) { - var blendingForTechnique = {}; - var materialPropertiesForTechnique = {}; - var techniquesLegacy = gltf.techniques; - if (!defined(techniquesLegacy)) { - return gltf; - } - - ForEach.technique(gltf, function (techniqueLegacy, techniqueIndex) { - var renderStates = techniqueLegacy.states; - if (defined(renderStates)) { - var materialProperties = materialPropertiesForTechnique[techniqueIndex] = {}; - - // If BLEND is enabled, the material should have alpha mode BLEND - if (isStateEnabled(renderStates, WebGLConstants.BLEND)) { - materialProperties.alphaMode = 'BLEND'; - - var blendFunctions = renderStates.functions; - if (defined(blendFunctions) && (defined(blendFunctions.blendEquationSeparate) - || defined(blendFunctions.blendFuncSeparate))) { - blendingForTechnique[techniqueIndex] = { - blendEquation: defaultValue(blendFunctions.blendEquationSeparate, defaultBlendEquation), - blendFactors: getSupportedBlendFactors(blendFunctions.blendFuncSeparate, defaultBlendFactors) - }; - } - } + return value; +} + +/** + * Move glTF 1.0 technique render states to glTF 2.0 materials properties and KHR_blend extension. + * + * @param {Object} gltf A javascript object containing a glTF asset. + * @returns {Object} The updated glTF asset. + * + * @private + */ +function moveTechniqueRenderStates(gltf) { + var blendingForTechnique = {}; + var materialPropertiesForTechnique = {}; + var techniquesLegacy = gltf.techniques; + if (!defined(techniquesLegacy)) { + return gltf; + } - // If CULL_FACE is not enabled, the material should be doubleSided - if (!isStateEnabled(renderStates, WebGLConstants.CULL_FACE)) { - materialProperties.doubleSided = true; + ForEach.technique(gltf, function (techniqueLegacy, techniqueIndex) { + var renderStates = techniqueLegacy.states; + if (defined(renderStates)) { + var materialProperties = materialPropertiesForTechnique[techniqueIndex] = {}; + + // If BLEND is enabled, the material should have alpha mode BLEND + if (isStateEnabled(renderStates, WebGLConstants.BLEND)) { + materialProperties.alphaMode = 'BLEND'; + + var blendFunctions = renderStates.functions; + if (defined(blendFunctions) && (defined(blendFunctions.blendEquationSeparate) + || defined(blendFunctions.blendFuncSeparate))) { + blendingForTechnique[techniqueIndex] = { + blendEquation: defaultValue(blendFunctions.blendEquationSeparate, defaultBlendEquation), + blendFactors: getSupportedBlendFactors(blendFunctions.blendFuncSeparate, defaultBlendFactors) + }; } - - delete techniqueLegacy.states; } - }); - if (Object.keys(blendingForTechnique).length > 0) { - if (!defined(gltf.extensions)) { - gltf.extensions = {}; + // If CULL_FACE is not enabled, the material should be doubleSided + if (!isStateEnabled(renderStates, WebGLConstants.CULL_FACE)) { + materialProperties.doubleSided = true; } - addExtensionsUsed(gltf, 'KHR_blend'); + delete techniqueLegacy.states; } + }); - ForEach.material(gltf, function (material) { - if (defined(material.technique)) { - var materialProperties = materialPropertiesForTechnique[material.technique]; - ForEach.objectLegacy(materialProperties, function (value, property) { - material[property] = value; - }); + if (Object.keys(blendingForTechnique).length > 0) { + if (!defined(gltf.extensions)) { + gltf.extensions = {}; + } - var blending = blendingForTechnique[material.technique]; - if (defined(blending)) { - if (!defined(material.extensions)) { - material.extensions = {}; - } + addExtensionsUsed(gltf, 'KHR_blend'); + } - material.extensions.KHR_blend = blending; + ForEach.material(gltf, function (material) { + if (defined(material.technique)) { + var materialProperties = materialPropertiesForTechnique[material.technique]; + ForEach.objectLegacy(materialProperties, function (value, property) { + material[property] = value; + }); + + var blending = blendingForTechnique[material.technique]; + if (defined(blending)) { + if (!defined(material.extensions)) { + material.extensions = {}; } + + material.extensions.KHR_blend = blending; } - }); + } + }); - return gltf; - } + return gltf; +} - export default moveTechniqueRenderStates; +export default moveTechniqueRenderStates; diff --git a/Source/ThirdParty/GltfPipeline/moveTechniquesToExtension.js b/Source/ThirdParty/GltfPipeline/moveTechniquesToExtension.js index 96c7631a6fc2..f47e57762c0a 100644 --- a/Source/ThirdParty/GltfPipeline/moveTechniquesToExtension.js +++ b/Source/ThirdParty/GltfPipeline/moveTechniquesToExtension.js @@ -1,63 +1,69 @@ -import addExtensionsUsed from './addExtensionsUsed.js' -import addExtensionsRequired from './addExtensionsRequired.js' -import addToArray from './addToArray.js' -import ForEach from './ForEach.js' -import defined from '../../Core/defined.js' - - /** - * Move glTF 1.0 material techniques to glTF 2.0 KHR_techniques_webgl extension. - * - * @param {Object} gltf A javascript object containing a glTF asset. - * @returns {Object} The updated glTF asset. - * - * @private - */ - function moveTechniquesToExtension(gltf) { - var techniquesLegacy = gltf.techniques; - var mappedUniforms = {}; - var updatedTechniqueIndices = {}; - if (defined(techniquesLegacy)) { - var extension = { - programs: [], - shaders: [], - techniques: [] +import addExtensionsUsed from "./addExtensionsUsed.js" +import addExtensionsRequired from "./addExtensionsRequired.js" +import addToArray from "./addToArray.js" +import ForEach from "./ForEach.js" +import defined from "../../Core/defined.js" + +/** + * Move glTF 1.0 material techniques to glTF 2.0 KHR_techniques_webgl extension. + * + * @param {Object} gltf A javascript object containing a glTF asset. + * @returns {Object} The updated glTF asset. + * + * @private + */ +function moveTechniquesToExtension(gltf) { + var techniquesLegacy = gltf.techniques; + var mappedUniforms = {}; + var updatedTechniqueIndices = {}; + var seenPrograms = {}; + if (defined(techniquesLegacy)) { + var extension = { + programs: [], + shaders: [], + techniques: [] + }; + + // Some 1.1 models have a glExtensionsUsed property that can be transferred to program.glExtensions + var glExtensions = gltf.glExtensionsUsed; + delete gltf.glExtensionsUsed; + + ForEach.technique(gltf, function (techniqueLegacy, techniqueId) { + var technique = { + name: techniqueLegacy.name, + program: undefined, + attributes: {}, + uniforms: {} }; - // Some 1.1 models have a glExtensionsUsed property that can be transferred to program.glExtensions - var glExtensions = gltf.glExtensionsUsed; - delete gltf.glExtensionsUsed; + var parameterLegacy; + ForEach.techniqueAttribute(techniqueLegacy, function (parameterName, attributeName) { + parameterLegacy = techniqueLegacy.parameters[parameterName]; + technique.attributes[attributeName] = { + semantic: parameterLegacy.semantic + }; + }); - ForEach.technique(gltf, function (techniqueLegacy, techniqueIndex) { - var technique = { - name: techniqueLegacy.name, - program: undefined, - attributes: {}, - uniforms: {} + ForEach.techniqueUniform(techniqueLegacy, function (parameterName, uniformName) { + parameterLegacy = techniqueLegacy.parameters[parameterName]; + technique.uniforms[uniformName] = { + count: parameterLegacy.count, + node: parameterLegacy.node, + type: parameterLegacy.type, + semantic: parameterLegacy.semantic, + value: parameterLegacy.value }; - var parameterLegacy; - ForEach.techniqueAttribute(techniqueLegacy, function (parameterName, attributeName) { - parameterLegacy = techniqueLegacy.parameters[parameterName]; - technique.attributes[attributeName] = { - semantic: parameterLegacy.semantic - }; - }); - - ForEach.techniqueUniform(techniqueLegacy, function (parameterName, uniformName) { - parameterLegacy = techniqueLegacy.parameters[parameterName]; - technique.uniforms[uniformName] = { - count: parameterLegacy.count, - node: parameterLegacy.node, - type: parameterLegacy.type, - semantic: parameterLegacy.semantic, - value: parameterLegacy.value - }; - - // Store the name of the uniform to update material values. - mappedUniforms[parameterName] = uniformName; - }); + // Store the name of the uniform to update material values. + if (!defined(mappedUniforms[techniqueId])) { + mappedUniforms[techniqueId] = {}; + } + mappedUniforms[techniqueId][parameterName] = uniformName; + }); + if (!defined(seenPrograms[techniqueLegacy.program])) { var programLegacy = gltf.programs[techniqueLegacy.program]; + var program = { name: programLegacy.name, fragmentShader: undefined, @@ -72,53 +78,57 @@ import defined from '../../Core/defined.js' program.vertexShader = addToArray(extension.shaders, vs, true); technique.program = addToArray(extension.programs, program); + seenPrograms[techniqueLegacy.program] = technique.program; + } else { + technique.program = seenPrograms[techniqueLegacy.program]; + } - // Store the index of the new technique to reference instead. - updatedTechniqueIndices[techniqueIndex] = addToArray(extension.techniques, technique); - }); - - if (extension.techniques.length > 0) { - if (!defined(gltf.extensions)) { - gltf.extensions = {}; - } + // Store the index of the new technique to reference instead. + updatedTechniqueIndices[techniqueId] = addToArray(extension.techniques, technique); + }); - gltf.extensions.KHR_techniques_webgl = extension; - addExtensionsUsed(gltf, 'KHR_techniques_webgl'); - addExtensionsRequired(gltf, 'KHR_techniques_webgl'); + if (extension.techniques.length > 0) { + if (!defined(gltf.extensions)) { + gltf.extensions = {}; } - } - ForEach.material(gltf, function (material) { - if (defined(material.technique)) { - var materialExtension = { - technique: updatedTechniqueIndices[material.technique] - }; - - ForEach.objectLegacy(material.values, function (value, parameterName) { - if (!defined(materialExtension.values)) { - materialExtension.values = {}; - } + gltf.extensions.KHR_techniques_webgl = extension; + addExtensionsUsed(gltf, 'KHR_techniques_webgl'); + addExtensionsRequired(gltf, 'KHR_techniques_webgl'); + } + } - var uniformName = mappedUniforms[parameterName]; - materialExtension.values[uniformName] = value; - }); + ForEach.material(gltf, function (material) { + if (defined(material.technique)) { + var materialExtension = { + technique: updatedTechniqueIndices[material.technique] + }; - if (!defined(material.extensions)) { - material.extensions = {}; + ForEach.objectLegacy(material.values, function (value, parameterName) { + if (!defined(materialExtension.values)) { + materialExtension.values = {}; } - material.extensions.KHR_techniques_webgl = materialExtension; + var uniformName = mappedUniforms[material.technique][parameterName]; + materialExtension.values[uniformName] = value; + }); + + if (!defined(material.extensions)) { + material.extensions = {}; } - delete material.technique; - delete material.values; - }); + material.extensions.KHR_techniques_webgl = materialExtension; + } - delete gltf.techniques; - delete gltf.programs; - delete gltf.shaders; + delete material.technique; + delete material.values; + }); - return gltf; - } + delete gltf.techniques; + delete gltf.programs; + delete gltf.shaders; + + return gltf; +} - export default moveTechniquesToExtension; +export default moveTechniquesToExtension; diff --git a/Source/ThirdParty/GltfPipeline/numberOfComponentsForType.js b/Source/ThirdParty/GltfPipeline/numberOfComponentsForType.js index 36af8038a64b..d211357f0634 100644 --- a/Source/ThirdParty/GltfPipeline/numberOfComponentsForType.js +++ b/Source/ThirdParty/GltfPipeline/numberOfComponentsForType.js @@ -1,29 +1,29 @@ - /** - * Utility function for retrieving the number of components in a given type. - * - * @param {String} type glTF type - * @returns {Number} The number of components in that type. - * - * @private - */ - function numberOfComponentsForType(type) { - switch (type) { - 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; - } +/** + * Utility function for retrieving the number of components in a given type. + * + * @param {String} type glTF type + * @returns {Number} The number of components in that type. + * + * @private + */ +function numberOfComponentsForType(type) { + switch (type) { + 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; } +} - export default numberOfComponentsForType; +export default numberOfComponentsForType; diff --git a/Source/ThirdParty/GltfPipeline/parseGlb.js b/Source/ThirdParty/GltfPipeline/parseGlb.js index e1460864700a..0acfd28f6a12 100644 --- a/Source/ThirdParty/GltfPipeline/parseGlb.js +++ b/Source/ThirdParty/GltfPipeline/parseGlb.js @@ -1,114 +1,116 @@ -import addPipelineExtras from './addPipelineExtras.js' -import removeExtensionsUsed from './removeExtensionsUsed.js' -import defaultValue from '../../Core/defaultValue.js' -import defined from '../../Core/defined.js' -import getJsonFromTypedArray from '../../Core/getJsonFromTypedArray.js' -import getMagic from '../../Core/getMagic.js' -import RuntimeError from '../../Core/RuntimeError.js' +import addPipelineExtras from "./addPipelineExtras.js" +import removeExtensionsUsed from "./removeExtensionsUsed.js" +import defaultValue from "../../Core/defaultValue.js" +import defined from "../../Core/defined.js" +import getMagic from "../../Core/getMagic.js" +import getStringFromTypedArray from "../../Core/getStringFromTypedArray.js" +import RuntimeError from "../../Core/RuntimeError.js" - var sizeOfUint32 = 4; +var sizeOfUint32 = 4; - /** - * Convert a binary glTF to glTF. - * - * The returned glTF has pipeline extras included. The embedded binary data is stored in gltf.buffers[0].extras._pipeline.source. - * - * @param {Buffer} glb The glb data to parse. - * @returns {Object} A javascript object containing a glTF asset with pipeline extras included. - * - * @private - */ - function parseGlb(glb) { - // Check that the magic string is present - var magic = getMagic(glb); - if (magic !== 'glTF') { - throw new RuntimeError('File is not valid binary glTF'); - } - - var header = readHeader(glb, 0, 5); - var version = header[1]; - if (version !== 1 && version !== 2) { - throw new RuntimeError('Binary glTF version is not 1 or 2'); - } +/** + * Convert a binary glTF to glTF. + * + * The returned glTF has pipeline extras included. The embedded binary data is stored in gltf.buffers[0].extras._pipeline.source. + * + * @param {Buffer} glb The glb data to parse. + * @returns {Object} A javascript object containing a glTF asset with pipeline extras included. + * + * @private + */ +function parseGlb(glb) { + // Check that the magic string is present + var magic = getMagic(glb); + if (magic !== 'glTF') { + throw new RuntimeError('File is not valid binary glTF'); + } - if (version === 1) { - return parseGlbVersion1(glb, header); - } + var header = readHeader(glb, 0, 5); + var version = header[1]; + if (version !== 1 && version !== 2) { + throw new RuntimeError('Binary glTF version is not 1 or 2'); + } - return parseGlbVersion2(glb, header); + if (version === 1) { + return parseGlbVersion1(glb, header); } - function readHeader(glb, byteOffset, count) { - var dataView = new DataView(glb.buffer); - var header = new Array(count); - for (var i = 0; i < count; ++i) { - header[i] = dataView.getUint32(glb.byteOffset + byteOffset + i * sizeOfUint32, true); - } - return header; + return parseGlbVersion2(glb, header); +} + +function readHeader(glb, byteOffset, count) { + var dataView = new DataView(glb.buffer); + var header = new Array(count); + for (var i = 0; i < count; ++i) { + header[i] = dataView.getUint32(glb.byteOffset + byteOffset + i * sizeOfUint32, true); } + return header; +} - function parseGlbVersion1(glb, header) { - var length = header[2]; - var contentLength = header[3]; - var contentFormat = header[4]; +function parseGlbVersion1(glb, header) { + var length = header[2]; + var contentLength = header[3]; + var contentFormat = header[4]; - // Check that the content format is 0, indicating that it is JSON - if (contentFormat !== 0) { - throw new RuntimeError('Binary glTF scene format is not JSON'); - } + // Check that the content format is 0, indicating that it is JSON + if (contentFormat !== 0) { + throw new RuntimeError('Binary glTF scene format is not JSON'); + } - var jsonStart = 20; - var binaryStart = jsonStart + contentLength; + var jsonStart = 20; + var binaryStart = jsonStart + contentLength; - var gltf = getJsonFromTypedArray(glb, jsonStart, contentLength); - addPipelineExtras(gltf); + var contentString = getStringFromTypedArray(glb, jsonStart, contentLength); + var gltf = JSON.parse(contentString); + addPipelineExtras(gltf); - var binaryBuffer = glb.subarray(binaryStart, length); + var binaryBuffer = glb.subarray(binaryStart, length); - var buffers = gltf.buffers; - if (defined(buffers) && Object.keys(buffers).length > 0) { - // In some older models, the binary glTF buffer is named KHR_binary_glTF - var binaryGltfBuffer = defaultValue(buffers.binary_glTF, buffers.KHR_binary_glTF); - if (defined(binaryGltfBuffer)) { - binaryGltfBuffer.extras._pipeline.source = binaryBuffer; - delete binaryGltfBuffer.uri; - } + var buffers = gltf.buffers; + if (defined(buffers) && Object.keys(buffers).length > 0) { + // In some older models, the binary glTF buffer is named KHR_binary_glTF + var binaryGltfBuffer = defaultValue(buffers.binary_glTF, buffers.KHR_binary_glTF); + if (defined(binaryGltfBuffer)) { + binaryGltfBuffer.extras._pipeline.source = binaryBuffer; + delete binaryGltfBuffer.uri; } - // Remove the KHR_binary_glTF extension - removeExtensionsUsed(gltf, 'KHR_binary_glTF'); - return gltf; } + // Remove the KHR_binary_glTF extension + removeExtensionsUsed(gltf, 'KHR_binary_glTF'); + return gltf; +} - function parseGlbVersion2(glb, header) { - var length = header[2]; - var byteOffset = 12; - var gltf; - var binaryBuffer; - while (byteOffset < length) { - var chunkHeader = readHeader(glb, byteOffset, 2); - var chunkLength = chunkHeader[0]; - var chunkType = chunkHeader[1]; - byteOffset += 8; - var chunkBuffer = glb.subarray(byteOffset, byteOffset + chunkLength); - byteOffset += chunkLength; - // Load JSON chunk - if (chunkType === 0x4E4F534A) { - gltf = getJsonFromTypedArray(chunkBuffer); - addPipelineExtras(gltf); - } - // Load Binary chunk - else if (chunkType === 0x004E4942) { - binaryBuffer = chunkBuffer; - } +function parseGlbVersion2(glb, header) { + var length = header[2]; + var byteOffset = 12; + var gltf; + var binaryBuffer; + while (byteOffset < length) { + var chunkHeader = readHeader(glb, byteOffset, 2); + var chunkLength = chunkHeader[0]; + var chunkType = chunkHeader[1]; + byteOffset += 8; + var chunkBuffer = glb.subarray(byteOffset, byteOffset + chunkLength); + byteOffset += chunkLength; + // Load JSON chunk + if (chunkType === 0x4E4F534A) { + var jsonString = getStringFromTypedArray(chunkBuffer); + gltf = JSON.parse(jsonString); + addPipelineExtras(gltf); } - if (defined(gltf) && defined(binaryBuffer)) { - var buffers = gltf.buffers; - if (defined(buffers) && buffers.length > 0) { - var buffer = buffers[0]; - buffer.extras._pipeline.source = binaryBuffer; - } + // Load Binary chunk + else if (chunkType === 0x004E4942) { + binaryBuffer = chunkBuffer; + } + } + if (defined(gltf) && defined(binaryBuffer)) { + var buffers = gltf.buffers; + if (defined(buffers) && buffers.length > 0) { + var buffer = buffers[0]; + buffer.extras._pipeline.source = binaryBuffer; } - return gltf; } + return gltf; +} - export default parseGlb; +export default parseGlb; diff --git a/Source/ThirdParty/GltfPipeline/readAccessorPacked.js b/Source/ThirdParty/GltfPipeline/readAccessorPacked.js index 6225e4f545be..0efb0217b93d 100644 --- a/Source/ThirdParty/GltfPipeline/readAccessorPacked.js +++ b/Source/ThirdParty/GltfPipeline/readAccessorPacked.js @@ -1,47 +1,47 @@ -import getAccessorByteStride from './getAccessorByteStride.js' -import getComponentReader from './getComponentReader.js' -import numberOfComponentsForType from './numberOfComponentsForType.js' -import arrayFill from '../../Core/arrayFill.js' -import ComponentDatatype from '../../Core/ComponentDatatype.js' -import defined from '../../Core/defined.js' +import getAccessorByteStride from "./getAccessorByteStride.js" +import getComponentReader from "./getComponentReader.js" +import numberOfComponentsForType from "./numberOfComponentsForType.js" +import arrayFill from "../../Core/arrayFill.js" +import ComponentDatatype from "../../Core/ComponentDatatype.js" +import defined from "../../Core/defined.js" - /** - * Returns the accessor data in a contiguous array. - * - * @param {Object} gltf A javascript object containing a glTF asset. - * @param {Object} accessor The accessor. - * @returns {Array} The accessor values in a contiguous array. - * - * @private - */ - function readAccessorPacked(gltf, accessor) { - var byteStride = getAccessorByteStride(gltf, accessor); - var componentTypeByteLength = ComponentDatatype.getSizeInBytes(accessor.componentType); - var numberOfComponents = numberOfComponentsForType(accessor.type); - var count = accessor.count; - var values = new Array(numberOfComponents * count); +/** + * Returns the accessor data in a contiguous array. + * + * @param {Object} gltf A javascript object containing a glTF asset. + * @param {Object} accessor The accessor. + * @returns {Array} The accessor values in a contiguous array. + * + * @private + */ +function readAccessorPacked(gltf, accessor) { + var byteStride = getAccessorByteStride(gltf, accessor); + var componentTypeByteLength = ComponentDatatype.getSizeInBytes(accessor.componentType); + var numberOfComponents = numberOfComponentsForType(accessor.type); + var count = accessor.count; + var values = new Array(numberOfComponents * count); - if (!defined(accessor.bufferView)) { - arrayFill(values, 0); - return values; - } + if (!defined(accessor.bufferView)) { + arrayFill(values, 0); + return values; + } - var bufferView = gltf.bufferViews[accessor.bufferView]; - var source = gltf.buffers[bufferView.buffer].extras._pipeline.source; - var byteOffset = accessor.byteOffset + bufferView.byteOffset + source.byteOffset; + var bufferView = gltf.bufferViews[accessor.bufferView]; + var source = gltf.buffers[bufferView.buffer].extras._pipeline.source; + var byteOffset = accessor.byteOffset + bufferView.byteOffset + source.byteOffset; - var dataView = new DataView(source.buffer); - var components = new Array(numberOfComponents); - var componentReader = getComponentReader(accessor.componentType); + var dataView = new DataView(source.buffer); + var components = new Array(numberOfComponents); + var componentReader = getComponentReader(accessor.componentType); - for (var i = 0; i < count; ++i) { - componentReader(dataView, byteOffset, numberOfComponents, componentTypeByteLength, components); - for (var j = 0; j < numberOfComponents; ++j) { - values[i * numberOfComponents + j] = components[j]; - } - byteOffset += byteStride; + for (var i = 0; i < count; ++i) { + componentReader(dataView, byteOffset, numberOfComponents, componentTypeByteLength, components); + for (var j = 0; j < numberOfComponents; ++j) { + values[i * numberOfComponents + j] = components[j]; } - return values; + byteOffset += byteStride; } + return values; +} - export default readAccessorPacked; +export default readAccessorPacked; diff --git a/Source/ThirdParty/GltfPipeline/removeExtensionsRequired.js b/Source/ThirdParty/GltfPipeline/removeExtensionsRequired.js index ba60c8211525..44fb89ddfd5e 100644 --- a/Source/ThirdParty/GltfPipeline/removeExtensionsRequired.js +++ b/Source/ThirdParty/GltfPipeline/removeExtensionsRequired.js @@ -1,24 +1,24 @@ -import defined from '../../Core/defined.js' +import defined from "../../Core/defined.js" - /** - * Removes an extension from gltf.extensionsRequired if it is present. - * - * @param {Object} gltf A javascript object containing a glTF asset. - * @param {String} extension The extension to remove. - * - * @private - */ - function removeExtensionsRequired(gltf, extension) { - var extensionsRequired = gltf.extensionsRequired; - if (defined(extensionsRequired)) { - var index = extensionsRequired.indexOf(extension); - if (index >= 0) { - extensionsRequired.splice(index, 1); - } - if (extensionsRequired.length === 0) { - delete gltf.extensionsRequired; - } +/** + * Removes an extension from gltf.extensionsRequired if it is present. + * + * @param {Object} gltf A javascript object containing a glTF asset. + * @param {String} extension The extension to remove. + * + * @private + */ +function removeExtensionsRequired(gltf, extension) { + var extensionsRequired = gltf.extensionsRequired; + if (defined(extensionsRequired)) { + var index = extensionsRequired.indexOf(extension); + if (index >= 0) { + extensionsRequired.splice(index, 1); + } + if (extensionsRequired.length === 0) { + delete gltf.extensionsRequired; } } +} - export default removeExtensionsRequired; +export default removeExtensionsRequired; diff --git a/Source/ThirdParty/GltfPipeline/removeExtensionsUsed.js b/Source/ThirdParty/GltfPipeline/removeExtensionsUsed.js index 83f8aad1ee38..28d199c18a55 100644 --- a/Source/ThirdParty/GltfPipeline/removeExtensionsUsed.js +++ b/Source/ThirdParty/GltfPipeline/removeExtensionsUsed.js @@ -1,26 +1,26 @@ -import removeExtensionsRequired from './removeExtensionsRequired.js' -import defined from '../../Core/defined.js' +import removeExtensionsRequired from "./removeExtensionsRequired.js" +import defined from "../../Core/defined.js" - /** - * Removes an extension from gltf.extensionsUsed and gltf.extensionsRequired if it is present. - * - * @param {Object} gltf A javascript object containing a glTF asset. - * @param {String} extension The extension to remove. - * - * @private - */ - function removeExtensionsUsed(gltf, extension) { - var extensionsUsed = gltf.extensionsUsed; - if (defined(extensionsUsed)) { - var index = extensionsUsed.indexOf(extension); - if (index >= 0) { - extensionsUsed.splice(index, 1); - } - removeExtensionsRequired(gltf, extension); - if (extensionsUsed.length === 0) { - delete gltf.extensionsUsed; - } +/** + * Removes an extension from gltf.extensionsUsed and gltf.extensionsRequired if it is present. + * + * @param {Object} gltf A javascript object containing a glTF asset. + * @param {String} extension The extension to remove. + * + * @private + */ +function removeExtensionsUsed(gltf, extension) { + var extensionsUsed = gltf.extensionsUsed; + if (defined(extensionsUsed)) { + var index = extensionsUsed.indexOf(extension); + if (index >= 0) { + extensionsUsed.splice(index, 1); + } + removeExtensionsRequired(gltf, extension); + if (extensionsUsed.length === 0) { + delete gltf.extensionsUsed; } } +} - export default removeExtensionsUsed; +export default removeExtensionsUsed; diff --git a/Source/ThirdParty/GltfPipeline/removePipelineExtras.js b/Source/ThirdParty/GltfPipeline/removePipelineExtras.js index 25fcbf760e81..5e5cdcac2fec 100644 --- a/Source/ThirdParty/GltfPipeline/removePipelineExtras.js +++ b/Source/ThirdParty/GltfPipeline/removePipelineExtras.js @@ -1,45 +1,42 @@ -import ForEach from './ForEach.js' -import defined from '../../Core/defined.js' +import ForEach from "./ForEach.js" +import defined from "../../Core/defined.js" - /** - * Iterate through the objects within the glTF and delete their pipeline extras object. - * - * @param {Object} gltf A javascript object containing a glTF asset. - * @returns {Object} glTF with no pipeline extras. - * - * @private - */ - function removePipelineExtras(gltf) { - ForEach.shader(gltf, function(shader) { - removeExtras(shader); - }); - ForEach.buffer(gltf, function(buffer) { - removeExtras(buffer); - }); - ForEach.image(gltf, function (image) { - removeExtras(image); - ForEach.compressedImage(image, function(compressedImage) { - removeExtras(compressedImage); - }); - }); +/** + * Iterate through the objects within the glTF and delete their pipeline extras object. + * + * @param {Object} gltf A javascript object containing a glTF asset. + * @returns {Object} glTF with no pipeline extras. + * + * @private + */ +function removePipelineExtras(gltf) { + ForEach.shader(gltf, function(shader) { + removeExtras(shader); + }); + ForEach.buffer(gltf, function(buffer) { + removeExtras(buffer); + }); + ForEach.image(gltf, function (image) { + removeExtras(image); + }); - removeExtras(gltf); + removeExtras(gltf); - return gltf; - } + return gltf; +} - function removeExtras(object) { - if (!defined(object.extras)) { - return; - } +function removeExtras(object) { + if (!defined(object.extras)) { + return; + } - if (defined(object.extras._pipeline)) { - delete object.extras._pipeline; - } + if (defined(object.extras._pipeline)) { + delete object.extras._pipeline; + } - if (Object.keys(object.extras).length === 0) { - delete object.extras; - } + if (Object.keys(object.extras).length === 0) { + delete object.extras; } +} - export default removePipelineExtras; +export default removePipelineExtras; diff --git a/Source/ThirdParty/GltfPipeline/removeUnusedElements.js b/Source/ThirdParty/GltfPipeline/removeUnusedElements.js index c7b5789c6a54..1852368da75b 100644 --- a/Source/ThirdParty/GltfPipeline/removeUnusedElements.js +++ b/Source/ThirdParty/GltfPipeline/removeUnusedElements.js @@ -1,428 +1,655 @@ -import ForEach from './ForEach.js' -import usesExtension from './usesExtension.js' -import defaultValue from '../../Core/defaultValue.js' -import defined from '../../Core/defined.js' - - var allElementTypes = ['mesh', 'node', 'material', 'accessor', 'bufferView', 'buffer']; - - /** - * Removes unused elements from gltf. - * - * @param {Object} gltf A javascript object containing a glTF asset. - * @param {String[]} [elementTypes=['mesh', 'node', 'material', 'accessor', 'bufferView', 'buffer']] Element types to be removed. Needs to be a subset of ['mesh', 'node', 'material', 'accessor', 'bufferView', 'buffer'], other items will be ignored. - * - * @private - */ - function removeUnusedElements(gltf, elementTypes) { - elementTypes = defaultValue(elementTypes, allElementTypes); - allElementTypes.forEach(function(type) { - if (elementTypes.indexOf(type) > -1) { - removeUnusedElementsByType(gltf, type); - } - }); - return gltf; - } - - var TypeToGltfElementName = { - accessor: 'accessors', - buffer: 'buffers', - bufferView: 'bufferViews', - node: 'nodes', - material: 'materials', - mesh: 'meshes' - }; - - function removeUnusedElementsByType(gltf, type) { - var name = TypeToGltfElementName[type]; - var arrayOfObjects = gltf[name]; - - if (defined(arrayOfObjects)) { - var removed = 0; - var usedIds = getListOfElementsIdsInUse[type](gltf); - var length = arrayOfObjects.length; - - for (var i = 0; i < length; ++i) { - if (!usedIds[i]) { - Remove[type](gltf, i - removed); - removed++; - } +import ForEach from "./ForEach.js" +import forEachTextureInMaterial from "./forEachTextureInMaterial.js" +import usesExtension from "./usesExtension.js" +import defaultValue from "../../Core/defaultValue.js" +import defined from "../../Core/defined.js" + +var allElementTypes = ['mesh', 'node', 'material', 'accessor', 'bufferView', 'buffer', 'texture', 'sampler', 'image']; + +/** + * Removes unused elements from gltf. + * + * @param {Object} gltf A javascript object containing a glTF asset. + * @param {String[]} [elementTypes=['mesh', 'node', 'material', 'accessor', 'bufferView', 'buffer']] Element types to be removed. Needs to be a subset of ['mesh', 'node', 'material', 'accessor', 'bufferView', 'buffer'], other items will be ignored. + * + * @private + */ +function removeUnusedElements(gltf, elementTypes) { + elementTypes = defaultValue(elementTypes, allElementTypes); + allElementTypes.forEach(function(type) { + if (elementTypes.indexOf(type) > -1) { + removeUnusedElementsByType(gltf, type); + } + }); + return gltf; +} + +var TypeToGltfElementName = { + accessor: 'accessors', + buffer: 'buffers', + bufferView: 'bufferViews', + image: 'images', + node: 'nodes', + material: 'materials', + mesh: 'meshes', + sampler: 'samplers', + texture: 'textures' +}; + +function removeUnusedElementsByType(gltf, type) { + var name = TypeToGltfElementName[type]; + var arrayOfObjects = gltf[name]; + + if (defined(arrayOfObjects)) { + var removed = 0; + var usedIds = getListOfElementsIdsInUse[type](gltf); + var length = arrayOfObjects.length; + + for (var i = 0; i < length; ++i) { + if (!usedIds[i]) { + Remove[type](gltf, i - removed); + removed++; } } } +} + +/** + * Contains functions for removing elements from a glTF hierarchy. + * Since top-level glTF elements are arrays, when something is removed, referring + * indices need to be updated. + * @constructor + * + * @private + */ +function Remove() {} + +Remove.accessor = function(gltf, accessorId) { + var accessors = gltf.accessors; + + accessors.splice(accessorId, 1); + + ForEach.mesh(gltf, function(mesh) { + ForEach.meshPrimitive(mesh, function(primitive) { + // Update accessor ids for the primitives. + ForEach.meshPrimitiveAttribute(primitive, function(attributeAccessorId, semantic) { + if (attributeAccessorId > accessorId) { + primitive.attributes[semantic]--; + } + }); - /** - * Contains functions for removing elements from a glTF hierarchy. - * Since top-level glTF elements are arrays, when something is removed, referring - * indices need to be updated. - * @constructor - * - * @private - */ - function Remove() {} - - Remove.accessor = function(gltf, accessorId) { - var accessors = gltf.accessors; - - accessors.splice(accessorId, 1); - - ForEach.mesh(gltf, function(mesh) { - ForEach.meshPrimitive(mesh, function(primitive) { - // Update accessor ids for the primitives. - ForEach.meshPrimitiveAttribute(primitive, function(attributeAccessorId, semantic) { + // Update accessor ids for the targets. + ForEach.meshPrimitiveTarget(primitive, function(target) { + ForEach.meshPrimitiveTargetAttribute(target, function(attributeAccessorId, semantic) { if (attributeAccessorId > accessorId) { - primitive.attributes[semantic]--; + target[semantic]--; } }); - - // Update accessor ids for the targets. - ForEach.meshPrimitiveTarget(primitive, function(target) { - ForEach.meshPrimitiveTargetAttribute(target, function(attributeAccessorId, semantic) { - if (attributeAccessorId > accessorId) { - target[semantic]--; - } - }); - }); - var indices = primitive.indices; - if (defined(indices) && indices > accessorId) { - primitive.indices--; - } }); + var indices = primitive.indices; + if (defined(indices) && indices > accessorId) { + primitive.indices--; + } }); + }); + + ForEach.skin(gltf, function(skin) { + if (defined(skin.inverseBindMatrices) && skin.inverseBindMatrices > accessorId) { + skin.inverseBindMatrices--; + } + }); - ForEach.skin(gltf, function(skin) { - if (defined(skin.inverseBindMatrices) && skin.inverseBindMatrices > accessorId) { - skin.inverseBindMatrices--; + ForEach.animation(gltf, function(animation) { + ForEach.animationSampler(animation, function(sampler) { + if (defined(sampler.input) && sampler.input > accessorId) { + sampler.input--; + } + if (defined(sampler.output) && sampler.output > accessorId) { + sampler.output--; } }); + }); +}; - ForEach.animation(gltf, function(animation) { - ForEach.animationSampler(animation, function(sampler) { - if (defined(sampler.input) && sampler.input > accessorId) { - sampler.input--; - } - if (defined(sampler.output) && sampler.output > accessorId) { - sampler.output--; - } - }); - }); - }; +Remove.buffer = function(gltf, bufferId) { + var buffers = gltf.buffers; - Remove.buffer = function(gltf, bufferId) { - var buffers = gltf.buffers; + buffers.splice(bufferId, 1); - buffers.splice(bufferId, 1); + ForEach.bufferView(gltf, function(bufferView) { + if (defined(bufferView.buffer) && bufferView.buffer > bufferId) { + bufferView.buffer--; + } + }); +}; - ForEach.bufferView(gltf, function(bufferView) { - if (defined(bufferView.buffer) && bufferView.buffer > bufferId) { - bufferView.buffer--; - } - }); - }; +Remove.bufferView = function(gltf, bufferViewId) { + var bufferViews = gltf.bufferViews; - Remove.bufferView = function(gltf, bufferViewId) { - var bufferViews = gltf.bufferViews; + bufferViews.splice(bufferViewId, 1); - bufferViews.splice(bufferViewId, 1); + ForEach.accessor(gltf, function(accessor) { + if (defined(accessor.bufferView) && accessor.bufferView > bufferViewId) { + accessor.bufferView--; + } + }); - ForEach.accessor(gltf, function(accessor) { - if (defined(accessor.bufferView) && accessor.bufferView > bufferViewId) { - accessor.bufferView--; - } - }); + ForEach.shader(gltf, function(shader) { + if (defined(shader.bufferView) && shader.bufferView > bufferViewId) { + shader.bufferView--; + } + }); - ForEach.shader(gltf, function(shader) { - if (defined(shader.bufferView) && shader.bufferView > bufferViewId) { - shader.bufferView--; - } - }); + ForEach.image(gltf, function(image) { + if (defined(image.bufferView) && image.bufferView > bufferViewId) { + image.bufferView--; + } + }); - ForEach.image(gltf, function(image) { - if (defined(image.bufferView) && image.bufferView > bufferViewId) { - image.bufferView--; - } - ForEach.compressedImage(image, function(compressedImage) { - var compressedImageBufferView = compressedImage.bufferView; - if (defined(compressedImageBufferView) && compressedImageBufferView > bufferViewId) { - compressedImage.bufferView--; + if (usesExtension(gltf, 'KHR_draco_mesh_compression')) { + ForEach.mesh(gltf, function(mesh) { + ForEach.meshPrimitive(mesh, function(primitive) { + if (defined(primitive.extensions) && + defined(primitive.extensions.KHR_draco_mesh_compression)) { + if (primitive.extensions.KHR_draco_mesh_compression.bufferView > bufferViewId) { + primitive.extensions.KHR_draco_mesh_compression.bufferView--; + } } }); }); + } - if (usesExtension(gltf, 'KHR_draco_mesh_compression')) { - ForEach.mesh(gltf, function(mesh) { - ForEach.meshPrimitive(mesh, function(primitive) { - if (defined(primitive.extensions) && - defined(primitive.extensions.KHR_draco_mesh_compression)) { - if (primitive.extensions.KHR_draco_mesh_compression.bufferView > bufferViewId) { - primitive.extensions.KHR_draco_mesh_compression.bufferView--; + if (usesExtension(gltf, 'EXT_feature_metadata')) { + var extension = gltf.extensions.EXT_feature_metadata; + var featureTables = extension.featureTables; + for (var featureTableId in featureTables) { + if (featureTables.hasOwnProperty(featureTableId)) { + var featureTable = featureTables[featureTableId]; + var properties = featureTable.properties; + if (defined(properties)) { + for (var propertyId in properties) { + if (properties.hasOwnProperty(propertyId)) { + var property = properties[propertyId]; + if (defined(property.bufferView) && property.bufferView > bufferViewId) { + property.bufferView--; + } + if (defined(property.arrayOffsetBufferView) && property.arrayOffsetBufferView > bufferViewId) { + property.arrayOffsetBufferView--; + } + if (defined(property.stringOffsetBufferView) && property.stringOffsetBufferView > bufferViewId) { + property.stringOffsetBufferView--; + } } } - }); - }); + } + } } - }; + } +}; - Remove.mesh = function(gltf, meshId) { - var meshes = gltf.meshes; - meshes.splice(meshId, 1); +Remove.image = function(gltf, imageId) { + var images = gltf.images; + images.splice(imageId, 1); - ForEach.node(gltf, function(node) { - if (defined(node.mesh)) { - if (node.mesh > meshId) { - node.mesh--; - } else if (node.mesh === meshId) { - // Remove reference to deleted mesh - delete node.mesh; - } + ForEach.texture(gltf, function (texture) { + if (defined(texture.source)) { + if (texture.source > imageId) { + --texture.source; } - }); - }; + } + var ext = texture.extensions; + if (defined(ext) && defined(ext.EXT_texture_webp) && ext.EXT_texture_webp.source > imageId) { + --texture.extensions.EXT_texture_webp.source; + } else if (defined(ext) && defined(ext.KHR_texture_basisu) && ext.KHR_texture_basisu.source > imageId) { + --texture.extensions.KHR_texture_basisu.source; + } + }); +}; + +Remove.mesh = function(gltf, meshId) { + var meshes = gltf.meshes; + meshes.splice(meshId, 1); + + ForEach.node(gltf, function(node) { + if (defined(node.mesh)) { + if (node.mesh > meshId) { + node.mesh--; + } else if (node.mesh === meshId) { + // Remove reference to deleted mesh + delete node.mesh; + } + } + }); +}; - Remove.node = function(gltf, nodeId) { - var nodes = gltf.nodes; - nodes.splice(nodeId, 1); +Remove.node = function(gltf, nodeId) { + var nodes = gltf.nodes; + nodes.splice(nodeId, 1); - // Shift all node references - ForEach.skin(gltf, function(skin) { - if (defined(skin.skeleton) && skin.skeleton > nodeId) { - skin.skeleton--; - } + // Shift all node references + ForEach.skin(gltf, function(skin) { + if (defined(skin.skeleton) && skin.skeleton > nodeId) { + skin.skeleton--; + } - skin.joints = skin.joints.map(function(x) { - return x > nodeId ? x - 1 : x; - }); + skin.joints = skin.joints.map(function(x) { + return x > nodeId ? x - 1 : x; }); - ForEach.animation(gltf, function(animation) { - ForEach.animationChannel(animation, function(channel) { - if (defined(channel.target) && defined(channel.target.node) && (channel.target.node > nodeId)) { - channel.target.node--; - } - }); + }); + ForEach.animation(gltf, function(animation) { + ForEach.animationChannel(animation, function(channel) { + if (defined(channel.target) && defined(channel.target.node) && (channel.target.node > nodeId)) { + channel.target.node--; + } }); - ForEach.technique(gltf, function(technique) { - ForEach.techniqueUniform(technique, function(uniform) { - if (defined(uniform.node) && uniform.node > nodeId) { - uniform.node--; - } + }); + ForEach.technique(gltf, function(technique) { + ForEach.techniqueUniform(technique, function(uniform) { + if (defined(uniform.node) && uniform.node > nodeId) { + uniform.node--; + } + }); + }); + ForEach.node(gltf, function(node) { + if (!defined(node.children)) { + return; + } + + node.children = node.children + .filter(function(x) { + return x !== nodeId; // Remove + }) + .map(function(x) { + return x > nodeId ? x - 1 : x; // Shift indices }); + }); + ForEach.scene(gltf, function(scene) { + scene.nodes = scene.nodes + .filter(function(x) { + return x !== nodeId; // Remove + }) + .map(function(x) { + return x > nodeId ? x - 1 : x; // Shift indices + }); + }); +}; + +Remove.material = function(gltf, materialId) { + var materials = gltf.materials; + materials.splice(materialId, 1); + + // Shift other material ids + ForEach.mesh(gltf, function(mesh) { + ForEach.meshPrimitive(mesh, function(primitive) { + if (defined(primitive.material) && primitive.material > materialId) { + primitive.material--; + } }); - ForEach.node(gltf, function(node) { - if (!defined(node.children)) { - return; + }); +}; + +Remove.sampler = function(gltf, samplerId) { + var samplers = gltf.samplers; + samplers.splice(samplerId, 1); + + ForEach.texture(gltf, function (texture) { + if (defined(texture.sampler)) { + if (texture.sampler > samplerId) { + --texture.sampler; } + } + }); +}; - node.children = node.children - .filter(function(x) { - return x !== nodeId; // Remove - }) - .map(function(x) { - return x > nodeId ? x - 1 : x; // Shift indices - }); - }); - ForEach.scene(gltf, function(scene) { - scene.nodes = scene.nodes - .filter(function(x) { - return x !== nodeId; // Remove - }) - .map(function(x) { - return x > nodeId ? x - 1 : x; // Shift indices - }); - }); - }; +Remove.texture = function(gltf, textureId) { + var textures = gltf.textures; + textures.splice(textureId, 1); - Remove.material = function(gltf, materialId) { - var materials = gltf.materials; - materials.splice(materialId, 1); + ForEach.material(gltf, function (material) { + forEachTextureInMaterial(material, function (textureIndex, textureInfo) { + if (textureInfo.index > textureId) { + --textureInfo.index; + } + }); + }); - // Shift other material ids + if (usesExtension(gltf, 'EXT_feature_metadata')) { ForEach.mesh(gltf, function(mesh) { ForEach.meshPrimitive(mesh, function(primitive) { - if (defined(primitive.material) && primitive.material > materialId) { - primitive.material--; + var extensions = primitive.extensions; + if (defined(extensions) && defined(extensions.EXT_feature_metadata)) { + var extension = extensions.EXT_feature_metadata; + var featureIdTextures = extension.featureIdTextures; + if (defined(featureIdTextures)) { + var featureIdTexturesLength = featureIdTextures.length; + for (var i = 0; i < featureIdTexturesLength; ++i) { + var featureIdTexture = featureIdTextures[i]; + var textureInfo = featureIdTexture.featureIds.texture; + if (textureInfo.index > textureId) { + --textureInfo.index; + } + } + } } }); }); - }; - - /** - * Contains functions for getting a list of element ids in use by the glTF asset. - * @constructor - * - * @private - */ - function getListOfElementsIdsInUse() {} - getListOfElementsIdsInUse.accessor = function(gltf) { - // Calculate accessor's that are currently in use. - var usedAccessorIds = {}; - - ForEach.mesh(gltf, function(mesh) { - ForEach.meshPrimitive(mesh, function(primitive) { - ForEach.meshPrimitiveAttribute(primitive, function(accessorId) { + var extension = gltf.extensions.EXT_feature_metadata; + var featureTextures = extension.featureTextures; + for (var featureTextureId in featureTextures) { + if (featureTextures.hasOwnProperty(featureTextureId)) { + var featureTexture = featureTextures[featureTextureId]; + var properties = featureTexture.properties; + if (defined(properties)) { + for (var propertyId in properties) { + if (properties.hasOwnProperty(propertyId)) { + var property = properties[propertyId]; + var textureInfo = property.texture; + if (textureInfo.index > textureId) { + --textureInfo.index; + } + } + } + } + } + } + } +}; + +/** + * Contains functions for getting a list of element ids in use by the glTF asset. + * @constructor + * + * @private + */ +function getListOfElementsIdsInUse() {} + +getListOfElementsIdsInUse.accessor = function(gltf) { + // Calculate accessor's that are currently in use. + var usedAccessorIds = {}; + + ForEach.mesh(gltf, function(mesh) { + ForEach.meshPrimitive(mesh, function(primitive) { + ForEach.meshPrimitiveAttribute(primitive, function(accessorId) { + usedAccessorIds[accessorId] = true; + }); + ForEach.meshPrimitiveTarget(primitive, function(target) { + ForEach.meshPrimitiveTargetAttribute(target, function(accessorId) { usedAccessorIds[accessorId] = true; }); - ForEach.meshPrimitiveTarget(primitive, function(target) { - ForEach.meshPrimitiveTargetAttribute(target, function(accessorId) { - usedAccessorIds[accessorId] = true; - }); - }); - var indices = primitive.indices; - if (defined(indices)) { - usedAccessorIds[indices] = true; - } }); + var indices = primitive.indices; + if (defined(indices)) { + usedAccessorIds[indices] = true; + } }); + }); + + ForEach.skin(gltf, function(skin) { + if (defined(skin.inverseBindMatrices)) { + usedAccessorIds[skin.inverseBindMatrices] = true; + } + }); - ForEach.skin(gltf, function(skin) { - if (defined(skin.inverseBindMatrices)) { - usedAccessorIds[skin.inverseBindMatrices] = true; + ForEach.animation(gltf, function(animation) { + ForEach.animationSampler(animation, function(sampler) { + if (defined(sampler.input)) { + usedAccessorIds[sampler.input] = true; + } + if (defined(sampler.output)) { + usedAccessorIds[sampler.output] = true; } }); + }); - ForEach.animation(gltf, function(animation) { - ForEach.animationSampler(animation, function(sampler) { - if (defined(sampler.input)) { - usedAccessorIds[sampler.input] = true; - } - if (defined(sampler.output)) { - usedAccessorIds[sampler.output] = true; - } - }); + if (usesExtension(gltf, 'EXT_mesh_gpu_instancing')) { + ForEach.node(gltf, function(node) { + if (defined(node.extensions) && defined(node.extensions.EXT_mesh_gpu_instancing)) { + Object.keys(node.extensions.EXT_mesh_gpu_instancing.attributes).forEach(function(key) { + var attributeAccessorId = node.extensions.EXT_mesh_gpu_instancing.attributes[key]; + usedAccessorIds[attributeAccessorId] = true; + }); + } }); + } - return usedAccessorIds; - }; + return usedAccessorIds; +}; - getListOfElementsIdsInUse.buffer = function(gltf) { - // Calculate buffer's that are currently in use. - var usedBufferIds = {}; +getListOfElementsIdsInUse.buffer = function(gltf) { + // Calculate buffer's that are currently in use. + var usedBufferIds = {}; - ForEach.bufferView(gltf, function(bufferView) { - if (defined(bufferView.buffer)) { - usedBufferIds[bufferView.buffer] = true; - } - }); + ForEach.bufferView(gltf, function(bufferView) { + if (defined(bufferView.buffer)) { + usedBufferIds[bufferView.buffer] = true; + } + }); - return usedBufferIds; - }; + return usedBufferIds; +}; - getListOfElementsIdsInUse.bufferView = function(gltf) { - // Calculate bufferView's that are currently in use. - var usedBufferViewIds = {}; +getListOfElementsIdsInUse.bufferView = function(gltf) { + // Calculate bufferView's that are currently in use. + var usedBufferViewIds = {}; - ForEach.accessor(gltf, function(accessor) { - if (defined(accessor.bufferView)) { - usedBufferViewIds[accessor.bufferView] = true; - } - }); + ForEach.accessor(gltf, function(accessor) { + if (defined(accessor.bufferView)) { + usedBufferViewIds[accessor.bufferView] = true; + } + }); - ForEach.shader(gltf, function(shader) { - if (defined(shader.bufferView)) { - usedBufferViewIds[shader.bufferView] = true; - } - }); + ForEach.shader(gltf, function(shader) { + if (defined(shader.bufferView)) { + usedBufferViewIds[shader.bufferView] = true; + } + }); - ForEach.image(gltf, function(image) { - if (defined(image.bufferView)) { - usedBufferViewIds[image.bufferView] = true; - } - ForEach.compressedImage(image, function(compressedImage) { - if (defined(compressedImage.bufferView)) { - usedBufferViewIds[compressedImage.bufferView] = true; + ForEach.image(gltf, function(image) { + if (defined(image.bufferView)) { + usedBufferViewIds[image.bufferView] = true; + } + }); + + if (usesExtension(gltf, 'KHR_draco_mesh_compression')) { + ForEach.mesh(gltf, function(mesh) { + ForEach.meshPrimitive(mesh, function(primitive) { + if (defined(primitive.extensions) && + defined(primitive.extensions.KHR_draco_mesh_compression)) { + usedBufferViewIds[primitive.extensions.KHR_draco_mesh_compression.bufferView] = true; } }); }); + } - if (usesExtension(gltf, 'KHR_draco_mesh_compression')) { - ForEach.mesh(gltf, function(mesh) { - ForEach.meshPrimitive(mesh, function(primitive) { - if (defined(primitive.extensions) && - defined(primitive.extensions.KHR_draco_mesh_compression)) { - usedBufferViewIds[primitive.extensions.KHR_draco_mesh_compression.bufferView] = true; + if (usesExtension(gltf, 'EXT_feature_metadata')) { + var extension = gltf.extensions.EXT_feature_metadata; + var featureTables = extension.featureTables; + for (var featureTableId in featureTables) { + if (featureTables.hasOwnProperty(featureTableId)) { + var featureTable = featureTables[featureTableId]; + var properties = featureTable.properties; + if (defined(properties)) { + for (var propertyId in properties) { + if (properties.hasOwnProperty(propertyId)) { + var property = properties[propertyId]; + if (defined(property.bufferView)) { + usedBufferViewIds[property.bufferView] = true; + } + if (defined(property.arrayOffsetBufferView)) { + usedBufferViewIds[property.arrayOffsetBufferView] = true; + } + if (defined(property.stringOffsetBufferView)) { + usedBufferViewIds[property.stringOffsetBufferView] = true; + } + } } - }); - }); + } + } } + } - return usedBufferViewIds; - }; + return usedBufferViewIds; +}; - getListOfElementsIdsInUse.mesh = function(gltf) { - var usedMeshIds = {}; - ForEach.node(gltf, function(node) { - if (defined(node.mesh && defined(gltf.meshes))) { - var mesh = gltf.meshes[node.mesh]; - if (defined(mesh) && defined(mesh.primitives) && (mesh.primitives.length > 0)) { - usedMeshIds[node.mesh] = true; - } - } - }); +getListOfElementsIdsInUse.image = function(gltf) { + var usedImageIds = {}; - return usedMeshIds; - }; + ForEach.texture(gltf, function (texture) { + if (defined(texture.source)) { + usedImageIds[texture.source] = true; + } - // Check if node is empty. It is considered empty if neither referencing - // mesh, camera, extensions and has no children - function nodeIsEmpty(gltf, node) { - if (defined(node.mesh) || defined(node.camera) || defined(node.skin) - || defined(node.weights) || defined(node.extras) - || (defined(node.extensions) && node.extensions.length !== 0)) { - return false; + if (defined(texture.extensions) && defined(texture.extensions.EXT_texture_webp)) { + usedImageIds[texture.extensions.EXT_texture_webp.source] = true; + } else if (defined(texture.extensions) && defined(texture.extensions.KHR_texture_basisu)) { + usedImageIds[texture.extensions.KHR_texture_basisu.source] = true; } - // Empty if no children or children are all empty nodes - return !defined(node.children) - || node.children.filter(function(n) { - return !nodeIsEmpty(gltf, gltf.nodes[n]); - }).length === 0; + }); + return usedImageIds; +}; + +getListOfElementsIdsInUse.mesh = function(gltf) { + var usedMeshIds = {}; + ForEach.node(gltf, function(node) { + if (defined(node.mesh && defined(gltf.meshes))) { + var mesh = gltf.meshes[node.mesh]; + if (defined(mesh) && defined(mesh.primitives) && (mesh.primitives.length > 0)) { + usedMeshIds[node.mesh] = true; + } + } + }); + + return usedMeshIds; +}; + +// Check if node is empty. It is considered empty if neither referencing +// mesh, camera, extensions and has no children +function nodeIsEmpty(gltf, nodeId, usedNodeIds) { + var node = gltf.nodes[nodeId]; + if (defined(node.mesh) || defined(node.camera) || defined(node.skin) + || defined(node.weights) || defined(node.extras) + || (defined(node.extensions) && Object.keys(node.extensions).length !== 0) + || defined(usedNodeIds[nodeId])) { + return false; } - getListOfElementsIdsInUse.node = function(gltf) { - var usedNodeIds = {}; - ForEach.node(gltf, function(node, nodeId) { - if (!nodeIsEmpty(gltf, node)) { - usedNodeIds[nodeId] = true; - } + // Empty if no children or children are all empty nodes + return !defined(node.children) + || node.children.filter(function(n) { + return !nodeIsEmpty(gltf, n, usedNodeIds); + }).length === 0; +} + +getListOfElementsIdsInUse.node = function(gltf) { + var usedNodeIds = {}; + ForEach.skin(gltf, function(skin) { + if (defined(skin.skeleton)) { + usedNodeIds[skin.skeleton] = true; + } + + ForEach.skinJoint(skin, function(joint) { + usedNodeIds[joint] = true; }); - ForEach.skin(gltf, function(skin) { - if (defined(skin.skeleton)) { - usedNodeIds[skin.skeleton] = true; + }); + ForEach.animation(gltf, function(animation) { + ForEach.animationChannel(animation, function(channel) { + if (defined(channel.target) && defined(channel.target.node)) { + usedNodeIds[channel.target.node] = true; } - - ForEach.skinJoint(skin, function(joint) { - usedNodeIds[joint] = true; - }); }); - ForEach.animation(gltf, function(animation) { - ForEach.animationChannel(animation, function(channel) { - if (defined(channel.target) && defined(channel.target.node)) { - usedNodeIds[channel.target.node] = true; - } - }); + }); + ForEach.technique(gltf, function(technique) { + ForEach.techniqueUniform(technique, function(uniform) { + if (defined(uniform.node)) { + usedNodeIds[uniform.node] = true; + } }); - ForEach.technique(gltf, function(technique) { - ForEach.techniqueUniform(technique, function(uniform) { - if (defined(uniform.node)) { - usedNodeIds[uniform.node] = true; - } - }); + }); + ForEach.node(gltf, function(node, nodeId) { + if (!nodeIsEmpty(gltf, nodeId, usedNodeIds)) { + usedNodeIds[nodeId] = true; + } + }); + + return usedNodeIds; +}; + +getListOfElementsIdsInUse.material = function(gltf) { + var usedMaterialIds = {}; + + ForEach.mesh(gltf, function(mesh) { + ForEach.meshPrimitive(mesh, function(primitive) { + if (defined(primitive.material)) { + usedMaterialIds[primitive.material] = true; + } }); + }); + + return usedMaterialIds; +}; - return usedNodeIds; - }; +getListOfElementsIdsInUse.texture = function(gltf) { + var usedTextureIds = {}; - getListOfElementsIdsInUse.material = function(gltf) { - var usedMaterialIds = {}; + ForEach.material(gltf, function(material) { + forEachTextureInMaterial(material, function(textureId) { + usedTextureIds[textureId] = true; + }); + }); + if (usesExtension(gltf, 'EXT_feature_metadata')) { ForEach.mesh(gltf, function(mesh) { ForEach.meshPrimitive(mesh, function(primitive) { - if (defined(primitive.material)) { - usedMaterialIds[primitive.material] = true; + var extensions = primitive.extensions; + if (defined(extensions) && defined(extensions.EXT_feature_metadata)) { + var extension = extensions.EXT_feature_metadata; + var featureIdTextures = extension.featureIdTextures; + if (defined(featureIdTextures)) { + var featureIdTexturesLength = featureIdTextures.length; + for (var i = 0; i < featureIdTexturesLength; ++i) { + var featureIdTexture = featureIdTextures[i]; + var textureInfo = featureIdTexture.featureIds.texture; + usedTextureIds[textureInfo.index] = true; + } + } } }); }); - return usedMaterialIds; - }; + var extension = gltf.extensions.EXT_feature_metadata; + var featureTextures = extension.featureTextures; + for (var featureTextureId in featureTextures) { + if (featureTextures.hasOwnProperty(featureTextureId)) { + var featureTexture = featureTextures[featureTextureId]; + var properties = featureTexture.properties; + if (defined(properties)) { + for (var propertyId in properties) { + if (properties.hasOwnProperty(propertyId)) { + var property = properties[propertyId]; + var textureInfo = property.texture; + usedTextureIds[textureInfo.index] = true; + } + } + } + } + } + } + + return usedTextureIds; +}; + +getListOfElementsIdsInUse.sampler = function(gltf) { + var usedSamplerIds = {}; + + ForEach.texture(gltf, function (texture) { + if (defined(texture.sampler)) { + usedSamplerIds[texture.sampler] = true; + } + }); + + return usedSamplerIds; +}; - export default removeUnusedElements; +export default removeUnusedElements; diff --git a/Source/ThirdParty/GltfPipeline/updateAccessorComponentTypes.js b/Source/ThirdParty/GltfPipeline/updateAccessorComponentTypes.js index 1efcb7bfe76e..fd035af0723e 100644 --- a/Source/ThirdParty/GltfPipeline/updateAccessorComponentTypes.js +++ b/Source/ThirdParty/GltfPipeline/updateAccessorComponentTypes.js @@ -1,48 +1,48 @@ -import addBuffer from './addBuffer.js' -import ForEach from './ForEach.js' -import readAccessorPacked from './readAccessorPacked.js' -import ComponentDatatype from '../../Core/ComponentDatatype.js' -import WebGLConstants from '../../Core/WebGLConstants.js' +import addBuffer from "./addBuffer.js" +import ForEach from "./ForEach.js" +import readAccessorPacked from "./readAccessorPacked.js" +import ComponentDatatype from "../../Core/ComponentDatatype.js" +import WebGLConstants from "../../Core/WebGLConstants.js" - /** - * Update accessors referenced by JOINTS_0 and WEIGHTS_0 attributes to use correct component types. - * - * @param {Object} gltf A javascript object containing a glTF asset. - * @returns {Object} The glTF asset with compressed meshes. - * - * @private - */ - function updateAccessorComponentTypes(gltf) { - var componentType; - ForEach.accessorWithSemantic(gltf, 'JOINTS_0', function(accessorId) { - var accessor = gltf.accessors[accessorId]; - componentType = accessor.componentType; - if (componentType === WebGLConstants.BYTE) { - convertType(gltf, accessor, ComponentDatatype.UNSIGNED_BYTE); - } else if (componentType !== WebGLConstants.UNSIGNED_BYTE - && componentType !== WebGLConstants.UNSIGNED_SHORT) { - convertType(gltf, accessor, ComponentDatatype.UNSIGNED_SHORT); - } - }); - ForEach.accessorWithSemantic(gltf, 'WEIGHTS_0', function(accessorId) { - var accessor = gltf.accessors[accessorId]; - componentType = accessor.componentType; - if (componentType === WebGLConstants.BYTE) { - convertType(gltf, accessor, ComponentDatatype.UNSIGNED_BYTE); - } else if (componentType === WebGLConstants.SHORT) { - convertType(gltf, accessor, ComponentDatatype.UNSIGNED_SHORT); - } - }); +/** + * Update accessors referenced by JOINTS_0 and WEIGHTS_0 attributes to use correct component types. + * + * @param {Object} gltf A javascript object containing a glTF asset. + * @returns {Object} The glTF asset with compressed meshes. + * + * @private + */ +function updateAccessorComponentTypes(gltf) { + var componentType; + ForEach.accessorWithSemantic(gltf, 'JOINTS_0', function(accessorId) { + var accessor = gltf.accessors[accessorId]; + componentType = accessor.componentType; + if (componentType === WebGLConstants.BYTE) { + convertType(gltf, accessor, ComponentDatatype.UNSIGNED_BYTE); + } else if (componentType !== WebGLConstants.UNSIGNED_BYTE + && componentType !== WebGLConstants.UNSIGNED_SHORT) { + convertType(gltf, accessor, ComponentDatatype.UNSIGNED_SHORT); + } + }); + ForEach.accessorWithSemantic(gltf, 'WEIGHTS_0', function(accessorId) { + var accessor = gltf.accessors[accessorId]; + componentType = accessor.componentType; + if (componentType === WebGLConstants.BYTE) { + convertType(gltf, accessor, ComponentDatatype.UNSIGNED_BYTE); + } else if (componentType === WebGLConstants.SHORT) { + convertType(gltf, accessor, ComponentDatatype.UNSIGNED_SHORT); + } + }); - return gltf; - } + return gltf; +} - function convertType(gltf, accessor, updatedComponentType) { - var typedArray = ComponentDatatype.createTypedArray(updatedComponentType, readAccessorPacked(gltf, accessor)); - var newBuffer = new Uint8Array(typedArray.buffer); - accessor.bufferView = addBuffer(gltf, newBuffer); - accessor.componentType = updatedComponentType; - accessor.byteOffset = 0; - } +function convertType(gltf, accessor, updatedComponentType) { + var typedArray = ComponentDatatype.createTypedArray(updatedComponentType, readAccessorPacked(gltf, accessor)); + var newBuffer = new Uint8Array(typedArray.buffer); + accessor.bufferView = addBuffer(gltf, newBuffer); + accessor.componentType = updatedComponentType; + accessor.byteOffset = 0; +} - export default updateAccessorComponentTypes; +export default updateAccessorComponentTypes; diff --git a/Source/ThirdParty/GltfPipeline/updateVersion.js b/Source/ThirdParty/GltfPipeline/updateVersion.js index dc4f91cf1cdd..10b579ff84d7 100644 --- a/Source/ThirdParty/GltfPipeline/updateVersion.js +++ b/Source/ThirdParty/GltfPipeline/updateVersion.js @@ -1,936 +1,922 @@ -import addExtensionsUsed from './addExtensionsUsed.js' -import addToArray from './addToArray.js' -import findAccessorMinMax from './findAccessorMinMax.js' -import ForEach from './ForEach.js' -import getAccessorByteStride from './getAccessorByteStride.js' -import numberOfComponentsForType from './numberOfComponentsForType.js' -import moveTechniqueRenderStates from './moveTechniqueRenderStates.js' -import moveTechniquesToExtension from './moveTechniquesToExtension.js' -import removeUnusedElements from './removeUnusedElements.js' -import updateAccessorComponentTypes from './updateAccessorComponentTypes.js' -import Cartesian3 from '../../Core/Cartesian3.js' -import Cartesian4 from '../../Core/Cartesian4.js' -import clone from '../../Core/clone.js' -import ComponentDatatype from '../../Core/ComponentDatatype.js' -import defaultValue from '../../Core/defaultValue.js' -import defined from '../../Core/defined.js' -import Matrix4 from '../../Core/Matrix4.js' -import Quaternion from '../../Core/Quaternion.js' -import WebGLConstants from '../../Core/WebGLConstants.js' - - var updateFunctions = { - '0.8': glTF08to10, - '1.0': glTF10to20, - '2.0': undefined - }; - - /** - * Update the glTF version to the latest version (2.0), or targetVersion if specified. - * Applies changes made to the glTF spec between revisions so that the core library - * only has to handle the latest version. - * - * @param {Object} gltf A javascript object containing a glTF asset. - * @param {Object} [options] Options for updating the glTF. - * @param {String} [options.targetVersion] The glTF will be upgraded until it hits the specified version. - * @returns {Object} The updated glTF asset. - * - * @private - */ - function updateVersion(gltf, options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - var targetVersion = options.targetVersion; - var version = gltf.version; - - gltf.asset = defaultValue(gltf.asset, { - version: '1.0' - }); - - gltf.asset.version = defaultValue(gltf.asset.version, '1.0'); - version = defaultValue(version, gltf.asset.version).toString(); - - // Invalid version +import addExtensionsUsed from "./addExtensionsUsed.js" +import addToArray from "./addToArray.js" +import findAccessorMinMax from "./findAccessorMinMax.js" +import ForEach from "./ForEach.js" +import getAccessorByteStride from "./getAccessorByteStride.js" +import numberOfComponentsForType from "./numberOfComponentsForType.js" +import moveTechniqueRenderStates from "./moveTechniqueRenderStates.js" +import moveTechniquesToExtension from "./moveTechniquesToExtension.js" +import removeUnusedElements from "./removeUnusedElements.js" +import updateAccessorComponentTypes from "./updateAccessorComponentTypes.js" +import Cartesian3 from "../../Core/Cartesian3.js" +import Cartesian4 from "../../Core/Cartesian4.js" +import clone from "../../Core/clone.js" +import ComponentDatatype from "../../Core/ComponentDatatype.js" +import defaultValue from "../../Core/defaultValue.js" +import defined from "../../Core/defined.js" +import Matrix4 from "../../Core/Matrix4.js" +import Quaternion from "../../Core/Quaternion.js" +import WebGLConstants from "../../Core/WebGLConstants.js" + +var updateFunctions = { + '0.8': glTF08to10, + '1.0': glTF10to20, + '2.0': undefined +}; + +/** + * Update the glTF version to the latest version (2.0), or targetVersion if specified. + * Applies changes made to the glTF spec between revisions so that the core library + * only has to handle the latest version. + * + * @param {Object} gltf A javascript object containing a glTF asset. + * @param {Object} [options] Options for updating the glTF. + * @param {String} [options.targetVersion] The glTF will be upgraded until it hits the specified version. + * @returns {Object} The updated glTF asset. + * + * @private + */ +function updateVersion(gltf, options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + var targetVersion = options.targetVersion; + var version = gltf.version; + + gltf.asset = defaultValue(gltf.asset, { + version: '1.0' + }); + + gltf.asset.version = defaultValue(gltf.asset.version, '1.0'); + version = defaultValue(version, gltf.asset.version).toString(); + + // Invalid version + if (!Object.prototype.hasOwnProperty.call(updateFunctions, version)) { + // Try truncating trailing version numbers, could be a number as well if it is 0.8 + if (defined(version)) { + version = version.substring(0, 3); + } + // Default to 1.0 if it cannot be determined if (!Object.prototype.hasOwnProperty.call(updateFunctions, version)) { - // Try truncating trailing version numbers, could be a number as well if it is 0.8 - if (defined(version)) { - version = version.substring(0, 3); - } - // Default to 1.0 if it cannot be determined - if (!Object.prototype.hasOwnProperty.call(updateFunctions, version)) { - version = '1.0'; - } + version = '1.0'; } + } - var updateFunction = updateFunctions[version]; + var updateFunction = updateFunctions[version]; - while (defined(updateFunction)) { - if (version === targetVersion) { - break; - } - updateFunction(gltf, options); - version = gltf.asset.version; - updateFunction = updateFunctions[version]; + while (defined(updateFunction)) { + if (version === targetVersion) { + break; } - return gltf; + updateFunction(gltf, options); + version = gltf.asset.version; + updateFunction = updateFunctions[version]; } - - function updateInstanceTechniques(gltf) { - var materials = gltf.materials; - for (var materialId in materials) { - if (Object.prototype.hasOwnProperty.call(materials, materialId)) { - var material = materials[materialId]; - var instanceTechnique = material.instanceTechnique; - if (defined(instanceTechnique)) { - material.technique = instanceTechnique.technique; - material.values = instanceTechnique.values; - delete material.instanceTechnique; - } + return gltf; +} + +function updateInstanceTechniques(gltf) { + var materials = gltf.materials; + for (var materialId in materials) { + if (Object.prototype.hasOwnProperty.call(materials, materialId)) { + var material = materials[materialId]; + var instanceTechnique = material.instanceTechnique; + if (defined(instanceTechnique)) { + material.technique = instanceTechnique.technique; + material.values = instanceTechnique.values; + delete material.instanceTechnique; } } } - - function setPrimitiveModes(gltf) { - var meshes = gltf.meshes; - for (var meshId in meshes) { - if (Object.prototype.hasOwnProperty.call(meshes, meshId)) { - var mesh = meshes[meshId]; - var primitives = mesh.primitives; - if (defined(primitives)) { - var primitivesLength = primitives.length; - for (var i = 0; i < primitivesLength; ++i) { - var primitive = primitives[i]; - var defaultMode = defaultValue(primitive.primitive, WebGLConstants.TRIANGLES); - primitive.mode = defaultValue(primitive.mode, defaultMode); - delete primitive.primitive; - } +} + +function setPrimitiveModes(gltf) { + var meshes = gltf.meshes; + for (var meshId in meshes) { + if (Object.prototype.hasOwnProperty.call(meshes, meshId)) { + var mesh = meshes[meshId]; + var primitives = mesh.primitives; + if (defined(primitives)) { + var primitivesLength = primitives.length; + for (var i = 0; i < primitivesLength; ++i) { + var primitive = primitives[i]; + var defaultMode = defaultValue(primitive.primitive, WebGLConstants.TRIANGLES); + primitive.mode = defaultValue(primitive.mode, defaultMode); + delete primitive.primitive; } } } } - - function updateNodes(gltf) { - var nodes = gltf.nodes; - var axis = new Cartesian3(); - var quat = new Quaternion(); - for (var nodeId in nodes) { - if (Object.prototype.hasOwnProperty.call(nodes, nodeId)) { - var node = nodes[nodeId]; - if (defined(node.rotation)) { - var rotation = node.rotation; - Cartesian3.fromArray(rotation, 0, axis); - Quaternion.fromAxisAngle(axis, rotation[3], quat); - node.rotation = [quat.x, quat.y, quat.z, quat.w]; - } - var instanceSkin = node.instanceSkin; - if (defined(instanceSkin)) { - node.skeletons = instanceSkin.skeletons; - node.skin = instanceSkin.skin; - node.meshes = instanceSkin.meshes; - delete node.instanceSkin; - } +} + +function updateNodes(gltf) { + var nodes = gltf.nodes; + var axis = new Cartesian3(); + var quat = new Quaternion(); + for (var nodeId in nodes) { + if (Object.prototype.hasOwnProperty.call(nodes, nodeId)) { + var node = nodes[nodeId]; + if (defined(node.rotation)) { + var rotation = node.rotation; + Cartesian3.fromArray(rotation, 0, axis); + Quaternion.fromAxisAngle(axis, rotation[3], quat); + node.rotation = [quat.x, quat.y, quat.z, quat.w]; + } + var instanceSkin = node.instanceSkin; + if (defined(instanceSkin)) { + node.skeletons = instanceSkin.skeletons; + node.skin = instanceSkin.skin; + node.meshes = instanceSkin.meshes; + delete node.instanceSkin; } } } - - function updateAnimations(gltf) { - var animations = gltf.animations; - var accessors = gltf.accessors; - var bufferViews = gltf.bufferViews; - var buffers = gltf.buffers; - var updatedAccessors = {}; - var axis = new Cartesian3(); - var quat = new Quaternion(); - for (var animationId in animations) { - if (Object.prototype.hasOwnProperty.call(animations, animationId)) { - var animation = animations[animationId]; - var channels = animation.channels; - var parameters = animation.parameters; - var samplers = animation.samplers; - if (defined(channels)) { - var channelsLength = channels.length; - for (var i = 0; i < channelsLength; ++i) { - var channel = channels[i]; - if (channel.target.path === 'rotation') { - var accessorId = parameters[samplers[channel.sampler].output]; - if (defined(updatedAccessors[accessorId])) { - continue; - } - updatedAccessors[accessorId] = true; - var accessor = accessors[accessorId]; - var bufferView = bufferViews[accessor.bufferView]; - var buffer = buffers[bufferView.buffer]; - var source = buffer.extras._pipeline.source; - var byteOffset = source.byteOffset + bufferView.byteOffset + accessor.byteOffset; - var componentType = accessor.componentType; - var count = accessor.count; - var componentsLength = numberOfComponentsForType(accessor.type); - var length = accessor.count * componentsLength; - var typedArray = ComponentDatatype.createArrayBufferView(componentType, source.buffer, byteOffset, length); - - for (var j = 0; j < count; j++) { - var offset = j * componentsLength; - Cartesian3.unpack(typedArray, offset, axis); - var angle = typedArray[offset + 3]; - Quaternion.fromAxisAngle(axis, angle, quat); - Quaternion.pack(quat, typedArray, offset); - } +} + +function updateAnimations(gltf) { + var animations = gltf.animations; + var accessors = gltf.accessors; + var bufferViews = gltf.bufferViews; + var buffers = gltf.buffers; + var updatedAccessors = {}; + var axis = new Cartesian3(); + var quat = new Quaternion(); + for (var animationId in animations) { + if (Object.prototype.hasOwnProperty.call(animations, animationId)) { + var animation = animations[animationId]; + var channels = animation.channels; + var parameters = animation.parameters; + var samplers = animation.samplers; + if (defined(channels)) { + var channelsLength = channels.length; + for (var i = 0; i < channelsLength; ++i) { + var channel = channels[i]; + if (channel.target.path === 'rotation') { + var accessorId = parameters[samplers[channel.sampler].output]; + if (defined(updatedAccessors[accessorId])) { + continue; + } + updatedAccessors[accessorId] = true; + var accessor = accessors[accessorId]; + var bufferView = bufferViews[accessor.bufferView]; + var buffer = buffers[bufferView.buffer]; + var source = buffer.extras._pipeline.source; + var byteOffset = source.byteOffset + bufferView.byteOffset + accessor.byteOffset; + var componentType = accessor.componentType; + var count = accessor.count; + var componentsLength = numberOfComponentsForType(accessor.type); + var length = accessor.count * componentsLength; + var typedArray = ComponentDatatype.createArrayBufferView(componentType, source.buffer, byteOffset, length); + + for (var j = 0; j < count; j++) { + var offset = j * componentsLength; + Cartesian3.unpack(typedArray, offset, axis); + var angle = typedArray[offset + 3]; + Quaternion.fromAxisAngle(axis, angle, quat); + Quaternion.pack(quat, typedArray, offset); } } } } } } - - function removeTechniquePasses(gltf) { - var techniques = gltf.techniques; - for (var techniqueId in techniques) { - if (Object.prototype.hasOwnProperty.call(techniques, techniqueId)) { - var technique = techniques[techniqueId]; - var passes = technique.passes; - if (defined(passes)) { - var passName = defaultValue(technique.pass, 'defaultPass'); - if (Object.prototype.hasOwnProperty.call(passes, passName)) { - var pass = passes[passName]; - var instanceProgram = pass.instanceProgram; - technique.attributes = defaultValue(technique.attributes, instanceProgram.attributes); - technique.program = defaultValue(technique.program, instanceProgram.program); - technique.uniforms = defaultValue(technique.uniforms, instanceProgram.uniforms); - technique.states = defaultValue(technique.states, pass.states); - } - delete technique.passes; - delete technique.pass; - } +} + +function removeTechniquePasses(gltf) { + var techniques = gltf.techniques; + for (var techniqueId in techniques) { + if (Object.prototype.hasOwnProperty.call(techniques, techniqueId)) { + var technique = techniques[techniqueId]; + var passes = technique.passes; + if (defined(passes)) { + var passName = defaultValue(technique.pass, 'defaultPass'); + if (Object.prototype.hasOwnProperty.call(passes, passName)) { + var pass = passes[passName]; + var instanceProgram = pass.instanceProgram; + technique.attributes = defaultValue(technique.attributes, instanceProgram.attributes); + technique.program = defaultValue(technique.program, instanceProgram.program); + technique.uniforms = defaultValue(technique.uniforms, instanceProgram.uniforms); + technique.states = defaultValue(technique.states, pass.states); + } + delete technique.passes; + delete technique.pass; } } } +} - function glTF08to10(gltf) { - if (!defined(gltf.asset)) { - gltf.asset = {}; - } - var asset = gltf.asset; - asset.version = '1.0'; - // Profile should be an object, not a string - if (typeof asset.profile === 'string') { - var split = asset.profile.split(' '); - asset.profile = { - api: split[0], - version: split[1] - }; - } else { - asset.profile = {}; - } - - // Version property should be in asset, not on the root element - if (defined(gltf.version)) { - delete gltf.version; - } - // material.instanceTechnique properties should be directly on the material - updateInstanceTechniques(gltf); - // primitive.primitive should be primitive.mode - setPrimitiveModes(gltf); - // Node rotation should be quaternion, not axis-angle - // node.instanceSkin is deprecated - updateNodes(gltf); - // Animations that target rotations should be quaternion, not axis-angle - updateAnimations(gltf); - // technique.pass and techniques.passes are deprecated - removeTechniquePasses(gltf); - // gltf.allExtensions -> extensionsUsed - if (defined(gltf.allExtensions)) { - gltf.extensionsUsed = gltf.allExtensions; - delete gltf.allExtensions; - } - // gltf.lights -> khrMaterialsCommon.lights - if (defined(gltf.lights)) { - var extensions = defaultValue(gltf.extensions, {}); - gltf.extensions = extensions; - var materialsCommon = defaultValue(extensions.KHR_materials_common, {}); - extensions.KHR_materials_common = materialsCommon; - materialsCommon.lights = gltf.lights; - delete gltf.lights; - addExtensionsUsed(gltf, 'KHR_materials_common'); - } +function glTF08to10(gltf) { + if (!defined(gltf.asset)) { + gltf.asset = {}; + } + var asset = gltf.asset; + asset.version = '1.0'; + // Profile should be an object, not a string + if (typeof asset.profile === 'string') { + var split = asset.profile.split(' '); + asset.profile = { + api: split[0], + version: split[1] + }; + } else { + asset.profile = {}; } - function removeAnimationSamplersIndirection(gltf) { - var animations = gltf.animations; - for (var animationId in animations) { - if (Object.prototype.hasOwnProperty.call(animations, animationId)) { - var animation = animations[animationId]; - var parameters = animation.parameters; - if (defined(parameters)) { - var samplers = animation.samplers; - for (var samplerId in samplers) { - if (Object.prototype.hasOwnProperty.call(samplers, samplerId)) { - var sampler = samplers[samplerId]; - sampler.input = parameters[sampler.input]; - sampler.output = parameters[sampler.output]; - } + // Version property should be in asset, not on the root element + if (defined(gltf.version)) { + delete gltf.version; + } + // material.instanceTechnique properties should be directly on the material + updateInstanceTechniques(gltf); + // primitive.primitive should be primitive.mode + setPrimitiveModes(gltf); + // Node rotation should be quaternion, not axis-angle + // node.instanceSkin is deprecated + updateNodes(gltf); + // Animations that target rotations should be quaternion, not axis-angle + updateAnimations(gltf); + // technique.pass and techniques.passes are deprecated + removeTechniquePasses(gltf); + // gltf.allExtensions -> extensionsUsed + if (defined(gltf.allExtensions)) { + gltf.extensionsUsed = gltf.allExtensions; + delete gltf.allExtensions; + } + // gltf.lights -> khrMaterialsCommon.lights + if (defined(gltf.lights)) { + var extensions = defaultValue(gltf.extensions, {}); + gltf.extensions = extensions; + var materialsCommon = defaultValue(extensions.KHR_materials_common, {}); + extensions.KHR_materials_common = materialsCommon; + materialsCommon.lights = gltf.lights; + delete gltf.lights; + addExtensionsUsed(gltf, 'KHR_materials_common'); + } +} + +function removeAnimationSamplersIndirection(gltf) { + var animations = gltf.animations; + for (var animationId in animations) { + if (Object.prototype.hasOwnProperty.call(animations, animationId)) { + var animation = animations[animationId]; + var parameters = animation.parameters; + if (defined(parameters)) { + var samplers = animation.samplers; + for (var samplerId in samplers) { + if (Object.prototype.hasOwnProperty.call(samplers, samplerId)) { + var sampler = samplers[samplerId]; + sampler.input = parameters[sampler.input]; + sampler.output = parameters[sampler.output]; } - delete animation.parameters; } + delete animation.parameters; } } } - - function objectToArray(object, mapping) { - var array = []; - for (var id in object) { - if (Object.prototype.hasOwnProperty.call(object, id)) { - var value = object[id]; - mapping[id] = array.length; - array.push(value); - if (!defined(value.name)) { - value.name = id; - } +} + +function objectToArray(object, mapping) { + var array = []; + for (var id in object) { + if (Object.prototype.hasOwnProperty.call(object, id)) { + var value = object[id]; + mapping[id] = array.length; + array.push(value); + if (!defined(value.name)) { + value.name = id; } } - return array; } + return array; +} + +function objectsToArrays(gltf) { + var i; + var globalMapping = { + accessors: {}, + animations: {}, + buffers: {}, + bufferViews: {}, + cameras: {}, + images: {}, + materials: {}, + meshes: {}, + nodes: {}, + programs: {}, + samplers: {}, + scenes: {}, + shaders: {}, + skins: {}, + textures: {}, + techniques: {} + }; - function objectsToArrays(gltf) { - var i; - var globalMapping = { - accessors: {}, - animations: {}, - buffers: {}, - bufferViews: {}, - cameras: {}, - images: {}, - materials: {}, - meshes: {}, - nodes: {}, - programs: {}, - samplers: {}, - scenes: {}, - shaders: {}, - skins: {}, - textures: {}, - techniques: {} - }; - - // Map joint names to id names - var jointName; - var jointNameToId = {}; - var nodes = gltf.nodes; - for (var id in nodes) { - if (Object.prototype.hasOwnProperty.call(nodes, id)) { - jointName = nodes[id].jointName; - if (defined(jointName)) { - jointNameToId[jointName] = id; - } + // Map joint names to id names + var jointName; + var jointNameToId = {}; + var nodes = gltf.nodes; + for (var id in nodes) { + if (Object.prototype.hasOwnProperty.call(nodes, id)) { + jointName = nodes[id].jointName; + if (defined(jointName)) { + jointNameToId[jointName] = id; } } + } - // Convert top level objects to arrays - for (var topLevelId in gltf) { - if (Object.prototype.hasOwnProperty.call(gltf, topLevelId) && defined(globalMapping[topLevelId])) { - var objectMapping = {}; - var object = gltf[topLevelId]; - gltf[topLevelId] = objectToArray(object, objectMapping); - globalMapping[topLevelId] = objectMapping; - } + // Convert top level objects to arrays + for (var topLevelId in gltf) { + if (Object.prototype.hasOwnProperty.call(gltf, topLevelId) && defined(globalMapping[topLevelId])) { + var objectMapping = {}; + var object = gltf[topLevelId]; + gltf[topLevelId] = objectToArray(object, objectMapping); + globalMapping[topLevelId] = objectMapping; } + } - // Remap joint names to array indexes - for (jointName in jointNameToId) { - if (Object.prototype.hasOwnProperty.call(jointNameToId, jointName)) { - jointNameToId[jointName] = globalMapping.nodes[jointNameToId[jointName]]; - } + // Remap joint names to array indexes + for (jointName in jointNameToId) { + if (Object.prototype.hasOwnProperty.call(jointNameToId, jointName)) { + jointNameToId[jointName] = globalMapping.nodes[jointNameToId[jointName]]; } + } - // Fix references - if (defined(gltf.scene)) { - gltf.scene = globalMapping.scenes[gltf.scene]; + // Fix references + if (defined(gltf.scene)) { + gltf.scene = globalMapping.scenes[gltf.scene]; + } + ForEach.bufferView(gltf, function(bufferView) { + if (defined(bufferView.buffer)) { + bufferView.buffer = globalMapping.buffers[bufferView.buffer]; } - ForEach.bufferView(gltf, function(bufferView) { - if (defined(bufferView.buffer)) { - bufferView.buffer = globalMapping.buffers[bufferView.buffer]; - } - }); - ForEach.accessor(gltf, function(accessor) { - if (defined(accessor.bufferView)) { - accessor.bufferView = globalMapping.bufferViews[accessor.bufferView]; - } - }); - ForEach.shader(gltf, function(shader) { - var extensions = shader.extensions; - if (defined(extensions)) { - var binaryGltf = extensions.KHR_binary_glTF; - if (defined(binaryGltf)) { - shader.bufferView = globalMapping.bufferViews[binaryGltf.bufferView]; - delete extensions.KHR_binary_glTF; - } - if (Object.keys(extensions).length === 0) { - delete shader.extensions; - } + }); + ForEach.accessor(gltf, function(accessor) { + if (defined(accessor.bufferView)) { + accessor.bufferView = globalMapping.bufferViews[accessor.bufferView]; + } + }); + ForEach.shader(gltf, function(shader) { + var extensions = shader.extensions; + if (defined(extensions)) { + var binaryGltf = extensions.KHR_binary_glTF; + if (defined(binaryGltf)) { + shader.bufferView = globalMapping.bufferViews[binaryGltf.bufferView]; + delete extensions.KHR_binary_glTF; + } + if (Object.keys(extensions).length === 0) { + delete shader.extensions; } - }); - ForEach.program(gltf, function(program) { - if (defined(program.vertexShader)) { - program.vertexShader = globalMapping.shaders[program.vertexShader]; + } + }); + ForEach.program(gltf, function(program) { + if (defined(program.vertexShader)) { + program.vertexShader = globalMapping.shaders[program.vertexShader]; + } + if (defined(program.fragmentShader)) { + program.fragmentShader = globalMapping.shaders[program.fragmentShader]; + } + }); + ForEach.technique(gltf, function(technique) { + if (defined(technique.program)) { + technique.program = globalMapping.programs[technique.program]; + } + ForEach.techniqueParameter(technique, function(parameter) { + if (defined(parameter.node)) { + parameter.node = globalMapping.nodes[parameter.node]; } - if (defined(program.fragmentShader)) { - program.fragmentShader = globalMapping.shaders[program.fragmentShader]; + var value = parameter.value; + if (typeof value === 'string') { + parameter.value = { + index: globalMapping.textures[value] + }; } }); - ForEach.technique(gltf, function(technique) { - if (defined(technique.program)) { - technique.program = globalMapping.programs[technique.program]; + }); + ForEach.mesh(gltf, function(mesh) { + ForEach.meshPrimitive(mesh, function(primitive) { + if (defined(primitive.indices)) { + primitive.indices = globalMapping.accessors[primitive.indices]; } - ForEach.techniqueParameter(technique, function(parameter) { - if (defined(parameter.node)) { - parameter.node = globalMapping.nodes[parameter.node]; - } - var value = parameter.value; - if (typeof value === 'string') { - parameter.value = { - index: globalMapping.textures[value] - }; - } - }); - }); - ForEach.mesh(gltf, function(mesh) { - ForEach.meshPrimitive(mesh, function(primitive) { - if (defined(primitive.indices)) { - primitive.indices = globalMapping.accessors[primitive.indices]; - } - ForEach.meshPrimitiveAttribute(primitive, function(accessorId, semantic) { - primitive.attributes[semantic] = globalMapping.accessors[accessorId]; - }); - if (defined(primitive.material)) { - primitive.material = globalMapping.materials[primitive.material]; - } + ForEach.meshPrimitiveAttribute(primitive, function(accessorId, semantic) { + primitive.attributes[semantic] = globalMapping.accessors[accessorId]; }); - }); - ForEach.node(gltf, function(node) { - var children = node.children; - if (defined(children)) { - var childrenLength = children.length; - for (i = 0; i < childrenLength; ++i) { - children[i] = globalMapping.nodes[children[i]]; - } - } - if (defined(node.meshes)) { - // Split out meshes on nodes - var meshes = node.meshes; - var meshesLength = meshes.length; - if (meshesLength > 0) { - node.mesh = globalMapping.meshes[meshes[0]]; - for (i = 1; i < meshesLength; ++i) { - var meshNode = { - mesh: globalMapping.meshes[meshes[i]] - }; - var meshNodeId = addToArray(gltf.nodes, meshNode); - if (!defined(children)) { - children = []; - node.children = children; - } - children.push(meshNodeId); - } - } - delete node.meshes; - } - if (defined(node.camera)) { - node.camera = globalMapping.cameras[node.camera]; - } - if (defined(node.skin)) { - node.skin = globalMapping.skins[node.skin]; - } - if (defined(node.skeletons)) { - // Assign skeletons to skins - var skeletons = node.skeletons; - var skeletonsLength = skeletons.length; - if ((skeletonsLength > 0) && defined(node.skin)) { - var skin = gltf.skins[node.skin]; - skin.skeleton = globalMapping.nodes[skeletons[0]]; - } - delete node.skeletons; - } - if (defined(node.jointName)) { - delete node.jointName; - } - }); - ForEach.skin(gltf, function(skin) { - if (defined(skin.inverseBindMatrices)) { - skin.inverseBindMatrices = globalMapping.accessors[skin.inverseBindMatrices]; - } - var jointNames = skin.jointNames; - if (defined(jointNames)) { - var joints = []; - var jointNamesLength = jointNames.length; - for (i = 0; i < jointNamesLength; ++i) { - joints[i] = jointNameToId[jointNames[i]]; - } - skin.joints = joints; - delete skin.jointNames; + if (defined(primitive.material)) { + primitive.material = globalMapping.materials[primitive.material]; } }); - ForEach.scene(gltf, function(scene) { - var sceneNodes = scene.nodes; - if (defined(sceneNodes)) { - var sceneNodesLength = sceneNodes.length; - for (i = 0; i < sceneNodesLength; ++i) { - sceneNodes[i] = globalMapping.nodes[sceneNodes[i]]; - } + }); + ForEach.node(gltf, function(node) { + var children = node.children; + if (defined(children)) { + var childrenLength = children.length; + for (i = 0; i < childrenLength; ++i) { + children[i] = globalMapping.nodes[children[i]]; } - }); - ForEach.animation(gltf, function(animation) { - var samplerMapping = {}; - animation.samplers = objectToArray(animation.samplers, samplerMapping); - ForEach.animationSampler(animation, function(sampler) { - sampler.input = globalMapping.accessors[sampler.input]; - sampler.output = globalMapping.accessors[sampler.output]; - }); - ForEach.animationChannel(animation, function(channel) { - channel.sampler = samplerMapping[channel.sampler]; - var target = channel.target; - if (defined(target)) { - target.node = globalMapping.nodes[target.id]; - delete target.id; - } - }); - }); - ForEach.material(gltf, function(material) { - if (defined(material.technique)) { - material.technique = globalMapping.techniques[material.technique]; - } - ForEach.materialValue(material, function(value, name) { - if (typeof value === 'string') { - material.values[name] = { - index: globalMapping.textures[value] + } + if (defined(node.meshes)) { + // Split out meshes on nodes + var meshes = node.meshes; + var meshesLength = meshes.length; + if (meshesLength > 0) { + node.mesh = globalMapping.meshes[meshes[0]]; + for (i = 1; i < meshesLength; ++i) { + var meshNode = { + mesh: globalMapping.meshes[meshes[i]] }; - } - }); - var extensions = material.extensions; - if (defined(extensions)) { - var materialsCommon = extensions.KHR_materials_common; - if (defined(materialsCommon)) { - ForEach.materialValue(materialsCommon, function(value, name) { - if (typeof value === 'string') { - materialsCommon.values[name] = { - index: globalMapping.textures[value] - }; - } - }); + var meshNodeId = addToArray(gltf.nodes, meshNode); + if (!defined(children)) { + children = []; + node.children = children; + } + children.push(meshNodeId); } } - }); - ForEach.image(gltf, function(image) { - var extensions = image.extensions; - if (defined(extensions)) { - var binaryGltf = extensions.KHR_binary_glTF; - if (defined(binaryGltf)) { - image.bufferView = globalMapping.bufferViews[binaryGltf.bufferView]; - image.mimeType = binaryGltf.mimeType; - delete extensions.KHR_binary_glTF; - } - if (Object.keys(extensions).length === 0) { - delete image.extensions; - } + delete node.meshes; + } + if (defined(node.camera)) { + node.camera = globalMapping.cameras[node.camera]; + } + if (defined(node.skin)) { + node.skin = globalMapping.skins[node.skin]; + } + if (defined(node.skeletons)) { + // Assign skeletons to skins + var skeletons = node.skeletons; + var skeletonsLength = skeletons.length; + if ((skeletonsLength > 0) && defined(node.skin)) { + var skin = gltf.skins[node.skin]; + skin.skeleton = globalMapping.nodes[skeletons[0]]; + } + delete node.skeletons; + } + if (defined(node.jointName)) { + delete node.jointName; + } + }); + ForEach.skin(gltf, function(skin) { + if (defined(skin.inverseBindMatrices)) { + skin.inverseBindMatrices = globalMapping.accessors[skin.inverseBindMatrices]; + } + var jointNames = skin.jointNames; + if (defined(jointNames)) { + var joints = []; + var jointNamesLength = jointNames.length; + for (i = 0; i < jointNamesLength; ++i) { + joints[i] = jointNameToId[jointNames[i]]; + } + skin.joints = joints; + delete skin.jointNames; + } + }); + ForEach.scene(gltf, function(scene) { + var sceneNodes = scene.nodes; + if (defined(sceneNodes)) { + var sceneNodesLength = sceneNodes.length; + for (i = 0; i < sceneNodesLength; ++i) { + sceneNodes[i] = globalMapping.nodes[sceneNodes[i]]; } - ForEach.compressedImage(image, function(compressedImage) { - var compressedExtensions = compressedImage.extensions; - if (defined(compressedExtensions)) { - var compressedBinaryGltf = compressedExtensions.KHR_binary_glTF; - if (defined(compressedBinaryGltf)) { - compressedImage.bufferView = globalMapping.bufferViews[compressedBinaryGltf.bufferView]; - compressedImage.mimeType = compressedBinaryGltf.mimeType; - delete compressedExtensions.KHR_binary_glTF; - } - if (Object.keys(extensions).length === 0) { - delete compressedImage.extensions; + } + }); + ForEach.animation(gltf, function(animation) { + var samplerMapping = {}; + animation.samplers = objectToArray(animation.samplers, samplerMapping); + ForEach.animationSampler(animation, function(sampler) { + sampler.input = globalMapping.accessors[sampler.input]; + sampler.output = globalMapping.accessors[sampler.output]; + }); + ForEach.animationChannel(animation, function(channel) { + channel.sampler = samplerMapping[channel.sampler]; + var target = channel.target; + if (defined(target)) { + target.node = globalMapping.nodes[target.id]; + delete target.id; + } + }); + }); + ForEach.material(gltf, function(material) { + if (defined(material.technique)) { + material.technique = globalMapping.techniques[material.technique]; + } + ForEach.materialValue(material, function(value, name) { + if (typeof value === 'string') { + material.values[name] = { + index: globalMapping.textures[value] + }; + } + }); + var extensions = material.extensions; + if (defined(extensions)) { + var materialsCommon = extensions.KHR_materials_common; + if (defined(materialsCommon)) { + ForEach.materialValue(materialsCommon, function(value, name) { + if (typeof value === 'string') { + materialsCommon.values[name] = { + index: globalMapping.textures[value] + }; } - } - }); - }); - ForEach.texture(gltf, function(texture) { - if (defined(texture.sampler)) { - texture.sampler = globalMapping.samplers[texture.sampler]; + }); } - if (defined(texture.source)) { - texture.source = globalMapping.images[texture.source]; + } + }); + ForEach.image(gltf, function(image) { + var extensions = image.extensions; + if (defined(extensions)) { + var binaryGltf = extensions.KHR_binary_glTF; + if (defined(binaryGltf)) { + image.bufferView = globalMapping.bufferViews[binaryGltf.bufferView]; + image.mimeType = binaryGltf.mimeType; + delete extensions.KHR_binary_glTF; + } + if (Object.keys(extensions).length === 0) { + delete image.extensions; } - }); - } + } + }); + ForEach.texture(gltf, function(texture) { + if (defined(texture.sampler)) { + texture.sampler = globalMapping.samplers[texture.sampler]; + } + if (defined(texture.source)) { + texture.source = globalMapping.images[texture.source]; + } + }); +} - function removeAnimationSamplerNames(gltf) { - ForEach.animation(gltf, function(animation) { - ForEach.animationSampler(animation, function(sampler) { - delete sampler.name; - }); +function removeAnimationSamplerNames(gltf) { + ForEach.animation(gltf, function(animation) { + ForEach.animationSampler(animation, function(sampler) { + delete sampler.name; }); - } + }); +} - function removeEmptyArrays(gltf) { - for (var topLevelId in gltf) { - if (Object.prototype.hasOwnProperty.call(gltf, topLevelId)) { - var array = gltf[topLevelId]; - if (Array.isArray(array) && array.length === 0) { - delete gltf[topLevelId]; - } +function removeEmptyArrays(gltf) { + for (var topLevelId in gltf) { + if (Object.prototype.hasOwnProperty.call(gltf, topLevelId)) { + var array = gltf[topLevelId]; + if (Array.isArray(array) && array.length === 0) { + delete gltf[topLevelId]; } } - ForEach.node(gltf, function(node) { - if (defined(node.children) && node.children.length === 0) { - delete node.children; - } - }); - } - - function stripAsset(gltf) { - var asset = gltf.asset; - delete asset.profile; - delete asset.premultipliedAlpha; } - - var knownExtensions = { - CESIUM_RTC: true, - KHR_materials_common: true, - WEB3D_quantized_attributes: true - }; - function requireKnownExtensions(gltf) { - var extensionsUsed = gltf.extensionsUsed; - gltf.extensionsRequired = defaultValue(gltf.extensionsRequired, []); - if (defined(extensionsUsed)) { - var extensionsUsedLength = extensionsUsed.length; - for (var i = 0; i < extensionsUsedLength; ++i) { - var extension = extensionsUsed[i]; - if (defined(knownExtensions[extension])) { - gltf.extensionsRequired.push(extension); - } + ForEach.node(gltf, function(node) { + if (defined(node.children) && node.children.length === 0) { + delete node.children; + } + }); +} + +function stripAsset(gltf) { + var asset = gltf.asset; + delete asset.profile; + delete asset.premultipliedAlpha; +} + +var knownExtensions = { + CESIUM_RTC: true, + KHR_materials_common: true, + WEB3D_quantized_attributes: true +}; +function requireKnownExtensions(gltf) { + var extensionsUsed = gltf.extensionsUsed; + gltf.extensionsRequired = defaultValue(gltf.extensionsRequired, []); + if (defined(extensionsUsed)) { + var extensionsUsedLength = extensionsUsed.length; + for (var i = 0; i < extensionsUsedLength; ++i) { + var extension = extensionsUsed[i]; + if (defined(knownExtensions[extension])) { + gltf.extensionsRequired.push(extension); } } } - - function removeBufferType(gltf) { - ForEach.buffer(gltf, function(buffer) { - delete buffer.type; - }); - } - - function removeTextureProperties(gltf) { - ForEach.texture(gltf, function(texture) { - delete texture.format; - delete texture.internalFormat; - delete texture.target; - delete texture.type; - }); - } - - function requireAttributeSetIndex(gltf) { - ForEach.mesh(gltf, function(mesh) { - ForEach.meshPrimitive(mesh, function(primitive) { - ForEach.meshPrimitiveAttribute(primitive, function(accessorId, semantic) { - if (semantic === 'TEXCOORD') { - primitive.attributes.TEXCOORD_0 = accessorId; - } else if (semantic === 'COLOR') { - primitive.attributes.COLOR_0 = accessorId; - } - }); - delete primitive.attributes.TEXCOORD; - delete primitive.attributes.COLOR; - }); - }); - ForEach.technique(gltf, function(technique) { - ForEach.techniqueParameter(technique, function(parameter) { - var semantic = parameter.semantic; - if (defined(semantic)) { - if (semantic === 'TEXCOORD') { - parameter.semantic = 'TEXCOORD_0'; - } else if (semantic === 'COLOR') { - parameter.semantic = 'COLOR_0'; - } +} + +function removeBufferType(gltf) { + ForEach.buffer(gltf, function(buffer) { + delete buffer.type; + }); +} + +function removeTextureProperties(gltf) { + ForEach.texture(gltf, function(texture) { + delete texture.format; + delete texture.internalFormat; + delete texture.target; + delete texture.type; + }); +} + +function requireAttributeSetIndex(gltf) { + ForEach.mesh(gltf, function(mesh) { + ForEach.meshPrimitive(mesh, function(primitive) { + ForEach.meshPrimitiveAttribute(primitive, function(accessorId, semantic) { + if (semantic === 'TEXCOORD') { + primitive.attributes.TEXCOORD_0 = accessorId; + } else if (semantic === 'COLOR') { + primitive.attributes.COLOR_0 = accessorId; } }); - }); - } - - var knownSemantics = { - POSITION: true, - NORMAL: true, - TANGENT: true - }; - var indexedSemantics = { - COLOR: 'COLOR', - JOINT : 'JOINTS', - JOINTS: 'JOINTS', - TEXCOORD: 'TEXCOORD', - WEIGHT: 'WEIGHTS', - WEIGHTS: 'WEIGHTS' - }; - function underscoreApplicationSpecificSemantics(gltf) { - var mappedSemantics = {}; - ForEach.mesh(gltf, function(mesh) { - ForEach.meshPrimitive(mesh, function(primitive) { - /*eslint-disable no-unused-vars*/ - ForEach.meshPrimitiveAttribute(primitive, function(accessorId, semantic) { - if (semantic.charAt(0) !== '_') { - var setIndex = semantic.search(/_[0-9]+/g); - var strippedSemantic = semantic; - var suffix = '_0'; - if (setIndex >= 0) { - strippedSemantic = semantic.substring(0, setIndex); - suffix = semantic.substring(setIndex); - } - var newSemantic; - var indexedSemantic = indexedSemantics[strippedSemantic]; - if (defined(indexedSemantic)) { - newSemantic = indexedSemantic + suffix; - mappedSemantics[semantic] = newSemantic; - } else if (!defined(knownSemantics[strippedSemantic])) { - newSemantic = '_' + semantic; - mappedSemantics[semantic] = newSemantic; - } + delete primitive.attributes.TEXCOORD; + delete primitive.attributes.COLOR; + }); + }); + ForEach.technique(gltf, function(technique) { + ForEach.techniqueParameter(technique, function(parameter) { + var semantic = parameter.semantic; + if (defined(semantic)) { + if (semantic === 'TEXCOORD') { + parameter.semantic = 'TEXCOORD_0'; + } else if (semantic === 'COLOR') { + parameter.semantic = 'COLOR_0'; + } + } + }); + }); +} + +var knownSemantics = { + POSITION: true, + NORMAL: true, + TANGENT: true +}; +var indexedSemantics = { + COLOR: 'COLOR', + JOINT : 'JOINTS', + JOINTS: 'JOINTS', + TEXCOORD: 'TEXCOORD', + WEIGHT: 'WEIGHTS', + WEIGHTS: 'WEIGHTS' +}; +function underscoreApplicationSpecificSemantics(gltf) { + var mappedSemantics = {}; + ForEach.mesh(gltf, function(mesh) { + ForEach.meshPrimitive(mesh, function(primitive) { + /*eslint-disable no-unused-vars*/ + ForEach.meshPrimitiveAttribute(primitive, function(accessorId, semantic) { + if (semantic.charAt(0) !== '_') { + var setIndex = semantic.search(/_[0-9]+/g); + var strippedSemantic = semantic; + var suffix = '_0'; + if (setIndex >= 0) { + strippedSemantic = semantic.substring(0, setIndex); + suffix = semantic.substring(setIndex); } - }); - for (var semantic in mappedSemantics) { - if (Object.prototype.hasOwnProperty.call(mappedSemantics, semantic)) { - var mappedSemantic = mappedSemantics[semantic]; - var accessorId = primitive.attributes[semantic]; - if (defined(accessorId)) { - delete primitive.attributes[semantic]; - primitive.attributes[mappedSemantic] = accessorId; - } + var newSemantic; + var indexedSemantic = indexedSemantics[strippedSemantic]; + if (defined(indexedSemantic)) { + newSemantic = indexedSemantic + suffix; + mappedSemantics[semantic] = newSemantic; + } else if (!defined(knownSemantics[strippedSemantic])) { + newSemantic = '_' + semantic; + mappedSemantics[semantic] = newSemantic; } } }); - }); - ForEach.technique(gltf, function(technique) { - ForEach.techniqueParameter(technique, function(parameter) { - var mappedSemantic = mappedSemantics[parameter.semantic]; - if (defined(mappedSemantic)) { - parameter.semantic = mappedSemantic; - } - }); - }); - } - - function clampCameraParameters(gltf) { - ForEach.camera(gltf, function(camera) { - var perspective = camera.perspective; - if (defined(perspective)) { - var aspectRatio = perspective.aspectRatio; - if (defined(aspectRatio) && aspectRatio === 0.0) { - delete perspective.aspectRatio; - } - var yfov = perspective.yfov; - if (defined(yfov) && yfov === 0.0) { - perspective.yfov = 1.0; + for (var semantic in mappedSemantics) { + if (Object.prototype.hasOwnProperty.call(mappedSemantics, semantic)) { + var mappedSemantic = mappedSemantics[semantic]; + var accessorId = primitive.attributes[semantic]; + if (defined(accessorId)) { + delete primitive.attributes[semantic]; + primitive.attributes[mappedSemantic] = accessorId; + } } } }); - } - - function computeAccessorByteStride(gltf, accessor) { - return (defined(accessor.byteStride) && accessor.byteStride !== 0) ? accessor.byteStride : getAccessorByteStride(gltf, accessor); - } - - function requireByteLength(gltf) { - ForEach.buffer(gltf, function(buffer) { - if (!defined(buffer.byteLength)) { - buffer.byteLength = buffer.extras._pipeline.source.length; + }); + ForEach.technique(gltf, function(technique) { + ForEach.techniqueParameter(technique, function(parameter) { + var mappedSemantic = mappedSemantics[parameter.semantic]; + if (defined(mappedSemantic)) { + parameter.semantic = mappedSemantic; } }); - ForEach.accessor(gltf, function(accessor) { - var bufferViewId = accessor.bufferView; - if (defined(bufferViewId)) { - var bufferView = gltf.bufferViews[bufferViewId]; - var accessorByteStride = computeAccessorByteStride(gltf, accessor); - var accessorByteEnd = accessor.byteOffset + accessor.count * accessorByteStride; - bufferView.byteLength = Math.max(defaultValue(bufferView.byteLength, 0), accessorByteEnd); - } - }); - } + }); +} - function moveByteStrideToBufferView(gltf) { - var i; - var j; - var bufferView; - var bufferViews = gltf.bufferViews; - - var bufferViewHasVertexAttributes = {}; - ForEach.accessorContainingVertexAttributeData(gltf, function(accessorId) { - var accessor = gltf.accessors[accessorId]; - if (defined(accessor.bufferView)) { - bufferViewHasVertexAttributes[accessor.bufferView] = true; +function clampCameraParameters(gltf) { + ForEach.camera(gltf, function(camera) { + var perspective = camera.perspective; + if (defined(perspective)) { + var aspectRatio = perspective.aspectRatio; + if (defined(aspectRatio) && aspectRatio === 0.0) { + delete perspective.aspectRatio; } - }); - - // Map buffer views to a list of accessors - var bufferViewMap = {}; - ForEach.accessor(gltf, function(accessor) { - if (defined(accessor.bufferView)) { - bufferViewMap[accessor.bufferView] = defaultValue(bufferViewMap[accessor.bufferView], []); - bufferViewMap[accessor.bufferView].push(accessor); + var yfov = perspective.yfov; + if (defined(yfov) && yfov === 0.0) { + perspective.yfov = 1.0; } - }); + } + }); +} - // Split accessors with different byte strides - for (var bufferViewId in bufferViewMap) { - if (Object.prototype.hasOwnProperty.call(bufferViewMap, bufferViewId)) { - bufferView = bufferViews[bufferViewId]; - var accessors = bufferViewMap[bufferViewId]; - accessors.sort(function(a, b) { - return a.byteOffset - b.byteOffset; - }); - var currentByteOffset = 0; - var currentIndex = 0; - var accessorsLength = accessors.length; - for (i = 0; i < accessorsLength; ++i) { - var accessor = accessors[i]; - var accessorByteStride = computeAccessorByteStride(gltf, accessor); - var accessorByteOffset = accessor.byteOffset; - var accessorByteLength = accessor.count * accessorByteStride; - delete accessor.byteStride; - - var hasNextAccessor = (i < accessorsLength - 1); - var nextAccessorByteStride = hasNextAccessor ? computeAccessorByteStride(gltf, accessors[i + 1]) : undefined; - if (accessorByteStride !== nextAccessorByteStride) { - var newBufferView = clone(bufferView, true); - if (bufferViewHasVertexAttributes[bufferViewId]) { - newBufferView.byteStride = accessorByteStride; - } - newBufferView.byteOffset += currentByteOffset; - newBufferView.byteLength = accessorByteOffset + accessorByteLength - currentByteOffset; - var newBufferViewId = addToArray(bufferViews, newBufferView); - for (j = currentIndex; j <= i; ++j) { - accessor = accessors[j]; - accessor.bufferView = newBufferViewId; - accessor.byteOffset = accessor.byteOffset - currentByteOffset; - } - // Set current byte offset to next accessor's byte offset - currentByteOffset = hasNextAccessor ? accessors[i + 1].byteOffset : undefined; - currentIndex = i + 1; +function computeAccessorByteStride(gltf, accessor) { + return (defined(accessor.byteStride) && accessor.byteStride !== 0) ? accessor.byteStride : getAccessorByteStride(gltf, accessor); +} + +function requireByteLength(gltf) { + ForEach.buffer(gltf, function(buffer) { + if (!defined(buffer.byteLength)) { + buffer.byteLength = buffer.extras._pipeline.source.length; + } + }); + ForEach.accessor(gltf, function(accessor) { + var bufferViewId = accessor.bufferView; + if (defined(bufferViewId)) { + var bufferView = gltf.bufferViews[bufferViewId]; + var accessorByteStride = computeAccessorByteStride(gltf, accessor); + var accessorByteEnd = accessor.byteOffset + accessor.count * accessorByteStride; + bufferView.byteLength = Math.max(defaultValue(bufferView.byteLength, 0), accessorByteEnd); + } + }); +} + +function moveByteStrideToBufferView(gltf) { + var i; + var j; + var bufferView; + var bufferViews = gltf.bufferViews; + + var bufferViewHasVertexAttributes = {}; + ForEach.accessorContainingVertexAttributeData(gltf, function(accessorId) { + var accessor = gltf.accessors[accessorId]; + if (defined(accessor.bufferView)) { + bufferViewHasVertexAttributes[accessor.bufferView] = true; + } + }); + + // Map buffer views to a list of accessors + var bufferViewMap = {}; + ForEach.accessor(gltf, function(accessor) { + if (defined(accessor.bufferView)) { + bufferViewMap[accessor.bufferView] = defaultValue(bufferViewMap[accessor.bufferView], []); + bufferViewMap[accessor.bufferView].push(accessor); + } + }); + + // Split accessors with different byte strides + for (var bufferViewId in bufferViewMap) { + if (Object.prototype.hasOwnProperty.call(bufferViewMap, bufferViewId)) { + bufferView = bufferViews[bufferViewId]; + var accessors = bufferViewMap[bufferViewId]; + accessors.sort(function(a, b) { + return a.byteOffset - b.byteOffset; + }); + var currentByteOffset = 0; + var currentIndex = 0; + var accessorsLength = accessors.length; + for (i = 0; i < accessorsLength; ++i) { + var accessor = accessors[i]; + var accessorByteStride = computeAccessorByteStride(gltf, accessor); + var accessorByteOffset = accessor.byteOffset; + var accessorByteLength = accessor.count * accessorByteStride; + delete accessor.byteStride; + + var hasNextAccessor = (i < accessorsLength - 1); + var nextAccessorByteStride = hasNextAccessor ? computeAccessorByteStride(gltf, accessors[i + 1]) : undefined; + if (accessorByteStride !== nextAccessorByteStride) { + var newBufferView = clone(bufferView, true); + if (bufferViewHasVertexAttributes[bufferViewId]) { + newBufferView.byteStride = accessorByteStride; } + newBufferView.byteOffset += currentByteOffset; + newBufferView.byteLength = accessorByteOffset + accessorByteLength - currentByteOffset; + var newBufferViewId = addToArray(bufferViews, newBufferView); + for (j = currentIndex; j <= i; ++j) { + accessor = accessors[j]; + accessor.bufferView = newBufferViewId; + accessor.byteOffset = accessor.byteOffset - currentByteOffset; + } + // Set current byte offset to next accessor's byte offset + currentByteOffset = hasNextAccessor ? accessors[i + 1].byteOffset : undefined; + currentIndex = i + 1; } } } - - // Remove unused buffer views - removeUnusedElements(gltf, ['accessor', 'bufferView', 'buffer']); - } - - function requirePositionAccessorMinMax(gltf) { - ForEach.accessorWithSemantic(gltf, 'POSITION', function(accessorId) { - var accessor = gltf.accessors[accessorId]; - if (!defined(accessor.min) || !defined(accessor.max)) { - var minMax = findAccessorMinMax(gltf, accessor); - accessor.min = minMax.min; - accessor.max = minMax.max; - } - }); - } - - function isNodeEmpty(node) { - return (!defined(node.children) || node.children.length === 0) && - (!defined(node.meshes) || node.meshes.length === 0) && - !defined(node.camera) && !defined(node.skin) && !defined(node.skeletons) && !defined(node.jointName) && - (!defined(node.translation) || Cartesian3.fromArray(node.translation).equals(Cartesian3.ZERO)) && - (!defined(node.scale) || Cartesian3.fromArray(node.scale).equals(new Cartesian3(1.0, 1.0, 1.0))) && - (!defined(node.rotation) || Cartesian4.fromArray(node.rotation).equals(new Cartesian4(0.0, 0.0, 0.0, 1.0))) && - (!defined(node.matrix) || Matrix4.fromColumnMajorArray(node.matrix).equals(Matrix4.IDENTITY)) && - !defined(node.extensions) && !defined(node.extras); } - function deleteNode(gltf, nodeId) { - // Remove from list of nodes in scene - ForEach.scene(gltf, function(scene) { - var sceneNodes = scene.nodes; - if (defined(sceneNodes)) { - var sceneNodesLength = sceneNodes.length; - for (var i = sceneNodesLength; i >= 0; --i) { - if (sceneNodes[i] === nodeId) { - sceneNodes.splice(i, 1); - return; - } + // Remove unused buffer views + removeUnusedElements(gltf, ['accessor', 'bufferView', 'buffer']); +} + +function requirePositionAccessorMinMax(gltf) { + ForEach.accessorWithSemantic(gltf, 'POSITION', function(accessorId) { + var accessor = gltf.accessors[accessorId]; + if (!defined(accessor.min) || !defined(accessor.max)) { + var minMax = findAccessorMinMax(gltf, accessor); + accessor.min = minMax.min; + accessor.max = minMax.max; + } + }); +} + +function isNodeEmpty(node) { + return (!defined(node.children) || node.children.length === 0) && + (!defined(node.meshes) || node.meshes.length === 0) && + !defined(node.camera) && !defined(node.skin) && !defined(node.skeletons) && !defined(node.jointName) && + (!defined(node.translation) || Cartesian3.fromArray(node.translation).equals(Cartesian3.ZERO)) && + (!defined(node.scale) || Cartesian3.fromArray(node.scale).equals(new Cartesian3(1.0, 1.0, 1.0))) && + (!defined(node.rotation) || Cartesian4.fromArray(node.rotation).equals(new Cartesian4(0.0, 0.0, 0.0, 1.0))) && + (!defined(node.matrix) || Matrix4.fromColumnMajorArray(node.matrix).equals(Matrix4.IDENTITY)) && + !defined(node.extensions) && !defined(node.extras); +} + +function deleteNode(gltf, nodeId) { + // Remove from list of nodes in scene + ForEach.scene(gltf, function(scene) { + var sceneNodes = scene.nodes; + if (defined(sceneNodes)) { + var sceneNodesLength = sceneNodes.length; + for (var i = sceneNodesLength; i >= 0; --i) { + if (sceneNodes[i] === nodeId) { + sceneNodes.splice(i, 1); + return; } } - }); + } + }); - // Remove parent node's reference to this node, and delete the parent if also empty - ForEach.node(gltf, function(parentNode, parentNodeId) { - if (defined(parentNode.children)) { - var index = parentNode.children.indexOf(nodeId); - if (index > -1) { - parentNode.children.splice(index, 1); + // Remove parent node's reference to this node, and delete the parent if also empty + ForEach.node(gltf, function(parentNode, parentNodeId) { + if (defined(parentNode.children)) { + var index = parentNode.children.indexOf(nodeId); + if (index > -1) { + parentNode.children.splice(index, 1); - if (isNodeEmpty(parentNode)) { - deleteNode(gltf, parentNodeId); - } + if (isNodeEmpty(parentNode)) { + deleteNode(gltf, parentNodeId); } } - }); + } + }); - delete gltf.nodes[nodeId]; - } + delete gltf.nodes[nodeId]; +} - function removeEmptyNodes(gltf) { - ForEach.node(gltf, function(node, nodeId) { - if (isNodeEmpty(node)) { - deleteNode(gltf, nodeId); - } - }); +function removeEmptyNodes(gltf) { + ForEach.node(gltf, function(node, nodeId) { + if (isNodeEmpty(node)) { + deleteNode(gltf, nodeId); + } + }); - return gltf; - } + return gltf; +} - function requireAnimationAccessorMinMax(gltf) { - ForEach.animation(gltf, function(animation) { - ForEach.animationSampler(animation, function(sampler) { - var accessor = gltf.accessors[sampler.input]; - if (!defined(accessor.min) || !defined(accessor.max)) { - var minMax = findAccessorMinMax(gltf, accessor); - accessor.min = minMax.min; - accessor.max = minMax.max; - } - }); +function requireAnimationAccessorMinMax(gltf) { + ForEach.animation(gltf, function(animation) { + ForEach.animationSampler(animation, function(sampler) { + var accessor = gltf.accessors[sampler.input]; + if (!defined(accessor.min) || !defined(accessor.max)) { + var minMax = findAccessorMinMax(gltf, accessor); + accessor.min = minMax.min; + accessor.max = minMax.max; + } }); - } - - function glTF10to20(gltf) { - gltf.asset = defaultValue(gltf.asset, {}); - gltf.asset.version = '2.0'; - // material.instanceTechnique properties should be directly on the material. instanceTechnique is a gltf 0.8 property but is seen in some 1.0 models. - updateInstanceTechniques(gltf); - // animation.samplers now refers directly to accessors and animation.parameters should be removed - removeAnimationSamplersIndirection(gltf); - // Remove empty nodes and re-assign referencing indices - removeEmptyNodes(gltf); - // Top-level objects are now arrays referenced by index instead of id - objectsToArrays(gltf); - // Animation.sampler objects cannot have names - removeAnimationSamplerNames(gltf); - // asset.profile no longer exists - stripAsset(gltf); - // Move known extensions from extensionsUsed to extensionsRequired - requireKnownExtensions(gltf); - // bufferView.byteLength and buffer.byteLength are required - requireByteLength(gltf); - // byteStride moved from accessor to bufferView - moveByteStrideToBufferView(gltf); - // accessor.min and accessor.max must be defined for accessors containing POSITION attributes - requirePositionAccessorMinMax(gltf); - // An animation sampler's input accessor must have min and max properties defined - requireAnimationAccessorMinMax(gltf); - // buffer.type is unnecessary and should be removed - removeBufferType(gltf); - // Remove format, internalFormat, target, and type - removeTextureProperties(gltf); - // TEXCOORD and COLOR attributes must be written with a set index (TEXCOORD_#) - requireAttributeSetIndex(gltf); - // Add underscores to application-specific parameters - underscoreApplicationSpecificSemantics(gltf); - // Accessors referenced by JOINTS_0 and WEIGHTS_0 attributes must have correct component types - updateAccessorComponentTypes(gltf); - // Clamp camera parameters - clampCameraParameters(gltf); - // Move legacy technique render states to material properties and add KHR_blend extension blending functions - moveTechniqueRenderStates(gltf); - // Add material techniques to KHR_techniques_webgl extension, removing shaders, programs, and techniques - moveTechniquesToExtension(gltf); - // Remove empty arrays - removeEmptyArrays(gltf); - } - - export default updateVersion; + }); +} + +function glTF10to20(gltf) { + gltf.asset = defaultValue(gltf.asset, {}); + gltf.asset.version = '2.0'; + // material.instanceTechnique properties should be directly on the material. instanceTechnique is a gltf 0.8 property but is seen in some 1.0 models. + updateInstanceTechniques(gltf); + // animation.samplers now refers directly to accessors and animation.parameters should be removed + removeAnimationSamplersIndirection(gltf); + // Remove empty nodes and re-assign referencing indices + removeEmptyNodes(gltf); + // Top-level objects are now arrays referenced by index instead of id + objectsToArrays(gltf); + // Animation.sampler objects cannot have names + removeAnimationSamplerNames(gltf); + // asset.profile no longer exists + stripAsset(gltf); + // Move known extensions from extensionsUsed to extensionsRequired + requireKnownExtensions(gltf); + // bufferView.byteLength and buffer.byteLength are required + requireByteLength(gltf); + // byteStride moved from accessor to bufferView + moveByteStrideToBufferView(gltf); + // accessor.min and accessor.max must be defined for accessors containing POSITION attributes + requirePositionAccessorMinMax(gltf); + // An animation sampler's input accessor must have min and max properties defined + requireAnimationAccessorMinMax(gltf); + // buffer.type is unnecessary and should be removed + removeBufferType(gltf); + // Remove format, internalFormat, target, and type + removeTextureProperties(gltf); + // TEXCOORD and COLOR attributes must be written with a set index (TEXCOORD_#) + requireAttributeSetIndex(gltf); + // Add underscores to application-specific parameters + underscoreApplicationSpecificSemantics(gltf); + // Accessors referenced by JOINTS_0 and WEIGHTS_0 attributes must have correct component types + updateAccessorComponentTypes(gltf); + // Clamp camera parameters + clampCameraParameters(gltf); + // Move legacy technique render states to material properties and add KHR_blend extension blending functions + moveTechniqueRenderStates(gltf); + // Add material techniques to KHR_techniques_webgl extension, removing shaders, programs, and techniques + moveTechniquesToExtension(gltf); + // Remove empty arrays + removeEmptyArrays(gltf); +} + +export default updateVersion; diff --git a/Source/ThirdParty/GltfPipeline/usesExtension.js b/Source/ThirdParty/GltfPipeline/usesExtension.js index c3726f0941cc..545e03725d50 100644 --- a/Source/ThirdParty/GltfPipeline/usesExtension.js +++ b/Source/ThirdParty/GltfPipeline/usesExtension.js @@ -1,16 +1,16 @@ -import defined from '../../Core/defined.js' +import defined from "../../Core/defined.js" - /** - * Checks whether the glTF uses the given extension. - * - * @param {Object} gltf A javascript object containing a glTF asset. - * @param {String} extension The name of the extension. - * @returns {Boolean} Whether the glTF uses the given extension. - * - * @private - */ - function usesExtension(gltf, extension) { - return defined(gltf.extensionsUsed) && (gltf.extensionsUsed.indexOf(extension) >= 0); - } +/** + * Checks whether the glTF uses the given extension. + * + * @param {Object} gltf A javascript object containing a glTF asset. + * @param {String} extension The name of the extension. + * @returns {Boolean} Whether the glTF uses the given extension. + * + * @private + */ +function usesExtension(gltf, extension) { + return defined(gltf.extensionsUsed) && (gltf.extensionsUsed.indexOf(extension) >= 0); +} - export default usesExtension; +export default usesExtension; diff --git a/Source/ThirdParty/Workers/basis_transcoder.js b/Source/ThirdParty/Workers/basis_transcoder.js new file mode 100644 index 000000000000..7ad429d4a9a6 --- /dev/null +++ b/Source/ThirdParty/Workers/basis_transcoder.js @@ -0,0 +1,21 @@ + +var BASIS = (function() { + var _scriptDir = typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : undefined; + if (typeof __filename !== 'undefined') _scriptDir = _scriptDir || __filename; + return ( +function(BASIS) { + BASIS = BASIS || {}; + +var Module=typeof BASIS!=="undefined"?BASIS:{};var readyPromiseResolve,readyPromiseReject;Module["ready"]=new Promise(function(resolve,reject){readyPromiseResolve=resolve;readyPromiseRejectza=reject});var moduleOverrides={};var key;for(key in Module){if(Module.hasOwnProperty(key)){moduleOverrides[key]=Module[key]}}var arguments_=[];var thisProgram="./this.program";var quit_=function(status,toThrow){throw toThrow};var ENVIRONMENT_IS_WEB=false;var ENVIRONMENT_IS_WORKER=false;var ENVIRONMENT_IS_NODE=false;var ENVIRONMENT_IS_SHELL=false;ENVIRONMENT_IS_WEB=typeof window==="object";ENVIRONMENT_IS_WORKER=typeof importScripts==="function";ENVIRONMENT_IS_NODE=typeof process==="object"&&typeof process.versions==="object"&&typeof process.versions.node==="string";ENVIRONMENT_IS_SHELL=!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_NODE&&!ENVIRONMENT_IS_WORKER;var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var read_,readAsync,readBinary,setWindowTitle;var nodeFS;var nodePath;if(ENVIRONMENT_IS_NODE){if(ENVIRONMENT_IS_WORKER){scriptDirectory=require("path").dirname(scriptDirectory)+"/"}else{scriptDirectory=__dirname+"/"}read_=function shell_read(filename,binary){if(!nodeFS)nodeFS=require("fs");if(!nodePath)nodePath=require("path");filename=nodePath["normalize"](filename);return nodeFS["readFileSync"](filename,binary?null:"utf8")};readBinary=function readBinary(filename){var ret=read_(filename,true);if(!ret.buffer){ret=new Uint8Array(ret)}assert(ret.buffer);return ret};if(process["argv"].length>1){thisProgram=process["argv"][1].replace(/\\/g,"/")}arguments_=process["argv"].slice(2);process["on"]("uncaughtException",function(ex){if(!(ex instanceof ExitStatus)){throw ex}});process["on"]("unhandledRejection",abort);quit_=function(status){process["exit"](status)};Module["inspect"]=function(){return"[Emscripten Module object]"}}else if(ENVIRONMENT_IS_SHELL){if(typeof read!="undefined"){read_=function shell_read(f){return read(f)}}readBinary=function readBinary(f){var data;if(typeof readbuffer==="function"){return new Uint8Array(readbuffer(f))}data=read(f,"binary");assert(typeof data==="object");return data};if(typeof scriptArgs!="undefined"){arguments_=scriptArgs}else if(typeof arguments!="undefined"){arguments_=arguments}if(typeof quit==="function"){quit_=function(status){quit(status)}}if(typeof print!=="undefined"){if(typeof console==="undefined")console={};console.log=print;console.warn=console.error=typeof printErr!=="undefined"?printErr:print}}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){if(ENVIRONMENT_IS_WORKER){scriptDirectory=self.location.href}else if(typeof document!=="undefined"&&document.currentScript){scriptDirectory=document.currentScript.src}if(_scriptDir){scriptDirectory=_scriptDir}if(scriptDirectory.indexOf("blob:")!==0){scriptDirectory=scriptDirectory.substr(0,scriptDirectory.lastIndexOf("/")+1)}else{scriptDirectory=""}{read_=function(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.send(null);return xhr.responseText};if(ENVIRONMENT_IS_WORKER){readBinary=function(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}}readAsync=function(url,onload,onerror){var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=function(){if(xhr.status==200||xhr.status==0&&xhr.response){onload(xhr.response);return}onerror()};xhr.onerror=onerror;xhr.send(null)}}setWindowTitle=function(title){document.title=title}}else{}var out=Module["print"]||console.log.bind(console);var err=Module["printErr"]||console.warn.bind(console);for(key in moduleOverrides){if(moduleOverrides.hasOwnProperty(key)){Module[key]=moduleOverrides[key]}}moduleOverrides=null;if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"];if(Module["quit"])quit_=Module["quit"];var tempRet0=0;var setTempRet0=function(value){tempRet0=value};var wasmBinary;if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];var noExitRuntime=Module["noExitRuntime"]||true;if(typeof WebAssembly!=="object"){abort("no native wasm support detected")}var wasmMemory;var ABORT=false;var EXITSTATUS;function assert(condition,text){if(!condition){abort("Assertion failed: "+text)}}var UTF8Decoder=typeof TextDecoder!=="undefined"?new TextDecoder("utf8"):undefined;function UTF8ArrayToString(heap,idx,maxBytesToRead){var endIdx=idx+maxBytesToRead;var endPtr=idx;while(heap[endPtr]&&!(endPtr>=endIdx))++endPtr;if(endPtr-idx>16&&heap.subarray&&UTF8Decoder){return UTF8Decoder.decode(heap.subarray(idx,endPtr))}else{var str="";while(idx>10,56320|ch&1023)}}}return str}function UTF8ToString(ptr,maxBytesToRead){return ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead):""}function stringToUTF8Array(str,heap,outIdx,maxBytesToWrite){if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i=55296&&u<=57343){var u1=str.charCodeAt(++i);u=65536+((u&1023)<<10)|u1&1023}if(u<=127){if(outIdx>=endIdx)break;heap[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;heap[outIdx++]=192|u>>6;heap[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;heap[outIdx++]=224|u>>12;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;heap[outIdx++]=240|u>>18;heap[outIdx++]=128|u>>12&63;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}}heap[outIdx]=0;return outIdx-startIdx}function stringToUTF8(str,outPtr,maxBytesToWrite){return stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite)}function lengthBytesUTF8(str){var len=0;for(var i=0;i=55296&&u<=57343)u=65536+((u&1023)<<10)|str.charCodeAt(++i)&1023;if(u<=127)++len;else if(u<=2047)len+=2;else if(u<=65535)len+=3;else len+=4}return len}var UTF16Decoder=typeof TextDecoder!=="undefined"?new TextDecoder("utf-16le"):undefined;function UTF16ToString(ptr,maxBytesToRead){var endPtr=ptr;var idx=endPtr>>1;var maxIdx=idx+maxBytesToRead/2;while(!(idx>=maxIdx)&&HEAPU16[idx])++idx;endPtr=idx<<1;if(endPtr-ptr>32&&UTF16Decoder){return UTF16Decoder.decode(HEAPU8.subarray(ptr,endPtr))}else{var str="";for(var i=0;!(i>=maxBytesToRead/2);++i){var codeUnit=HEAP16[ptr+i*2>>1];if(codeUnit==0)break;str+=String.fromCharCode(codeUnit)}return str}}function stringToUTF16(str,outPtr,maxBytesToWrite){if(maxBytesToWrite===undefined){maxBytesToWrite=2147483647}if(maxBytesToWrite<2)return 0;maxBytesToWrite-=2;var startPtr=outPtr;var numCharsToWrite=maxBytesToWrite>1]=codeUnit;outPtr+=2}HEAP16[outPtr>>1]=0;return outPtr-startPtr}function lengthBytesUTF16(str){return str.length*2}function UTF32ToString(ptr,maxBytesToRead){var i=0;var str="";while(!(i>=maxBytesToRead/4)){var utf32=HEAP32[ptr+i*4>>2];if(utf32==0)break;++i;if(utf32>=65536){var ch=utf32-65536;str+=String.fromCharCode(55296|ch>>10,56320|ch&1023)}else{str+=String.fromCharCode(utf32)}}return str}function stringToUTF32(str,outPtr,maxBytesToWrite){if(maxBytesToWrite===undefined){maxBytesToWrite=2147483647}if(maxBytesToWrite<4)return 0;var startPtr=outPtr;var endPtr=startPtr+maxBytesToWrite-4;for(var i=0;i=55296&&codeUnit<=57343){var trailSurrogate=str.charCodeAt(++i);codeUnit=65536+((codeUnit&1023)<<10)|trailSurrogate&1023}HEAP32[outPtr>>2]=codeUnit;outPtr+=4;if(outPtr+4>endPtr)break}HEAP32[outPtr>>2]=0;return outPtr-startPtr}function lengthBytesUTF32(str){var len=0;for(var i=0;i=55296&&codeUnit<=57343)++i;len+=4}return len}function alignUp(x,multiple){if(x%multiple>0){x+=multiple-x%multiple}return x}var buffer,HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;function updateGlobalBufferAndViews(buf){buffer=buf;Module["HEAP8"]=HEAP8=new Int8Array(buf);Module["HEAP16"]=HEAP16=new Int16Array(buf);Module["HEAP32"]=HEAP32=new Int32Array(buf);Module["HEAPU8"]=HEAPU8=new Uint8Array(buf);Module["HEAPU16"]=HEAPU16=new Uint16Array(buf);Module["HEAPU32"]=HEAPU32=new Uint32Array(buf);Module["HEAPF32"]=HEAPF32=new Float32Array(buf);Module["HEAPF64"]=HEAPF64=new Float64Array(buf)}var INITIAL_MEMORY=Module["INITIAL_MEMORY"]||16777216;var wasmTable;var __ATPRERUN__=[];var __ATINIT__=[];var __ATMAIN__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(__ATPRERUN__)}function initRuntime(){runtimeInitialized=true;callRuntimeCallbacks(__ATINIT__)}function preMain(){callRuntimeCallbacks(__ATMAIN__)}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}function addOnInit(cb){__ATINIT__.unshift(cb)}function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;function addRunDependency(id){runDependencies++;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}}function removeRunDependency(id){runDependencies--;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}if(runDependencies==0){if(runDependencyWatcher!==null){clearInterval(runDependencyWatcher);runDependencyWatcher=null}if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}Module["preloadedImages"]={};Module["preloadedAudios"]={};function abort(what){if(Module["onAbort"]){Module["onAbort"](what)}what+="";err(what);ABORT=true;EXITSTATUS=1;what="abort("+what+"). Build with -s ASSERTIONS=1 for more info.";var e=new WebAssembly.RuntimeError(what);readyPromiseReject(e);throw e}function hasPrefix(str,prefix){return String.prototype.startsWith?str.startsWith(prefix):str.indexOf(prefix)===0}var dataURIPrefix="data:application/octet-stream;base64,";function isDataURI(filename){return hasPrefix(filename,dataURIPrefix)}var fileURIPrefix="file://";function isFileURI(filename){return hasPrefix(filename,fileURIPrefix)}var wasmBinaryFile="basis_transcoder.wasm";if(!isDataURI(wasmBinaryFile)){wasmBinaryFile=locateFile(wasmBinaryFile)}function getBinary(file){try{if(file==wasmBinaryFile&&wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(file)}else{throw"both async and sync fetching of the wasm failed"}}catch(err){abort(err)}}function getBinaryPromise(){if(!wasmBinary&&(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER)){if(typeof fetch==="function"&&!isFileURI(wasmBinaryFile)){return fetch(wasmBinaryFile,{credentials:"same-origin"}).then(function(response){if(!response["ok"]){throw"failed to load wasm binary file at '"+wasmBinaryFile+"'"}return response["arrayBuffer"]()}).catch(function(){return getBinary(wasmBinaryFile)})}else{if(readAsync){return new Promise(function(resolve,reject){readAsync(wasmBinaryFile,function(response){resolve(new Uint8Array(response))},reject)})}}}return Promise.resolve().then(function(){return getBinary(wasmBinaryFile)})}function createWasm(){var info={"a":asmLibraryArg};function receiveInstance(instance,module){var exports=instance.exports;Module["asm"]=exports;wasmMemory=Module["asm"]["K"];updateGlobalBufferAndViews(wasmMemory.buffer);wasmTable=Module["asm"]["O"];addOnInit(Module["asm"]["L"]);removeRunDependency("wasm-instantiate")}addRunDependency("wasm-instantiate");function receiveInstantiatedSource(output){receiveInstance(output["instance"])}function instantiateArrayBuffer(receiver){return getBinaryPromise().then(function(binary){var result=WebAssembly.instantiate(binary,info);return result}).then(receiver,function(reason){err("failed to asynchronously prepare wasm: "+reason);abort(reason)})}function instantiateAsync(){if(!wasmBinary&&typeof WebAssembly.instantiateStreaming==="function"&&!isDataURI(wasmBinaryFile)&&!isFileURI(wasmBinaryFile)&&typeof fetch==="function"){return fetch(wasmBinaryFile,{credentials:"same-origin"}).then(function(response){var result=WebAssembly.instantiateStreaming(response,info);return result.then(receiveInstantiatedSource,function(reason){err("wasm streaming compile failed: "+reason);err("falling back to ArrayBuffer instantiation");return instantiateArrayBuffer(receiveInstantiatedSource)})})}else{return instantiateArrayBuffer(receiveInstantiatedSource)}}if(Module["instantiateWasm"]){try{var exports=Module["instantiateWasm"](info,receiveInstance);return exports}catch(e){err("Module.instantiateWasm callback failed with error: "+e);return false}}instantiateAsync().catch(readyPromiseReject);return{}}function callRuntimeCallbacks(callbacks){while(callbacks.length>0){var callback=callbacks.shift();if(typeof callback=="function"){callback(Module);continue}var func=callback.func;if(typeof func==="number"){if(callback.arg===undefined){wasmTable.get(func)()}else{wasmTable.get(func)(callback.arg)}}else{func(callback.arg===undefined?null:callback.arg)}}}var structRegistrations={};function runDestructors(destructors){while(destructors.length){var ptr=destructors.pop();var del=destructors.pop();del(ptr)}}function simpleReadValueFromPointer(pointer){return this["fromWireType"](HEAPU32[pointer>>2])}var awaitingDependencies={};var registeredTypes={};var typeDependencies={};var char_0=48;var char_9=57;function makeLegalFunctionName(name){if(undefined===name){return"_unknown"}name=name.replace(/[^a-zA-Z0-9_]/g,"$");var f=name.charCodeAt(0);if(f>=char_0&&f<=char_9){return"_"+name}else{return name}}function createNamedFunction(name,body){name=makeLegalFunctionName(name);return new Function("body","return function "+name+"() {\n"+' "use strict";'+" return body.apply(this, arguments);\n"+"};\n")(body)}function extendError(baseErrorType,errorName){var errorClass=createNamedFunction(errorName,function(message){this.name=errorName;this.message=message;var stack=new Error(message).stack;if(stack!==undefined){this.stack=this.toString()+"\n"+stack.replace(/^Error(:[^\n]*)?\n/,"")}});errorClass.prototype=Object.create(baseErrorType.prototype);errorClass.prototype.constructor=errorClass;errorClass.prototype.toString=function(){if(this.message===undefined){return this.name}else{return this.name+": "+this.message}};return errorClass}var InternalError=undefined;function throwInternalError(message){throw new InternalError(message)}function whenDependentTypesAreResolved(myTypes,dependentTypes,getTypeConverters){myTypes.forEach(function(type){typeDependencies[type]=dependentTypes});function onComplete(typeConverters){var myTypeConverters=getTypeConverters(typeConverters);if(myTypeConverters.length!==myTypes.length){throwInternalError("Mismatched type converter count")}for(var i=0;i>shift])},destructorFunction:null})}function ClassHandle_isAliasOf(other){if(!(this instanceof ClassHandle)){return false}if(!(other instanceof ClassHandle)){return false}var leftClass=this.$$.ptrType.registeredClass;var left=this.$$.ptr;var rightClass=other.$$.ptrType.registeredClass;var right=other.$$.ptr;while(leftClass.baseClass){left=leftClass.upcast(left);leftClass=leftClass.baseClass}while(rightClass.baseClass){right=rightClass.upcast(right);rightClass=rightClass.baseClass}return leftClass===rightClass&&left===right}function shallowCopyInternalPointer(o){return{count:o.count,deleteScheduled:o.deleteScheduled,preservePointerOnDelete:o.preservePointerOnDelete,ptr:o.ptr,ptrType:o.ptrType,smartPtr:o.smartPtr,smartPtrType:o.smartPtrType}}function throwInstanceAlreadyDeleted(obj){function getInstanceTypeName(handle){return handle.$$.ptrType.registeredClass.name}throwBindingError(getInstanceTypeName(obj)+" instance already deleted")}var finalizationGroup=false;function detachFinalizer(handle){}function runDestructor($$){if($$.smartPtr){$$.smartPtrType.rawDestructor($$.smartPtr)}else{$$.ptrType.registeredClass.rawDestructor($$.ptr)}}function releaseClassHandle($$){$$.count.value-=1;var toDelete=0===$$.count.value;if(toDelete){runDestructor($$)}}function attachFinalizer(handle){if("undefined"===typeof FinalizationGroup){attachFinalizer=function(handle){return handle};return handle}finalizationGroup=new FinalizationGroup(function(iter){for(var result=iter.next();!result.done;result=iter.next()){var $$=result.value;if(!$$.ptr){console.warn("object already deleted: "+$$.ptr)}else{releaseClassHandle($$)}}});attachFinalizer=function(handle){finalizationGroup.register(handle,handle.$$,handle.$$);return handle};detachFinalizer=function(handle){finalizationGroup.unregister(handle.$$)};return attachFinalizer(handle)}function ClassHandle_clone(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.preservePointerOnDelete){this.$$.count.value+=1;return this}else{var clone=attachFinalizer(Object.create(Object.getPrototypeOf(this),{$$:{value:shallowCopyInternalPointer(this.$$)}}));clone.$$.count.value+=1;clone.$$.deleteScheduled=false;return clone}}function ClassHandle_delete(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.deleteScheduled&&!this.$$.preservePointerOnDelete){throwBindingError("Object already scheduled for deletion")}detachFinalizer(this);releaseClassHandle(this.$$);if(!this.$$.preservePointerOnDelete){this.$$.smartPtr=undefined;this.$$.ptr=undefined}}function ClassHandle_isDeleted(){return!this.$$.ptr}var delayFunction=undefined;var deletionQueue=[];function flushPendingDeletes(){while(deletionQueue.length){var obj=deletionQueue.pop();obj.$$.deleteScheduled=false;obj["delete"]()}}function ClassHandle_deleteLater(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.deleteScheduled&&!this.$$.preservePointerOnDelete){throwBindingError("Object already scheduled for deletion")}deletionQueue.push(this);if(deletionQueue.length===1&&delayFunction){delayFunction(flushPendingDeletes)}this.$$.deleteScheduled=true;return this}function init_ClassHandle(){ClassHandle.prototype["isAliasOf"]=ClassHandle_isAliasOf;ClassHandle.prototype["clone"]=ClassHandle_clone;ClassHandle.prototype["delete"]=ClassHandle_delete;ClassHandle.prototype["isDeleted"]=ClassHandle_isDeleted;ClassHandle.prototype["deleteLater"]=ClassHandle_deleteLater}function ClassHandle(){}var registeredPointers={};function ensureOverloadTable(proto,methodName,humanName){if(undefined===proto[methodName].overloadTable){var prevFunc=proto[methodName];proto[methodName]=function(){if(!proto[methodName].overloadTable.hasOwnProperty(arguments.length)){throwBindingError("Function '"+humanName+"' called with an invalid number of arguments ("+arguments.length+") - expects one of ("+proto[methodName].overloadTable+")!")}return proto[methodName].overloadTable[arguments.length].apply(this,arguments)};proto[methodName].overloadTable=[];proto[methodName].overloadTable[prevFunc.argCount]=prevFunc}}function exposePublicSymbol(name,value,numArguments){if(Module.hasOwnProperty(name)){if(undefined===numArguments||undefined!==Module[name].overloadTable&&undefined!==Module[name].overloadTable[numArguments]){throwBindingError("Cannot register public name '"+name+"' twice")}ensureOverloadTable(Module,name,name);if(Module.hasOwnProperty(numArguments)){throwBindingError("Cannot register multiple overloads of a function with the same number of arguments ("+numArguments+")!")}Module[name].overloadTable[numArguments]=value}else{Module[name]=value;if(undefined!==numArguments){Module[name].numArguments=numArguments}}}function RegisteredClass(name,constructor,instancePrototype,rawDestructor,baseClass,getActualType,upcast,downcast){this.name=name;this.constructor=constructor;this.instancePrototype=instancePrototype;this.rawDestructor=rawDestructor;this.baseClass=baseClass;this.getActualType=getActualType;this.upcast=upcast;this.downcast=downcast;this.pureVirtualFunctions=[]}function upcastPointer(ptr,ptrClass,desiredClass){while(ptrClass!==desiredClass){if(!ptrClass.upcast){throwBindingError("Expected null or instance of "+desiredClass.name+", got an instance of "+ptrClass.name)}ptr=ptrClass.upcast(ptr);ptrClass=ptrClass.baseClass}return ptr}function constNoSmartPtrRawPointerToWireType(destructors,handle){if(handle===null){if(this.isReference){throwBindingError("null is not a valid "+this.name)}return 0}if(!handle.$$){throwBindingError('Cannot pass "'+_embind_repr(handle)+'" as a '+this.name)}if(!handle.$$.ptr){throwBindingError("Cannot pass deleted object as a pointer of type "+this.name)}var handleClass=handle.$$.ptrType.registeredClass;var ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);return ptr}function genericPointerToWireType(destructors,handle){var ptr;if(handle===null){if(this.isReference){throwBindingError("null is not a valid "+this.name)}if(this.isSmartPointer){ptr=this.rawConstructor();if(destructors!==null){destructors.push(this.rawDestructor,ptr)}return ptr}else{return 0}}if(!handle.$$){throwBindingError('Cannot pass "'+_embind_repr(handle)+'" as a '+this.name)}if(!handle.$$.ptr){throwBindingError("Cannot pass deleted object as a pointer of type "+this.name)}if(!this.isConst&&handle.$$.ptrType.isConst){throwBindingError("Cannot convert argument of type "+(handle.$$.smartPtrType?handle.$$.smartPtrType.name:handle.$$.ptrType.name)+" to parameter type "+this.name)}var handleClass=handle.$$.ptrType.registeredClass;ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);if(this.isSmartPointer){if(undefined===handle.$$.smartPtr){throwBindingError("Passing raw pointer to smart pointer is illegal")}switch(this.sharingPolicy){case 0:if(handle.$$.smartPtrType===this){ptr=handle.$$.smartPtr}else{throwBindingError("Cannot convert argument of type "+(handle.$$.smartPtrType?handle.$$.smartPtrType.name:handle.$$.ptrType.name)+" to parameter type "+this.name)}break;case 1:ptr=handle.$$.smartPtr;break;case 2:if(handle.$$.smartPtrType===this){ptr=handle.$$.smartPtr}else{var clonedHandle=handle["clone"]();ptr=this.rawShare(ptr,__emval_register(function(){clonedHandle["delete"]()}));if(destructors!==null){destructors.push(this.rawDestructor,ptr)}}break;default:throwBindingError("Unsupporting sharing policy")}}return ptr}function nonConstNoSmartPtrRawPointerToWireType(destructors,handle){if(handle===null){if(this.isReference){throwBindingError("null is not a valid "+this.name)}return 0}if(!handle.$$){throwBindingError('Cannot pass "'+_embind_repr(handle)+'" as a '+this.name)}if(!handle.$$.ptr){throwBindingError("Cannot pass deleted object as a pointer of type "+this.name)}if(handle.$$.ptrType.isConst){throwBindingError("Cannot convert argument of type "+handle.$$.ptrType.name+" to parameter type "+this.name)}var handleClass=handle.$$.ptrType.registeredClass;var ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);return ptr}function RegisteredPointer_getPointee(ptr){if(this.rawGetPointee){ptr=this.rawGetPointee(ptr)}return ptr}function RegisteredPointer_destructor(ptr){if(this.rawDestructor){this.rawDestructor(ptr)}}function RegisteredPointer_deleteObject(handle){if(handle!==null){handle["delete"]()}}function downcastPointer(ptr,ptrClass,desiredClass){if(ptrClass===desiredClass){return ptr}if(undefined===desiredClass.baseClass){return null}var rv=downcastPointer(ptr,ptrClass,desiredClass.baseClass);if(rv===null){return null}return desiredClass.downcast(rv)}function getInheritedInstanceCount(){return Object.keys(registeredInstances).length}function getLiveInheritedInstances(){var rv=[];for(var k in registeredInstances){if(registeredInstances.hasOwnProperty(k)){rv.push(registeredInstances[k])}}return rv}function setDelayFunction(fn){delayFunction=fn;if(deletionQueue.length&&delayFunction){delayFunction(flushPendingDeletes)}}function init_embind(){Module["getInheritedInstanceCount"]=getInheritedInstanceCount;Module["getLiveInheritedInstances"]=getLiveInheritedInstances;Module["flushPendingDeletes"]=flushPendingDeletes;Module["setDelayFunction"]=setDelayFunction}var registeredInstances={};function getBasestPointer(class_,ptr){if(ptr===undefined){throwBindingError("ptr should not be undefined")}while(class_.baseClass){ptr=class_.upcast(ptr);class_=class_.baseClass}return ptr}function getInheritedInstance(class_,ptr){ptr=getBasestPointer(class_,ptr);return registeredInstances[ptr]}function makeClassHandle(prototype,record){if(!record.ptrType||!record.ptr){throwInternalError("makeClassHandle requires ptr and ptrType")}var hasSmartPtrType=!!record.smartPtrType;var hasSmartPtr=!!record.smartPtr;if(hasSmartPtrType!==hasSmartPtr){throwInternalError("Both smartPtrType and smartPtr must be specified")}record.count={value:1};return attachFinalizer(Object.create(prototype,{$$:{value:record}}))}function RegisteredPointer_fromWireType(ptr){var rawPointer=this.getPointee(ptr);if(!rawPointer){this.destructor(ptr);return null}var registeredInstance=getInheritedInstance(this.registeredClass,rawPointer);if(undefined!==registeredInstance){if(0===registeredInstance.$$.count.value){registeredInstance.$$.ptr=rawPointer;registeredInstance.$$.smartPtr=ptr;return registeredInstance["clone"]()}else{var rv=registeredInstance["clone"]();this.destructor(ptr);return rv}}function makeDefaultHandle(){if(this.isSmartPointer){return makeClassHandle(this.registeredClass.instancePrototype,{ptrType:this.pointeeType,ptr:rawPointer,smartPtrType:this,smartPtr:ptr})}else{return makeClassHandle(this.registeredClass.instancePrototype,{ptrType:this,ptr:ptr})}}var actualType=this.registeredClass.getActualType(rawPointer);var registeredPointerRecord=registeredPointers[actualType];if(!registeredPointerRecord){return makeDefaultHandle.call(this)}var toType;if(this.isConst){toType=registeredPointerRecord.constPointerType}else{toType=registeredPointerRecord.pointerType}var dp=downcastPointer(rawPointer,this.registeredClass,toType.registeredClass);if(dp===null){return makeDefaultHandle.call(this)}if(this.isSmartPointer){return makeClassHandle(toType.registeredClass.instancePrototype,{ptrType:toType,ptr:dp,smartPtrType:this,smartPtr:ptr})}else{return makeClassHandle(toType.registeredClass.instancePrototype,{ptrType:toType,ptr:dp})}}function init_RegisteredPointer(){RegisteredPointer.prototype.getPointee=RegisteredPointer_getPointee;RegisteredPointer.prototype.destructor=RegisteredPointer_destructor;RegisteredPointer.prototype["argPackAdvance"]=8;RegisteredPointer.prototype["readValueFromPointer"]=simpleReadValueFromPointer;RegisteredPointer.prototype["deleteObject"]=RegisteredPointer_deleteObject;RegisteredPointer.prototype["fromWireType"]=RegisteredPointer_fromWireType}function RegisteredPointer(name,registeredClass,isReference,isConst,isSmartPointer,pointeeType,sharingPolicy,rawGetPointee,rawConstructor,rawShare,rawDestructor){this.name=name;this.registeredClass=registeredClass;this.isReference=isReference;this.isConst=isConst;this.isSmartPointer=isSmartPointer;this.pointeeType=pointeeType;this.sharingPolicy=sharingPolicy;this.rawGetPointee=rawGetPointee;this.rawConstructor=rawConstructor;this.rawShare=rawShare;this.rawDestructor=rawDestructor;if(!isSmartPointer&®isteredClass.baseClass===undefined){if(isConst){this["toWireType"]=constNoSmartPtrRawPointerToWireType;this.destructorFunction=null}else{this["toWireType"]=nonConstNoSmartPtrRawPointerToWireType;this.destructorFunction=null}}else{this["toWireType"]=genericPointerToWireType}}function replacePublicSymbol(name,value,numArguments){if(!Module.hasOwnProperty(name)){throwInternalError("Replacing nonexistant public symbol")}if(undefined!==Module[name].overloadTable&&undefined!==numArguments){Module[name].overloadTable[numArguments]=value}else{Module[name]=value;Module[name].argCount=numArguments}}function dynCallLegacy(sig,ptr,args){var f=Module["dynCall_"+sig];return args&&args.length?f.apply(null,[ptr].concat(args)):f.call(null,ptr)}function dynCall(sig,ptr,args){if(sig.indexOf("j")!=-1){return dynCallLegacy(sig,ptr,args)}return wasmTable.get(ptr).apply(null,args)}function getDynCaller(sig,ptr){var argCache=[];return function(){argCache.length=arguments.length;for(var i=0;i>2)+i])}return array}function __embind_register_class_constructor(rawClassType,argCount,rawArgTypesAddr,invokerSignature,invoker,rawConstructor){assert(argCount>0);var rawArgTypes=heap32VectorToArray(argCount,rawArgTypesAddr);invoker=embind__requireFunction(invokerSignature,invoker);var args=[rawConstructor];var destructors=[];whenDependentTypesAreResolved([],[rawClassType],function(classType){classType=classType[0];var humanName="constructor "+classType.name;if(undefined===classType.registeredClass.constructor_body){classType.registeredClass.constructor_body=[]}if(undefined!==classType.registeredClass.constructor_body[argCount-1]){throw new BindingError("Cannot register multiple constructors with identical number of parameters ("+(argCount-1)+") for class '"+classType.name+"'! Overload resolution is currently only performed using the parameter count, not actual type info!")}classType.registeredClass.constructor_body[argCount-1]=function unboundTypeHandler(){throwUnboundTypeError("Cannot construct "+classType.name+" due to unbound types",rawArgTypes)};whenDependentTypesAreResolved([],rawArgTypes,function(argTypes){classType.registeredClass.constructor_body[argCount-1]=function constructor_body(){if(arguments.length!==argCount-1){throwBindingError(humanName+" called with "+arguments.length+" arguments, expected "+(argCount-1))}destructors.length=0;args.length=argCount;for(var i=1;i0?", ":"")+argsListWired}invokerFnBody+=(returns?"var rv = ":"")+"invoker(fn"+(argsListWired.length>0?", ":"")+argsListWired+");\n";if(needsDestructorStack){invokerFnBody+="runDestructors(destructors);\n"}else{for(var i=isClassMethodFunc?1:2;i4&&0===--emval_handle_array[handle].refcount){emval_handle_array[handle]=undefined;emval_free_list.push(handle)}}function count_emval_handles(){var count=0;for(var i=5;i>1])};case 2:return function(pointer){var heap=signed?HEAP32:HEAPU32;return this["fromWireType"](heap[pointer>>2])};default:throw new TypeError("Unknown integer type: "+name)}}function __embind_register_enum(rawType,name,size,isSigned){var shift=getShiftFromSize(size);name=readLatin1String(name);function ctor(){}ctor.values={};registerType(rawType,{name:name,constructor:ctor,"fromWireType":function(c){return this.constructor.values[c]},"toWireType":function(destructors,c){return c.value},"argPackAdvance":8,"readValueFromPointer":enumReadValueFromPointer(name,shift,isSigned),destructorFunction:null});exposePublicSymbol(name,ctor)}function requireRegisteredType(rawType,humanName){var impl=registeredTypes[rawType];if(undefined===impl){throwBindingError(humanName+" has unknown type "+getTypeName(rawType))}return impl}function __embind_register_enum_value(rawEnumType,name,enumValue){var enumType=requireRegisteredType(rawEnumType,"enum");name=readLatin1String(name);var Enum=enumType.constructor;var Value=Object.create(enumType.constructor.prototype,{value:{value:enumValue},constructor:{value:createNamedFunction(enumType.name+"_"+name,function(){})}});Enum.values[enumValue]=Value;Enum[name]=Value}function _embind_repr(v){if(v===null){return"null"}var t=typeof v;if(t==="object"||t==="array"||t==="function"){return v.toString()}else{return""+v}}function floatReadValueFromPointer(name,shift){switch(shift){case 2:return function(pointer){return this["fromWireType"](HEAPF32[pointer>>2])};case 3:return function(pointer){return this["fromWireType"](HEAPF64[pointer>>3])};default:throw new TypeError("Unknown float type: "+name)}}function __embind_register_float(rawType,name,size){var shift=getShiftFromSize(size);name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":function(value){return value},"toWireType":function(destructors,value){if(typeof value!=="number"&&typeof value!=="boolean"){throw new TypeError('Cannot convert "'+_embind_repr(value)+'" to '+this.name)}return value},"argPackAdvance":8,"readValueFromPointer":floatReadValueFromPointer(name,shift),destructorFunction:null})}function __embind_register_function(name,argCount,rawArgTypesAddr,signature,rawInvoker,fn){var argTypes=heap32VectorToArray(argCount,rawArgTypesAddr);name=readLatin1String(name);rawInvoker=embind__requireFunction(signature,rawInvoker);exposePublicSymbol(name,function(){throwUnboundTypeError("Cannot call "+name+" due to unbound types",argTypes)},argCount-1);whenDependentTypesAreResolved([],argTypes,function(argTypes){var invokerArgsArray=[argTypes[0],null].concat(argTypes.slice(1));replacePublicSymbol(name,craftInvokerFunction(name,invokerArgsArray,null,rawInvoker,fn),argCount-1);return[]})}function integerReadValueFromPointer(name,shift,signed){switch(shift){case 0:return signed?function readS8FromPointer(pointer){return HEAP8[pointer]}:function readU8FromPointer(pointer){return HEAPU8[pointer]};case 1:return signed?function readS16FromPointer(pointer){return HEAP16[pointer>>1]}:function readU16FromPointer(pointer){return HEAPU16[pointer>>1]};case 2:return signed?function readS32FromPointer(pointer){return HEAP32[pointer>>2]}:function readU32FromPointer(pointer){return HEAPU32[pointer>>2]};default:throw new TypeError("Unknown integer type: "+name)}}function __embind_register_integer(primitiveType,name,size,minRange,maxRange){name=readLatin1String(name);if(maxRange===-1){maxRange=4294967295}var shift=getShiftFromSize(size);var fromWireType=function(value){return value};if(minRange===0){var bitshift=32-8*size;fromWireType=function(value){return value<>>bitshift}}var isUnsignedType=name.indexOf("unsigned")!=-1;registerType(primitiveType,{name:name,"fromWireType":fromWireType,"toWireType":function(destructors,value){if(typeof value!=="number"&&typeof value!=="boolean"){throw new TypeError('Cannot convert "'+_embind_repr(value)+'" to '+this.name)}if(valuemaxRange){throw new TypeError('Passing a number "'+_embind_repr(value)+'" from JS side to C/C++ side to an argument of type "'+name+'", which is outside the valid range ['+minRange+", "+maxRange+"]!")}return isUnsignedType?value>>>0:value|0},"argPackAdvance":8,"readValueFromPointer":integerReadValueFromPointer(name,shift,minRange!==0),destructorFunction:null})}function __embind_register_memory_view(rawType,dataTypeIndex,name){var typeMapping=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array];var TA=typeMapping[dataTypeIndex];function decodeMemoryView(handle){handle=handle>>2;var heap=HEAPU32;var size=heap[handle];var data=heap[handle+1];return new TA(buffer,data,size)}name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":decodeMemoryView,"argPackAdvance":8,"readValueFromPointer":decodeMemoryView},{ignoreDuplicateRegistrations:true})}function __embind_register_std_string(rawType,name){name=readLatin1String(name);var stdStringIsUTF8=name==="std::string";registerType(rawType,{name:name,"fromWireType":function(value){var length=HEAPU32[value>>2];var str;if(stdStringIsUTF8){var decodeStartPtr=value+4;for(var i=0;i<=length;++i){var currentBytePtr=value+4+i;if(i==length||HEAPU8[currentBytePtr]==0){var maxRead=currentBytePtr-decodeStartPtr;var stringSegment=UTF8ToString(decodeStartPtr,maxRead);if(str===undefined){str=stringSegment}else{str+=String.fromCharCode(0);str+=stringSegment}decodeStartPtr=currentBytePtr+1}}}else{var a=new Array(length);for(var i=0;i>2]=length;if(stdStringIsUTF8&&valueIsOfTypeString){stringToUTF8(value,ptr+4,length+1)}else{if(valueIsOfTypeString){for(var i=0;i255){_free(ptr);throwBindingError("String has UTF-16 code units that do not fit in 8 bits")}HEAPU8[ptr+4+i]=charCode}}else{for(var i=0;i>2];var HEAP=getHeap();var str;var decodeStartPtr=value+4;for(var i=0;i<=length;++i){var currentBytePtr=value+4+i*charSize;if(i==length||HEAP[currentBytePtr>>shift]==0){var maxReadBytes=currentBytePtr-decodeStartPtr;var stringSegment=decodeString(decodeStartPtr,maxReadBytes);if(str===undefined){str=stringSegment}else{str+=String.fromCharCode(0);str+=stringSegment}decodeStartPtr=currentBytePtr+charSize}}_free(value);return str},"toWireType":function(destructors,value){if(!(typeof value==="string")){throwBindingError("Cannot pass non-string to C++ string type "+name)}var length=lengthBytesUTF(value);var ptr=_malloc(4+length+charSize);HEAPU32[ptr>>2]=length>>shift;encodeString(value,ptr+4,length+charSize);if(destructors!==null){destructors.push(_free,ptr)}return ptr},"argPackAdvance":8,"readValueFromPointer":simpleReadValueFromPointer,destructorFunction:function(ptr){_free(ptr)}})}function __embind_register_value_object(rawType,name,constructorSignature,rawConstructor,destructorSignature,rawDestructor){structRegistrations[rawType]={name:readLatin1String(name),rawConstructor:embind__requireFunction(constructorSignature,rawConstructor),rawDestructor:embind__requireFunction(destructorSignature,rawDestructor),fields:[]}}function __embind_register_value_object_field(structType,fieldName,getterReturnType,getterSignature,getter,getterContext,setterArgumentType,setterSignature,setter,setterContext){structRegistrations[structType].fields.push({fieldName:readLatin1String(fieldName),getterReturnType:getterReturnType,getter:embind__requireFunction(getterSignature,getter),getterContext:getterContext,setterArgumentType:setterArgumentType,setter:embind__requireFunction(setterSignature,setter),setterContext:setterContext})}function __embind_register_void(rawType,name){name=readLatin1String(name);registerType(rawType,{isVoid:true,name:name,"argPackAdvance":0,"fromWireType":function(){return undefined},"toWireType":function(destructors,o){return undefined}})}function requireHandle(handle){if(!handle){throwBindingError("Cannot use deleted val. handle = "+handle)}return emval_handle_array[handle].value}function __emval_as(handle,returnType,destructorsRef){handle=requireHandle(handle);returnType=requireRegisteredType(returnType,"emval::as");var destructors=[];var rd=__emval_register(destructors);HEAP32[destructorsRef>>2]=rd;return returnType["toWireType"](destructors,handle)}var emval_symbols={};function getStringOrSymbol(address){var symbol=emval_symbols[address];if(symbol===undefined){return readLatin1String(address)}else{return symbol}}var emval_methodCallers=[];function __emval_call_void_method(caller,handle,methodName,args){caller=emval_methodCallers[caller];handle=requireHandle(handle);methodName=getStringOrSymbol(methodName);caller(handle,methodName,null,args)}function emval_get_global(){if(typeof globalThis==="object"){return globalThis}return function(){return Function}()("return this")()}function __emval_get_global(name){if(name===0){return __emval_register(emval_get_global())}else{name=getStringOrSymbol(name);return __emval_register(emval_get_global()[name])}}function __emval_addMethodCaller(caller){var id=emval_methodCallers.length;emval_methodCallers.push(caller);return id}function __emval_lookupTypes(argCount,argTypes){var a=new Array(argCount);for(var i=0;i>2)+i],"parameter "+i)}return a}function __emval_get_method_caller(argCount,argTypes){var types=__emval_lookupTypes(argCount,argTypes);var retType=types[0];var signatureName=retType.name+"_$"+types.slice(1).map(function(t){return t.name}).join("_")+"$";var params=["retType"];var args=[retType];var argsList="";for(var i=0;i4){emval_handle_array[handle].refcount+=1}}function craftEmvalAllocator(argCount){var argsList="";for(var i=0;i>> 2) + "+i+'], "parameter '+i+'");\n'+"var arg"+i+" = argType"+i+".readValueFromPointer(args);\n"+"args += argType"+i+"['argPackAdvance'];\n"}functionBody+="var obj = new constructor("+argsList+");\n"+"return __emval_register(obj);\n"+"}\n";return new Function("requireRegisteredType","Module","__emval_register",functionBody)(requireRegisteredType,Module,__emval_register)}var emval_newers={};function __emval_new(handle,argCount,argTypes,args){handle=requireHandle(handle);var newer=emval_newers[argCount];if(!newer){newer=craftEmvalAllocator(argCount);emval_newers[argCount]=newer}return newer(handle,argTypes,args)}function __emval_new_cstring(v){return __emval_register(getStringOrSymbol(v))}function __emval_run_destructors(handle){var destructors=emval_handle_array[handle].value;runDestructors(destructors);__emval_decref(handle)}function _abort(){abort()}function _emscripten_memcpy_big(dest,src,num){HEAPU8.copyWithin(dest,src,src+num)}function emscripten_realloc_buffer(size){try{wasmMemory.grow(size-buffer.byteLength+65535>>>16);updateGlobalBufferAndViews(wasmMemory.buffer);return 1}catch(e){}}function _emscripten_resize_heap(requestedSize){var oldSize=HEAPU8.length;requestedSize=requestedSize>>>0;var maxHeapSize=2147483648;if(requestedSize>maxHeapSize){return false}for(var cutDown=1;cutDown<=4;cutDown*=2){var overGrownHeapSize=oldSize*(1+.2/cutDown);overGrownHeapSize=Math.min(overGrownHeapSize,requestedSize+100663296);var newSize=Math.min(maxHeapSize,alignUp(Math.max(requestedSize,overGrownHeapSize),65536));var replacement=emscripten_realloc_buffer(newSize);if(replacement){return true}}return false}var SYSCALLS={mappings:{},buffers:[null,[],[]],printChar:function(stream,curr){var buffer=SYSCALLS.buffers[stream];if(curr===0||curr===10){(stream===1?out:err)(UTF8ArrayToString(buffer,0));buffer.length=0}else{buffer.push(curr)}},varargs:undefined,get:function(){SYSCALLS.varargs+=4;var ret=HEAP32[SYSCALLS.varargs-4>>2];return ret},getStr:function(ptr){var ret=UTF8ToString(ptr);return ret},get64:function(low,high){return low}};function _fd_close(fd){return 0}function _fd_seek(fd,offset_low,offset_high,whence,newOffset){}function _fd_write(fd,iov,iovcnt,pnum){var num=0;for(var i=0;i>2];var len=HEAP32[iov+(i*8+4)>>2];for(var j=0;j>2]=num;return 0}function _setTempRet0($i){setTempRet0($i|0)}InternalError=Module["InternalError"]=extendError(Error,"InternalError");embind_init_charCodes();BindingError=Module["BindingError"]=extendError(Error,"BindingError");init_ClassHandle();init_RegisteredPointer();init_embind();UnboundTypeError=Module["UnboundTypeError"]=extendError(Error,"UnboundTypeError");init_emval();var asmLibraryArg={"t":__embind_finalize_value_object,"I":__embind_register_bool,"x":__embind_register_class,"w":__embind_register_class_constructor,"d":__embind_register_class_function,"k":__embind_register_constant,"H":__embind_register_emval,"n":__embind_register_enum,"a":__embind_register_enum_value,"A":__embind_register_float,"i":__embind_register_function,"j":__embind_register_integer,"h":__embind_register_memory_view,"B":__embind_register_std_string,"v":__embind_register_std_wstring,"u":__embind_register_value_object,"c":__embind_register_value_object_field,"J":__embind_register_void,"m":__emval_as,"s":__emval_call_void_method,"b":__emval_decref,"y":__emval_get_global,"p":__emval_get_method_caller,"r":__emval_get_module_property,"e":__emval_get_property,"g":__emval_incref,"q":__emval_new,"f":__emval_new_cstring,"l":__emval_run_destructors,"o":_abort,"E":_emscripten_memcpy_big,"F":_emscripten_resize_heap,"G":_fd_close,"C":_fd_seek,"z":_fd_write,"D":_setTempRet0};var asm=createWasm();var ___wasm_call_ctors=Module["___wasm_call_ctors"]=function(){return(___wasm_call_ctors=Module["___wasm_call_ctors"]=Module["asm"]["L"]).apply(null,arguments)};var _malloc=Module["_malloc"]=function(){return(_malloc=Module["_malloc"]=Module["asm"]["M"]).apply(null,arguments)};var _free=Module["_free"]=function(){return(_free=Module["_free"]=Module["asm"]["N"]).apply(null,arguments)};var ___getTypeName=Module["___getTypeName"]=function(){return(___getTypeName=Module["___getTypeName"]=Module["asm"]["P"]).apply(null,arguments)};var ___embind_register_native_and_builtin_types=Module["___embind_register_native_and_builtin_types"]=function(){return(___embind_register_native_and_builtin_types=Module["___embind_register_native_and_builtin_types"]=Module["asm"]["Q"]).apply(null,arguments)};var dynCall_jiji=Module["dynCall_jiji"]=function(){return(dynCall_jiji=Module["dynCall_jiji"]=Module["asm"]["R"]).apply(null,arguments)};var calledRun;function ExitStatus(status){this.name="ExitStatus";this.message="Program terminated with exit("+status+")";this.status=status}dependenciesFulfilled=function runCaller(){if(!calledRun)run();if(!calledRun)dependenciesFulfilled=runCaller};function run(args){args=args||arguments_;if(runDependencies>0){return}preRun();if(runDependencies>0){return}function doRun(){if(calledRun)return;calledRun=true;Module["calledRun"]=true;if(ABORT)return;initRuntime();preMain();readyPromiseResolve(Module);if(Module["onRuntimeInitialized"])Module["onRuntimeInitialized"]();postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(function(){setTimeout(function(){Module["setStatus"]("")},1);doRun()},1)}else{doRun()}}Module["run"]=run;if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}run(); + + + return BASIS.ready +} +); +})(); +if (typeof exports === 'object' && typeof module === 'object') + module.exports = BASIS; +else if (typeof define === 'function' && define['amd']) + define([], function() { return BASIS; }); +else if (typeof exports === 'object') + exports["BASIS"] = BASIS; diff --git a/Source/ThirdParty/Workers/ktx-parse.modern.js b/Source/ThirdParty/Workers/ktx-parse.modern.js new file mode 100644 index 000000000000..5d007f16fddd --- /dev/null +++ b/Source/ThirdParty/Workers/ktx-parse.modern.js @@ -0,0 +1,2 @@ +const t=new Uint8Array([0]),e=[171,75,84,88,32,50,48,187,13,10,26,10];var n,i,s,a,r,o,l,f;!function(t){t[t.NONE=0]="NONE",t[t.BASISLZ=1]="BASISLZ",t[t.ZSTD=2]="ZSTD",t[t.ZLIB=3]="ZLIB"}(n||(n={})),function(t){t[t.BASICFORMAT=0]="BASICFORMAT"}(i||(i={})),function(t){t[t.UNSPECIFIED=0]="UNSPECIFIED",t[t.ETC1S=163]="ETC1S",t[t.UASTC=166]="UASTC"}(s||(s={})),function(t){t[t.UNSPECIFIED=0]="UNSPECIFIED",t[t.SRGB=1]="SRGB"}(a||(a={})),function(t){t[t.UNSPECIFIED=0]="UNSPECIFIED",t[t.LINEAR=1]="LINEAR",t[t.SRGB=2]="SRGB",t[t.ITU=3]="ITU",t[t.NTSC=4]="NTSC",t[t.SLOG=5]="SLOG",t[t.SLOG2=6]="SLOG2"}(r||(r={})),function(t){t[t.ALPHA_STRAIGHT=0]="ALPHA_STRAIGHT",t[t.ALPHA_PREMULTIPLIED=1]="ALPHA_PREMULTIPLIED"}(o||(o={})),function(t){t[t.RGB=0]="RGB",t[t.RRR=3]="RRR",t[t.GGG=4]="GGG",t[t.AAA=15]="AAA"}(l||(l={})),function(t){t[t.RGB=0]="RGB",t[t.RGBA=3]="RGBA",t[t.RRR=4]="RRR",t[t.RRRG=5]="RRRG"}(f||(f={}));class U{constructor(){this.vkFormat=0,this.typeSize=1,this.pixelWidth=0,this.pixelHeight=0,this.pixelDepth=0,this.layerCount=0,this.faceCount=1,this.supercompressionScheme=n.NONE,this.levels=[],this.dataFormatDescriptor=[{vendorId:0,descriptorType:i.BASICFORMAT,versionNumber:2,descriptorBlockSize:40,colorModel:s.UNSPECIFIED,colorPrimaries:a.SRGB,transferFunction:a.SRGB,flags:o.ALPHA_STRAIGHT,texelBlockDimension:{x:4,y:4,z:1,w:1},bytesPlane:[],samples:[]}],this.keyValue={},this.globalData=null}}class c{constructor(t,e,n,i){this._dataView=new DataView(t.buffer,t.byteOffset+e,n),this._littleEndian=i,this._offset=0}_nextUint8(){const t=this._dataView.getUint8(this._offset);return this._offset+=1,t}_nextUint16(){const t=this._dataView.getUint16(this._offset,this._littleEndian);return this._offset+=2,t}_nextUint32(){const t=this._dataView.getUint32(this._offset,this._littleEndian);return this._offset+=4,t}_nextUint64(){const t=this._dataView.getUint32(this._offset,this._littleEndian)+2**32*this._dataView.getUint32(this._offset+4,this._littleEndian);return this._offset+=8,t}_skip(t){return this._offset+=t,this}_scan(t,e=0){const n=this._offset;let i=0;for(;this._dataView.getUint8(this._offset)!==e&&i1){Module["thisProgram"]=process["argv"][1].replace(/\\/g,"/")}else{Module["thisProgram"]="unknown-program"}}Module["arguments"]=process["argv"].slice(2);if(typeof module!=="undefined"){module["exports"]=Module}process["on"]("uncaughtException",(function(ex){if(!(ex instanceof ExitStatus)){throw ex}}));Module["inspect"]=(function(){return"[Emscripten Module object]"})}else if(ENVIRONMENT_IS_SHELL){if(!Module["print"])Module["print"]=print;if(typeof printErr!="undefined")Module["printErr"]=printErr;if(typeof read!="undefined"){Module["read"]=read}else{Module["read"]=function shell_read(){throw"no read() available"}}Module["readBinary"]=function readBinary(f){if(typeof readbuffer==="function"){return new Uint8Array(readbuffer(f))}var data=read(f,"binary");assert(typeof data==="object");return data};if(typeof scriptArgs!="undefined"){Module["arguments"]=scriptArgs}else if(typeof arguments!="undefined"){Module["arguments"]=arguments}if(typeof quit==="function"){Module["quit"]=(function(status,toThrow){quit(status)})}}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){Module["read"]=function shell_read(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.send(null);return xhr.responseText};if(ENVIRONMENT_IS_WORKER){Module["readBinary"]=function readBinary(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}}Module["readAsync"]=function readAsync(url,onload,onerror){var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=function xhr_onload(){if(xhr.status==200||xhr.status==0&&xhr.response){onload(xhr.response)}else{onerror()}};xhr.onerror=onerror;xhr.send(null)};if(typeof arguments!="undefined"){Module["arguments"]=arguments}if(typeof console!=="undefined"){if(!Module["print"])Module["print"]=function shell_print(x){console.log(x)};if(!Module["printErr"])Module["printErr"]=function shell_printErr(x){console.warn(x)}}else{var TRY_USE_DUMP=false;if(!Module["print"])Module["print"]=TRY_USE_DUMP&&typeof dump!=="undefined"?(function(x){dump(x)}):(function(x){})}if(ENVIRONMENT_IS_WORKER){Module["load"]=importScripts}if(typeof Module["setWindowTitle"]==="undefined"){Module["setWindowTitle"]=(function(title){document.title=title})}}else{throw"Unknown runtime environment. Where are we?"}function globalEval(x){eval.call(null,x)}if(!Module["load"]&&Module["read"]){Module["load"]=function load(f){globalEval(Module["read"](f))}}if(!Module["print"]){Module["print"]=(function(){})}if(!Module["printErr"]){Module["printErr"]=Module["print"]}if(!Module["arguments"]){Module["arguments"]=[]}if(!Module["thisProgram"]){Module["thisProgram"]="./this.program"}if(!Module["quit"]){Module["quit"]=(function(status,toThrow){throw toThrow})}Module.print=Module["print"];Module.printErr=Module["printErr"];Module["preRun"]=[];Module["postRun"]=[];for(var key in moduleOverrides){if(moduleOverrides.hasOwnProperty(key)){Module[key]=moduleOverrides[key]}}moduleOverrides=undefined;var Runtime={setTempRet0:(function(value){tempRet0=value;return value}),getTempRet0:(function(){return tempRet0}),stackSave:(function(){return STACKTOP}),stackRestore:(function(stackTop){STACKTOP=stackTop}),getNativeTypeSize:(function(type){switch(type){case"i1":case"i8":return 1;case"i16":return 2;case"i32":return 4;case"i64":return 8;case"float":return 4;case"double":return 8;default:{if(type[type.length-1]==="*"){return Runtime.QUANTUM_SIZE}else if(type[0]==="i"){var bits=parseInt(type.substr(1));assert(bits%8===0);return bits/8}else{return 0}}}}),getNativeFieldSize:(function(type){return Math.max(Runtime.getNativeTypeSize(type),Runtime.QUANTUM_SIZE)}),STACK_ALIGN:16,prepVararg:(function(ptr,type){if(type==="double"||type==="i64"){if(ptr&7){assert((ptr&7)===4);ptr+=4}}else{assert((ptr&3)===0)}return ptr}),getAlignSize:(function(type,size,vararg){if(!vararg&&(type=="i64"||type=="double"))return 8;if(!type)return Math.min(size,8);return Math.min(size||(type?Runtime.getNativeFieldSize(type):0),Runtime.QUANTUM_SIZE)}),dynCall:(function(sig,ptr,args){if(args&&args.length){return Module["dynCall_"+sig].apply(null,[ptr].concat(args))}else{return Module["dynCall_"+sig].call(null,ptr)}}),functionPointers:[],addFunction:(function(func){for(var i=0;i>2];var end=(ret+size+15|0)&-16;HEAP32[DYNAMICTOP_PTR>>2]=end;if(end>=TOTAL_MEMORY){var success=enlargeMemory();if(!success){HEAP32[DYNAMICTOP_PTR>>2]=ret;return 0}}return ret}),alignMemory:(function(size,quantum){var ret=size=Math.ceil(size/(quantum?quantum:16))*(quantum?quantum:16);return ret}),makeBigInt:(function(low,high,unsigned){var ret=unsigned?+(low>>>0)+ +(high>>>0)*+4294967296:+(low>>>0)+ +(high|0)*+4294967296;return ret}),GLOBAL_BASE:8,QUANTUM_SIZE:4,__dummy__:0};Module["Runtime"]=Runtime;var ABORT=0;var EXITSTATUS=0;function assert(condition,text){if(!condition){abort("Assertion failed: "+text)}}function getCFunc(ident){var func=Module["_"+ident];if(!func){try{func=eval("_"+ident)}catch(e){}}assert(func,"Cannot call unknown function "+ident+" (perhaps LLVM optimizations or closure removed it?)");return func}var cwrap,ccall;((function(){var JSfuncs={"stackSave":(function(){Runtime.stackSave()}),"stackRestore":(function(){Runtime.stackRestore()}),"arrayToC":(function(arr){var ret=Runtime.stackAlloc(arr.length);writeArrayToMemory(arr,ret);return ret}),"stringToC":(function(str){var ret=0;if(str!==null&&str!==undefined&&str!==0){var len=(str.length<<2)+1;ret=Runtime.stackAlloc(len);stringToUTF8(str,ret,len)}return ret})};var toC={"string":JSfuncs["stringToC"],"array":JSfuncs["arrayToC"]};ccall=function ccallFunc(ident,returnType,argTypes,args,opts){var func=getCFunc(ident);var cArgs=[];var stack=0;if(args){for(var i=0;i>0]=value;break;case"i8":HEAP8[ptr>>0]=value;break;case"i16":HEAP16[ptr>>1]=value;break;case"i32":HEAP32[ptr>>2]=value;break;case"i64":tempI64=[value>>>0,(tempDouble=value,+Math_abs(tempDouble)>=+1?tempDouble>+0?(Math_min(+Math_floor(tempDouble/+4294967296),+4294967295)|0)>>>0:~~+Math_ceil((tempDouble- +(~~tempDouble>>>0))/+4294967296)>>>0:0)],HEAP32[ptr>>2]=tempI64[0],HEAP32[ptr+4>>2]=tempI64[1];break;case"float":HEAPF32[ptr>>2]=value;break;case"double":HEAPF64[ptr>>3]=value;break;default:abort("invalid type for setValue: "+type)}}Module["setValue"]=setValue;function getValue(ptr,type,noSafe){type=type||"i8";if(type.charAt(type.length-1)==="*")type="i32";switch(type){case"i1":return HEAP8[ptr>>0];case"i8":return HEAP8[ptr>>0];case"i16":return HEAP16[ptr>>1];case"i32":return HEAP32[ptr>>2];case"i64":return HEAP32[ptr>>2];case"float":return HEAPF32[ptr>>2];case"double":return HEAPF64[ptr>>3];default:abort("invalid type for setValue: "+type)}return null}Module["getValue"]=getValue;var ALLOC_NORMAL=0;var ALLOC_STACK=1;var ALLOC_STATIC=2;var ALLOC_DYNAMIC=3;var ALLOC_NONE=4;Module["ALLOC_NORMAL"]=ALLOC_NORMAL;Module["ALLOC_STACK"]=ALLOC_STACK;Module["ALLOC_STATIC"]=ALLOC_STATIC;Module["ALLOC_DYNAMIC"]=ALLOC_DYNAMIC;Module["ALLOC_NONE"]=ALLOC_NONE;function allocate(slab,types,allocator,ptr){var zeroinit,size;if(typeof slab==="number"){zeroinit=true;size=slab}else{zeroinit=false;size=slab.length}var singleType=typeof types==="string"?types:null;var ret;if(allocator==ALLOC_NONE){ret=ptr}else{ret=[typeof _malloc==="function"?_malloc:Runtime.staticAlloc,Runtime.stackAlloc,Runtime.staticAlloc,Runtime.dynamicAlloc][allocator===undefined?ALLOC_STATIC:allocator](Math.max(size,singleType?1:types.length))}if(zeroinit){var ptr=ret,stop;assert((ret&3)==0);stop=ret+(size&~3);for(;ptr>2]=0}stop=ret+size;while(ptr>0]=0}return ret}if(singleType==="i8"){if(slab.subarray||slab.slice){HEAPU8.set(slab,ret)}else{HEAPU8.set(new Uint8Array(slab),ret)}return ret}var i=0,type,typeSize,previousType;while(i>0];hasUtf|=t;if(t==0&&!length)break;i++;if(length&&i==length)break}if(!length)length=i;var ret="";if(hasUtf<128){var MAX_CHUNK=1024;var curr;while(length>0){curr=String.fromCharCode.apply(String,HEAPU8.subarray(ptr,ptr+Math.min(length,MAX_CHUNK)));ret=ret?ret+curr:curr;ptr+=MAX_CHUNK;length-=MAX_CHUNK}return ret}return Module["UTF8ToString"](ptr)}Module["Pointer_stringify"]=Pointer_stringify;function AsciiToString(ptr){var str="";while(1){var ch=HEAP8[ptr++>>0];if(!ch)return str;str+=String.fromCharCode(ch)}}Module["AsciiToString"]=AsciiToString;function stringToAscii(str,outPtr){return writeAsciiToMemory(str,outPtr,false)}Module["stringToAscii"]=stringToAscii;var UTF8Decoder=typeof TextDecoder!=="undefined"?new TextDecoder("utf8"):undefined;function UTF8ArrayToString(u8Array,idx){var endPtr=idx;while(u8Array[endPtr])++endPtr;if(endPtr-idx>16&&u8Array.subarray&&UTF8Decoder){return UTF8Decoder.decode(u8Array.subarray(idx,endPtr))}else{var u0,u1,u2,u3,u4,u5;var str="";while(1){u0=u8Array[idx++];if(!u0)return str;if(!(u0&128)){str+=String.fromCharCode(u0);continue}u1=u8Array[idx++]&63;if((u0&224)==192){str+=String.fromCharCode((u0&31)<<6|u1);continue}u2=u8Array[idx++]&63;if((u0&240)==224){u0=(u0&15)<<12|u1<<6|u2}else{u3=u8Array[idx++]&63;if((u0&248)==240){u0=(u0&7)<<18|u1<<12|u2<<6|u3}else{u4=u8Array[idx++]&63;if((u0&252)==248){u0=(u0&3)<<24|u1<<18|u2<<12|u3<<6|u4}else{u5=u8Array[idx++]&63;u0=(u0&1)<<30|u1<<24|u2<<18|u3<<12|u4<<6|u5}}}if(u0<65536){str+=String.fromCharCode(u0)}else{var ch=u0-65536;str+=String.fromCharCode(55296|ch>>10,56320|ch&1023)}}}}Module["UTF8ArrayToString"]=UTF8ArrayToString;function UTF8ToString(ptr){return UTF8ArrayToString(HEAPU8,ptr)}Module["UTF8ToString"]=UTF8ToString;function stringToUTF8Array(str,outU8Array,outIdx,maxBytesToWrite){if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i=55296&&u<=57343)u=65536+((u&1023)<<10)|str.charCodeAt(++i)&1023;if(u<=127){if(outIdx>=endIdx)break;outU8Array[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;outU8Array[outIdx++]=192|u>>6;outU8Array[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;outU8Array[outIdx++]=224|u>>12;outU8Array[outIdx++]=128|u>>6&63;outU8Array[outIdx++]=128|u&63}else if(u<=2097151){if(outIdx+3>=endIdx)break;outU8Array[outIdx++]=240|u>>18;outU8Array[outIdx++]=128|u>>12&63;outU8Array[outIdx++]=128|u>>6&63;outU8Array[outIdx++]=128|u&63}else if(u<=67108863){if(outIdx+4>=endIdx)break;outU8Array[outIdx++]=248|u>>24;outU8Array[outIdx++]=128|u>>18&63;outU8Array[outIdx++]=128|u>>12&63;outU8Array[outIdx++]=128|u>>6&63;outU8Array[outIdx++]=128|u&63}else{if(outIdx+5>=endIdx)break;outU8Array[outIdx++]=252|u>>30;outU8Array[outIdx++]=128|u>>24&63;outU8Array[outIdx++]=128|u>>18&63;outU8Array[outIdx++]=128|u>>12&63;outU8Array[outIdx++]=128|u>>6&63;outU8Array[outIdx++]=128|u&63}}outU8Array[outIdx]=0;return outIdx-startIdx}Module["stringToUTF8Array"]=stringToUTF8Array;function stringToUTF8(str,outPtr,maxBytesToWrite){return stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite)}Module["stringToUTF8"]=stringToUTF8;function lengthBytesUTF8(str){var len=0;for(var i=0;i=55296&&u<=57343)u=65536+((u&1023)<<10)|str.charCodeAt(++i)&1023;if(u<=127){++len}else if(u<=2047){len+=2}else if(u<=65535){len+=3}else if(u<=2097151){len+=4}else if(u<=67108863){len+=5}else{len+=6}}return len}Module["lengthBytesUTF8"]=lengthBytesUTF8;var UTF16Decoder=typeof TextDecoder!=="undefined"?new TextDecoder("utf-16le"):undefined;function demangle(func){var __cxa_demangle_func=Module["___cxa_demangle"]||Module["__cxa_demangle"];if(__cxa_demangle_func){try{var s=func.substr(1);var len=lengthBytesUTF8(s)+1;var buf=_malloc(len);stringToUTF8(s,buf,len);var status=_malloc(4);var ret=__cxa_demangle_func(buf,0,0,status);if(getValue(status,"i32")===0&&ret){return Pointer_stringify(ret)}}catch(e){}finally{if(buf)_free(buf);if(status)_free(status);if(ret)_free(ret)}return func}Runtime.warnOnce("warning: build with -s DEMANGLE_SUPPORT=1 to link in libcxxabi demangling");return func}function demangleAll(text){var regex=/__Z[\w\d_]+/g;return text.replace(regex,(function(x){var y=demangle(x);return x===y?x:x+" ["+y+"]"}))}function jsStackTrace(){var err=new Error;if(!err.stack){try{throw new Error(0)}catch(e){err=e}if(!err.stack){return"(no stack trace available)"}}return err.stack.toString()}function stackTrace(){var js=jsStackTrace();if(Module["extraStackTrace"])js+="\n"+Module["extraStackTrace"]();return demangleAll(js)}Module["stackTrace"]=stackTrace;var WASM_PAGE_SIZE=65536;var ASMJS_PAGE_SIZE=16777216;var MIN_TOTAL_MEMORY=16777216;function alignUp(x,multiple){if(x%multiple>0){x+=multiple-x%multiple}return x}var HEAP,buffer,HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;function updateGlobalBuffer(buf){Module["buffer"]=buffer=buf}function updateGlobalBufferViews(){Module["HEAP8"]=HEAP8=new Int8Array(buffer);Module["HEAP16"]=HEAP16=new Int16Array(buffer);Module["HEAP32"]=HEAP32=new Int32Array(buffer);Module["HEAPU8"]=HEAPU8=new Uint8Array(buffer);Module["HEAPU16"]=HEAPU16=new Uint16Array(buffer);Module["HEAPU32"]=HEAPU32=new Uint32Array(buffer);Module["HEAPF32"]=HEAPF32=new Float32Array(buffer);Module["HEAPF64"]=HEAPF64=new Float64Array(buffer)}var STATIC_BASE,STATICTOP,staticSealed;var STACK_BASE,STACKTOP,STACK_MAX;var DYNAMIC_BASE,DYNAMICTOP_PTR;STATIC_BASE=STATICTOP=STACK_BASE=STACKTOP=STACK_MAX=DYNAMIC_BASE=DYNAMICTOP_PTR=0;staticSealed=false;function abortOnCannotGrowMemory(){abort("Cannot enlarge memory arrays. Either (1) compile with -s TOTAL_MEMORY=X with X higher than the current value "+TOTAL_MEMORY+", (2) compile with -s ALLOW_MEMORY_GROWTH=1 which allows increasing the size at runtime but prevents some optimizations, (3) set Module.TOTAL_MEMORY to a higher value before the program runs, or (4) if you want malloc to return NULL (0) instead of this abort, compile with -s ABORTING_MALLOC=0 ")}if(!Module["reallocBuffer"])Module["reallocBuffer"]=(function(size){var ret;try{if(ArrayBuffer.transfer){ret=ArrayBuffer.transfer(buffer,size)}else{var oldHEAP8=HEAP8;ret=new ArrayBuffer(size);var temp=new Int8Array(ret);temp.set(oldHEAP8)}}catch(e){return false}var success=_emscripten_replace_memory(ret);if(!success)return false;return ret});function enlargeMemory(){var PAGE_MULTIPLE=Module["usingWasm"]?WASM_PAGE_SIZE:ASMJS_PAGE_SIZE;var LIMIT=2147483648-PAGE_MULTIPLE;if(HEAP32[DYNAMICTOP_PTR>>2]>LIMIT){return false}var OLD_TOTAL_MEMORY=TOTAL_MEMORY;TOTAL_MEMORY=Math.max(TOTAL_MEMORY,MIN_TOTAL_MEMORY);while(TOTAL_MEMORY>2]){if(TOTAL_MEMORY<=536870912){TOTAL_MEMORY=alignUp(2*TOTAL_MEMORY,PAGE_MULTIPLE)}else{TOTAL_MEMORY=Math.min(alignUp((3*TOTAL_MEMORY+2147483648)/4,PAGE_MULTIPLE),LIMIT)}}var replacement=Module["reallocBuffer"](TOTAL_MEMORY);if(!replacement||replacement.byteLength!=TOTAL_MEMORY){TOTAL_MEMORY=OLD_TOTAL_MEMORY;return false}updateGlobalBuffer(replacement);updateGlobalBufferViews();return true}var byteLength;try{byteLength=Function.prototype.call.bind(Object.getOwnPropertyDescriptor(ArrayBuffer.prototype,"byteLength").get);byteLength(new ArrayBuffer(4))}catch(e){byteLength=(function(buffer){return buffer.byteLength})}var TOTAL_STACK=Module["TOTAL_STACK"]||5242880;var TOTAL_MEMORY=Module["TOTAL_MEMORY"]||16777216;if(TOTAL_MEMORY0){var callback=callbacks.shift();if(typeof callback=="function"){callback();continue}var func=callback.func;if(typeof func==="number"){if(callback.arg===undefined){Module["dynCall_v"](func)}else{Module["dynCall_vi"](func,callback.arg)}}else{func(callback.arg===undefined?null:callback.arg)}}}var __ATPRERUN__=[];var __ATINIT__=[];var __ATMAIN__=[];var __ATEXIT__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;var runtimeExited=false;function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(__ATPRERUN__)}function ensureInitRuntime(){if(runtimeInitialized)return;runtimeInitialized=true;callRuntimeCallbacks(__ATINIT__)}function preMain(){callRuntimeCallbacks(__ATMAIN__)}function exitRuntime(){callRuntimeCallbacks(__ATEXIT__);runtimeExited=true}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}Module["addOnPreRun"]=addOnPreRun;function addOnInit(cb){__ATINIT__.unshift(cb)}Module["addOnInit"]=addOnInit;function addOnPreMain(cb){__ATMAIN__.unshift(cb)}Module["addOnPreMain"]=addOnPreMain;function addOnExit(cb){__ATEXIT__.unshift(cb)}Module["addOnExit"]=addOnExit;function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}Module["addOnPostRun"]=addOnPostRun;function intArrayFromString(stringy,dontAddNull,length){var len=length>0?length:lengthBytesUTF8(stringy)+1;var u8array=new Array(len);var numBytesWritten=stringToUTF8Array(stringy,u8array,0,u8array.length);if(dontAddNull)u8array.length=numBytesWritten;return u8array}Module["intArrayFromString"]=intArrayFromString;function intArrayToString(array){var ret=[];for(var i=0;i255){chr&=255}ret.push(String.fromCharCode(chr))}return ret.join("")}Module["intArrayToString"]=intArrayToString;function writeStringToMemory(string,buffer,dontAddNull){Runtime.warnOnce("writeStringToMemory is deprecated and should not be called! Use stringToUTF8() instead!");var lastChar,end;if(dontAddNull){end=buffer+lengthBytesUTF8(string);lastChar=HEAP8[end]}stringToUTF8(string,buffer,Infinity);if(dontAddNull)HEAP8[end]=lastChar}Module["writeStringToMemory"]=writeStringToMemory;function writeArrayToMemory(array,buffer){HEAP8.set(array,buffer)}Module["writeArrayToMemory"]=writeArrayToMemory;function writeAsciiToMemory(str,buffer,dontAddNull){for(var i=0;i>0]=str.charCodeAt(i)}if(!dontAddNull)HEAP8[buffer>>0]=0}Module["writeAsciiToMemory"]=writeAsciiToMemory;if(!Math["imul"]||Math["imul"](4294967295,5)!==-5)Math["imul"]=function imul(a,b){var ah=a>>>16;var al=a&65535;var bh=b>>>16;var bl=b&65535;return al*bl+(ah*bl+al*bh<<16)|0};Math.imul=Math["imul"];if(!Math["clz32"])Math["clz32"]=(function(x){x=x>>>0;for(var i=0;i<32;i++){if(x&1<<31-i)return i}return 32});Math.clz32=Math["clz32"];if(!Math["trunc"])Math["trunc"]=(function(x){return x<0?Math.ceil(x):Math.floor(x)});Math.trunc=Math["trunc"];var Math_abs=Math.abs;var Math_cos=Math.cos;var Math_sin=Math.sin;var Math_tan=Math.tan;var Math_acos=Math.acos;var Math_asin=Math.asin;var Math_atan=Math.atan;var Math_atan2=Math.atan2;var Math_exp=Math.exp;var Math_log=Math.log;var Math_sqrt=Math.sqrt;var Math_ceil=Math.ceil;var Math_floor=Math.floor;var Math_pow=Math.pow;var Math_imul=Math.imul;var Math_fround=Math.fround;var Math_round=Math.round;var Math_min=Math.min;var Math_clz32=Math.clz32;var Math_trunc=Math.trunc;var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;function addRunDependency(id){runDependencies++;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}}Module["addRunDependency"]=addRunDependency;function removeRunDependency(id){runDependencies--;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}if(runDependencies==0){if(runDependencyWatcher!==null){clearInterval(runDependencyWatcher);runDependencyWatcher=null}if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}Module["removeRunDependency"]=removeRunDependency;Module["preloadedImages"]={};Module["preloadedAudios"]={};var ASM_CONSTS=[];STATIC_BASE=Runtime.GLOBAL_BASE;STATICTOP=STATIC_BASE+6192;__ATINIT__.push();allocate([228,2,0,0,81,16,0,0,12,3,0,0,177,16,0,0,32,0,0,0,0,0,0,0,12,3,0,0,94,16,0,0,48,0,0,0,0,0,0,0,228,2,0,0,127,16,0,0,12,3,0,0,140,16,0,0,16,0,0,0,0,0,0,0,12,3,0,0,183,17,0,0,32,0,0,0,0,0,0,0,12,3,0,0,147,17,0,0,72,0,0,0,0,0,0,0,108,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,2,0,0,0,32,20,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,248,19,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,224,1,0,0,5,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,2,0,0,0,40,20,0,0,0,4,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,16,0,0,0,1,0,0,0,2,0,0,0,3,0,0,0,4,0,0,0,5,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,56,0,0,0,1,0,0,0,5,0,0,0,3,0,0,0,4,0,0,0,5,0,0,0,2,0,0,0,2,0,0,0,2,0,0,0,37,115,40,37,117,41,58,32,65,115,115,101,114,116,105,111,110,32,102,97,105,108,117,114,101,58,32,34,37,115,34,10,0,109,95,115,105,122,101,32,60,61,32,109,95,99,97,112,97,99,105,116,121,0,46,47,105,110,99,92,99,114,110,95,100,101,99,111,109,112,46,104,0,109,105,110,95,110,101,119,95,99,97,112,97,99,105,116,121,32,60,32,40,48,120,55,70,70,70,48,48,48,48,85,32,47,32,101,108,101,109,101,110,116,95,115,105,122,101,41,0,110,101,119,95,99,97,112,97,99,105,116,121,32,38,38,32,40,110,101,119,95,99,97,112,97,99,105,116,121,32,62,32,109,95,99,97,112,97,99,105,116,121,41,0,110,117,109,95,99,111,100,101,115,91,99,93,0,115,111,114,116,101,100,95,112,111,115,32,60,32,116,111,116,97,108,95,117,115,101,100,95,115,121,109,115,0,112,67,111,100,101,115,105,122,101,115,91,115,121,109,95,105,110,100,101,120,93,32,61,61,32,99,111,100,101,115,105,122,101,0,116,32,60,32,40,49,85,32,60,60,32,116,97,98,108,101,95,98,105,116,115,41,0,109,95,108,111,111,107,117,112,91,116,93,32,61,61,32,99,85,73,78,84,51,50,95,77,65,88,0,99,114,110,100,95,109,97,108,108,111,99,58,32,115,105,122,101,32,116,111,111,32,98,105,103,0,99,114,110,100,95,109,97,108,108,111,99,58,32,111,117,116,32,111,102,32,109,101,109,111,114,121,0,40,40,117,105,110,116,51,50,41,112,95,110,101,119,32,38,32,40,67,82,78,68,95,77,73,78,95,65,76,76,79,67,95,65,76,73,71,78,77,69,78,84,32,45,32,49,41,41,32,61,61,32,48,0,99,114,110,100,95,114,101,97,108,108,111,99,58,32,98,97,100,32,112,116,114,0,99,114,110,100,95,102,114,101,101,58,32,98,97,100,32,112,116,114,0,102,97,108,115,101,0,40,116,111,116,97,108,95,115,121,109,115,32,62,61,32,49,41,32,38,38,32,40,116,111,116,97,108,95,115,121,109,115,32,60,61,32,112,114,101,102,105,120,95,99,111,100,105,110,103,58,58,99,77,97,120,83,117,112,112,111,114,116,101,100,83,121,109,115,41,0,17,18,19,20,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15,16,48,0,110,117,109,95,98,105,116,115,32,60,61,32,51,50,85,0,109,95,98,105,116,95,99,111,117,110,116,32,60,61,32,99,66,105,116,66,117,102,83,105,122,101,0,116,32,33,61,32,99,85,73,78,84,51,50,95,77,65,88,0,109,111,100,101,108,46,109,95,99,111,100,101,95,115,105,122,101,115,91,115,121,109,93,32,61,61,32,108,101,110,0,0,2,3,1,0,2,3,4,5,6,7,1,40,108,101,110,32,62,61,32,49,41,32,38,38,32,40,108,101,110,32,60,61,32,99,77,97,120,69,120,112,101,99,116,101,100,67,111,100,101,83,105,122,101,41,0,105,32,60,32,109,95,115,105,122,101,0,110,101,120,116,95,108,101,118,101,108,95,111,102,115,32,62,32,99,117,114,95,108,101,118,101,108,95,111,102,115,0,1,2,2,3,3,3,3,4,0,0,0,0,0,0,1,1,0,1,0,1,0,0,1,2,1,2,0,0,0,1,0,2,1,0,2,0,0,1,2,3,110,117,109,32,38,38,32,40,110,117,109,32,61,61,32,126,110,117,109,95,99,104,101,99,107,41,0,17,0,10,0,17,17,17,0,0,0,0,5,0,0,0,0,0,0,9,0,0,0,0,11,0,0,0,0,0,0,0,0,17,0,15,10,17,17,17,3,10,7,0,1,19,9,11,11,0,0,9,6,11,0,0,11,0,6,17,0,0,0,17,17,17,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,17,0,10,10,17,17,17,0,10,0,0,2,0,9,11,0,0,0,9,0,11,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,12,0,0,0,0,9,12,0,0,0,0,0,12,0,0,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,13,0,0,0,4,13,0,0,0,0,9,14,0,0,0,0,0,14,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,15,0,0,0,0,15,0,0,0,0,9,16,0,0,0,0,0,16,0,0,16,0,0,18,0,0,0,18,18,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,0,0,0,18,18,18,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,10,0,0,0,0,9,11,0,0,0,0,0,11,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,12,0,0,0,0,9,12,0,0,0,0,0,12,0,0,12,0,0,45,43,32,32,32,48,88,48,120,0,40,110,117,108,108,41,0,45,48,88,43,48,88,32,48,88,45,48,120,43,48,120,32,48,120,0,105,110,102,0,73,78,70,0,110,97,110,0,78,65,78,0,48,49,50,51,52,53,54,55,56,57,65,66,67,68,69,70,46,0,84,33,34,25,13,1,2,3,17,75,28,12,16,4,11,29,18,30,39,104,110,111,112,113,98,32,5,6,15,19,20,21,26,8,22,7,40,36,23,24,9,10,14,27,31,37,35,131,130,125,38,42,43,60,61,62,63,67,71,74,77,88,89,90,91,92,93,94,95,96,97,99,100,101,102,103,105,106,107,108,114,115,116,121,122,123,124,0,73,108,108,101,103,97,108,32,98,121,116,101,32,115,101,113,117,101,110,99,101,0,68,111,109,97,105,110,32,101,114,114,111,114,0,82,101,115,117,108,116,32,110,111,116,32,114,101,112,114,101,115,101,110,116,97,98,108,101,0,78,111,116,32,97,32,116,116,121,0,80,101,114,109,105,115,115,105,111,110,32,100,101,110,105,101,100,0,79,112,101,114,97,116,105,111,110,32,110,111,116,32,112,101,114,109,105,116,116,101,100,0,78,111,32,115,117,99,104,32,102,105,108,101,32,111,114,32,100,105,114,101,99,116,111,114,121,0,78,111,32,115,117,99,104,32,112,114,111,99,101,115,115,0,70,105,108,101,32,101,120,105,115,116,115,0,86,97,108,117,101,32,116,111,111,32,108,97,114,103,101,32,102,111,114,32,100,97,116,97,32,116,121,112,101,0,78,111,32,115,112,97,99,101,32,108,101,102,116,32,111,110,32,100,101,118,105,99,101,0,79,117,116,32,111,102,32,109,101,109,111,114,121,0,82,101,115,111,117,114,99,101,32,98,117,115,121,0,73,110,116,101,114,114,117,112,116,101,100,32,115,121,115,116,101,109,32,99,97,108,108,0,82,101,115,111,117,114,99,101,32,116,101,109,112,111,114,97,114,105,108,121,32,117,110,97,118,97,105,108,97,98,108,101,0,73,110,118,97,108,105,100,32,115,101,101,107,0,67,114,111,115,115,45,100,101,118,105,99,101,32,108,105,110,107,0,82,101,97,100,45,111,110,108,121,32,102,105,108,101,32,115,121,115,116,101,109,0,68,105,114,101,99,116,111,114,121,32,110,111,116,32,101,109,112,116,121,0,67,111,110,110,101,99,116,105,111,110,32,114,101,115,101,116,32,98,121,32,112,101,101,114,0,79,112,101,114,97,116,105,111,110,32,116,105,109,101,100,32,111,117,116,0,67,111,110,110,101,99,116,105,111,110,32,114,101,102,117,115,101,100,0,72,111,115,116,32,105,115,32,100,111,119,110,0,72,111,115,116,32,105,115,32,117,110,114,101,97,99,104,97,98,108,101,0,65,100,100,114,101,115,115,32,105,110,32,117,115,101,0,66,114,111,107,101,110,32,112,105,112,101,0,73,47,79,32,101,114,114,111,114,0,78,111,32,115,117,99,104,32,100,101,118,105,99,101,32,111,114,32,97,100,100,114,101,115,115,0,66,108,111,99,107,32,100,101,118,105,99,101,32,114,101,113,117,105,114,101,100,0,78,111,32,115,117,99,104,32,100,101,118,105,99,101,0,78,111,116,32,97,32,100,105,114,101,99,116,111,114,121,0,73,115,32,97,32,100,105,114,101,99,116,111,114,121,0,84,101,120,116,32,102,105,108,101,32,98,117,115,121,0,69,120,101,99,32,102,111,114,109,97,116,32,101,114,114,111,114,0,73,110,118,97,108,105,100,32,97,114,103,117,109,101,110,116,0,65,114,103,117,109,101,110,116,32,108,105,115,116,32,116,111,111,32,108,111,110,103,0,83,121,109,98,111,108,105,99,32,108,105,110,107,32,108,111,111,112,0,70,105,108,101,110,97,109,101,32,116,111,111,32,108,111,110,103,0,84,111,111,32,109,97,110,121,32,111,112,101,110,32,102,105,108,101,115,32,105,110,32,115,121,115,116,101,109,0,78,111,32,102,105,108,101,32,100,101,115,99,114,105,112,116,111,114,115,32,97,118,97,105,108,97,98,108,101,0,66,97,100,32,102,105,108,101,32,100,101,115,99,114,105,112,116,111,114,0,78,111,32,99,104,105,108,100,32,112,114,111,99,101,115,115,0,66,97,100,32,97,100,100,114,101,115,115,0,70,105,108,101,32,116,111,111,32,108,97,114,103,101,0,84,111,111,32,109,97,110,121,32,108,105,110,107,115,0,78,111,32,108,111,99,107,115,32,97,118,97,105,108,97,98,108,101,0,82,101,115,111,117,114,99,101,32,100,101,97,100,108,111,99,107,32,119,111,117,108,100,32,111,99,99,117,114,0,83,116,97,116,101,32,110,111,116,32,114,101,99,111,118,101,114,97,98,108,101,0,80,114,101,118,105,111,117,115,32,111,119,110,101,114,32,100,105,101,100,0,79,112,101,114,97,116,105,111,110,32,99,97,110,99,101,108,101,100,0,70,117,110,99,116,105,111,110,32,110,111,116,32,105,109,112,108,101,109,101,110,116,101,100,0,78,111,32,109,101,115,115,97,103,101,32,111,102,32,100,101,115,105,114,101,100,32,116,121,112,101,0,73,100,101,110,116,105,102,105,101,114,32,114,101,109,111,118,101,100,0,68,101,118,105,99,101,32,110,111,116,32,97,32,115,116,114,101,97,109,0,78,111,32,100,97,116,97,32,97,118,97,105,108,97,98,108,101,0,68,101,118,105,99,101,32,116,105,109,101,111,117,116,0,79,117,116,32,111,102,32,115,116,114,101,97,109,115,32,114,101,115,111,117,114,99,101,115,0,76,105,110,107,32,104,97,115,32,98,101,101,110,32,115,101,118,101,114,101,100,0,80,114,111,116,111,99,111,108,32,101,114,114,111,114,0,66,97,100,32,109,101,115,115,97,103,101,0,70,105,108,101,32,100,101,115,99,114,105,112,116,111,114,32,105,110,32,98,97,100,32,115,116,97,116,101,0,78,111,116,32,97,32,115,111,99,107,101,116,0,68,101,115,116,105,110,97,116,105,111,110,32,97,100,100,114,101,115,115,32,114,101,113,117,105,114,101,100,0,77,101,115,115,97,103,101,32,116,111,111,32,108,97,114,103,101,0,80,114,111,116,111,99,111,108,32,119,114,111,110,103,32,116,121,112,101,32,102,111,114,32,115,111,99,107,101,116,0,80,114,111,116,111,99,111,108,32,110,111,116,32,97,118,97,105,108,97,98,108,101,0,80,114,111,116,111,99,111,108,32,110,111,116,32,115,117,112,112,111,114,116,101,100,0,83,111,99,107,101,116,32,116,121,112,101,32,110,111,116,32,115,117,112,112,111,114,116,101,100,0,78,111,116,32,115,117,112,112,111,114,116,101,100,0,80,114,111,116,111,99,111,108,32,102,97,109,105,108,121,32,110,111,116,32,115,117,112,112,111,114,116,101,100,0,65,100,100,114,101,115,115,32,102,97,109,105,108,121,32,110,111,116,32,115,117,112,112,111,114,116,101,100,32,98,121,32,112,114,111,116,111,99,111,108,0,65,100,100,114,101,115,115,32,110,111,116,32,97,118,97,105,108,97,98,108,101,0,78,101,116,119,111,114,107,32,105,115,32,100,111,119,110,0,78,101,116,119,111,114,107,32,117,110,114,101,97,99,104,97,98,108,101,0,67,111,110,110,101,99,116,105,111,110,32,114,101,115,101,116,32,98,121,32,110,101,116,119,111,114,107,0,67,111,110,110,101,99,116,105,111,110,32,97,98,111,114,116,101,100,0,78,111,32,98,117,102,102,101,114,32,115,112,97,99,101,32,97,118,97,105,108,97,98,108,101,0,83,111,99,107,101,116,32,105,115,32,99,111,110,110,101,99,116,101,100,0,83,111,99,107,101,116,32,110,111,116,32,99,111,110,110,101,99,116,101,100,0,67,97,110,110,111,116,32,115,101,110,100,32,97,102,116,101,114,32,115,111,99,107,101,116,32,115,104,117,116,100,111,119,110,0,79,112,101,114,97,116,105,111,110,32,97,108,114,101,97,100,121,32,105,110,32,112,114,111,103,114,101,115,115,0,79,112,101,114,97,116,105,111,110,32,105,110,32,112,114,111,103,114,101,115,115,0,83,116,97,108,101,32,102,105,108,101,32,104,97,110,100,108,101,0,82,101,109,111,116,101,32,73,47,79,32,101,114,114,111,114,0,81,117,111,116,97,32,101,120,99,101,101,100,101,100,0,78,111,32,109,101,100,105,117,109,32,102,111,117,110,100,0,87,114,111,110,103,32,109,101,100,105,117,109,32,116,121,112,101,0,78,111,32,101,114,114,111,114,32,105,110,102,111,114,109,97,116,105,111,110,0,0,116,101,114,109,105,110,97,116,105,110,103,32,119,105,116,104,32,37,115,32,101,120,99,101,112,116,105,111,110,32,111,102,32,116,121,112,101,32,37,115,58,32,37,115,0,116,101,114,109,105,110,97,116,105,110,103,32,119,105,116,104,32,37,115,32,101,120,99,101,112,116,105,111,110,32,111,102,32,116,121,112,101,32,37,115,0,116,101,114,109,105,110,97,116,105,110,103,32,119,105,116,104,32,37,115,32,102,111,114,101,105,103,110,32,101,120,99,101,112,116,105,111,110,0,116,101,114,109,105,110,97,116,105,110,103,0,117,110,99,97,117,103,104,116,0,83,116,57,101,120,99,101,112,116,105,111,110,0,78,49,48,95,95,99,120,120,97,98,105,118,49,49,54,95,95,115,104,105,109,95,116,121,112,101,95,105,110,102,111,69,0,83,116,57,116,121,112,101,95,105,110,102,111,0,78,49,48,95,95,99,120,120,97,98,105,118,49,50,48,95,95,115,105,95,99,108,97,115,115,95,116,121,112,101,95,105,110,102,111,69,0,78,49,48,95,95,99,120,120,97,98,105,118,49,49,55,95,95,99,108,97,115,115,95,116,121,112,101,95,105,110,102,111,69,0,112,116,104,114,101,97,100,95,111,110,99,101,32,102,97,105,108,117,114,101,32,105,110,32,95,95,99,120,97,95,103,101,116,95,103,108,111,98,97,108,115,95,102,97,115,116,40,41,0,99,97,110,110,111,116,32,99,114,101,97,116,101,32,112,116,104,114,101,97,100,32,107,101,121,32,102,111,114,32,95,95,99,120,97,95,103,101,116,95,103,108,111,98,97,108,115,40,41,0,99,97,110,110,111,116,32,122,101,114,111,32,111,117,116,32,116,104,114,101,97,100,32,118,97,108,117,101,32,102,111,114,32,95,95,99,120,97,95,103,101,116,95,103,108,111,98,97,108,115,40,41,0,116,101,114,109,105,110,97,116,101,95,104,97,110,100,108,101,114,32,117,110,101,120,112,101,99,116,101,100,108,121,32,114,101,116,117,114,110,101,100,0,78,49,48,95,95,99,120,120,97,98,105,118,49,49,57,95,95,112,111,105,110,116,101,114,95,116,121,112,101,95,105,110,102,111,69,0,78,49,48,95,95,99,120,120,97,98,105,118,49,49,55,95,95,112,98,97,115,101,95,116,121,112,101,95,105,110,102,111,69,0],"i8",ALLOC_NONE,Runtime.GLOBAL_BASE);var tempDoublePtr=STATICTOP;STATICTOP+=16;function _abort(){Module["abort"]()}function __ZSt18uncaught_exceptionv(){return!!__ZSt18uncaught_exceptionv.uncaught_exception}var EXCEPTIONS={last:0,caught:[],infos:{},deAdjust:(function(adjusted){if(!adjusted||EXCEPTIONS.infos[adjusted])return adjusted;for(var ptr in EXCEPTIONS.infos){var info=EXCEPTIONS.infos[ptr];if(info.adjusted===adjusted){return ptr}}return adjusted}),addRef:(function(ptr){if(!ptr)return;var info=EXCEPTIONS.infos[ptr];info.refcount++}),decRef:(function(ptr){if(!ptr)return;var info=EXCEPTIONS.infos[ptr];assert(info.refcount>0);info.refcount--;if(info.refcount===0&&!info.rethrown){if(info.destructor){Module["dynCall_vi"](info.destructor,ptr)}delete EXCEPTIONS.infos[ptr];___cxa_free_exception(ptr)}}),clearRef:(function(ptr){if(!ptr)return;var info=EXCEPTIONS.infos[ptr];info.refcount=0})};function ___cxa_begin_catch(ptr){var info=EXCEPTIONS.infos[ptr];if(info&&!info.caught){info.caught=true;__ZSt18uncaught_exceptionv.uncaught_exception--}if(info)info.rethrown=false;EXCEPTIONS.caught.push(ptr);EXCEPTIONS.addRef(EXCEPTIONS.deAdjust(ptr));return ptr}function _pthread_once(ptr,func){if(!_pthread_once.seen)_pthread_once.seen={};if(ptr in _pthread_once.seen)return;Module["dynCall_v"](func);_pthread_once.seen[ptr]=1}function _emscripten_memcpy_big(dest,src,num){HEAPU8.set(HEAPU8.subarray(src,src+num),dest);return dest}var SYSCALLS={varargs:0,get:(function(varargs){SYSCALLS.varargs+=4;var ret=HEAP32[SYSCALLS.varargs-4>>2];return ret}),getStr:(function(){var ret=Pointer_stringify(SYSCALLS.get());return ret}),get64:(function(){var low=SYSCALLS.get(),high=SYSCALLS.get();if(low>=0)assert(high===0);else assert(high===-1);return low}),getZero:(function(){assert(SYSCALLS.get()===0)})};function ___syscall6(which,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD();FS.close(stream);return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}var cttz_i8=allocate([8,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,7,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0],"i8",ALLOC_STATIC);var PTHREAD_SPECIFIC={};function _pthread_getspecific(key){return PTHREAD_SPECIFIC[key]||0}function ___setErrNo(value){if(Module["___errno_location"])HEAP32[Module["___errno_location"]()>>2]=value;return value}var PTHREAD_SPECIFIC_NEXT_KEY=1;var ERRNO_CODES={EPERM:1,ENOENT:2,ESRCH:3,EINTR:4,EIO:5,ENXIO:6,E2BIG:7,ENOEXEC:8,EBADF:9,ECHILD:10,EAGAIN:11,EWOULDBLOCK:11,ENOMEM:12,EACCES:13,EFAULT:14,ENOTBLK:15,EBUSY:16,EEXIST:17,EXDEV:18,ENODEV:19,ENOTDIR:20,EISDIR:21,EINVAL:22,ENFILE:23,EMFILE:24,ENOTTY:25,ETXTBSY:26,EFBIG:27,ENOSPC:28,ESPIPE:29,EROFS:30,EMLINK:31,EPIPE:32,EDOM:33,ERANGE:34,ENOMSG:42,EIDRM:43,ECHRNG:44,EL2NSYNC:45,EL3HLT:46,EL3RST:47,ELNRNG:48,EUNATCH:49,ENOCSI:50,EL2HLT:51,EDEADLK:35,ENOLCK:37,EBADE:52,EBADR:53,EXFULL:54,ENOANO:55,EBADRQC:56,EBADSLT:57,EDEADLOCK:35,EBFONT:59,ENOSTR:60,ENODATA:61,ETIME:62,ENOSR:63,ENONET:64,ENOPKG:65,EREMOTE:66,ENOLINK:67,EADV:68,ESRMNT:69,ECOMM:70,EPROTO:71,EMULTIHOP:72,EDOTDOT:73,EBADMSG:74,ENOTUNIQ:76,EBADFD:77,EREMCHG:78,ELIBACC:79,ELIBBAD:80,ELIBSCN:81,ELIBMAX:82,ELIBEXEC:83,ENOSYS:38,ENOTEMPTY:39,ENAMETOOLONG:36,ELOOP:40,EOPNOTSUPP:95,EPFNOSUPPORT:96,ECONNRESET:104,ENOBUFS:105,EAFNOSUPPORT:97,EPROTOTYPE:91,ENOTSOCK:88,ENOPROTOOPT:92,ESHUTDOWN:108,ECONNREFUSED:111,EADDRINUSE:98,ECONNABORTED:103,ENETUNREACH:101,ENETDOWN:100,ETIMEDOUT:110,EHOSTDOWN:112,EHOSTUNREACH:113,EINPROGRESS:115,EALREADY:114,EDESTADDRREQ:89,EMSGSIZE:90,EPROTONOSUPPORT:93,ESOCKTNOSUPPORT:94,EADDRNOTAVAIL:99,ENETRESET:102,EISCONN:106,ENOTCONN:107,ETOOMANYREFS:109,EUSERS:87,EDQUOT:122,ESTALE:116,ENOTSUP:95,ENOMEDIUM:123,EILSEQ:84,EOVERFLOW:75,ECANCELED:125,ENOTRECOVERABLE:131,EOWNERDEAD:130,ESTRPIPE:86};function _pthread_key_create(key,destructor){if(key==0){return ERRNO_CODES.EINVAL}HEAP32[key>>2]=PTHREAD_SPECIFIC_NEXT_KEY;PTHREAD_SPECIFIC[PTHREAD_SPECIFIC_NEXT_KEY]=0;PTHREAD_SPECIFIC_NEXT_KEY++;return 0}function ___resumeException(ptr){if(!EXCEPTIONS.last){EXCEPTIONS.last=ptr}throw ptr+" - Exception catching is disabled, this exception cannot be caught. Compile with -s DISABLE_EXCEPTION_CATCHING=0 or DISABLE_EXCEPTION_CATCHING=2 to catch."}function ___cxa_find_matching_catch(){var thrown=EXCEPTIONS.last;if(!thrown){return(Runtime.setTempRet0(0),0)|0}var info=EXCEPTIONS.infos[thrown];var throwntype=info.type;if(!throwntype){return(Runtime.setTempRet0(0),thrown)|0}var typeArray=Array.prototype.slice.call(arguments);var pointer=Module["___cxa_is_pointer_type"](throwntype);if(!___cxa_find_matching_catch.buffer)___cxa_find_matching_catch.buffer=_malloc(4);HEAP32[___cxa_find_matching_catch.buffer>>2]=thrown;thrown=___cxa_find_matching_catch.buffer;for(var i=0;i>2];info.adjusted=thrown;return(Runtime.setTempRet0(typeArray[i]),thrown)|0}}thrown=HEAP32[thrown>>2];return(Runtime.setTempRet0(throwntype),thrown)|0}function ___gxx_personality_v0(){}function _pthread_setspecific(key,value){if(!(key in PTHREAD_SPECIFIC)){return ERRNO_CODES.EINVAL}PTHREAD_SPECIFIC[key]=value;return 0}function ___syscall140(which,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(),offset_high=SYSCALLS.get(),offset_low=SYSCALLS.get(),result=SYSCALLS.get(),whence=SYSCALLS.get();var offset=offset_low;FS.llseek(stream,offset,whence);HEAP32[result>>2]=stream.position;if(stream.getdents&&offset===0&&whence===0)stream.getdents=null;return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function ___syscall146(which,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.get(),iov=SYSCALLS.get(),iovcnt=SYSCALLS.get();var ret=0;if(!___syscall146.buffer){___syscall146.buffers=[null,[],[]];___syscall146.printChar=(function(stream,curr){var buffer=___syscall146.buffers[stream];assert(buffer);if(curr===0||curr===10){(stream===1?Module["print"]:Module["printErr"])(UTF8ArrayToString(buffer,0));buffer.length=0}else{buffer.push(curr)}})}for(var i=0;i>2];var len=HEAP32[iov+(i*8+4)>>2];for(var j=0;j>2]=DYNAMIC_BASE;staticSealed=true;function invoke_iiii(index,a1,a2,a3){try{return Module["dynCall_iiii"](index,a1,a2,a3)}catch(e){if(typeof e!=="number"&&e!=="longjmp")throw e;Module["setThrew"](1,0)}}function invoke_viiiii(index,a1,a2,a3,a4,a5){try{Module["dynCall_viiiii"](index,a1,a2,a3,a4,a5)}catch(e){if(typeof e!=="number"&&e!=="longjmp")throw e;Module["setThrew"](1,0)}}function invoke_vi(index,a1){try{Module["dynCall_vi"](index,a1)}catch(e){if(typeof e!=="number"&&e!=="longjmp")throw e;Module["setThrew"](1,0)}}function invoke_ii(index,a1){try{return Module["dynCall_ii"](index,a1)}catch(e){if(typeof e!=="number"&&e!=="longjmp")throw e;Module["setThrew"](1,0)}}function invoke_viii(index,a1,a2,a3){try{Module["dynCall_viii"](index,a1,a2,a3)}catch(e){if(typeof e!=="number"&&e!=="longjmp")throw e;Module["setThrew"](1,0)}}function invoke_v(index){try{Module["dynCall_v"](index)}catch(e){if(typeof e!=="number"&&e!=="longjmp")throw e;Module["setThrew"](1,0)}}function invoke_viiiiii(index,a1,a2,a3,a4,a5,a6){try{Module["dynCall_viiiiii"](index,a1,a2,a3,a4,a5,a6)}catch(e){if(typeof e!=="number"&&e!=="longjmp")throw e;Module["setThrew"](1,0)}}function invoke_viiii(index,a1,a2,a3,a4){try{Module["dynCall_viiii"](index,a1,a2,a3,a4)}catch(e){if(typeof e!=="number"&&e!=="longjmp")throw e;Module["setThrew"](1,0)}}Module.asmGlobalArg={"Math":Math,"Int8Array":Int8Array,"Int16Array":Int16Array,"Int32Array":Int32Array,"Uint8Array":Uint8Array,"Uint16Array":Uint16Array,"Uint32Array":Uint32Array,"Float32Array":Float32Array,"Float64Array":Float64Array,"NaN":NaN,"Infinity":Infinity,"byteLength":byteLength};Module.asmLibraryArg={"abort":abort,"assert":assert,"enlargeMemory":enlargeMemory,"getTotalMemory":getTotalMemory,"abortOnCannotGrowMemory":abortOnCannotGrowMemory,"invoke_iiii":invoke_iiii,"invoke_viiiii":invoke_viiiii,"invoke_vi":invoke_vi,"invoke_ii":invoke_ii,"invoke_viii":invoke_viii,"invoke_v":invoke_v,"invoke_viiiiii":invoke_viiiiii,"invoke_viiii":invoke_viiii,"_pthread_getspecific":_pthread_getspecific,"___syscall54":___syscall54,"_pthread_setspecific":_pthread_setspecific,"___gxx_personality_v0":___gxx_personality_v0,"___syscall6":___syscall6,"___setErrNo":___setErrNo,"_abort":_abort,"___cxa_begin_catch":___cxa_begin_catch,"_pthread_once":_pthread_once,"_emscripten_memcpy_big":_emscripten_memcpy_big,"_pthread_key_create":_pthread_key_create,"___syscall140":___syscall140,"___resumeException":___resumeException,"___cxa_find_matching_catch":___cxa_find_matching_catch,"___syscall146":___syscall146,"__ZSt18uncaught_exceptionv":__ZSt18uncaught_exceptionv,"DYNAMICTOP_PTR":DYNAMICTOP_PTR,"tempDoublePtr":tempDoublePtr,"ABORT":ABORT,"STACKTOP":STACKTOP,"STACK_MAX":STACK_MAX,"cttz_i8":cttz_i8};// EMSCRIPTEN_START_ASM -var asm=(function(global,env,buffer) { -"almost asm";var a=global.Int8Array;var b=new a(buffer);var c=global.Int16Array;var d=new c(buffer);var e=global.Int32Array;var f=new e(buffer);var g=global.Uint8Array;var h=new g(buffer);var i=global.Uint16Array;var j=new i(buffer);var k=global.Uint32Array;var l=new k(buffer);var m=global.Float32Array;var n=new m(buffer);var o=global.Float64Array;var p=new o(buffer);var q=global.byteLength;var r=env.DYNAMICTOP_PTR|0;var s=env.tempDoublePtr|0;var t=env.ABORT|0;var u=env.STACKTOP|0;var v=env.STACK_MAX|0;var w=env.cttz_i8|0;var x=0;var y=0;var z=0;var A=0;var B=global.NaN,C=global.Infinity;var D=0,E=0,F=0,G=0,H=0.0;var I=0;var J=global.Math.floor;var K=global.Math.abs;var L=global.Math.sqrt;var M=global.Math.pow;var N=global.Math.cos;var O=global.Math.sin;var P=global.Math.tan;var Q=global.Math.acos;var R=global.Math.asin;var S=global.Math.atan;var T=global.Math.atan2;var U=global.Math.exp;var V=global.Math.log;var W=global.Math.ceil;var X=global.Math.imul;var Y=global.Math.min;var Z=global.Math.max;var _=global.Math.clz32;var $=env.abort;var aa=env.assert;var ba=env.enlargeMemory;var ca=env.getTotalMemory;var da=env.abortOnCannotGrowMemory;var ea=env.invoke_iiii;var fa=env.invoke_viiiii;var ga=env.invoke_vi;var ha=env.invoke_ii;var ia=env.invoke_viii;var ja=env.invoke_v;var ka=env.invoke_viiiiii;var la=env.invoke_viiii;var ma=env._pthread_getspecific;var na=env.___syscall54;var oa=env._pthread_setspecific;var pa=env.___gxx_personality_v0;var qa=env.___syscall6;var ra=env.___setErrNo;var sa=env._abort;var ta=env.___cxa_begin_catch;var ua=env._pthread_once;var va=env._emscripten_memcpy_big;var wa=env._pthread_key_create;var xa=env.___syscall140;var ya=env.___resumeException;var za=env.___cxa_find_matching_catch;var Aa=env.___syscall146;var Ba=env.__ZSt18uncaught_exceptionv;var Ca=0.0;function Da(newBuffer){if(q(newBuffer)&16777215||q(newBuffer)<=16777215||q(newBuffer)>2147483648)return false;b=new a(newBuffer);d=new c(newBuffer);f=new e(newBuffer);h=new g(newBuffer);j=new i(newBuffer);l=new k(newBuffer);n=new m(newBuffer);p=new o(newBuffer);buffer=newBuffer;return true} -// EMSCRIPTEN_START_FUNCS -function Ma(a){a=a|0;var b=0,c=0,d=0,e=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,v=0,w=0,x=0;x=u;u=u+16|0;n=x;do if(a>>>0<245){k=a>>>0<11?16:a+11&-8;a=k>>>3;m=f[1144]|0;c=m>>>a;if(c&3|0){b=(c&1^1)+a|0;a=4616+(b<<1<<2)|0;c=a+8|0;d=f[c>>2]|0;e=d+8|0;g=f[e>>2]|0;if((a|0)==(g|0))f[1144]=m&~(1<>2]=a;f[c>>2]=g}w=b<<3;f[d+4>>2]=w|3;w=d+w+4|0;f[w>>2]=f[w>>2]|1;w=e;u=x;return w|0}l=f[1146]|0;if(k>>>0>l>>>0){if(c|0){b=2<>>12&16;b=b>>>h;c=b>>>5&8;b=b>>>c;e=b>>>2&4;b=b>>>e;a=b>>>1&2;b=b>>>a;d=b>>>1&1;d=(c|h|e|a|d)+(b>>>d)|0;b=4616+(d<<1<<2)|0;a=b+8|0;e=f[a>>2]|0;h=e+8|0;c=f[h>>2]|0;if((b|0)==(c|0)){a=m&~(1<>2]=b;f[a>>2]=c;a=m}g=(d<<3)-k|0;f[e+4>>2]=k|3;d=e+k|0;f[d+4>>2]=g|1;f[d+g>>2]=g;if(l|0){e=f[1149]|0;b=l>>>3;c=4616+(b<<1<<2)|0;b=1<>2]|0}f[a>>2]=e;f[b+12>>2]=e;f[e+8>>2]=b;f[e+12>>2]=c}f[1146]=g;f[1149]=d;w=h;u=x;return w|0}i=f[1145]|0;if(i){c=(i&0-i)+-1|0;h=c>>>12&16;c=c>>>h;g=c>>>5&8;c=c>>>g;j=c>>>2&4;c=c>>>j;d=c>>>1&2;c=c>>>d;a=c>>>1&1;a=f[4880+((g|h|j|d|a)+(c>>>a)<<2)>>2]|0;c=(f[a+4>>2]&-8)-k|0;d=f[a+16+(((f[a+16>>2]|0)==0&1)<<2)>>2]|0;if(!d){j=a;g=c}else{do{h=(f[d+4>>2]&-8)-k|0;j=h>>>0>>0;c=j?h:c;a=j?d:a;d=f[d+16+(((f[d+16>>2]|0)==0&1)<<2)>>2]|0}while((d|0)!=0);j=a;g=c}h=j+k|0;if(j>>>0>>0){e=f[j+24>>2]|0;b=f[j+12>>2]|0;do if((b|0)==(j|0)){a=j+20|0;b=f[a>>2]|0;if(!b){a=j+16|0;b=f[a>>2]|0;if(!b){c=0;break}}while(1){c=b+20|0;d=f[c>>2]|0;if(d|0){b=d;a=c;continue}c=b+16|0;d=f[c>>2]|0;if(!d)break;else{b=d;a=c}}f[a>>2]=0;c=b}else{c=f[j+8>>2]|0;f[c+12>>2]=b;f[b+8>>2]=c;c=b}while(0);do if(e|0){b=f[j+28>>2]|0;a=4880+(b<<2)|0;if((j|0)==(f[a>>2]|0)){f[a>>2]=c;if(!c){f[1145]=i&~(1<>2]|0)!=(j|0)&1)<<2)>>2]=c;if(!c)break}f[c+24>>2]=e;b=f[j+16>>2]|0;if(b|0){f[c+16>>2]=b;f[b+24>>2]=c}b=f[j+20>>2]|0;if(b|0){f[c+20>>2]=b;f[b+24>>2]=c}}while(0);if(g>>>0<16){w=g+k|0;f[j+4>>2]=w|3;w=j+w+4|0;f[w>>2]=f[w>>2]|1}else{f[j+4>>2]=k|3;f[h+4>>2]=g|1;f[h+g>>2]=g;if(l|0){d=f[1149]|0;b=l>>>3;c=4616+(b<<1<<2)|0;b=1<>2]|0}f[a>>2]=d;f[b+12>>2]=d;f[d+8>>2]=b;f[d+12>>2]=c}f[1146]=g;f[1149]=h}w=j+8|0;u=x;return w|0}else m=k}else m=k}else m=k}else if(a>>>0<=4294967231){a=a+11|0;k=a&-8;j=f[1145]|0;if(j){d=0-k|0;a=a>>>8;if(a)if(k>>>0>16777215)i=31;else{m=(a+1048320|0)>>>16&8;v=a<>>16&4;v=v<>>16&2;i=14-(l|m|i)+(v<>>15)|0;i=k>>>(i+7|0)&1|i<<1}else i=0;c=f[4880+(i<<2)>>2]|0;a:do if(!c){c=0;a=0;v=57}else{a=0;h=k<<((i|0)==31?0:25-(i>>>1)|0);g=0;while(1){e=(f[c+4>>2]&-8)-k|0;if(e>>>0>>0)if(!e){a=c;d=0;e=c;v=61;break a}else{a=c;d=e}e=f[c+20>>2]|0;c=f[c+16+(h>>>31<<2)>>2]|0;g=(e|0)==0|(e|0)==(c|0)?g:e;e=(c|0)==0;if(e){c=g;v=57;break}else h=h<<((e^1)&1)}}while(0);if((v|0)==57){if((c|0)==0&(a|0)==0){a=2<>>12&16;m=m>>>h;g=m>>>5&8;m=m>>>g;i=m>>>2&4;m=m>>>i;l=m>>>1&2;m=m>>>l;c=m>>>1&1;a=0;c=f[4880+((g|h|i|l|c)+(m>>>c)<<2)>>2]|0}if(!c){i=a;h=d}else{e=c;v=61}}if((v|0)==61)while(1){v=0;c=(f[e+4>>2]&-8)-k|0;m=c>>>0>>0;c=m?c:d;a=m?e:a;e=f[e+16+(((f[e+16>>2]|0)==0&1)<<2)>>2]|0;if(!e){i=a;h=c;break}else{d=c;v=61}}if((i|0)!=0?h>>>0<((f[1146]|0)-k|0)>>>0:0){g=i+k|0;if(i>>>0>=g>>>0){w=0;u=x;return w|0}e=f[i+24>>2]|0;b=f[i+12>>2]|0;do if((b|0)==(i|0)){a=i+20|0;b=f[a>>2]|0;if(!b){a=i+16|0;b=f[a>>2]|0;if(!b){b=0;break}}while(1){c=b+20|0;d=f[c>>2]|0;if(d|0){b=d;a=c;continue}c=b+16|0;d=f[c>>2]|0;if(!d)break;else{b=d;a=c}}f[a>>2]=0}else{w=f[i+8>>2]|0;f[w+12>>2]=b;f[b+8>>2]=w}while(0);do if(e){a=f[i+28>>2]|0;c=4880+(a<<2)|0;if((i|0)==(f[c>>2]|0)){f[c>>2]=b;if(!b){d=j&~(1<>2]|0)!=(i|0)&1)<<2)>>2]=b;if(!b){d=j;break}}f[b+24>>2]=e;a=f[i+16>>2]|0;if(a|0){f[b+16>>2]=a;f[a+24>>2]=b}a=f[i+20>>2]|0;if(a){f[b+20>>2]=a;f[a+24>>2]=b;d=j}else d=j}else d=j;while(0);do if(h>>>0>=16){f[i+4>>2]=k|3;f[g+4>>2]=h|1;f[g+h>>2]=h;b=h>>>3;if(h>>>0<256){c=4616+(b<<1<<2)|0;a=f[1144]|0;b=1<>2]|0}f[a>>2]=g;f[b+12>>2]=g;f[g+8>>2]=b;f[g+12>>2]=c;break}b=h>>>8;if(b)if(h>>>0>16777215)b=31;else{v=(b+1048320|0)>>>16&8;w=b<>>16&4;w=w<>>16&2;b=14-(t|v|b)+(w<>>15)|0;b=h>>>(b+7|0)&1|b<<1}else b=0;c=4880+(b<<2)|0;f[g+28>>2]=b;a=g+16|0;f[a+4>>2]=0;f[a>>2]=0;a=1<>2]=g;f[g+24>>2]=c;f[g+12>>2]=g;f[g+8>>2]=g;break}a=h<<((b|0)==31?0:25-(b>>>1)|0);c=f[c>>2]|0;while(1){if((f[c+4>>2]&-8|0)==(h|0)){v=97;break}d=c+16+(a>>>31<<2)|0;b=f[d>>2]|0;if(!b){v=96;break}else{a=a<<1;c=b}}if((v|0)==96){f[d>>2]=g;f[g+24>>2]=c;f[g+12>>2]=g;f[g+8>>2]=g;break}else if((v|0)==97){v=c+8|0;w=f[v>>2]|0;f[w+12>>2]=g;f[v>>2]=g;f[g+8>>2]=w;f[g+12>>2]=c;f[g+24>>2]=0;break}}else{w=h+k|0;f[i+4>>2]=w|3;w=i+w+4|0;f[w>>2]=f[w>>2]|1}while(0);w=i+8|0;u=x;return w|0}else m=k}else m=k}else m=-1;while(0);c=f[1146]|0;if(c>>>0>=m>>>0){b=c-m|0;a=f[1149]|0;if(b>>>0>15){w=a+m|0;f[1149]=w;f[1146]=b;f[w+4>>2]=b|1;f[w+b>>2]=b;f[a+4>>2]=m|3}else{f[1146]=0;f[1149]=0;f[a+4>>2]=c|3;w=a+c+4|0;f[w>>2]=f[w>>2]|1}w=a+8|0;u=x;return w|0}h=f[1147]|0;if(h>>>0>m>>>0){t=h-m|0;f[1147]=t;w=f[1150]|0;v=w+m|0;f[1150]=v;f[v+4>>2]=t|1;f[w+4>>2]=m|3;w=w+8|0;u=x;return w|0}if(!(f[1262]|0)){f[1264]=4096;f[1263]=4096;f[1265]=-1;f[1266]=-1;f[1267]=0;f[1255]=0;a=n&-16^1431655768;f[n>>2]=a;f[1262]=a;a=4096}else a=f[1264]|0;i=m+48|0;j=m+47|0;g=a+j|0;e=0-a|0;k=g&e;if(k>>>0<=m>>>0){w=0;u=x;return w|0}a=f[1254]|0;if(a|0?(l=f[1252]|0,n=l+k|0,n>>>0<=l>>>0|n>>>0>a>>>0):0){w=0;u=x;return w|0}b:do if(!(f[1255]&4)){c=f[1150]|0;c:do if(c){d=5024;while(1){a=f[d>>2]|0;if(a>>>0<=c>>>0?(q=d+4|0,(a+(f[q>>2]|0)|0)>>>0>c>>>0):0)break;a=f[d+8>>2]|0;if(!a){v=118;break c}else d=a}b=g-h&e;if(b>>>0<2147483647){a=ac(b|0)|0;if((a|0)==((f[d>>2]|0)+(f[q>>2]|0)|0)){if((a|0)!=(-1|0)){h=b;g=a;v=135;break b}}else{d=a;v=126}}else b=0}else v=118;while(0);do if((v|0)==118){c=ac(0)|0;if((c|0)!=(-1|0)?(b=c,o=f[1263]|0,p=o+-1|0,b=((p&b|0)==0?0:(p+b&0-o)-b|0)+k|0,o=f[1252]|0,p=b+o|0,b>>>0>m>>>0&b>>>0<2147483647):0){q=f[1254]|0;if(q|0?p>>>0<=o>>>0|p>>>0>q>>>0:0){b=0;break}a=ac(b|0)|0;if((a|0)==(c|0)){h=b;g=c;v=135;break b}else{d=a;v=126}}else b=0}while(0);do if((v|0)==126){c=0-b|0;if(!(i>>>0>b>>>0&(b>>>0<2147483647&(d|0)!=(-1|0))))if((d|0)==(-1|0)){b=0;break}else{h=b;g=d;v=135;break b}a=f[1264]|0;a=j-b+a&0-a;if(a>>>0>=2147483647){h=b;g=d;v=135;break b}if((ac(a|0)|0)==(-1|0)){ac(c|0)|0;b=0;break}else{h=a+b|0;g=d;v=135;break b}}while(0);f[1255]=f[1255]|4;v=133}else{b=0;v=133}while(0);if(((v|0)==133?k>>>0<2147483647:0)?(t=ac(k|0)|0,q=ac(0)|0,r=q-t|0,s=r>>>0>(m+40|0)>>>0,!((t|0)==(-1|0)|s^1|t>>>0>>0&((t|0)!=(-1|0)&(q|0)!=(-1|0))^1)):0){h=s?r:b;g=t;v=135}if((v|0)==135){b=(f[1252]|0)+h|0;f[1252]=b;if(b>>>0>(f[1253]|0)>>>0)f[1253]=b;j=f[1150]|0;do if(j){b=5024;while(1){a=f[b>>2]|0;c=b+4|0;d=f[c>>2]|0;if((g|0)==(a+d|0)){v=145;break}e=f[b+8>>2]|0;if(!e)break;else b=e}if(((v|0)==145?(f[b+12>>2]&8|0)==0:0)?j>>>0>>0&j>>>0>=a>>>0:0){f[c>>2]=d+h;w=j+8|0;w=(w&7|0)==0?0:0-w&7;v=j+w|0;w=(f[1147]|0)+(h-w)|0;f[1150]=v;f[1147]=w;f[v+4>>2]=w|1;f[v+w+4>>2]=40;f[1151]=f[1266];break}if(g>>>0<(f[1148]|0)>>>0)f[1148]=g;c=g+h|0;b=5024;while(1){if((f[b>>2]|0)==(c|0)){v=153;break}a=f[b+8>>2]|0;if(!a)break;else b=a}if((v|0)==153?(f[b+12>>2]&8|0)==0:0){f[b>>2]=g;l=b+4|0;f[l>>2]=(f[l>>2]|0)+h;l=g+8|0;l=g+((l&7|0)==0?0:0-l&7)|0;b=c+8|0;b=c+((b&7|0)==0?0:0-b&7)|0;k=l+m|0;i=b-l-m|0;f[l+4>>2]=m|3;do if((b|0)!=(j|0)){if((b|0)==(f[1149]|0)){w=(f[1146]|0)+i|0;f[1146]=w;f[1149]=k;f[k+4>>2]=w|1;f[k+w>>2]=w;break}a=f[b+4>>2]|0;if((a&3|0)==1){h=a&-8;d=a>>>3;d:do if(a>>>0<256){a=f[b+8>>2]|0;c=f[b+12>>2]|0;if((c|0)==(a|0)){f[1144]=f[1144]&~(1<>2]=c;f[c+8>>2]=a;break}}else{g=f[b+24>>2]|0;a=f[b+12>>2]|0;do if((a|0)==(b|0)){d=b+16|0;c=d+4|0;a=f[c>>2]|0;if(!a){a=f[d>>2]|0;if(!a){a=0;break}else c=d}while(1){d=a+20|0;e=f[d>>2]|0;if(e|0){a=e;c=d;continue}d=a+16|0;e=f[d>>2]|0;if(!e)break;else{a=e;c=d}}f[c>>2]=0}else{w=f[b+8>>2]|0;f[w+12>>2]=a;f[a+8>>2]=w}while(0);if(!g)break;c=f[b+28>>2]|0;d=4880+(c<<2)|0;do if((b|0)!=(f[d>>2]|0)){f[g+16+(((f[g+16>>2]|0)!=(b|0)&1)<<2)>>2]=a;if(!a)break d}else{f[d>>2]=a;if(a|0)break;f[1145]=f[1145]&~(1<>2]=g;c=b+16|0;d=f[c>>2]|0;if(d|0){f[a+16>>2]=d;f[d+24>>2]=a}c=f[c+4>>2]|0;if(!c)break;f[a+20>>2]=c;f[c+24>>2]=a}while(0);b=b+h|0;e=h+i|0}else e=i;b=b+4|0;f[b>>2]=f[b>>2]&-2;f[k+4>>2]=e|1;f[k+e>>2]=e;b=e>>>3;if(e>>>0<256){c=4616+(b<<1<<2)|0;a=f[1144]|0;b=1<>2]|0}f[a>>2]=k;f[b+12>>2]=k;f[k+8>>2]=b;f[k+12>>2]=c;break}b=e>>>8;do if(!b)b=0;else{if(e>>>0>16777215){b=31;break}v=(b+1048320|0)>>>16&8;w=b<>>16&4;w=w<>>16&2;b=14-(t|v|b)+(w<>>15)|0;b=e>>>(b+7|0)&1|b<<1}while(0);d=4880+(b<<2)|0;f[k+28>>2]=b;a=k+16|0;f[a+4>>2]=0;f[a>>2]=0;a=f[1145]|0;c=1<>2]=k;f[k+24>>2]=d;f[k+12>>2]=k;f[k+8>>2]=k;break}a=e<<((b|0)==31?0:25-(b>>>1)|0);c=f[d>>2]|0;while(1){if((f[c+4>>2]&-8|0)==(e|0)){v=194;break}d=c+16+(a>>>31<<2)|0;b=f[d>>2]|0;if(!b){v=193;break}else{a=a<<1;c=b}}if((v|0)==193){f[d>>2]=k;f[k+24>>2]=c;f[k+12>>2]=k;f[k+8>>2]=k;break}else if((v|0)==194){v=c+8|0;w=f[v>>2]|0;f[w+12>>2]=k;f[v>>2]=k;f[k+8>>2]=w;f[k+12>>2]=c;f[k+24>>2]=0;break}}else{w=(f[1147]|0)+i|0;f[1147]=w;f[1150]=k;f[k+4>>2]=w|1}while(0);w=l+8|0;u=x;return w|0}b=5024;while(1){a=f[b>>2]|0;if(a>>>0<=j>>>0?(w=a+(f[b+4>>2]|0)|0,w>>>0>j>>>0):0)break;b=f[b+8>>2]|0}e=w+-47|0;a=e+8|0;a=e+((a&7|0)==0?0:0-a&7)|0;e=j+16|0;a=a>>>0>>0?j:a;b=a+8|0;c=g+8|0;c=(c&7|0)==0?0:0-c&7;v=g+c|0;c=h+-40-c|0;f[1150]=v;f[1147]=c;f[v+4>>2]=c|1;f[v+c+4>>2]=40;f[1151]=f[1266];c=a+4|0;f[c>>2]=27;f[b>>2]=f[1256];f[b+4>>2]=f[1257];f[b+8>>2]=f[1258];f[b+12>>2]=f[1259];f[1256]=g;f[1257]=h;f[1259]=0;f[1258]=b;b=a+24|0;do{v=b;b=b+4|0;f[b>>2]=7}while((v+8|0)>>>0>>0);if((a|0)!=(j|0)){g=a-j|0;f[c>>2]=f[c>>2]&-2;f[j+4>>2]=g|1;f[a>>2]=g;b=g>>>3;if(g>>>0<256){c=4616+(b<<1<<2)|0;a=f[1144]|0;b=1<>2]|0}f[a>>2]=j;f[b+12>>2]=j;f[j+8>>2]=b;f[j+12>>2]=c;break}b=g>>>8;if(b)if(g>>>0>16777215)c=31;else{v=(b+1048320|0)>>>16&8;w=b<>>16&4;w=w<>>16&2;c=14-(t|v|c)+(w<>>15)|0;c=g>>>(c+7|0)&1|c<<1}else c=0;d=4880+(c<<2)|0;f[j+28>>2]=c;f[j+20>>2]=0;f[e>>2]=0;b=f[1145]|0;a=1<>2]=j;f[j+24>>2]=d;f[j+12>>2]=j;f[j+8>>2]=j;break}a=g<<((c|0)==31?0:25-(c>>>1)|0);c=f[d>>2]|0;while(1){if((f[c+4>>2]&-8|0)==(g|0)){v=216;break}d=c+16+(a>>>31<<2)|0;b=f[d>>2]|0;if(!b){v=215;break}else{a=a<<1;c=b}}if((v|0)==215){f[d>>2]=j;f[j+24>>2]=c;f[j+12>>2]=j;f[j+8>>2]=j;break}else if((v|0)==216){v=c+8|0;w=f[v>>2]|0;f[w+12>>2]=j;f[v>>2]=j;f[j+8>>2]=w;f[j+12>>2]=c;f[j+24>>2]=0;break}}}else{w=f[1148]|0;if((w|0)==0|g>>>0>>0)f[1148]=g;f[1256]=g;f[1257]=h;f[1259]=0;f[1153]=f[1262];f[1152]=-1;b=0;do{w=4616+(b<<1<<2)|0;f[w+12>>2]=w;f[w+8>>2]=w;b=b+1|0}while((b|0)!=32);w=g+8|0;w=(w&7|0)==0?0:0-w&7;v=g+w|0;w=h+-40-w|0;f[1150]=v;f[1147]=w;f[v+4>>2]=w|1;f[v+w+4>>2]=40;f[1151]=f[1266]}while(0);b=f[1147]|0;if(b>>>0>m>>>0){t=b-m|0;f[1147]=t;w=f[1150]|0;v=w+m|0;f[1150]=v;f[v+4>>2]=t|1;f[w+4>>2]=m|3;w=w+8|0;u=x;return w|0}}w=jd()|0;f[w>>2]=12;w=0;u=x;return w|0}function Na(a,c,d,e,g,i){a=a|0;c=+c;d=d|0;e=e|0;g=g|0;i=i|0;var j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0.0,r=0,s=0,t=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0;G=u;u=u+560|0;l=G+8|0;t=G;F=G+524|0;E=F;m=G+512|0;f[t>>2]=0;D=m+12|0;Fc(c)|0;if((I|0)<0){c=-c;B=1;A=2087}else{B=(g&2049|0)!=0&1;A=(g&2048|0)==0?((g&1|0)==0?2088:2093):2090}Fc(c)|0;C=I&2146435072;do if(C>>>0<2146435072|(C|0)==2146435072&0<0){q=+hd(c,t)*2.0;j=q!=0.0;if(j)f[t>>2]=(f[t>>2]|0)+-1;w=i|32;if((w|0)==97){r=i&32;p=(r|0)==0?A:A+9|0;o=B|2;j=12-e|0;do if(!(e>>>0>11|(j|0)==0)){c=8.0;do{j=j+-1|0;c=c*16.0}while((j|0)!=0);if((b[p>>0]|0)==45){c=-(c+(-q-c));break}else{c=q+c-c;break}}else c=q;while(0);k=f[t>>2]|0;j=(k|0)<0?0-k|0:k;j=Rb(j,((j|0)<0)<<31>>31,D)|0;if((j|0)==(D|0)){j=m+11|0;b[j>>0]=48}b[j+-1>>0]=(k>>31&2)+43;n=j+-2|0;b[n>>0]=i+15;m=(e|0)<1;l=(g&8|0)==0;j=F;do{C=~~c;k=j+1|0;b[j>>0]=h[2122+C>>0]|r;c=(c-+(C|0))*16.0;if((k-E|0)==1?!(l&(m&c==0.0)):0){b[k>>0]=46;j=j+2|0}else j=k}while(c!=0.0);C=j-E|0;E=D-n|0;D=(e|0)!=0&(C+-2|0)<(e|0)?e+2|0:C;j=E+o+D|0;Wb(a,32,d,j,g);Nc(a,p,o);Wb(a,48,d,j,g^65536);Nc(a,F,C);Wb(a,48,D-C|0,0,0);Nc(a,n,E);Wb(a,32,d,j,g^8192);break}k=(e|0)<0?6:e;if(j){j=(f[t>>2]|0)+-28|0;f[t>>2]=j;c=q*268435456.0}else{c=q;j=f[t>>2]|0}C=(j|0)<0?l:l+288|0;l=C;do{y=~~c>>>0;f[l>>2]=y;l=l+4|0;c=(c-+(y>>>0))*1.0e9}while(c!=0.0);if((j|0)>0){m=C;o=l;while(1){n=(j|0)<29?j:29;j=o+-4|0;if(j>>>0>=m>>>0){l=0;do{x=yc(f[j>>2]|0,0,n|0)|0;x=Gc(x|0,I|0,l|0,0)|0;y=I;v=mc(x|0,y|0,1e9,0)|0;f[j>>2]=v;l=Uc(x|0,y|0,1e9,0)|0;j=j+-4|0}while(j>>>0>=m>>>0);if(l){m=m+-4|0;f[m>>2]=l}}l=o;while(1){if(l>>>0<=m>>>0)break;j=l+-4|0;if(!(f[j>>2]|0))l=j;else break}j=(f[t>>2]|0)-n|0;f[t>>2]=j;if((j|0)>0)o=l;else break}}else m=C;if((j|0)<0){e=((k+25|0)/9|0)+1|0;s=(w|0)==102;do{r=0-j|0;r=(r|0)<9?r:9;if(m>>>0>>0){n=(1<>>r;p=0;j=m;do{y=f[j>>2]|0;f[j>>2]=(y>>>r)+p;p=X(y&n,o)|0;j=j+4|0}while(j>>>0>>0);j=(f[m>>2]|0)==0?m+4|0:m;if(!p){m=j;j=l}else{f[l>>2]=p;m=j;j=l+4|0}}else{m=(f[m>>2]|0)==0?m+4|0:m;j=l}l=s?C:m;l=(j-l>>2|0)>(e|0)?l+(e<<2)|0:j;j=(f[t>>2]|0)+r|0;f[t>>2]=j}while((j|0)<0);j=m;e=l}else{j=m;e=l}y=C;if(j>>>0>>0){l=(y-j>>2)*9|0;n=f[j>>2]|0;if(n>>>0>=10){m=10;do{m=m*10|0;l=l+1|0}while(n>>>0>=m>>>0)}}else l=0;s=(w|0)==103;v=(k|0)!=0;m=k-((w|0)!=102?l:0)+((v&s)<<31>>31)|0;if((m|0)<(((e-y>>2)*9|0)+-9|0)){m=m+9216|0;r=C+4+(((m|0)/9|0)+-1024<<2)|0;m=((m|0)%9|0)+1|0;if((m|0)<9){n=10;do{n=n*10|0;m=m+1|0}while((m|0)!=9)}else n=10;o=f[r>>2]|0;p=(o>>>0)%(n>>>0)|0;m=(r+4|0)==(e|0);if(!(m&(p|0)==0)){q=(((o>>>0)/(n>>>0)|0)&1|0)==0?9007199254740992.0:9007199254740994.0;x=(n|0)/2|0;c=p>>>0>>0?.5:m&(p|0)==(x|0)?1.0:1.5;if(B){x=(b[A>>0]|0)==45;c=x?-c:c;q=x?-q:q}m=o-p|0;f[r>>2]=m;if(q+c!=q){x=m+n|0;f[r>>2]=x;if(x>>>0>999999999){l=r;while(1){m=l+-4|0;f[l>>2]=0;if(m>>>0>>0){j=j+-4|0;f[j>>2]=0}x=(f[m>>2]|0)+1|0;f[m>>2]=x;if(x>>>0>999999999)l=m;else break}}else m=r;l=(y-j>>2)*9|0;o=f[j>>2]|0;if(o>>>0>=10){n=10;do{n=n*10|0;l=l+1|0}while(o>>>0>=n>>>0)}}else m=r}else m=r;m=m+4|0;m=e>>>0>m>>>0?m:e;x=j}else{m=e;x=j}w=m;while(1){if(w>>>0<=x>>>0){t=0;break}j=w+-4|0;if(!(f[j>>2]|0))w=j;else{t=1;break}}e=0-l|0;do if(s){j=((v^1)&1)+k|0;if((j|0)>(l|0)&(l|0)>-5){n=i+-1|0;k=j+-1-l|0}else{n=i+-2|0;k=j+-1|0}j=g&8;if(!j){if(t?(z=f[w+-4>>2]|0,(z|0)!=0):0)if(!((z>>>0)%10|0)){m=0;j=10;do{j=j*10|0;m=m+1|0}while(!((z>>>0)%(j>>>0)|0|0))}else m=0;else m=9;j=((w-y>>2)*9|0)+-9|0;if((n|32|0)==102){r=j-m|0;r=(r|0)>0?r:0;k=(k|0)<(r|0)?k:r;r=0;break}else{r=j+l-m|0;r=(r|0)>0?r:0;k=(k|0)<(r|0)?k:r;r=0;break}}else r=j}else{n=i;r=g&8}while(0);s=k|r;o=(s|0)!=0&1;p=(n|32|0)==102;if(p){v=0;j=(l|0)>0?l:0}else{j=(l|0)<0?e:l;j=Rb(j,((j|0)<0)<<31>>31,D)|0;m=D;if((m-j|0)<2)do{j=j+-1|0;b[j>>0]=48}while((m-j|0)<2);b[j+-1>>0]=(l>>31&2)+43;j=j+-2|0;b[j>>0]=n;v=j;j=m-j|0}j=B+1+k+o+j|0;Wb(a,32,d,j,g);Nc(a,A,B);Wb(a,48,d,j,g^65536);if(p){n=x>>>0>C>>>0?C:x;r=F+9|0;o=r;p=F+8|0;m=n;do{l=Rb(f[m>>2]|0,0,r)|0;if((m|0)==(n|0)){if((l|0)==(r|0)){b[p>>0]=48;l=p}}else if(l>>>0>F>>>0){Ib(F|0,48,l-E|0)|0;do l=l+-1|0;while(l>>>0>F>>>0)}Nc(a,l,o-l|0);m=m+4|0}while(m>>>0<=C>>>0);if(s|0)Nc(a,2138,1);if(m>>>0>>0&(k|0)>0)while(1){l=Rb(f[m>>2]|0,0,r)|0;if(l>>>0>F>>>0){Ib(F|0,48,l-E|0)|0;do l=l+-1|0;while(l>>>0>F>>>0)}Nc(a,l,(k|0)<9?k:9);m=m+4|0;l=k+-9|0;if(!(m>>>0>>0&(k|0)>9)){k=l;break}else k=l}Wb(a,48,k+9|0,9,0)}else{s=t?w:x+4|0;if((k|0)>-1){t=F+9|0;r=(r|0)==0;e=t;o=0-E|0;p=F+8|0;n=x;do{l=Rb(f[n>>2]|0,0,t)|0;if((l|0)==(t|0)){b[p>>0]=48;l=p}do if((n|0)==(x|0)){m=l+1|0;Nc(a,l,1);if(r&(k|0)<1){l=m;break}Nc(a,2138,1);l=m}else{if(l>>>0<=F>>>0)break;Ib(F|0,48,l+o|0)|0;do l=l+-1|0;while(l>>>0>F>>>0)}while(0);E=e-l|0;Nc(a,l,(k|0)>(E|0)?E:k);k=k-E|0;n=n+4|0}while(n>>>0>>0&(k|0)>-1)}Wb(a,48,k+18|0,18,0);Nc(a,v,D-v|0)}Wb(a,32,d,j,g^8192)}else{F=(i&32|0)!=0;j=B+3|0;Wb(a,32,d,j,g&-65537);Nc(a,A,B);Nc(a,c!=c|0.0!=0.0?(F?2114:2118):F?2106:2110,3);Wb(a,32,d,j,g^8192)}while(0);u=G;return ((j|0)<(d|0)?d:j)|0}function Oa(a,c,e,g,h){a=a|0;c=c|0;e=e|0;g=g|0;h=h|0;var i=0,j=0,k=0,l=0,m=0,n=0,o=0,q=0,r=0,s=0,t=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0;G=u;u=u+64|0;C=G+16|0;D=G;A=G+24|0;E=G+8|0;F=G+20|0;f[C>>2]=c;x=(a|0)!=0;y=A+40|0;z=y;A=A+39|0;B=E+4|0;j=0;i=0;n=0;a:while(1){do if((i|0)>-1)if((j|0)>(2147483647-i|0)){i=jd()|0;f[i>>2]=75;i=-1;break}else{i=j+i|0;break}while(0);j=b[c>>0]|0;if(!(j<<24>>24)){w=87;break}else k=c;b:while(1){switch(j<<24>>24){case 37:{j=k;w=9;break b}case 0:{j=k;break b}default:{}}v=k+1|0;f[C>>2]=v;j=b[v>>0]|0;k=v}c:do if((w|0)==9)while(1){w=0;if((b[k+1>>0]|0)!=37)break c;j=j+1|0;k=k+2|0;f[C>>2]=k;if((b[k>>0]|0)==37)w=9;else break}while(0);j=j-c|0;if(x)Nc(a,c,j);if(j|0){c=k;continue}l=k+1|0;j=(b[l>>0]|0)+-48|0;if(j>>>0<10){v=(b[k+2>>0]|0)==36;t=v?j:-1;n=v?1:n;l=v?k+3|0:l}else t=-1;f[C>>2]=l;j=b[l>>0]|0;k=(j<<24>>24)+-32|0;d:do if(k>>>0<32){m=0;o=j;while(1){j=1<>2]=l;j=b[l>>0]|0;k=(j<<24>>24)+-32|0;if(k>>>0>=32)break;else o=j}}else m=0;while(0);if(j<<24>>24==42){k=l+1|0;j=(b[k>>0]|0)+-48|0;if(j>>>0<10?(b[l+2>>0]|0)==36:0){f[h+(j<<2)>>2]=10;j=f[g+((b[k>>0]|0)+-48<<3)>>2]|0;n=1;l=l+3|0}else{if(n|0){i=-1;break}if(x){n=(f[e>>2]|0)+(4-1)&~(4-1);j=f[n>>2]|0;f[e>>2]=n+4;n=0;l=k}else{j=0;n=0;l=k}}f[C>>2]=l;v=(j|0)<0;j=v?0-j|0:j;m=v?m|8192:m}else{j=ec(C)|0;if((j|0)<0){i=-1;break}l=f[C>>2]|0}do if((b[l>>0]|0)==46){if((b[l+1>>0]|0)!=42){f[C>>2]=l+1;k=ec(C)|0;l=f[C>>2]|0;break}o=l+2|0;k=(b[o>>0]|0)+-48|0;if(k>>>0<10?(b[l+3>>0]|0)==36:0){f[h+(k<<2)>>2]=10;k=f[g+((b[o>>0]|0)+-48<<3)>>2]|0;l=l+4|0;f[C>>2]=l;break}if(n|0){i=-1;break a}if(x){v=(f[e>>2]|0)+(4-1)&~(4-1);k=f[v>>2]|0;f[e>>2]=v+4}else k=0;f[C>>2]=o;l=o}else k=-1;while(0);s=0;while(1){if(((b[l>>0]|0)+-65|0)>>>0>57){i=-1;break a}v=l+1|0;f[C>>2]=v;o=b[(b[l>>0]|0)+-65+(1606+(s*58|0))>>0]|0;q=o&255;if((q+-1|0)>>>0<8){s=q;l=v}else break}if(!(o<<24>>24)){i=-1;break}r=(t|0)>-1;do if(o<<24>>24==19)if(r){i=-1;break a}else w=49;else{if(r){f[h+(t<<2)>>2]=q;r=g+(t<<3)|0;t=f[r+4>>2]|0;w=D;f[w>>2]=f[r>>2];f[w+4>>2]=t;w=49;break}if(!x){i=0;break a}db(D,q,e)}while(0);if((w|0)==49?(w=0,!x):0){j=0;c=v;continue}l=b[l>>0]|0;l=(s|0)!=0&(l&15|0)==3?l&-33:l;r=m&-65537;t=(m&8192|0)==0?m:r;e:do switch(l|0){case 110:switch((s&255)<<24>>24){case 0:{f[f[D>>2]>>2]=i;j=0;c=v;continue a}case 1:{f[f[D>>2]>>2]=i;j=0;c=v;continue a}case 2:{j=f[D>>2]|0;f[j>>2]=i;f[j+4>>2]=((i|0)<0)<<31>>31;j=0;c=v;continue a}case 3:{d[f[D>>2]>>1]=i;j=0;c=v;continue a}case 4:{b[f[D>>2]>>0]=i;j=0;c=v;continue a}case 6:{f[f[D>>2]>>2]=i;j=0;c=v;continue a}case 7:{j=f[D>>2]|0;f[j>>2]=i;f[j+4>>2]=((i|0)<0)<<31>>31;j=0;c=v;continue a}default:{j=0;c=v;continue a}}case 112:{l=120;k=k>>>0>8?k:8;c=t|8;w=61;break}case 88:case 120:{c=t;w=61;break}case 111:{l=D;c=f[l>>2]|0;l=f[l+4>>2]|0;q=kc(c,l,y)|0;r=z-q|0;m=0;o=2070;k=(t&8|0)==0|(k|0)>(r|0)?k:r+1|0;r=t;w=67;break}case 105:case 100:{l=D;c=f[l>>2]|0;l=f[l+4>>2]|0;if((l|0)<0){c=Cc(0,0,c|0,l|0)|0;l=I;m=D;f[m>>2]=c;f[m+4>>2]=l;m=1;o=2070;w=66;break e}else{m=(t&2049|0)!=0&1;o=(t&2048|0)==0?((t&1|0)==0?2070:2072):2071;w=66;break e}}case 117:{l=D;m=0;o=2070;c=f[l>>2]|0;l=f[l+4>>2]|0;w=66;break}case 99:{b[A>>0]=f[D>>2];c=A;m=0;o=2070;q=y;l=1;k=r;break}case 109:{l=jd()|0;l=Qc(f[l>>2]|0)|0;w=71;break}case 115:{l=f[D>>2]|0;l=l|0?l:2080;w=71;break}case 67:{f[E>>2]=f[D>>2];f[B>>2]=0;f[D>>2]=E;q=-1;l=E;w=75;break}case 83:{c=f[D>>2]|0;if(!k){Wb(a,32,j,0,t);c=0;w=84}else{q=k;l=c;w=75}break}case 65:case 71:case 70:case 69:case 97:case 103:case 102:case 101:{j=Na(a,+p[D>>3],j,k,t,l)|0;c=v;continue a}default:{m=0;o=2070;q=y;l=k;k=t}}while(0);f:do if((w|0)==61){t=D;s=f[t>>2]|0;t=f[t+4>>2]|0;q=gc(s,t,y,l&32)|0;o=(c&8|0)==0|(s|0)==0&(t|0)==0;m=o?0:2;o=o?2070:2070+(l>>4)|0;r=c;c=s;l=t;w=67}else if((w|0)==66){q=Rb(c,l,y)|0;r=t;w=67}else if((w|0)==71){w=0;t=vb(l,0,k)|0;s=(t|0)==0;c=l;m=0;o=2070;q=s?l+k|0:t;l=s?k:t-l|0;k=r}else if((w|0)==75){w=0;o=l;c=0;k=0;while(1){m=f[o>>2]|0;if(!m)break;k=Rc(F,m)|0;if((k|0)<0|k>>>0>(q-c|0)>>>0)break;c=k+c|0;if(q>>>0>c>>>0)o=o+4|0;else break}if((k|0)<0){i=-1;break a}Wb(a,32,j,c,t);if(!c){c=0;w=84}else{m=0;while(1){k=f[l>>2]|0;if(!k){w=84;break f}k=Rc(F,k)|0;m=k+m|0;if((m|0)>(c|0)){w=84;break f}Nc(a,F,k);if(m>>>0>=c>>>0){w=84;break}else l=l+4|0}}}while(0);if((w|0)==67){w=0;l=(c|0)!=0|(l|0)!=0;t=(k|0)!=0|l;l=((l^1)&1)+(z-q)|0;c=t?q:y;q=y;l=t?((k|0)>(l|0)?k:l):k;k=(k|0)>-1?r&-65537:r}else if((w|0)==84){w=0;Wb(a,32,j,c,t^8192);j=(j|0)>(c|0)?j:c;c=v;continue}s=q-c|0;r=(l|0)<(s|0)?s:l;t=r+m|0;j=(j|0)<(t|0)?t:j;Wb(a,32,j,t,k);Nc(a,o,m);Wb(a,48,j,t,k^65536);Wb(a,48,r,s,0);Nc(a,c,s);Wb(a,32,j,t,k^8192);c=v}g:do if((w|0)==87)if(!a)if(!n)i=0;else{i=1;while(1){c=f[h+(i<<2)>>2]|0;if(!c)break;db(g+(i<<3)|0,c,e);i=i+1|0;if((i|0)>=10){i=1;break g}}while(1){if(f[h+(i<<2)>>2]|0){i=-1;break g}i=i+1|0;if((i|0)>=10){i=1;break}}}while(0);u=G;return i|0}function Pa(a,c){a=a|0;c=c|0;var d=0,e=0,g=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0;E=u;u=u+704|0;A=E+144|0;z=E+128|0;y=E+112|0;x=E+96|0;w=E+80|0;v=E+64|0;t=E+48|0;B=E+32|0;n=E+16|0;k=E;p=E+184|0;D=E+160|0;q=yb(a,14)|0;if(!q){Eb(c);D=1;u=E;return D|0}r=c+4|0;s=c+8|0;d=f[s>>2]|0;if((d|0)!=(q|0)){if(d>>>0<=q>>>0){do if((f[c+12>>2]|0)>>>0>>0){if(fb(r,q,(d+1|0)==(q|0),1,0)|0){d=f[s>>2]|0;break}b[c+16>>0]=1;D=0;u=E;return D|0}while(0);Ib((f[r>>2]|0)+d|0,0,q-d|0)|0}f[s>>2]=q}Ib(f[r>>2]|0,0,q|0)|0;o=a+20|0;d=f[o>>2]|0;if((d|0)<5){i=a+4|0;j=a+8|0;g=a+16|0;do{e=f[i>>2]|0;if((e|0)==(f[j>>2]|0))e=0;else{f[i>>2]=e+1;e=h[e>>0]|0}d=d+8|0;f[o>>2]=d;if((d|0)>=33){f[k>>2]=866;f[k+4>>2]=3208;f[k+8>>2]=1366;vc(p,812,k)|0;Ub(p)|0;d=f[o>>2]|0}e=e<<32-d|f[g>>2];f[g>>2]=e}while((d|0)<5)}else{e=a+16|0;g=e;e=f[e>>2]|0}m=e>>>27;f[g>>2]=e<<5;f[o>>2]=d+-5;if((m+-1|0)>>>0>20){D=0;u=E;return D|0}f[D+20>>2]=0;f[D>>2]=0;f[D+4>>2]=0;f[D+8>>2]=0;f[D+12>>2]=0;b[D+16>>0]=0;d=D+4|0;e=D+8|0;a:do if(fb(d,21,0,1,0)|0){i=f[e>>2]|0;l=f[d>>2]|0;Ib(l+i|0,0,21-i|0)|0;f[e>>2]=21;i=a+4|0;j=a+8|0;k=a+16|0;g=0;do{d=f[o>>2]|0;if((d|0)<3)do{e=f[i>>2]|0;if((e|0)==(f[j>>2]|0))e=0;else{f[i>>2]=e+1;e=h[e>>0]|0}d=d+8|0;f[o>>2]=d;if((d|0)>=33){f[n>>2]=866;f[n+4>>2]=3208;f[n+8>>2]=1366;vc(p,812,n)|0;Ub(p)|0;d=f[o>>2]|0}e=e<<32-d|f[k>>2];f[k>>2]=e}while((d|0)<3);else e=f[k>>2]|0;f[k>>2]=e<<3;f[o>>2]=d+-3;b[l+(h[1327+g>>0]|0)>>0]=e>>>29;g=g+1|0}while((g|0)!=(m|0));if(qb(D)|0){k=a+4|0;l=a+8|0;m=a+16|0;d=0;b:do{j=q-d|0;g=bb(a,D)|0;c:do if(g>>>0<17){if((f[s>>2]|0)>>>0<=d>>>0){f[B>>2]=866;f[B+4>>2]=910;f[B+8>>2]=1497;vc(p,812,B)|0;Ub(p)|0}b[(f[r>>2]|0)+d>>0]=g;d=d+1|0}else switch(g|0){case 17:{e=f[o>>2]|0;if((e|0)<3)do{g=f[k>>2]|0;if((g|0)==(f[l>>2]|0))g=0;else{f[k>>2]=g+1;g=h[g>>0]|0}e=e+8|0;f[o>>2]=e;if((e|0)>=33){f[t>>2]=866;f[t+4>>2]=3208;f[t+8>>2]=1366;vc(p,812,t)|0;Ub(p)|0;e=f[o>>2]|0}g=g<<32-e|f[m>>2];f[m>>2]=g}while((e|0)<3);else g=f[m>>2]|0;f[m>>2]=g<<3;f[o>>2]=e+-3;g=(g>>>29)+3|0;e=g>>>0>j>>>0;if(e){d=0;break a}else{d=(e?0:g)+d|0;break c}}case 18:{e=f[o>>2]|0;if((e|0)<7)do{g=f[k>>2]|0;if((g|0)==(f[l>>2]|0))g=0;else{f[k>>2]=g+1;g=h[g>>0]|0}e=e+8|0;f[o>>2]=e;if((e|0)>=33){f[v>>2]=866;f[v+4>>2]=3208;f[v+8>>2]=1366;vc(p,812,v)|0;Ub(p)|0;e=f[o>>2]|0}g=g<<32-e|f[m>>2];f[m>>2]=g}while((e|0)<7);else g=f[m>>2]|0;f[m>>2]=g<<7;f[o>>2]=e+-7;g=(g>>>25)+11|0;e=g>>>0>j>>>0;if(e){d=0;break a}else{d=(e?0:g)+d|0;break c}}default:{if((g+-19|0)>>>0>=2){C=81;break b}e=f[o>>2]|0;if((g|0)==19){if((e|0)<2){g=e;while(1){e=f[k>>2]|0;if((e|0)==(f[l>>2]|0))i=0;else{f[k>>2]=e+1;i=h[e>>0]|0}e=g+8|0;f[o>>2]=e;if((e|0)>=33){f[w>>2]=866;f[w+4>>2]=3208;f[w+8>>2]=1366;vc(p,812,w)|0;Ub(p)|0;e=f[o>>2]|0}g=i<<32-e|f[m>>2];f[m>>2]=g;if((e|0)<2)g=e;else break}}else g=f[m>>2]|0;f[m>>2]=g<<2;g=g>>>30;i=3;e=e+-2|0}else{if((e|0)<6)do{g=f[k>>2]|0;if((g|0)==(f[l>>2]|0))g=0;else{f[k>>2]=g+1;g=h[g>>0]|0}e=e+8|0;f[o>>2]=e;if((e|0)>=33){f[x>>2]=866;f[x+4>>2]=3208;f[x+8>>2]=1366;vc(p,812,x)|0;Ub(p)|0;e=f[o>>2]|0}g=g<<32-e|f[m>>2];f[m>>2]=g}while((e|0)<6);else g=f[m>>2]|0;f[m>>2]=g<<6;g=g>>>26;i=7;e=e+-6|0}f[o>>2]=e;g=g+i|0;if((d|0)==0|g>>>0>j>>>0){d=0;break a}e=d+-1|0;if((f[s>>2]|0)>>>0<=e>>>0){f[y>>2]=866;f[y+4>>2]=910;f[y+8>>2]=1497;vc(p,812,y)|0;Ub(p)|0}i=b[(f[r>>2]|0)+e>>0]|0;if(!(i<<24>>24)){d=0;break a}e=g+d|0;if(d>>>0>=e>>>0)break c;do{if((f[s>>2]|0)>>>0<=d>>>0){f[z>>2]=866;f[z+4>>2]=910;f[z+8>>2]=1497;vc(p,812,z)|0;Ub(p)|0}b[(f[r>>2]|0)+d>>0]=i;d=d+1|0}while((d|0)!=(e|0));d=e}}while(0)}while(q>>>0>d>>>0);if((C|0)==81){f[A>>2]=866;f[A+4>>2]=3149;f[A+8>>2]=1348;vc(p,812,A)|0;Ub(p)|0;d=0;break}if((q|0)==(d|0))d=qb(c)|0;else d=0}else d=0}else{b[D+16>>0]=1;d=0}while(0);Cb(D);D=d;u=E;return D|0}function Qa(a,c,e,g){a=a|0;c=c|0;e=e|0;g=g|0;var i=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0;L=u;u=u+880|0;J=L+144|0;I=L+128|0;H=L+112|0;G=L+96|0;C=L+80|0;x=L+64|0;v=L+48|0;w=L+32|0;q=L+16|0;p=L;E=L+360|0;F=L+296|0;K=L+224|0;t=L+156|0;if((c|0)==0|g>>>0>11){K=0;u=L;return K|0}f[a>>2]=c;i=K;k=i+68|0;do{f[i>>2]=0;i=i+4|0}while((i|0)<(k|0));i=0;do{D=b[e+i>>0]|0;k=K+((D&255)<<2)|0;if(D<<24>>24)f[k>>2]=(f[k>>2]|0)+1;i=i+1|0}while((i|0)!=(c|0));k=0;l=0;m=0;n=-1;o=1;while(1){i=f[K+(o<<2)>>2]|0;if(!i){f[a+28+(o+-1<<2)>>2]=0;r=l}else{r=o+-1|0;f[F+(r<<2)>>2]=k;k=i+k|0;D=16-o|0;f[a+28+(r<<2)>>2]=(k+-1<>2]=l;f[t+(o<<2)>>2]=l;r=i+l|0;m=m>>>0>o>>>0?m:o;n=n>>>0>>0?n:o}o=o+1|0;if((o|0)==17)break;else{k=k<<1;l=r}}f[a+4>>2]=r;k=a+172|0;do if(r>>>0>(f[k>>2]|0)>>>0){i=r+-1|0;if(!(i&r))i=r;else{i=i>>>16|i;i=i>>>8|i;i=i>>>4|i;i=i>>>2|i;i=(i>>>1|i)+1|0;i=i>>>0>c>>>0?c:i}f[k>>2]=i;l=a+176|0;i=f[l>>2]|0;do if(i|0){D=f[i+-4>>2]|0;i=i+-8|0;if(!((D|0)!=0?(D|0)==(~f[i>>2]|0):0)){f[p>>2]=866;f[p+4>>2]=651;f[p+8>>2]=1579;vc(E,812,p)|0;Ub(E)|0}if(!(i&7)){Nb(i,0,0,1,0)|0;break}else{f[q>>2]=866;f[q+4>>2]=2506;f[q+8>>2]=1232;vc(E,812,q)|0;Ub(E)|0;break}}while(0);i=f[k>>2]|0;i=i|0?i:1;k=Db((i<<1)+8|0,0)|0;if(!k){f[l>>2]=0;g=0;break}else{f[k+4>>2]=i;f[k>>2]=~i;f[l>>2]=k+8;s=24;break}}else s=24;while(0);a:do if((s|0)==24){D=a+24|0;b[D>>0]=n;b[a+25>>0]=m;l=a+176|0;k=0;do{B=b[e+k>>0]|0;i=B&255;if(B<<24>>24){if(!(f[K+(i<<2)>>2]|0)){f[w>>2]=866;f[w+4>>2]=2276;f[w+8>>2]=977;vc(E,812,w)|0;Ub(E)|0}B=t+(i<<2)|0;i=f[B>>2]|0;f[B>>2]=i+1;if(i>>>0>=r>>>0){f[v>>2]=866;f[v+4>>2]=2280;f[v+8>>2]=990;vc(E,812,v)|0;Ub(E)|0}d[(f[l>>2]|0)+(i<<1)>>1]=k}k=k+1|0}while((k|0)!=(c|0));A=(h[D>>0]|0)>>>0>>0?g:0;B=a+8|0;f[B>>2]=A;z=(A|0)!=0;if(z){y=1<>>0>(f[i>>2]|0)>>>0){f[i>>2]=y;l=a+168|0;i=f[l>>2]|0;do if(i|0){w=f[i+-4>>2]|0;i=i+-8|0;if(!((w|0)!=0?(w|0)==(~f[i>>2]|0):0)){f[x>>2]=866;f[x+4>>2]=651;f[x+8>>2]=1579;vc(E,812,x)|0;Ub(E)|0}if(!(i&7)){Nb(i,0,0,1,0)|0;break}else{f[C>>2]=866;f[C+4>>2]=2506;f[C+8>>2]=1232;vc(E,812,C)|0;Ub(E)|0;break}}while(0);i=y<<2;k=Db(i+8|0,0)|0;if(!k){f[l>>2]=0;g=0;break a}else{C=k+8|0;f[k+4>>2]=y;f[k>>2]=~y;f[l>>2]=C;k=C;break}}else{k=a+168|0;i=y<<2;l=k;k=f[k>>2]|0}while(0);Ib(k|0,-1,i|0)|0;v=a+176|0;t=1;do{if(f[K+(t<<2)>>2]|0){w=A-t|0;x=1<>2]|0;if(i>>>0>=16){f[G>>2]=866;f[G+4>>2]=1960;f[G+8>>2]=1453;vc(E,812,G)|0;Ub(E)|0}c=f[a+28+(i<<2)>>2]|0;c=(c|0)==0?-1:(c+-1|0)>>>(16-t|0);if(k>>>0<=c>>>0){r=(f[a+96+(i<<2)>>2]|0)-k|0;s=t<<16;do{i=j[(f[v>>2]|0)+(r+k<<1)>>1]|0;if((h[e+i>>0]|0|0)!=(t|0)){f[H>>2]=866;f[H+4>>2]=2322;f[H+8>>2]=1019;vc(E,812,H)|0;Ub(E)|0}q=k<>>0>=y>>>0){f[I>>2]=866;f[I+4>>2]=2328;f[I+8>>2]=1053;vc(E,812,I)|0;Ub(E)|0}i=f[l>>2]|0;if((f[i+(p<<2)>>2]|0)!=-1){f[J>>2]=866;f[J+4>>2]=2330;f[J+8>>2]=1076;vc(E,812,J)|0;Ub(E)|0;i=f[l>>2]|0}f[i+(p<<2)>>2]=o;n=n+1|0}while(n>>>0>>0);k=k+1|0}while(k>>>0<=c>>>0)}}t=t+1|0}while(A>>>0>=t>>>0)}i=a+96|0;f[i>>2]=(f[i>>2]|0)-(f[F>>2]|0);i=a+100|0;f[i>>2]=(f[i>>2]|0)-(f[F+4>>2]|0);i=a+104|0;f[i>>2]=(f[i>>2]|0)-(f[F+8>>2]|0);i=a+108|0;f[i>>2]=(f[i>>2]|0)-(f[F+12>>2]|0);i=a+112|0;f[i>>2]=(f[i>>2]|0)-(f[F+16>>2]|0);i=a+116|0;f[i>>2]=(f[i>>2]|0)-(f[F+20>>2]|0);i=a+120|0;f[i>>2]=(f[i>>2]|0)-(f[F+24>>2]|0);i=a+124|0;f[i>>2]=(f[i>>2]|0)-(f[F+28>>2]|0);i=a+128|0;f[i>>2]=(f[i>>2]|0)-(f[F+32>>2]|0);i=a+132|0;f[i>>2]=(f[i>>2]|0)-(f[F+36>>2]|0);i=a+136|0;f[i>>2]=(f[i>>2]|0)-(f[F+40>>2]|0);i=a+140|0;f[i>>2]=(f[i>>2]|0)-(f[F+44>>2]|0);i=a+144|0;f[i>>2]=(f[i>>2]|0)-(f[F+48>>2]|0);i=a+148|0;f[i>>2]=(f[i>>2]|0)-(f[F+52>>2]|0);i=a+152|0;f[i>>2]=(f[i>>2]|0)-(f[F+56>>2]|0);i=a+156|0;f[i>>2]=(f[i>>2]|0)-(f[F+60>>2]|0);i=a+16|0;f[i>>2]=0;k=a+20|0;f[k>>2]=h[D>>0];b:do if(z){do{if(!g)break b;J=g;g=g+-1|0}while(!(f[K+(J<<2)>>2]|0));f[i>>2]=f[a+28+(g<<2)>>2];g=A+1|0;f[k>>2]=g;if(g>>>0<=m>>>0){while(1){if(f[K+(g<<2)>>2]|0)break;g=g+1|0;if(g>>>0>m>>>0)break b}f[k>>2]=g}}while(0);f[a+92>>2]=-1;f[a+160>>2]=1048575;f[a+12>>2]=32-(f[B>>2]|0);g=1}while(0);K=g;u=L;return K|0}function Ra(a,c,d,e,g,i,j,k){a=a|0;c=c|0;d=d|0;e=e|0;g=g|0;i=i|0;j=j|0;k=k|0;var l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,Y=0,Z=0,_=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0;ga=u;u=u+656|0;ea=ga+112|0;ca=ga+96|0;ba=ga+80|0;aa=ga+64|0;$=ga+48|0;fa=ga+32|0;da=ga+16|0;_=ga;Y=ga+144|0;Z=ga+128|0;N=a+240|0;O=f[N>>2]|0;P=a+256|0;Q=f[P>>2]|0;W=b[(f[a+88>>2]|0)+17>>0]|0;R=W&255;S=e>>>2;if(!(W<<24>>24)){u=ga;return 1}T=(k|0)==0;U=j+-1|0;V=U<<4;W=k+-1|0;H=(i&1|0)!=0;I=e<<1;J=a+92|0;K=a+116|0;L=a+140|0;M=a+236|0;G=(g&1|0)!=0;F=a+188|0;B=a+252|0;C=S+1|0;D=S+2|0;E=S+3|0;A=0;i=0;d=0;g=1;do{if(!T){y=f[c+(A<<2)>>2]|0;z=0;while(1){w=z&1;m=(w|0)==0;v=(w<<5^32)+-16|0;w=(w<<1^2)+-1|0;t=m?j:-1;l=m?0:U;a=(z|0)==(W|0);x=H&a;if((l|0)!=(t|0)){s=H&a^1;r=m?y:y+V|0;while(1){if((g|0)==1)g=bb(J,K)|0|512;q=g&7;g=g>>>3;m=h[1539+q>>0]|0;a=0;do{n=(bb(J,L)|0)+d|0;o=n-O|0;p=o>>31;d=p&n|o&~p;if((f[N>>2]|0)>>>0<=d>>>0){f[_>>2]=866;f[_+4>>2]=910;f[_+8>>2]=1497;vc(Y,812,_)|0;Ub(Y)|0}f[Z+(a<<2)>>2]=f[(f[M>>2]|0)+(d<<2)>>2];a=a+1|0}while(a>>>0>>0);p=G&(l|0)==(U|0);if(x|p){o=0;do{a=r+(X(o,e)|0)|0;n=(o|0)==0|s;m=o<<1;ia=(bb(J,F)|0)+i|0;ha=ia-Q|0;i=ha>>31;i=i&ia|ha&~i;do if(!p){if(n){f[a>>2]=f[Z+((h[1547+(q<<2)+m>>0]|0)<<2)>>2];if((f[P>>2]|0)>>>0<=i>>>0){f[ba>>2]=866;f[ba+4>>2]=910;f[ba+8>>2]=1497;vc(Y,812,ba)|0;Ub(Y)|0}f[a+4>>2]=f[(f[B>>2]|0)+(i<<2)>>2]}a=a+8|0;ha=(bb(J,F)|0)+i|0;ia=ha-Q|0;i=ia>>31;i=i&ha|ia&~i;if(n){f[a>>2]=f[Z+((h[(m|1)+(1547+(q<<2))>>0]|0)<<2)>>2];if((f[P>>2]|0)>>>0<=i>>>0){f[ea>>2]=866;f[ea+4>>2]=910;f[ea+8>>2]=1497;vc(Y,812,ea)|0;Ub(Y)|0}f[a+4>>2]=f[(f[B>>2]|0)+(i<<2)>>2]}}else{if(!n){ha=(bb(J,F)|0)+i|0;ia=ha-Q|0;i=ia>>31;i=i&ha|ia&~i;break}f[a>>2]=f[Z+((h[1547+(q<<2)+m>>0]|0)<<2)>>2];if((f[P>>2]|0)>>>0<=i>>>0){f[ca>>2]=866;f[ca+4>>2]=910;f[ca+8>>2]=1497;vc(Y,812,ca)|0;Ub(Y)|0}f[a+4>>2]=f[(f[B>>2]|0)+(i<<2)>>2];ha=(bb(J,F)|0)+i|0;ia=ha-Q|0;i=ia>>31;i=i&ha|ia&~i}while(0);o=o+1|0}while((o|0)!=2)}else{f[r>>2]=f[Z+((h[1547+(q<<2)>>0]|0)<<2)>>2];ha=(bb(J,F)|0)+i|0;ia=ha-Q|0;i=ia>>31;i=i&ha|ia&~i;if((f[P>>2]|0)>>>0<=i>>>0){f[da>>2]=866;f[da+4>>2]=910;f[da+8>>2]=1497;vc(Y,812,da)|0;Ub(Y)|0}f[r+4>>2]=f[(f[B>>2]|0)+(i<<2)>>2];f[r+8>>2]=f[Z+((h[1547+(q<<2)+1>>0]|0)<<2)>>2];ha=(bb(J,F)|0)+i|0;ia=ha-Q|0;i=ia>>31;i=i&ha|ia&~i;if((f[P>>2]|0)>>>0<=i>>>0){f[fa>>2]=866;f[fa+4>>2]=910;f[fa+8>>2]=1497;vc(Y,812,fa)|0;Ub(Y)|0}f[r+12>>2]=f[(f[B>>2]|0)+(i<<2)>>2];f[r+(S<<2)>>2]=f[Z+((h[1547+(q<<2)+2>>0]|0)<<2)>>2];ha=(bb(J,F)|0)+i|0;ia=ha-Q|0;i=ia>>31;i=i&ha|ia&~i;if((f[P>>2]|0)>>>0<=i>>>0){f[$>>2]=866;f[$+4>>2]=910;f[$+8>>2]=1497;vc(Y,812,$)|0;Ub(Y)|0}f[r+(C<<2)>>2]=f[(f[B>>2]|0)+(i<<2)>>2];f[r+(D<<2)>>2]=f[Z+((h[1547+(q<<2)+3>>0]|0)<<2)>>2];ha=(bb(J,F)|0)+i|0;ia=ha-Q|0;i=ia>>31;i=i&ha|ia&~i;if((f[P>>2]|0)>>>0<=i>>>0){f[aa>>2]=866;f[aa+4>>2]=910;f[aa+8>>2]=1497;vc(Y,812,aa)|0;Ub(Y)|0}f[r+(E<<2)>>2]=f[(f[B>>2]|0)+(i<<2)>>2]}l=w+l|0;if((l|0)==(t|0))break;else r=r+v|0}}z=z+1|0;if((z|0)==(k|0))break;else y=y+I|0}}A=A+1|0}while((A|0)!=(R|0));u=ga;return 1}function Sa(a,c,d,e,g,i,k,l){a=a|0;c=c|0;d=d|0;e=e|0;g=g|0;i=i|0;k=k|0;l=l|0;var m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,_=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,ka=0;ka=u;u=u+640|0;ha=ka+80|0;ga=ka+64|0;fa=ka+48|0;ja=ka+32|0;ia=ka+16|0;ea=ka;ca=ka+128|0;da=ka+112|0;P=ka+96|0;Q=a+272|0;R=f[Q>>2]|0;ba=f[a+88>>2]|0;S=(h[ba+63>>0]|0)<<8|(h[ba+64>>0]|0);ba=b[ba+17>>0]|0;T=ba&255;if(!(ba<<24>>24)){u=ka;return 1}U=(l|0)==0;V=k+-1|0;W=V<<5;X=l+-1|0;Y=e<<1;Z=a+92|0;_=a+116|0;$=a+164|0;aa=a+268|0;ba=a+212|0;O=(g&1|0)==0;N=(i&1|0)==0;M=a+288|0;L=a+284|0;K=0;a=0;i=0;g=0;d=0;m=1;do{if(!U){I=f[c+(K<<2)>>2]|0;J=0;while(1){H=J&1;o=(H|0)==0;G=(H<<6^64)+-32|0;H=(H<<1^2)+-1|0;E=o?k:-1;n=o?0:V;if((n|0)!=(E|0)){F=N|(J|0)!=(X|0);D=o?I:I+W|0;while(1){if((m|0)==1)m=bb(Z,_)|0|512;C=m&7;m=m>>>3;p=h[1539+C>>0]|0;o=0;do{z=(bb(Z,$)|0)+d|0;A=z-R|0;B=A>>31;d=B&z|A&~B;if((f[Q>>2]|0)>>>0<=d>>>0){f[ea>>2]=866;f[ea+4>>2]=910;f[ea+8>>2]=1497;vc(ca,812,ea)|0;Ub(ca)|0}f[da+(o<<2)>>2]=j[(f[aa>>2]|0)+(d<<1)>>1];o=o+1|0}while(o>>>0

    >>0);o=0;do{z=(bb(Z,$)|0)+i|0;A=z-R|0;B=A>>31;i=B&z|A&~B;if((f[Q>>2]|0)>>>0<=i>>>0){f[ia>>2]=866;f[ia+4>>2]=910;f[ia+8>>2]=1497;vc(ca,812,ia)|0;Ub(ca)|0}f[P+(o<<2)>>2]=j[(f[aa>>2]|0)+(i<<1)>>1];o=o+1|0}while(o>>>0

    >>0);B=O|(n|0)!=(V|0);z=0;A=D;while(1){w=F|(z|0)==0;x=z<<1;if(B){t=0;v=A;while(1){y=(bb(Z,ba)|0)+g|0;s=y-S|0;g=s>>31;g=g&y|s&~g;s=(bb(Z,ba)|0)+a|0;y=s-S|0;a=y>>31;a=a&s|y&~a;if(w){s=h[t+x+(1547+(C<<2))>>0]|0;p=g*3|0;o=f[M>>2]|0;if(o>>>0<=p>>>0){f[ja>>2]=866;f[ja+4>>2]=910;f[ja+8>>2]=1497;vc(ca,812,ja)|0;Ub(ca)|0;o=f[M>>2]|0}q=f[L>>2]|0;p=q+(p<<1)|0;r=a*3|0;if(o>>>0>r>>>0)o=q;else{f[fa>>2]=866;f[fa+4>>2]=910;f[fa+8>>2]=1497;vc(ca,812,fa)|0;Ub(ca)|0;o=f[L>>2]|0}y=o+(r<<1)|0;f[v>>2]=(j[p>>1]|0)<<16|f[da+(s<<2)>>2];f[v+4>>2]=(j[p+4>>1]|0)<<16|(j[p+2>>1]|0);f[v+8>>2]=(j[y>>1]|0)<<16|f[P+(s<<2)>>2];f[v+12>>2]=(j[y+4>>1]|0)<<16|(j[y+2>>1]|0)}t=t+1|0;if((t|0)==2)break;else v=v+16|0}}else{y=w^1;w=1547+(C<<2)+x|0;t=0;v=A;while(1){x=(bb(Z,ba)|0)+g|0;s=x-S|0;g=s>>31;g=g&x|s&~g;s=(bb(Z,ba)|0)+a|0;x=s-S|0;a=x>>31;a=a&s|x&~a;if(!((t|0)!=0|y)){s=h[w>>0]|0;p=g*3|0;o=f[M>>2]|0;if(o>>>0<=p>>>0){f[ga>>2]=866;f[ga+4>>2]=910;f[ga+8>>2]=1497;vc(ca,812,ga)|0;Ub(ca)|0;o=f[M>>2]|0}q=f[L>>2]|0;p=q+(p<<1)|0;r=a*3|0;if(o>>>0>r>>>0)o=q;else{f[ha>>2]=866;f[ha+4>>2]=910;f[ha+8>>2]=1497;vc(ca,812,ha)|0;Ub(ca)|0;o=f[L>>2]|0}x=o+(r<<1)|0;f[v>>2]=(j[p>>1]|0)<<16|f[da+(s<<2)>>2];f[v+4>>2]=(j[p+4>>1]|0)<<16|(j[p+2>>1]|0);f[v+8>>2]=(j[x>>1]|0)<<16|f[P+(s<<2)>>2];f[v+12>>2]=(j[x+4>>1]|0)<<16|(j[x+2>>1]|0)}t=t+1|0;if((t|0)==2)break;else v=v+16|0}}z=z+1|0;if((z|0)==2)break;else A=A+e|0}n=H+n|0;if((n|0)==(E|0))break;else D=D+G|0}}J=J+1|0;if((J|0)==(l|0))break;else I=I+Y|0}}K=K+1|0}while((K|0)!=(T|0));u=ka;return 1}function Ta(a){a=a|0;var b=0,c=0,d=0,e=0,g=0,h=0,i=0,j=0;if(!a)return;c=a+-8|0;e=f[1148]|0;a=f[a+-4>>2]|0;b=a&-8;j=c+b|0;do if(!(a&1)){d=f[c>>2]|0;if(!(a&3))return;h=c+(0-d)|0;g=d+b|0;if(h>>>0>>0)return;if((h|0)==(f[1149]|0)){a=j+4|0;b=f[a>>2]|0;if((b&3|0)!=3){i=h;b=g;break}f[1146]=g;f[a>>2]=b&-2;f[h+4>>2]=g|1;f[h+g>>2]=g;return}c=d>>>3;if(d>>>0<256){a=f[h+8>>2]|0;b=f[h+12>>2]|0;if((b|0)==(a|0)){f[1144]=f[1144]&~(1<>2]=b;f[b+8>>2]=a;i=h;b=g;break}}e=f[h+24>>2]|0;a=f[h+12>>2]|0;do if((a|0)==(h|0)){c=h+16|0;b=c+4|0;a=f[b>>2]|0;if(!a){a=f[c>>2]|0;if(!a){a=0;break}else b=c}while(1){c=a+20|0;d=f[c>>2]|0;if(d|0){a=d;b=c;continue}c=a+16|0;d=f[c>>2]|0;if(!d)break;else{a=d;b=c}}f[b>>2]=0}else{i=f[h+8>>2]|0;f[i+12>>2]=a;f[a+8>>2]=i}while(0);if(e){b=f[h+28>>2]|0;c=4880+(b<<2)|0;if((h|0)==(f[c>>2]|0)){f[c>>2]=a;if(!a){f[1145]=f[1145]&~(1<>2]|0)!=(h|0)&1)<<2)>>2]=a;if(!a){i=h;b=g;break}}f[a+24>>2]=e;b=h+16|0;c=f[b>>2]|0;if(c|0){f[a+16>>2]=c;f[c+24>>2]=a}b=f[b+4>>2]|0;if(b){f[a+20>>2]=b;f[b+24>>2]=a;i=h;b=g}else{i=h;b=g}}else{i=h;b=g}}else{i=c;h=c}while(0);if(h>>>0>=j>>>0)return;a=j+4|0;d=f[a>>2]|0;if(!(d&1))return;if(!(d&2)){a=f[1149]|0;if((j|0)==(f[1150]|0)){j=(f[1147]|0)+b|0;f[1147]=j;f[1150]=i;f[i+4>>2]=j|1;if((i|0)!=(a|0))return;f[1149]=0;f[1146]=0;return}if((j|0)==(a|0)){j=(f[1146]|0)+b|0;f[1146]=j;f[1149]=h;f[i+4>>2]=j|1;f[h+j>>2]=j;return}e=(d&-8)+b|0;c=d>>>3;do if(d>>>0<256){b=f[j+8>>2]|0;a=f[j+12>>2]|0;if((a|0)==(b|0)){f[1144]=f[1144]&~(1<>2]=a;f[a+8>>2]=b;break}}else{g=f[j+24>>2]|0;a=f[j+12>>2]|0;do if((a|0)==(j|0)){c=j+16|0;b=c+4|0;a=f[b>>2]|0;if(!a){a=f[c>>2]|0;if(!a){c=0;break}else b=c}while(1){c=a+20|0;d=f[c>>2]|0;if(d|0){a=d;b=c;continue}c=a+16|0;d=f[c>>2]|0;if(!d)break;else{a=d;b=c}}f[b>>2]=0;c=a}else{c=f[j+8>>2]|0;f[c+12>>2]=a;f[a+8>>2]=c;c=a}while(0);if(g|0){a=f[j+28>>2]|0;b=4880+(a<<2)|0;if((j|0)==(f[b>>2]|0)){f[b>>2]=c;if(!c){f[1145]=f[1145]&~(1<>2]|0)!=(j|0)&1)<<2)>>2]=c;if(!c)break}f[c+24>>2]=g;a=j+16|0;b=f[a>>2]|0;if(b|0){f[c+16>>2]=b;f[b+24>>2]=c}a=f[a+4>>2]|0;if(a|0){f[c+20>>2]=a;f[a+24>>2]=c}}}while(0);f[i+4>>2]=e|1;f[h+e>>2]=e;if((i|0)==(f[1149]|0)){f[1146]=e;return}}else{f[a>>2]=d&-2;f[i+4>>2]=b|1;f[h+b>>2]=b;e=b}a=e>>>3;if(e>>>0<256){c=4616+(a<<1<<2)|0;b=f[1144]|0;a=1<>2]|0}f[b>>2]=i;f[a+12>>2]=i;f[i+8>>2]=a;f[i+12>>2]=c;return}a=e>>>8;if(a)if(e>>>0>16777215)a=31;else{h=(a+1048320|0)>>>16&8;j=a<>>16&4;j=j<>>16&2;a=14-(g|h|a)+(j<>>15)|0;a=e>>>(a+7|0)&1|a<<1}else a=0;d=4880+(a<<2)|0;f[i+28>>2]=a;f[i+20>>2]=0;f[i+16>>2]=0;b=f[1145]|0;c=1<>>1)|0);c=f[d>>2]|0;while(1){if((f[c+4>>2]&-8|0)==(e|0)){a=73;break}d=c+16+(b>>>31<<2)|0;a=f[d>>2]|0;if(!a){a=72;break}else{b=b<<1;c=a}}if((a|0)==72){f[d>>2]=i;f[i+24>>2]=c;f[i+12>>2]=i;f[i+8>>2]=i;break}else if((a|0)==73){h=c+8|0;j=f[h>>2]|0;f[j+12>>2]=i;f[h>>2]=i;f[i+8>>2]=j;f[i+12>>2]=c;f[i+24>>2]=0;break}}else{f[1145]=b|c;f[d>>2]=i;f[i+24>>2]=d;f[i+12>>2]=i;f[i+8>>2]=i}while(0);j=(f[1152]|0)+-1|0;f[1152]=j;if(!j)a=5032;else return;while(1){a=f[a>>2]|0;if(!a)break;else a=a+8|0}f[1152]=-1;return}function Ua(a,c,d,e,g,i,k,l){a=a|0;c=c|0;d=d|0;e=e|0;g=g|0;i=i|0;k=k|0;l=l|0;var m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,_=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,ka=0,la=0,ma=0,na=0,oa=0,pa=0;pa=u;u=u+640|0;ma=pa+80|0;la=pa+64|0;ka=pa+48|0;oa=pa+32|0;na=pa+16|0;ja=pa;ha=pa+128|0;ia=pa+112|0;N=pa+96|0;O=a+240|0;P=f[O>>2]|0;Q=a+256|0;R=f[Q>>2]|0;S=a+272|0;T=f[S>>2]|0;ga=f[a+88>>2]|0;U=(h[ga+63>>0]|0)<<8|(h[ga+64>>0]|0);ga=b[ga+17>>0]|0;V=ga&255;if(!(ga<<24>>24)){u=pa;return 1}W=(l|0)==0;X=k+-1|0;Y=X<<5;Z=l+-1|0;_=e<<1;$=a+92|0;aa=a+116|0;ba=a+164|0;ca=a+268|0;da=a+140|0;ea=a+236|0;fa=a+212|0;ga=a+188|0;M=(g&1|0)==0;L=(i&1|0)==0;J=a+288|0;K=a+284|0;I=a+252|0;H=0;a=0;i=0;g=0;d=0;m=1;do{if(!W){F=f[c+(H<<2)>>2]|0;G=0;while(1){E=G&1;o=(E|0)==0;D=(E<<6^64)+-32|0;E=(E<<1^2)+-1|0;B=o?k:-1;n=o?0:X;if((n|0)!=(B|0)){C=L|(G|0)!=(Z|0);A=o?F:F+Y|0;while(1){if((m|0)==1)m=bb($,aa)|0|512;z=m&7;m=m>>>3;p=h[1539+z>>0]|0;o=0;do{w=(bb($,ba)|0)+i|0;x=w-T|0;y=x>>31;i=y&w|x&~y;if((f[S>>2]|0)>>>0<=i>>>0){f[ja>>2]=866;f[ja+4>>2]=910;f[ja+8>>2]=1497;vc(ha,812,ja)|0;Ub(ha)|0}f[N+(o<<2)>>2]=j[(f[ca>>2]|0)+(i<<1)>>1];o=o+1|0}while(o>>>0

    >>0);o=0;do{w=(bb($,da)|0)+d|0;x=w-P|0;y=x>>31;d=y&w|x&~y;if((f[O>>2]|0)>>>0<=d>>>0){f[na>>2]=866;f[na+4>>2]=910;f[na+8>>2]=1497;vc(ha,812,na)|0;Ub(ha)|0}f[ia+(o<<2)>>2]=f[(f[ea>>2]|0)+(d<<2)>>2];o=o+1|0}while(o>>>0

    >>0);y=M|(n|0)!=(X|0);w=0;x=A;while(1){s=C|(w|0)==0;t=w<<1;if(y){q=0;r=x;while(1){v=(bb($,fa)|0)+a|0;p=v-U|0;a=p>>31;a=a&v|p&~a;p=(bb($,ga)|0)+g|0;v=p-R|0;g=v>>31;g=g&p|v&~g;if(s){o=h[q+t+(1547+(z<<2))>>0]|0;p=a*3|0;if((f[J>>2]|0)>>>0<=p>>>0){f[oa>>2]=866;f[oa+4>>2]=910;f[oa+8>>2]=1497;vc(ha,812,oa)|0;Ub(ha)|0}v=(f[K>>2]|0)+(p<<1)|0;f[r>>2]=(j[v>>1]|0)<<16|f[N+(o<<2)>>2];f[r+4>>2]=(j[v+4>>1]|0)<<16|(j[v+2>>1]|0);f[r+8>>2]=f[ia+(o<<2)>>2];if((f[Q>>2]|0)>>>0<=g>>>0){f[ka>>2]=866;f[ka+4>>2]=910;f[ka+8>>2]=1497;vc(ha,812,ka)|0;Ub(ha)|0}f[r+12>>2]=f[(f[I>>2]|0)+(g<<2)>>2]}q=q+1|0;if((q|0)==2)break;else r=r+16|0}}else{v=s^1;s=1547+(z<<2)+t|0;q=0;r=x;while(1){t=(bb($,fa)|0)+a|0;p=t-U|0;a=p>>31;a=a&t|p&~a;p=(bb($,ga)|0)+g|0;t=p-R|0;g=t>>31;g=g&p|t&~g;if(!((q|0)!=0|v)){o=h[s>>0]|0;p=a*3|0;if((f[J>>2]|0)>>>0<=p>>>0){f[la>>2]=866;f[la+4>>2]=910;f[la+8>>2]=1497;vc(ha,812,la)|0;Ub(ha)|0}t=(f[K>>2]|0)+(p<<1)|0;f[r>>2]=(j[t>>1]|0)<<16|f[N+(o<<2)>>2];f[r+4>>2]=(j[t+4>>1]|0)<<16|(j[t+2>>1]|0);f[r+8>>2]=f[ia+(o<<2)>>2];if((f[Q>>2]|0)>>>0<=g>>>0){f[ma>>2]=866;f[ma+4>>2]=910;f[ma+8>>2]=1497;vc(ha,812,ma)|0;Ub(ha)|0}f[r+12>>2]=f[(f[I>>2]|0)+(g<<2)>>2]}q=q+1|0;if((q|0)==2)break;else r=r+16|0}}w=w+1|0;if((w|0)==2)break;else x=x+e|0}n=E+n|0;if((n|0)==(B|0))break;else A=A+D|0}}G=G+1|0;if((G|0)==(l|0))break;else F=F+_|0}}H=H+1|0}while((H|0)!=(V|0));u=pa;return 1}function Va(a,b){a=a|0;b=b|0;var c=0,d=0,e=0,g=0,h=0,i=0,j=0;j=a+b|0;c=f[a+4>>2]|0;do if(!(c&1)){d=f[a>>2]|0;if(!(c&3))return;g=a+(0-d)|0;h=d+b|0;if((g|0)==(f[1149]|0)){a=j+4|0;c=f[a>>2]|0;if((c&3|0)!=3){i=g;c=h;break}f[1146]=h;f[a>>2]=c&-2;f[g+4>>2]=h|1;f[g+h>>2]=h;return}b=d>>>3;if(d>>>0<256){a=f[g+8>>2]|0;c=f[g+12>>2]|0;if((c|0)==(a|0)){f[1144]=f[1144]&~(1<>2]=c;f[c+8>>2]=a;i=g;c=h;break}}e=f[g+24>>2]|0;a=f[g+12>>2]|0;do if((a|0)==(g|0)){b=g+16|0;c=b+4|0;a=f[c>>2]|0;if(!a){a=f[b>>2]|0;if(!a){a=0;break}else c=b}while(1){b=a+20|0;d=f[b>>2]|0;if(d|0){a=d;c=b;continue}b=a+16|0;d=f[b>>2]|0;if(!d)break;else{a=d;c=b}}f[c>>2]=0}else{i=f[g+8>>2]|0;f[i+12>>2]=a;f[a+8>>2]=i}while(0);if(e){c=f[g+28>>2]|0;b=4880+(c<<2)|0;if((g|0)==(f[b>>2]|0)){f[b>>2]=a;if(!a){f[1145]=f[1145]&~(1<>2]|0)!=(g|0)&1)<<2)>>2]=a;if(!a){i=g;c=h;break}}f[a+24>>2]=e;c=g+16|0;b=f[c>>2]|0;if(b|0){f[a+16>>2]=b;f[b+24>>2]=a}c=f[c+4>>2]|0;if(c){f[a+20>>2]=c;f[c+24>>2]=a;i=g;c=h}else{i=g;c=h}}else{i=g;c=h}}else{i=a;c=b}while(0);a=j+4|0;d=f[a>>2]|0;if(!(d&2)){a=f[1149]|0;if((j|0)==(f[1150]|0)){j=(f[1147]|0)+c|0;f[1147]=j;f[1150]=i;f[i+4>>2]=j|1;if((i|0)!=(a|0))return;f[1149]=0;f[1146]=0;return}if((j|0)==(a|0)){j=(f[1146]|0)+c|0;f[1146]=j;f[1149]=i;f[i+4>>2]=j|1;f[i+j>>2]=j;return}g=(d&-8)+c|0;b=d>>>3;do if(d>>>0<256){c=f[j+8>>2]|0;a=f[j+12>>2]|0;if((a|0)==(c|0)){f[1144]=f[1144]&~(1<>2]=a;f[a+8>>2]=c;break}}else{e=f[j+24>>2]|0;a=f[j+12>>2]|0;do if((a|0)==(j|0)){b=j+16|0;c=b+4|0;a=f[c>>2]|0;if(!a){a=f[b>>2]|0;if(!a){b=0;break}else c=b}while(1){b=a+20|0;d=f[b>>2]|0;if(d|0){a=d;c=b;continue}b=a+16|0;d=f[b>>2]|0;if(!d)break;else{a=d;c=b}}f[c>>2]=0;b=a}else{b=f[j+8>>2]|0;f[b+12>>2]=a;f[a+8>>2]=b;b=a}while(0);if(e|0){a=f[j+28>>2]|0;c=4880+(a<<2)|0;if((j|0)==(f[c>>2]|0)){f[c>>2]=b;if(!b){f[1145]=f[1145]&~(1<>2]|0)!=(j|0)&1)<<2)>>2]=b;if(!b)break}f[b+24>>2]=e;a=j+16|0;c=f[a>>2]|0;if(c|0){f[b+16>>2]=c;f[c+24>>2]=b}a=f[a+4>>2]|0;if(a|0){f[b+20>>2]=a;f[a+24>>2]=b}}}while(0);f[i+4>>2]=g|1;f[i+g>>2]=g;if((i|0)==(f[1149]|0)){f[1146]=g;return}else c=g}else{f[a>>2]=d&-2;f[i+4>>2]=c|1;f[i+c>>2]=c}a=c>>>3;if(c>>>0<256){b=4616+(a<<1<<2)|0;c=f[1144]|0;a=1<>2]|0}f[c>>2]=i;f[a+12>>2]=i;f[i+8>>2]=a;f[i+12>>2]=b;return}a=c>>>8;if(a)if(c>>>0>16777215)a=31;else{h=(a+1048320|0)>>>16&8;j=a<>>16&4;j=j<>>16&2;a=14-(g|h|a)+(j<>>15)|0;a=c>>>(a+7|0)&1|a<<1}else a=0;e=4880+(a<<2)|0;f[i+28>>2]=a;f[i+20>>2]=0;f[i+16>>2]=0;b=f[1145]|0;d=1<>2]=i;f[i+24>>2]=e;f[i+12>>2]=i;f[i+8>>2]=i;return}b=c<<((a|0)==31?0:25-(a>>>1)|0);d=f[e>>2]|0;while(1){if((f[d+4>>2]&-8|0)==(c|0)){a=69;break}e=d+16+(b>>>31<<2)|0;a=f[e>>2]|0;if(!a){a=68;break}else{b=b<<1;d=a}}if((a|0)==68){f[e>>2]=i;f[i+24>>2]=d;f[i+12>>2]=i;f[i+8>>2]=i;return}else if((a|0)==69){h=d+8|0;j=f[h>>2]|0;f[j+12>>2]=i;f[h>>2]=i;f[i+8>>2]=j;f[i+12>>2]=d;f[i+24>>2]=0;return}}function Wa(a){a=a|0;var c=0,e=0,g=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0;S=u;u=u+2416|0;k=S;j=S+1904|0;R=S+1880|0;O=S+980|0;P=S+80|0;Q=S+16|0;e=f[a+88>>2]|0;M=(h[e+63>>0]|0)<<8|(h[e+64>>0]|0);N=a+92|0;c=(f[a+4>>2]|0)+((h[e+58>>0]|0)<<8|(h[e+57>>0]|0)<<16|(h[e+59>>0]|0))|0;e=(h[e+61>>0]|0)<<8|(h[e+60>>0]|0)<<16|(h[e+62>>0]|0);if(!e){R=0;u=S;return R|0}f[N>>2]=c;f[a+96>>2]=c;f[a+104>>2]=e;f[a+100>>2]=c+e;f[a+108>>2]=0;f[a+112>>2]=0;f[R+20>>2]=0;f[R>>2]=0;f[R+4>>2]=0;f[R+8>>2]=0;f[R+12>>2]=0;b[R+16>>0]=0;if(Pa(N,R)|0){c=0;e=-7;g=-7;while(1){f[O+(c<<2)>>2]=g;f[P+(c<<2)>>2]=e;i=(g|0)>6;c=c+1|0;if((c|0)==225)break;else{e=(i&1)+e|0;g=i?-7:g+1|0}}c=Q;e=c+64|0;do{f[c>>2]=0;c=c+4|0}while((c|0)<(e|0));i=a+284|0;e=M*3|0;g=a+288|0;c=f[g>>2]|0;a:do if((c|0)==(e|0))l=13;else{if(c>>>0<=e>>>0){do if((f[a+292>>2]|0)>>>0>>0)if(fb(i,e,(c+1|0)==(e|0),2,0)|0){c=f[g>>2]|0;break}else{b[a+296>>0]=1;c=0;break a}while(0);Ib((f[i>>2]|0)+(c<<1)|0,0,e-c<<1|0)|0}f[g>>2]=e;l=13}while(0);do if((l|0)==13){if(!M){f[k>>2]=866;f[k+4>>2]=910;f[k+8>>2]=1497;vc(j,812,k)|0;Ub(j)|0;c=1;break}x=Q+4|0;y=Q+8|0;z=Q+12|0;A=Q+16|0;B=Q+20|0;C=Q+24|0;D=Q+28|0;E=Q+32|0;F=Q+36|0;G=Q+40|0;H=Q+44|0;I=Q+48|0;J=Q+52|0;K=Q+56|0;L=Q+60|0;w=0;c=f[i>>2]|0;e=f[Q>>2]|0;g=f[x>>2]|0;i=f[y>>2]|0;a=f[z>>2]|0;j=f[A>>2]|0;k=f[B>>2]|0;l=f[C>>2]|0;m=f[D>>2]|0;n=f[E>>2]|0;o=f[F>>2]|0;p=f[G>>2]|0;q=f[H>>2]|0;r=0;s=0;t=0;v=0;while(1){U=bb(N,R)|0;e=e+(f[O+(U<<2)>>2]|0)&7;g=g+(f[P+(U<<2)>>2]|0)&7;U=bb(N,R)|0;i=i+(f[O+(U<<2)>>2]|0)&7;a=a+(f[P+(U<<2)>>2]|0)&7;U=bb(N,R)|0;j=j+(f[O+(U<<2)>>2]|0)&7;k=k+(f[P+(U<<2)>>2]|0)&7;U=bb(N,R)|0;l=l+(f[O+(U<<2)>>2]|0)&7;m=m+(f[P+(U<<2)>>2]|0)&7;U=bb(N,R)|0;n=n+(f[O+(U<<2)>>2]|0)&7;o=o+(f[P+(U<<2)>>2]|0)&7;U=bb(N,R)|0;p=p+(f[O+(U<<2)>>2]|0)&7;q=q+(f[P+(U<<2)>>2]|0)&7;U=bb(N,R)|0;r=r+(f[O+(U<<2)>>2]|0)&7;s=s+(f[P+(U<<2)>>2]|0)&7;U=bb(N,R)|0;t=t+(f[O+(U<<2)>>2]|0)&7;v=v+(f[P+(U<<2)>>2]|0)&7;U=h[1445+k>>0]|0;d[c>>1]=(h[1445+g>>0]|0)<<3|(h[1445+e>>0]|0)|(h[1445+i>>0]|0)<<6|(h[1445+a>>0]|0)<<9|(h[1445+j>>0]|0)<<12|U<<15;T=h[1445+p>>0]|0;d[c+2>>1]=(h[1445+l>>0]|0)<<2|U>>>1|(h[1445+m>>0]|0)<<5|(h[1445+n>>0]|0)<<8|(h[1445+o>>0]|0)<<11|T<<14;d[c+4>>1]=(h[1445+q>>0]|0)<<1|T>>>2|(h[1445+r>>0]|0)<<4|(h[1445+s>>0]|0)<<7|(h[1445+t>>0]|0)<<10|(h[1445+v>>0]|0)<<13;w=w+1|0;if(w>>>0>=M>>>0)break;else c=c+6|0}f[Q>>2]=e;f[x>>2]=g;f[y>>2]=i;f[z>>2]=a;f[A>>2]=j;f[B>>2]=k;f[C>>2]=l;f[D>>2]=m;f[E>>2]=n;f[F>>2]=o;f[G>>2]=p;f[H>>2]=q;f[I>>2]=r;f[J>>2]=s;f[K>>2]=t;f[L>>2]=v;c=1}while(0)}else c=0;Cb(R);U=c;u=S;return U|0}function Xa(a){a=a|0;var c=0,d=0,e=0,g=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0;D=u;u=u+1008|0;j=D;i=D+496|0;C=D+472|0;z=D+276|0;A=D+80|0;B=D+16|0;d=f[a+88>>2]|0;x=(h[d+47>>0]|0)<<8|(h[d+48>>0]|0);y=a+92|0;c=(f[a+4>>2]|0)+((h[d+42>>0]|0)<<8|(h[d+41>>0]|0)<<16|(h[d+43>>0]|0))|0;d=(h[d+45>>0]|0)<<8|(h[d+44>>0]|0)<<16|(h[d+46>>0]|0);if(!d){C=0;u=D;return C|0}f[y>>2]=c;f[a+96>>2]=c;f[a+104>>2]=d;f[a+100>>2]=c+d;f[a+108>>2]=0;f[a+112>>2]=0;f[C+20>>2]=0;f[C>>2]=0;f[C+4>>2]=0;f[C+8>>2]=0;f[C+12>>2]=0;b[C+16>>0]=0;if(Pa(y,C)|0){c=0;d=-3;e=-3;while(1){f[z+(c<<2)>>2]=e;f[A+(c<<2)>>2]=d;g=(e|0)>2;c=c+1|0;if((c|0)==49)break;else{d=(g&1)+d|0;e=g?-3:e+1|0}}c=B;d=c+64|0;do{f[c>>2]=0;c=c+4|0}while((c|0)<(d|0));e=a+252|0;d=a+256|0;c=f[d>>2]|0;a:do if((c|0)==(x|0))k=13;else{if(c>>>0<=x>>>0){do if((f[a+260>>2]|0)>>>0>>0)if(fb(e,x,(c+1|0)==(x|0),4,0)|0){c=f[d>>2]|0;break}else{b[a+264>>0]=1;c=0;break a}while(0);Ib((f[e>>2]|0)+(c<<2)|0,0,x-c<<2|0)|0}f[d>>2]=x;k=13}while(0);do if((k|0)==13){if(!x){f[j>>2]=866;f[j+4>>2]=910;f[j+8>>2]=1497;vc(i,812,j)|0;Ub(i)|0;c=1;break}a=B+4|0;i=B+8|0;j=B+12|0;k=B+16|0;l=B+20|0;m=B+24|0;n=B+28|0;o=B+32|0;p=B+36|0;q=B+40|0;r=B+44|0;s=B+48|0;t=B+52|0;v=B+56|0;w=B+60|0;g=0;c=f[e>>2]|0;d=f[a>>2]|0;e=f[B>>2]|0;while(1){Q=bb(y,C)|0;e=e+(f[z+(Q<<2)>>2]|0)&3;d=d+(f[A+(Q<<2)>>2]|0)&3;Q=bb(y,C)|0;R=(f[i>>2]|0)+(f[z+(Q<<2)>>2]|0)&3;f[i>>2]=R;Q=(f[j>>2]|0)+(f[A+(Q<<2)>>2]|0)&3;f[j>>2]=Q;O=bb(y,C)|0;P=(f[k>>2]|0)+(f[z+(O<<2)>>2]|0)&3;f[k>>2]=P;O=(f[l>>2]|0)+(f[A+(O<<2)>>2]|0)&3;f[l>>2]=O;M=bb(y,C)|0;N=(f[m>>2]|0)+(f[z+(M<<2)>>2]|0)&3;f[m>>2]=N;M=(f[n>>2]|0)+(f[A+(M<<2)>>2]|0)&3;f[n>>2]=M;K=bb(y,C)|0;L=(f[o>>2]|0)+(f[z+(K<<2)>>2]|0)&3;f[o>>2]=L;K=(f[p>>2]|0)+(f[A+(K<<2)>>2]|0)&3;f[p>>2]=K;I=bb(y,C)|0;J=(f[q>>2]|0)+(f[z+(I<<2)>>2]|0)&3;f[q>>2]=J;I=(f[r>>2]|0)+(f[A+(I<<2)>>2]|0)&3;f[r>>2]=I;G=bb(y,C)|0;H=(f[s>>2]|0)+(f[z+(G<<2)>>2]|0)&3;f[s>>2]=H;G=(f[t>>2]|0)+(f[A+(G<<2)>>2]|0)&3;f[t>>2]=G;E=bb(y,C)|0;F=(f[v>>2]|0)+(f[z+(E<<2)>>2]|0)&3;f[v>>2]=F;E=(f[w>>2]|0)+(f[A+(E<<2)>>2]|0)&3;f[w>>2]=E;f[c>>2]=(h[1441+d>>0]|0)<<2|(h[1441+e>>0]|0)|(h[1441+R>>0]|0)<<4|(h[1441+Q>>0]|0)<<6|(h[1441+P>>0]|0)<<8|(h[1441+O>>0]|0)<<10|(h[1441+N>>0]|0)<<12|(h[1441+M>>0]|0)<<14|(h[1441+L>>0]|0)<<16|(h[1441+K>>0]|0)<<18|(h[1441+J>>0]|0)<<20|(h[1441+I>>0]|0)<<22|(h[1441+H>>0]|0)<<24|(h[1441+G>>0]|0)<<26|(h[1441+F>>0]|0)<<28|(h[1441+E>>0]|0)<<30;g=g+1|0;if(g>>>0>=x>>>0)break;else c=c+4|0}f[B>>2]=e;f[a>>2]=d;c=1}while(0)}else c=0;Cb(C);R=c;u=D;return R|0}function Ya(a,c,d,e,g,i,k,l){a=a|0;c=c|0;d=d|0;e=e|0;g=g|0;i=i|0;k=k|0;l=l|0;var m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,_=0,$=0,aa=0;aa=u;u=u+592|0;Z=aa+48|0;$=aa+32|0;_=aa+16|0;Y=aa;W=aa+80|0;X=aa+64|0;I=a+272|0;J=f[I>>2]|0;V=f[a+88>>2]|0;K=(h[V+63>>0]|0)<<8|(h[V+64>>0]|0);V=b[V+17>>0]|0;L=V&255;if(!(V<<24>>24)){u=aa;return 1}M=(l|0)==0;N=k+-1|0;O=N<<4;P=l+-1|0;Q=e<<1;R=a+92|0;S=a+116|0;T=a+164|0;U=a+268|0;V=a+212|0;H=(g&1|0)==0;G=(i&1|0)==0;F=a+288|0;E=a+284|0;D=0;g=0;d=0;i=1;do{if(!M){B=f[c+(D<<2)>>2]|0;C=0;while(1){A=C&1;m=(A|0)==0;z=(A<<5^32)+-16|0;A=(A<<1^2)+-1|0;x=m?k:-1;a=m?0:N;if((a|0)!=(x|0)){y=G|(C|0)!=(P|0);w=m?B:B+O|0;while(1){if((i|0)==1)i=bb(R,S)|0|512;v=i&7;i=i>>>3;n=h[1539+v>>0]|0;m=0;do{r=(bb(R,T)|0)+d|0;s=r-J|0;t=s>>31;d=t&r|s&~t;if((f[I>>2]|0)>>>0<=d>>>0){f[Y>>2]=866;f[Y+4>>2]=910;f[Y+8>>2]=1497;vc(W,812,Y)|0;Ub(W)|0}f[X+(m<<2)>>2]=j[(f[U>>2]|0)+(d<<1)>>1];m=m+1|0}while(m>>>0>>0);t=H|(a|0)!=(N|0);r=0;s=w;while(1){q=y|(r|0)==0;n=r<<1;m=(bb(R,V)|0)+g|0;o=m-K|0;p=o>>31;p=p&m|o&~p;if(t){if(q){g=h[1547+(v<<2)+n>>0]|0;m=p*3|0;if((f[F>>2]|0)>>>0<=m>>>0){f[_>>2]=866;f[_+4>>2]=910;f[_+8>>2]=1497;vc(W,812,_)|0;Ub(W)|0}o=(f[E>>2]|0)+(m<<1)|0;f[s>>2]=(j[o>>1]|0)<<16|f[X+(g<<2)>>2];f[s+4>>2]=(j[o+4>>1]|0)<<16|(j[o+2>>1]|0)}o=s+8|0;m=(bb(R,V)|0)+p|0;p=m-K|0;g=p>>31;g=g&m|p&~g;if(q){m=h[(n|1)+(1547+(v<<2))>>0]|0;n=g*3|0;if((f[F>>2]|0)>>>0<=n>>>0){f[Z>>2]=866;f[Z+4>>2]=910;f[Z+8>>2]=1497;vc(W,812,Z)|0;Ub(W)|0}q=(f[E>>2]|0)+(n<<1)|0;f[o>>2]=(j[q>>1]|0)<<16|f[X+(m<<2)>>2];f[s+12>>2]=(j[q+4>>1]|0)<<16|(j[q+2>>1]|0)}}else{if(q){g=h[1547+(v<<2)+n>>0]|0;m=p*3|0;if((f[F>>2]|0)>>>0<=m>>>0){f[$>>2]=866;f[$+4>>2]=910;f[$+8>>2]=1497;vc(W,812,$)|0;Ub(W)|0}q=(f[E>>2]|0)+(m<<1)|0;f[s>>2]=(j[q>>1]|0)<<16|f[X+(g<<2)>>2];f[s+4>>2]=(j[q+4>>1]|0)<<16|(j[q+2>>1]|0)}p=(bb(R,V)|0)+p|0;q=p-K|0;g=q>>31;g=g&p|q&~g}r=r+1|0;if((r|0)==2)break;else s=s+e|0}a=A+a|0;if((a|0)==(x|0))break;else w=w+z|0}}C=C+1|0;if((C|0)==(l|0))break;else B=B+Q|0}}D=D+1|0}while((D|0)!=(L|0));u=aa;return 1}function Za(a,b,c,d,e){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;l=a;j=b;k=j;h=c;n=d;i=n;if(!k){g=(e|0)!=0;if(!i){if(g){f[e>>2]=(l>>>0)%(h>>>0);f[e+4>>2]=0}n=0;e=(l>>>0)/(h>>>0)>>>0;return (I=n,e)|0}else{if(!g){n=0;e=0;return (I=n,e)|0}f[e>>2]=a|0;f[e+4>>2]=b&0;n=0;e=0;return (I=n,e)|0}}g=(i|0)==0;do if(h){if(!g){g=(_(i|0)|0)-(_(k|0)|0)|0;if(g>>>0<=31){m=g+1|0;i=31-g|0;b=g-31>>31;h=m;a=l>>>(m>>>0)&b|k<>>(m>>>0)&b;g=0;i=l<>2]=a|0;f[e+4>>2]=j|b&0;n=0;e=0;return (I=n,e)|0}g=h-1|0;if(g&h|0){i=(_(h|0)|0)+33-(_(k|0)|0)|0;p=64-i|0;m=32-i|0;j=m>>31;o=i-32|0;b=o>>31;h=i;a=m-1>>31&k>>>(o>>>0)|(k<>>(i>>>0))&b;b=b&k>>>(i>>>0);g=l<>>(o>>>0))&j|l<>31;break}if(e|0){f[e>>2]=g&l;f[e+4>>2]=0}if((h|0)==1){o=j|b&0;p=a|0|0;return (I=o,p)|0}else{p=ic(h|0)|0;o=k>>>(p>>>0)|0;p=k<<32-p|l>>>(p>>>0)|0;return (I=o,p)|0}}else{if(g){if(e|0){f[e>>2]=(k>>>0)%(h>>>0);f[e+4>>2]=0}o=0;p=(k>>>0)/(h>>>0)>>>0;return (I=o,p)|0}if(!l){if(e|0){f[e>>2]=0;f[e+4>>2]=(k>>>0)%(i>>>0)}o=0;p=(k>>>0)/(i>>>0)>>>0;return (I=o,p)|0}g=i-1|0;if(!(g&i)){if(e|0){f[e>>2]=a|0;f[e+4>>2]=g&k|b&0}o=0;p=k>>>((ic(i|0)|0)>>>0);return (I=o,p)|0}g=(_(i|0)|0)-(_(k|0)|0)|0;if(g>>>0<=30){b=g+1|0;i=31-g|0;h=b;a=k<>>(b>>>0);b=k>>>(b>>>0);g=0;i=l<>2]=a|0;f[e+4>>2]=j|b&0;o=0;p=0;return (I=o,p)|0}while(0);if(!h){k=i;j=0;i=0}else{m=c|0|0;l=n|d&0;k=Gc(m|0,l|0,-1,-1)|0;c=I;j=i;i=0;do{d=j;j=g>>>31|j<<1;g=i|g<<1;d=a<<1|d>>>31|0;n=a>>>31|b<<1|0;Cc(k|0,c|0,d|0,n|0)|0;p=I;o=p>>31|((p|0)<0?-1:0)<<1;i=o&1;a=Cc(d|0,n|0,o&m|0,(((p|0)<0?-1:0)>>31|((p|0)<0?-1:0)<<1)&l|0)|0;b=I;h=h-1|0}while((h|0)!=0);k=j;j=0}h=0;if(e|0){f[e>>2]=a;f[e+4>>2]=b}o=(g|0)>>>31|(k|h)<<1|(h<<1|g>>>31)&0|j;p=(g<<1|0>>>31)&-2|i;return (I=o,p)|0}function _a(a,b){a=a|0;b=b|0;var c=0,d=0,e=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0;m=a+4|0;l=f[m>>2]|0;c=l&-8;i=a+c|0;if(!(l&3)){if(b>>>0<256){a=0;return a|0}if(c>>>0>=(b+4|0)>>>0?(c-b|0)>>>0<=f[1264]<<1>>>0:0)return a|0;a=0;return a|0}if(c>>>0>=b>>>0){c=c-b|0;if(c>>>0<=15)return a|0;k=a+b|0;f[m>>2]=l&1|b|2;f[k+4>>2]=c|3;m=k+c+4|0;f[m>>2]=f[m>>2]|1;Va(k,c);return a|0}if((i|0)==(f[1150]|0)){k=(f[1147]|0)+c|0;c=k-b|0;d=a+b|0;if(k>>>0<=b>>>0){a=0;return a|0}f[m>>2]=l&1|b|2;f[d+4>>2]=c|1;f[1150]=d;f[1147]=c;return a|0}if((i|0)==(f[1149]|0)){e=(f[1146]|0)+c|0;if(e>>>0>>0){a=0;return a|0}c=e-b|0;d=l&1;if(c>>>0>15){l=a+b|0;k=l+c|0;f[m>>2]=d|b|2;f[l+4>>2]=c|1;f[k>>2]=c;d=k+4|0;f[d>>2]=f[d>>2]&-2;d=l}else{f[m>>2]=d|e|2;d=a+e+4|0;f[d>>2]=f[d>>2]|1;d=0;c=0}f[1146]=c;f[1149]=d;return a|0}d=f[i+4>>2]|0;if(d&2|0){a=0;return a|0}j=(d&-8)+c|0;if(j>>>0>>0){a=0;return a|0}k=j-b|0;e=d>>>3;do if(d>>>0<256){d=f[i+8>>2]|0;c=f[i+12>>2]|0;if((c|0)==(d|0)){f[1144]=f[1144]&~(1<>2]=c;f[c+8>>2]=d;break}}else{h=f[i+24>>2]|0;c=f[i+12>>2]|0;do if((c|0)==(i|0)){e=i+16|0;d=e+4|0;c=f[d>>2]|0;if(!c){c=f[e>>2]|0;if(!c){e=0;break}else g=e}else g=d;while(1){e=c+20|0;d=f[e>>2]|0;if(d|0){c=d;g=e;continue}d=c+16|0;e=f[d>>2]|0;if(!e)break;else{c=e;g=d}}f[g>>2]=0;e=c}else{e=f[i+8>>2]|0;f[e+12>>2]=c;f[c+8>>2]=e;e=c}while(0);if(h|0){c=f[i+28>>2]|0;d=4880+(c<<2)|0;if((i|0)==(f[d>>2]|0)){f[d>>2]=e;if(!e){f[1145]=f[1145]&~(1<>2]|0)!=(i|0)&1)<<2)>>2]=e;if(!e)break}f[e+24>>2]=h;c=i+16|0;d=f[c>>2]|0;if(d|0){f[e+16>>2]=d;f[d+24>>2]=e}c=f[c+4>>2]|0;if(c|0){f[e+20>>2]=c;f[c+24>>2]=e}}}while(0);c=l&1;if(k>>>0<16){f[m>>2]=j|c|2;m=a+j+4|0;f[m>>2]=f[m>>2]|1;return a|0}else{l=a+b|0;f[m>>2]=c|b|2;f[l+4>>2]=k|3;m=l+k+4|0;f[m>>2]=f[m>>2]|1;Va(l,k);return a|0}return 0}function $a(a,b,c,d,e,g){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;g=g|0;var h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;p=u;u=u+592|0;o=p+56|0;j=p+40|0;m=p+72|0;l=p;n=p+68|0;f[l>>2]=40;tb(a,b,l)|0;h=(f[l+4>>2]|0)>>>e;i=(f[l+8>>2]|0)>>>e;l=l+32|0;d=f[l+4>>2]|0;do switch(f[l>>2]|0){case 0:{if(!d)l=8;else k=14;break}case 1:{if(!d)k=13;else k=14;break}case 2:{if(!d)k=13;else k=14;break}case 3:{if(!d)k=13;else k=14;break}case 4:{if(!d)k=13;else k=14;break}case 5:{if(!d)k=13;else k=14;break}case 6:{if(!d)k=13;else k=14;break}case 7:{if(!d)k=13;else k=14;break}case 8:{if(!d)k=13;else k=14;break}case 9:{if(!d)l=8;else k=14;break}case 10:{if(!d)l=8;else k=14;break}default:k=14}while(0);if((k|0)==13)l=16;else if((k|0)==14){f[j>>2]=866;f[j+4>>2]=2672;f[j+8>>2]=1251;vc(m,812,j)|0;Ub(m)|0;l=0}f[n>>2]=c;k=gb(a,b)|0;b=g+e|0;do if(b>>>0>e>>>0){if(!k){d=c;while(1){d=d+(X(X((h+3|0)>>>2,l)|0,(i+3|0)>>>2)|0)|0;e=e+1|0;if((e|0)==(b|0))break;else{i=i>>>1;h=h>>>1}}f[n>>2]=d;break}else{a=i;d=c}while(1){i=X((h+3|0)>>>2,l)|0;j=X(i,(a+3|0)>>>2)|0;if(!(e>>>0>15|j>>>0<8)?(f[k>>2]|0)==519686845:0){wb(k,n,j,i,e)|0;d=f[n>>2]|0}d=d+j|0;f[n>>2]=d;e=e+1|0;if((e|0)==(b|0))break;else{a=a>>>1;h=h>>>1}}}while(0);if(!k){u=p;return}if((f[k>>2]|0)!=519686845){u=p;return}cb(k);if(!(k&7)){Nb(k,0,0,1,0)|0;u=p;return}else{f[o>>2]=866;f[o+4>>2]=2506;f[o+8>>2]=1232;vc(m,812,o)|0;Ub(m)|0;u=p;return}}function ab(a){a=a|0;var c=0,d=0,e=0,g=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;q=u;u=u+576|0;j=q;g=q+64|0;p=q+16|0;e=a+88|0;c=f[e>>2]|0;o=(h[c+39>>0]|0)<<8|(h[c+40>>0]|0);m=a+236|0;i=a+240|0;d=f[i>>2]|0;if((d|0)!=(o|0)){if(d>>>0<=o>>>0){do if((f[a+244>>2]|0)>>>0>>0){if(fb(m,o,(d+1|0)==(o|0),4,0)|0){c=f[i>>2]|0;break}b[a+248>>0]=1;p=0;u=q;return p|0}else c=d;while(0);Ib((f[m>>2]|0)+(c<<2)|0,0,o-c<<2|0)|0;c=f[e>>2]|0}f[i>>2]=o}n=a+92|0;d=(f[a+4>>2]|0)+((h[c+34>>0]|0)<<8|(h[c+33>>0]|0)<<16|(h[c+35>>0]|0))|0;c=(h[c+37>>0]|0)<<8|(h[c+36>>0]|0)<<16|(h[c+38>>0]|0);if(!c){p=0;u=q;return p|0}f[n>>2]=d;f[a+96>>2]=d;f[a+104>>2]=c;f[a+100>>2]=d+c;f[a+108>>2]=0;f[a+112>>2]=0;k=p+20|0;f[p>>2]=0;f[p+4>>2]=0;f[p+8>>2]=0;f[p+12>>2]=0;b[p+16>>0]=0;l=p+24|0;f[p+44>>2]=0;f[k>>2]=0;f[k+4>>2]=0;f[k+8>>2]=0;f[k+12>>2]=0;f[k+16>>2]=0;b[k+20>>0]=0;if(Pa(n,p)|0?Pa(n,l)|0:0){if(!(f[i>>2]|0)){f[j>>2]=866;f[j+4>>2]=910;f[j+8>>2]=1497;vc(g,812,j)|0;Ub(g)|0}if(!o)c=1;else{j=0;k=0;d=f[m>>2]|0;e=0;a=0;c=0;g=0;i=0;while(1){j=(bb(n,p)|0)+j&31;i=(bb(n,l)|0)+i&63;g=(bb(n,p)|0)+g&31;c=(bb(n,p)|0)+c|0;a=(bb(n,l)|0)+a&63;e=(bb(n,p)|0)+e&31;f[d>>2]=i<<5|j<<11|g|c<<27|a<<21|e<<16;k=k+1|0;if(k>>>0>=o>>>0){c=1;break}else{d=d+4|0;c=c&31}}}}else c=0;Cb(p+24|0);Cb(p);p=c;u=q;return p|0}function bb(a,b){a=a|0;b=b|0;var c=0,d=0,e=0,g=0,i=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0;s=u;u=u+576|0;m=s+48|0;o=s+32|0;n=s+16|0;l=s;q=s+64|0;p=f[b+20>>2]|0;r=a+20|0;k=f[r>>2]|0;if((k|0)<24){i=a+4|0;c=f[i>>2]|0;e=f[a+8>>2]|0;d=c>>>0>>0;if((k|0)<16){if(d){g=(h[c>>0]|0)<<8;c=c+1|0}else g=0;if(c>>>0>>0){e=h[c>>0]|0;c=c+1|0}else e=0;f[i>>2]=c;f[r>>2]=k+16;d=16;c=e|g}else{if(d){f[i>>2]=c+1;c=h[c>>0]|0}else c=0;f[r>>2]=k+8;d=24}i=a+16|0;e=f[i>>2]|c<>2]=e}else{e=a+16|0;i=e;e=f[e>>2]|0}g=(e>>>16)+1|0;do if(g>>>0<=(f[p+16>>2]|0)>>>0){d=f[(f[p+168>>2]|0)+(e>>>(32-(f[p+8>>2]|0)|0)<<2)>>2]|0;if((d|0)==-1){f[l>>2]=866;f[l+4>>2]=3253;f[l+8>>2]=1393;vc(q,812,l)|0;Ub(q)|0}c=d&65535;d=d>>>16;if((f[b+8>>2]|0)>>>0<=c>>>0){f[n>>2]=866;f[n+4>>2]=909;f[n+8>>2]=1497;vc(q,812,n)|0;Ub(q)|0}if((h[(f[b+4>>2]|0)+c>>0]|0|0)!=(d|0)){f[o>>2]=866;f[o+4>>2]=3257;f[o+8>>2]=1410;vc(q,812,o)|0;Ub(q)|0}}else{d=f[p+20>>2]|0;while(1){c=d+-1|0;if(g>>>0>(f[p+28+(c<<2)>>2]|0)>>>0)d=d+1|0;else break}c=(e>>>(32-d|0))+(f[p+96+(c<<2)>>2]|0)|0;if(c>>>0<(f[b>>2]|0)>>>0){c=j[(f[p+176>>2]|0)+(c<<1)>>1]|0;break}f[m>>2]=866;f[m+4>>2]=3275;f[m+8>>2]=1348;vc(q,812,m)|0;Ub(q)|0;r=0;u=s;return r|0}while(0);f[i>>2]=f[i>>2]<>2]=(f[r>>2]|0)-d;r=c;u=s;return r|0}function cb(a){a=a|0;var c=0,d=0,e=0,g=0,h=0,i=0,j=0,k=0;k=u;u=u+576|0;j=k+48|0;h=k+32|0;g=k+16|0;e=k;i=k+64|0;f[a>>2]=0;c=a+284|0;d=f[c>>2]|0;if(d|0){if(!(d&7))Nb(d,0,0,1,0)|0;else{f[e>>2]=866;f[e+4>>2]=2506;f[e+8>>2]=1232;vc(i,812,e)|0;Ub(i)|0}f[c>>2]=0;f[a+288>>2]=0;f[a+292>>2]=0}b[a+296>>0]=0;c=a+268|0;d=f[c>>2]|0;if(d|0){if(!(d&7))Nb(d,0,0,1,0)|0;else{f[g>>2]=866;f[g+4>>2]=2506;f[g+8>>2]=1232;vc(i,812,g)|0;Ub(i)|0}f[c>>2]=0;f[a+272>>2]=0;f[a+276>>2]=0}b[a+280>>0]=0;c=a+252|0;d=f[c>>2]|0;if(d|0){if(!(d&7))Nb(d,0,0,1,0)|0;else{f[h>>2]=866;f[h+4>>2]=2506;f[h+8>>2]=1232;vc(i,812,h)|0;Ub(i)|0}f[c>>2]=0;f[a+256>>2]=0;f[a+260>>2]=0}b[a+264>>0]=0;c=a+236|0;d=f[c>>2]|0;if(!d){j=a+248|0;b[j>>0]=0;j=a+212|0;Cb(j);j=a+188|0;Cb(j);j=a+164|0;Cb(j);j=a+140|0;Cb(j);j=a+116|0;Cb(j);u=k;return}if(!(d&7))Nb(d,0,0,1,0)|0;else{f[j>>2]=866;f[j+4>>2]=2506;f[j+8>>2]=1232;vc(i,812,j)|0;Ub(i)|0}f[c>>2]=0;f[a+240>>2]=0;f[a+244>>2]=0;j=a+248|0;b[j>>0]=0;j=a+212|0;Cb(j);j=a+188|0;Cb(j);j=a+164|0;Cb(j);j=a+140|0;Cb(j);j=a+116|0;Cb(j);u=k;return}function db(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0,g=0.0;a:do if(b>>>0<=20)do switch(b|0){case 9:{d=(f[c>>2]|0)+(4-1)&~(4-1);b=f[d>>2]|0;f[c>>2]=d+4;f[a>>2]=b;break a}case 10:{d=(f[c>>2]|0)+(4-1)&~(4-1);b=f[d>>2]|0;f[c>>2]=d+4;d=a;f[d>>2]=b;f[d+4>>2]=((b|0)<0)<<31>>31;break a}case 11:{d=(f[c>>2]|0)+(4-1)&~(4-1);b=f[d>>2]|0;f[c>>2]=d+4;d=a;f[d>>2]=b;f[d+4>>2]=0;break a}case 12:{d=(f[c>>2]|0)+(8-1)&~(8-1);b=d;e=f[b>>2]|0;b=f[b+4>>2]|0;f[c>>2]=d+8;d=a;f[d>>2]=e;f[d+4>>2]=b;break a}case 13:{e=(f[c>>2]|0)+(4-1)&~(4-1);d=f[e>>2]|0;f[c>>2]=e+4;d=(d&65535)<<16>>16;e=a;f[e>>2]=d;f[e+4>>2]=((d|0)<0)<<31>>31;break a}case 14:{e=(f[c>>2]|0)+(4-1)&~(4-1);d=f[e>>2]|0;f[c>>2]=e+4;e=a;f[e>>2]=d&65535;f[e+4>>2]=0;break a}case 15:{e=(f[c>>2]|0)+(4-1)&~(4-1);d=f[e>>2]|0;f[c>>2]=e+4;d=(d&255)<<24>>24;e=a;f[e>>2]=d;f[e+4>>2]=((d|0)<0)<<31>>31;break a}case 16:{e=(f[c>>2]|0)+(4-1)&~(4-1);d=f[e>>2]|0;f[c>>2]=e+4;e=a;f[e>>2]=d&255;f[e+4>>2]=0;break a}case 17:{e=(f[c>>2]|0)+(8-1)&~(8-1);g=+p[e>>3];f[c>>2]=e+8;p[a>>3]=g;break a}case 18:{e=(f[c>>2]|0)+(8-1)&~(8-1);g=+p[e>>3];f[c>>2]=e+8;p[a>>3]=g;break a}default:break a}while(0);while(0);return}function eb(a){a=a|0;var c=0,e=0,g=0,i=0,j=0,k=0,l=0,m=0,n=0;n=u;u=u+560|0;i=n;g=n+40|0;m=n+16|0;e=f[a+88>>2]|0;k=(h[e+55>>0]|0)<<8|(h[e+56>>0]|0);l=a+92|0;c=(f[a+4>>2]|0)+((h[e+50>>0]|0)<<8|(h[e+49>>0]|0)<<16|(h[e+51>>0]|0))|0;e=(h[e+53>>0]|0)<<8|(h[e+52>>0]|0)<<16|(h[e+54>>0]|0);if(!e){m=0;u=n;return m|0}f[l>>2]=c;f[a+96>>2]=c;f[a+104>>2]=e;f[a+100>>2]=c+e;f[a+108>>2]=0;f[a+112>>2]=0;f[m+20>>2]=0;f[m>>2]=0;f[m+4>>2]=0;f[m+8>>2]=0;f[m+12>>2]=0;b[m+16>>0]=0;a:do if(Pa(l,m)|0){j=a+268|0;e=a+272|0;c=f[e>>2]|0;if((c|0)!=(k|0)){if(c>>>0<=k>>>0){do if((f[a+276>>2]|0)>>>0>>0)if(fb(j,k,(c+1|0)==(k|0),2,0)|0){c=f[e>>2]|0;break}else{b[a+280>>0]=1;c=0;break a}while(0);Ib((f[j>>2]|0)+(c<<1)|0,0,k-c<<1|0)|0}f[e>>2]=k}if(!k){f[i>>2]=866;f[i+4>>2]=910;f[i+8>>2]=1497;vc(g,812,i)|0;Ub(g)|0;c=1;break}e=0;a=0;g=0;c=f[j>>2]|0;while(1){j=bb(l,m)|0;g=j+g&255;a=(bb(l,m)|0)+a&255;d[c>>1]=a<<8|g;e=e+1|0;if(e>>>0>=k>>>0){c=1;break}else c=c+2|0}}else c=0;while(0);Cb(m);m=c;u=n;return m|0}function fb(a,b,c,d,e){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;p=u;u=u+576|0;m=p+48|0;j=p+32|0;h=p+16|0;g=p;l=p+64|0;n=p+60|0;k=a+4|0;o=a+8|0;if((f[k>>2]|0)>>>0>(f[o>>2]|0)>>>0){f[g>>2]=866;f[g+4>>2]=2123;f[g+8>>2]=845;vc(l,812,g)|0;Ub(l)|0}if((2147418112/(d>>>0)|0)>>>0<=b>>>0){f[h>>2]=866;f[h+4>>2]=2124;f[h+8>>2]=885;vc(l,812,h)|0;Ub(l)|0}g=f[o>>2]|0;if(g>>>0>=b>>>0){o=1;u=p;return o|0}if(c?(i=b+-1|0,(i&b|0)!=0):0){b=i>>>16|i;b=b>>>8|b;b=b>>>4|b;b=b>>>2|b;b=(b>>>1|b)+1|0;if(!b){b=0;c=10}else c=9}else c=9;if((c|0)==9)if(b>>>0<=g>>>0)c=10;if((c|0)==10){f[j>>2]=866;f[j+4>>2]=2133;f[j+8>>2]=933;vc(l,812,j)|0;Ub(l)|0}i=X(b,d)|0;if(!e){g=Gb(f[a>>2]|0,i,n,1)|0;if(!g)b=0;else{f[a>>2]=g;c=20}}else{h=Db(i,n)|0;if(!h)b=0;else{Ia[e&0](h,f[a>>2]|0,f[k>>2]|0);g=f[a>>2]|0;do if(g|0)if(!(g&7)){Nb(g,0,0,1,0)|0;break}else{f[m>>2]=866;f[m+4>>2]=2506;f[m+8>>2]=1232;vc(l,812,m)|0;Ub(l)|0;break}while(0);f[a>>2]=h;c=20}}if((c|0)==20){g=f[n>>2]|0;if(g>>>0>i>>>0)b=(g>>>0)/(d>>>0)|0;f[o>>2]=b;b=1}o=b;u=p;return o|0}function gb(a,c){a=a|0;c=c|0;var d=0,e=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;o=u;u=u+528|0;m=o;j=o+16|0;if((a|0)==0|c>>>0<62){p=0;u=o;return p|0}k=Db(300,0)|0;if(!k){p=0;u=o;return p|0}f[k>>2]=519686845;f[k+4>>2]=0;f[k+8>>2]=0;l=k+88|0;d=k+136|0;e=k+160|0;g=k+184|0;h=k+208|0;i=k+232|0;n=k+252|0;f[n>>2]=0;f[n+4>>2]=0;f[n+8>>2]=0;b[n+12>>0]=0;n=k+268|0;f[n>>2]=0;f[n+4>>2]=0;f[n+8>>2]=0;b[n+12>>0]=0;n=k+284|0;f[n>>2]=0;f[n+4>>2]=0;f[n+8>>2]=0;b[n+12>>0]=0;n=l;p=n+44|0;do{f[n>>2]=0;n=n+4|0}while((n|0)<(p|0));b[l+44>>0]=0;f[d>>2]=0;f[d+4>>2]=0;f[d+8>>2]=0;f[d+12>>2]=0;f[d+16>>2]=0;b[d+20>>0]=0;f[e>>2]=0;f[e+4>>2]=0;f[e+8>>2]=0;f[e+12>>2]=0;f[e+16>>2]=0;b[e+20>>0]=0;f[g>>2]=0;f[g+4>>2]=0;f[g+8>>2]=0;f[g+12>>2]=0;f[g+16>>2]=0;b[g+20>>0]=0;f[h>>2]=0;f[h+4>>2]=0;f[h+8>>2]=0;f[h+12>>2]=0;f[h+16>>2]=0;b[h+20>>0]=0;f[i>>2]=0;f[i+4>>2]=0;f[i+8>>2]=0;f[i+12>>2]=0;b[i+16>>0]=0;if(xb(k,a,c)|0){p=k;u=o;return p|0}cb(k);if(!(k&7)){Nb(k,0,0,1,0)|0;p=0;u=o;return p|0}else{f[m>>2]=866;f[m+4>>2]=2506;f[m+8>>2]=1232;vc(j,812,m)|0;Ub(j)|0;p=0;u=o;return p|0}return 0}function hb(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0,g=0,h=0,i=0,j=0;i=u;u=u+576|0;g=i+40|0;e=i+56|0;j=i;f[j>>2]=40;tb(a,b,j)|0;d=(((f[j+4>>2]|0)>>>c)+3|0)>>>2;b=(((f[j+8>>2]|0)>>>c)+3|0)>>>2;c=j+32|0;a=f[c+4>>2]|0;do switch(f[c>>2]|0){case 0:{if(!a)a=8;else h=14;break}case 1:{if(!a)h=13;else h=14;break}case 2:{if(!a)h=13;else h=14;break}case 3:{if(!a)h=13;else h=14;break}case 4:{if(!a)h=13;else h=14;break}case 5:{if(!a)h=13;else h=14;break}case 6:{if(!a)h=13;else h=14;break}case 7:{if(!a)h=13;else h=14;break}case 8:{if(!a)h=13;else h=14;break}case 9:{if(!a)a=8;else h=14;break}case 10:{if(!a)a=8;else h=14;break}default:h=14}while(0);if((h|0)==13)a=16;else if((h|0)==14){f[g>>2]=866;f[g+4>>2]=2672;f[g+8>>2]=1251;vc(e,812,g)|0;Ub(e)|0;a=0}j=X(X(b,d)|0,a)|0;u=i;return j|0}function ib(a,b){a=a|0;b=b|0;var c=0,d=0,e=0,g=0;e=u;u=u+576|0;d=e+40|0;c=e+56|0;g=e;f[g>>2]=40;tb(a,b,g)|0;b=g+32|0;a=f[b+4>>2]|0;do switch(f[b>>2]|0){case 0:{if(!a){g=8;u=e;return g|0}else a=14;break}case 1:{if(!a)a=13;else a=14;break}case 2:{if(!a)a=13;else a=14;break}case 3:{if(!a)a=13;else a=14;break}case 4:{if(!a)a=13;else a=14;break}case 5:{if(!a)a=13;else a=14;break}case 6:{if(!a)a=13;else a=14;break}case 7:{if(!a)a=13;else a=14;break}case 8:{if(!a)a=13;else a=14;break}case 9:{if(!a){g=8;u=e;return g|0}else a=14;break}case 10:{if(!a){g=8;u=e;return g|0}else a=14;break}default:a=14}while(0);if((a|0)==13){g=16;u=e;return g|0}else if((a|0)==14){f[d>>2]=866;f[d+4>>2]=2672;f[d+8>>2]=1251;vc(c,812,d)|0;Ub(c)|0;g=0;u=e;return g|0}return 0}function jb(a,c,d,e,g,i,j){a=a|0;c=c|0;d=d|0;e=e|0;g=g|0;i=i|0;j=j|0;var k=0,l=0,m=0,n=0;n=f[a+88>>2]|0;l=(h[n+12>>0]<<8|h[n+13>>0])>>>j;m=(h[n+14>>0]<<8|h[n+15>>0])>>>j;l=((l>>>0>1?l:1)+3|0)>>>2;m=((m>>>0>1?m:1)+3|0)>>>2;n=n+18|0;j=b[n>>0]|0;j=X(l,j<<24>>24==0|j<<24>>24==9?8:16)|0;if(i)if((i&3|0)==0&j>>>0<=i>>>0)j=i;else{g=0;return g|0}if((X(j,m)|0)>>>0>g>>>0){g=0;return g|0}i=(l+1|0)>>>1;k=(m+1|0)>>>1;if(!d){g=0;return g|0}f[a+92>>2]=c;f[a+96>>2]=c;f[a+104>>2]=d;f[a+100>>2]=c+d;f[a+108>>2]=0;f[a+112>>2]=0;switch(b[n>>0]|0){case 0:{if(!(Ra(a,e,g,j,l,m,i,k)|0)){g=0;return g|0}break}case 4:case 6:case 5:case 3:case 2:{if(!(Ua(a,e,g,j,l,m,i,k)|0)){g=0;return g|0}break}case 9:{if(!(Ya(a,e,g,j,l,m,i,k)|0)){g=0;return g|0}break}case 8:case 7:{if(!(Sa(a,e,g,j,l,m,i,k)|0)){g=0;return g|0}break}default:{g=0;return g|0}}g=1;return g|0}function kb(a,c,d){a=a|0;c=c|0;d=d|0;var e=0,g=0,h=0;if((d|0)>=8192)return va(a|0,c|0,d|0)|0;h=a|0;g=a+d|0;if((a&3)==(c&3)){while(a&3){if(!d)return h|0;b[a>>0]=b[c>>0]|0;a=a+1|0;c=c+1|0;d=d-1|0}d=g&-4|0;e=d-64|0;while((a|0)<=(e|0)){f[a>>2]=f[c>>2];f[a+4>>2]=f[c+4>>2];f[a+8>>2]=f[c+8>>2];f[a+12>>2]=f[c+12>>2];f[a+16>>2]=f[c+16>>2];f[a+20>>2]=f[c+20>>2];f[a+24>>2]=f[c+24>>2];f[a+28>>2]=f[c+28>>2];f[a+32>>2]=f[c+32>>2];f[a+36>>2]=f[c+36>>2];f[a+40>>2]=f[c+40>>2];f[a+44>>2]=f[c+44>>2];f[a+48>>2]=f[c+48>>2];f[a+52>>2]=f[c+52>>2];f[a+56>>2]=f[c+56>>2];f[a+60>>2]=f[c+60>>2];a=a+64|0;c=c+64|0}while((a|0)<(d|0)){f[a>>2]=f[c>>2];a=a+4|0;c=c+4|0}}else{d=g-4|0;while((a|0)<(d|0)){b[a>>0]=b[c>>0]|0;b[a+1>>0]=b[c+1>>0]|0;b[a+2>>0]=b[c+2>>0]|0;b[a+3>>0]=b[c+3>>0]|0;a=a+4|0;c=c+4|0}}while((a|0)<(g|0)){b[a>>0]=b[c>>0]|0;a=a+1|0;c=c+1|0}return h|0}function lb(a){a=a|0;var b=0,c=0,d=0,e=0;e=a+92|0;d=a+88|0;c=f[d>>2]|0;b=(f[a+4>>2]|0)+((h[c+68>>0]|0)<<8|(h[c+67>>0]|0)<<16|(h[c+69>>0]|0))|0;c=(h[c+65>>0]|0)<<8|(h[c+66>>0]|0);if(!c){e=0;return e|0}f[e>>2]=b;f[a+96>>2]=b;f[a+104>>2]=c;f[a+100>>2]=b+c;f[a+108>>2]=0;f[a+112>>2]=0;if(!(Pa(e,a+116|0)|0)){e=0;return e|0}b=f[d>>2]|0;do if(!((h[b+39>>0]|0)<<8|(h[b+40>>0]|0))){if(!((h[b+55>>0]|0)<<8|(h[b+56>>0]|0))){e=0;return e|0}}else{if(!(Pa(e,a+140|0)|0)){e=0;return e|0}if(Pa(e,a+188|0)|0){b=f[d>>2]|0;break}else{e=0;return e|0}}while(0);if((h[b+55>>0]|0)<<8|(h[b+56>>0]|0)|0){if(!(Pa(e,a+164|0)|0)){e=0;return e|0}if(!(Pa(e,a+212|0)|0)){e=0;return e|0}}e=1;return e|0}function mb(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0;m=u;u=u+48|0;k=m+16|0;g=m;e=m+32|0;i=a+28|0;d=f[i>>2]|0;f[e>>2]=d;j=a+20|0;d=(f[j>>2]|0)-d|0;f[e+4>>2]=d;f[e+8>>2]=b;f[e+12>>2]=c;d=d+c|0;h=a+60|0;f[g>>2]=f[h>>2];f[g+4>>2]=e;f[g+8>>2]=2;g=Ic(Aa(146,g|0)|0)|0;a:do if((d|0)!=(g|0)){b=2;while(1){if((g|0)<0)break;d=d-g|0;o=f[e+4>>2]|0;n=g>>>0>o>>>0;e=n?e+8|0:e;b=(n<<31>>31)+b|0;o=g-(n?o:0)|0;f[e>>2]=(f[e>>2]|0)+o;n=e+4|0;f[n>>2]=(f[n>>2]|0)-o;f[k>>2]=f[h>>2];f[k+4>>2]=e;f[k+8>>2]=b;g=Ic(Aa(146,k|0)|0)|0;if((d|0)==(g|0)){l=3;break a}}f[a+16>>2]=0;f[i>>2]=0;f[j>>2]=0;f[a>>2]=f[a>>2]|32;if((b|0)==2)c=0;else c=c-(f[e+4>>2]|0)|0}else l=3;while(0);if((l|0)==3){o=f[a+44>>2]|0;f[a+16>>2]=o+(f[a+48>>2]|0);f[i>>2]=o;f[j>>2]=o}u=m;return c|0}function nb(a,c,d,e,g){a=a|0;c=c|0;d=d|0;e=e|0;g=g|0;var h=0,i=0,j=0,k=0;do if(!(Sc(a,f[c+8>>2]|0,g)|0)){h=a+8|0;if(!(Sc(a,f[c>>2]|0,g)|0)){j=f[h>>2]|0;Fa[f[(f[j>>2]|0)+24>>2]&3](j,c,d,e,g);break}a=c+32|0;if((f[c+16>>2]|0)!=(d|0)?(i=c+20|0,(f[i>>2]|0)!=(d|0)):0){f[a>>2]=e;e=c+44|0;if((f[e>>2]|0)==4)break;a=c+52|0;b[a>>0]=0;k=c+53|0;b[k>>0]=0;h=f[h>>2]|0;Ka[f[(f[h>>2]|0)+20>>2]&3](h,c,d,d,1,g);if(b[k>>0]|0)if(!(b[a>>0]|0)){a=3;j=11}else a=3;else{a=4;j=11}if((j|0)==11){f[i>>2]=d;k=c+40|0;f[k>>2]=(f[k>>2]|0)+1;if((f[c+36>>2]|0)==1?(f[c+24>>2]|0)==2:0)b[c+54>>0]=1}f[e>>2]=a;break}if((e|0)==1)f[a>>2]=1}else jc(0,c,d,e);while(0);return}function ob(a,c,d){a=a|0;c=c|0;d=d|0;var e=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0;r=u;u=u+224|0;m=r+120|0;n=r+80|0;p=r;q=r+136|0;e=n;g=e+40|0;do{f[e>>2]=0;e=e+4|0}while((e|0)<(g|0));f[m>>2]=f[d>>2];if((Oa(0,c,m,p,n)|0)<0)d=-1;else{if((f[a+76>>2]|0)>-1)o=td(a)|0;else o=0;d=f[a>>2]|0;l=d&32;if((b[a+74>>0]|0)<1)f[a>>2]=d&-33;e=a+48|0;if(!(f[e>>2]|0)){g=a+44|0;h=f[g>>2]|0;f[g>>2]=q;i=a+28|0;f[i>>2]=q;j=a+20|0;f[j>>2]=q;f[e>>2]=80;k=a+16|0;f[k>>2]=q+80;d=Oa(a,c,m,p,n)|0;if(h){Ea[f[a+36>>2]&7](a,0,0)|0;d=(f[j>>2]|0)==0?-1:d;f[g>>2]=h;f[e>>2]=0;f[k>>2]=0;f[i>>2]=0;f[j>>2]=0}}else d=Oa(a,c,m,p,n)|0;e=f[a>>2]|0;f[a>>2]=e|l;if(o|0)sd(a);d=(e&32|0)==0?d:-1}u=r;return d|0}function pb(a,c,e,g){a=a|0;c=c|0;e=e|0;g=g|0;var h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;p=u;u=u+64|0;n=p;m=f[a>>2]|0;o=a+(f[m+-8>>2]|0)|0;m=f[m+-4>>2]|0;f[n>>2]=e;f[n+4>>2]=a;f[n+8>>2]=c;f[n+12>>2]=g;a=n+16|0;c=n+20|0;g=n+24|0;h=n+28|0;i=n+32|0;j=n+40|0;k=a;l=k+36|0;do{f[k>>2]=0;k=k+4|0}while((k|0)<(l|0));d[a+36>>1]=0;b[a+38>>0]=0;a:do if(Sc(m,e,0)|0){f[n+48>>2]=1;Ka[f[(f[m>>2]|0)+20>>2]&3](m,n,o,o,1,0);a=(f[g>>2]|0)==1?o:0}else{Fa[f[(f[m>>2]|0)+24>>2]&3](m,n,o,1,0);switch(f[n+36>>2]|0){case 0:{a=(f[j>>2]|0)==1&(f[h>>2]|0)==1&(f[i>>2]|0)==1?f[c>>2]|0:0;break a}case 1:break;default:{a=0;break a}}if((f[g>>2]|0)!=1?!((f[j>>2]|0)==0&(f[h>>2]|0)==1&(f[i>>2]|0)==1):0){a=0;break}a=f[a>>2]|0}while(0);u=p;return a|0}function qb(a){a=a|0;var b=0,c=0,d=0,e=0,g=0,h=0,i=0,j=0;j=u;u=u+544|0;h=j+16|0;b=j;e=j+32|0;g=a+8|0;c=f[g>>2]|0;if((c+-1|0)>>>0>=8192){f[b>>2]=866;f[b+4>>2]=3006;f[b+8>>2]=1257;vc(e,812,b)|0;Ub(e)|0}f[a>>2]=c;d=a+20|0;b=f[d>>2]|0;if(!b){b=Db(180,0)|0;if(!b)b=0;else{i=b+164|0;f[i>>2]=0;f[i+4>>2]=0;f[i+8>>2]=0;f[i+12>>2]=0}f[d>>2]=b;i=f[a>>2]|0}else i=c;if(!(f[g>>2]|0)){f[h>>2]=866;f[h+4>>2]=910;f[h+8>>2]=1497;vc(e,812,h)|0;Ub(e)|0;h=f[a>>2]|0}else h=i;e=f[a+4>>2]|0;if(h>>>0>16){c=h;d=0}else{a=0;a=Qa(b,i,e,a)|0;u=j;return a|0}while(1){g=d+1|0;if(c>>>0>3){c=c>>>1;d=g}else break}a=d+2+((g|0)!=32&1<>>0>>0&1)|0;a=(a>>>0<11?a:11)&255;a=Qa(b,i,e,a)|0;u=j;return a|0}function rb(a,c,d){a=a|0;c=c|0;d=d|0;var e=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0;o=(f[a>>2]|0)+1794895138|0;h=Tc(f[a+8>>2]|0,o)|0;e=Tc(f[a+12>>2]|0,o)|0;g=Tc(f[a+16>>2]|0,o)|0;a:do if((h>>>0>>2>>>0?(n=c-(h<<2)|0,e>>>0>>0&g>>>0>>0):0)?((g|e)&3|0)==0:0){n=e>>>2;m=g>>>2;l=0;while(1){j=h>>>1;k=l+j|0;i=k<<1;g=i+n|0;e=Tc(f[a+(g<<2)>>2]|0,o)|0;g=Tc(f[a+(g+1<<2)>>2]|0,o)|0;if(!(g>>>0>>0&e>>>0<(c-g|0)>>>0)){e=0;break a}if(b[a+(g+e)>>0]|0){e=0;break a}e=_b(d,a+g|0)|0;if(!e)break;e=(e|0)<0;if((h|0)==1){e=0;break a}else{l=e?l:k;h=e?j:h-j|0}}e=i+m|0;g=Tc(f[a+(e<<2)>>2]|0,o)|0;e=Tc(f[a+(e+1<<2)>>2]|0,o)|0;if(e>>>0>>0&g>>>0<(c-e|0)>>>0)e=(b[a+(e+g)>>0]|0)==0?a+e|0:0;else e=0}else e=0;while(0);return e|0}function sb(a){a=a|0;var b=0,c=0,d=0,e=0,g=0,h=0,i=0,j=0;i=u;u=u+576|0;g=i+48|0;h=i+32|0;d=i+16|0;c=i;e=i+64|0;b=f[a+168>>2]|0;do if(b|0){j=f[b+-4>>2]|0;b=b+-8|0;if(!((j|0)!=0?(j|0)==(~f[b>>2]|0):0)){f[c>>2]=866;f[c+4>>2]=651;f[c+8>>2]=1579;vc(e,812,c)|0;Ub(e)|0}if(!(b&7)){Nb(b,0,0,1,0)|0;break}else{f[d>>2]=866;f[d+4>>2]=2506;f[d+8>>2]=1232;vc(e,812,d)|0;Ub(e)|0;break}}while(0);b=f[a+176>>2]|0;if(!b){u=i;return}j=f[b+-4>>2]|0;b=b+-8|0;if(!((j|0)!=0?(j|0)==(~f[b>>2]|0):0)){f[h>>2]=866;f[h+4>>2]=651;f[h+8>>2]=1579;vc(e,812,h)|0;Ub(e)|0}if(!(b&7)){Nb(b,0,0,1,0)|0;u=i;return}else{f[g>>2]=866;f[g+4>>2]=2506;f[g+8>>2]=1232;vc(e,812,g)|0;Ub(e)|0;u=i;return}}function tb(a,c,d){a=a|0;c=c|0;d=d|0;var e=0;if(!((a|0)!=0&c>>>0>73&(d|0)!=0)){d=0;return d|0}if((f[d>>2]|0)!=40){d=0;return d|0}if(((h[a>>0]|0)<<8|(h[a+1>>0]|0)|0)!=18552){d=0;return d|0}if(((h[a+2>>0]|0)<<8|(h[a+3>>0]|0))>>>0<74){d=0;return d|0}if(((h[a+7>>0]|0)<<16|(h[a+6>>0]|0)<<24|(h[a+8>>0]|0)<<8|(h[a+9>>0]|0))>>>0>c>>>0){d=0;return d|0}f[d+4>>2]=(h[a+12>>0]|0)<<8|(h[a+13>>0]|0);f[d+8>>2]=(h[a+14>>0]|0)<<8|(h[a+15>>0]|0);f[d+12>>2]=h[a+16>>0];f[d+16>>2]=h[a+17>>0];c=a+18|0;e=d+32|0;f[e>>2]=h[c>>0];f[e+4>>2]=0;c=b[c>>0]|0;f[d+20>>2]=c<<24>>24==0|c<<24>>24==9?8:16;f[d+24>>2]=(h[a+26>>0]|0)<<16|(h[a+25>>0]|0)<<24|(h[a+27>>0]|0)<<8|(h[a+28>>0]|0);f[d+28>>2]=(h[a+30>>0]|0)<<16|(h[a+29>>0]|0)<<24|(h[a+31>>0]|0)<<8|(h[a+32>>0]|0);d=1;return d|0}function ub(a,b){a=a|0;b=b|0;var c=0,d=0,e=0,g=0,i=0,j=0,k=0,l=0;l=u;u=u+544|0;j=l+16|0;c=l;i=l+32|0;if(b>>>0>=33){f[c>>2]=866;f[c+4>>2]=3199;f[c+8>>2]=1350;vc(i,812,c)|0;Ub(i)|0}k=a+20|0;c=f[k>>2]|0;if((c|0)>=(b|0)){e=a+16|0;g=e;e=f[e>>2]|0;i=c;j=32-b|0;j=e>>>j;e=e<>2]=e;b=i-b|0;f[k>>2]=b;u=l;return j|0}e=a+4|0;g=a+8|0;d=a+16|0;do{a=f[e>>2]|0;if((a|0)==(f[g>>2]|0))a=0;else{f[e>>2]=a+1;a=h[a>>0]|0}c=c+8|0;f[k>>2]=c;if((c|0)>=33){f[j>>2]=866;f[j+4>>2]=3208;f[j+8>>2]=1366;vc(i,812,j)|0;Ub(i)|0;c=f[k>>2]|0}a=a<<32-c|f[d>>2];f[d>>2]=a}while((c|0)<(b|0));j=32-b|0;j=a>>>j;i=a<>2]=i;b=c-b|0;f[k>>2]=b;u=l;return j|0}function vb(a,c,d){a=a|0;c=c|0;d=d|0;var e=0,g=0,h=0,i=0;h=c&255;e=(d|0)!=0;a:do if(e&(a&3|0)!=0){g=c&255;while(1){if((b[a>>0]|0)==g<<24>>24){i=6;break a}a=a+1|0;d=d+-1|0;e=(d|0)!=0;if(!(e&(a&3|0)!=0)){i=5;break}}}else i=5;while(0);if((i|0)==5)if(e)i=6;else d=0;b:do if((i|0)==6){g=c&255;if((b[a>>0]|0)!=g<<24>>24){e=X(h,16843009)|0;c:do if(d>>>0>3)while(1){h=f[a>>2]^e;if((h&-2139062144^-2139062144)&h+-16843009|0)break;a=a+4|0;d=d+-4|0;if(d>>>0<=3){i=11;break c}}else i=11;while(0);if((i|0)==11)if(!d){d=0;break}while(1){if((b[a>>0]|0)==g<<24>>24)break b;a=a+1|0;d=d+-1|0;if(!d){d=0;break}}}}while(0);return (d|0?a:0)|0}function wb(a,b,c,d,e){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;var g=0,i=0,j=0,k=0,l=0,m=0;m=u;u=u+528|0;l=m;k=m+16|0;i=f[a+88>>2]|0;j=(h[i+70+(e<<2)+1>>0]|0)<<16|(h[i+70+(e<<2)>>0]|0)<<24|(h[i+70+(e<<2)+2>>0]|0)<<8|(h[i+70+(e<<2)+3>>0]|0);g=e+1|0;if(g>>>0<(h[i+16>>0]|0)>>>0)g=(h[i+70+(g<<2)+1>>0]|0)<<16|(h[i+70+(g<<2)>>0]|0)<<24|(h[i+70+(g<<2)+2>>0]|0)<<8|(h[i+70+(g<<2)+3>>0]|0);else g=f[a+8>>2]|0;if(g>>>0>j>>>0){k=a+4|0;k=f[k>>2]|0;k=k+j|0;l=g-j|0;l=jb(a,k,l,b,c,d,e)|0;u=m;return l|0}f[l>>2]=866;f[l+4>>2]=3694;f[l+8>>2]=1508;vc(k,812,l)|0;Ub(k)|0;k=a+4|0;k=f[k>>2]|0;k=k+j|0;l=g-j|0;l=jb(a,k,l,b,c,d,e)|0;u=m;return l|0}function xb(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0;if(((!((b|0)==0|c>>>0<74)?((h[b>>0]|0)<<8|(h[b+1>>0]|0)|0)==18552:0)?((h[b+2>>0]|0)<<8|(h[b+3>>0]|0))>>>0>=74:0)?((h[b+7>>0]|0)<<16|(h[b+6>>0]|0)<<24|(h[b+8>>0]|0)<<8|(h[b+9>>0]|0))>>>0<=c>>>0:0){d=a+88|0;f[d>>2]=b;f[a+4>>2]=b;f[a+8>>2]=c;if(!(lb(a)|0)){e=0;return e|0}b=f[d>>2]|0;if((h[b+39>>0]|0)<<8|(h[b+40>>0]|0)){if(ab(a)|0?Xa(a)|0:0){b=f[d>>2]|0;e=11}}else e=11;if((e|0)==11){if(!((h[b+55>>0]|0)<<8|(h[b+56>>0]|0))){e=1;return e|0}if(eb(a)|0?Wa(a)|0:0){e=1;return e|0}}e=0;return e|0}f[a+88>>2]=0;e=0;return e|0}function yb(a,b){a=a|0;b=b|0;var c=0,d=0,e=0,g=0,i=0,j=0,k=0,l=0;l=u;u=u+528|0;i=l;g=l+16|0;if(!b){k=0;u=l;return k|0}if(b>>>0<=16){k=ub(a,b)|0;u=l;return k|0}j=ub(a,b+-16|0)|0;k=a+20|0;b=f[k>>2]|0;if((b|0)<16){d=a+4|0;e=a+8|0;c=a+16|0;do{a=f[d>>2]|0;if((a|0)==(f[e>>2]|0))a=0;else{f[d>>2]=a+1;a=h[a>>0]|0}b=b+8|0;f[k>>2]=b;if((b|0)>=33){f[i>>2]=866;f[i+4>>2]=3208;f[i+8>>2]=1366;vc(g,812,i)|0;Ub(g)|0;b=f[k>>2]|0}a=a<<32-b|f[c>>2];f[c>>2]=a}while((b|0)<16)}else{a=a+16|0;c=a;a=f[a>>2]|0}f[c>>2]=a<<16;f[k>>2]=b+-16;k=a>>>16|j<<16;u=l;return k|0}function zb(a,c,d){a=a|0;c=c|0;d=d|0;var e=0,g=0,h=0,i=0,j=0;e=d+16|0;g=f[e>>2]|0;if(!g)if(!(Zb(d)|0)){g=f[e>>2]|0;h=5}else e=0;else h=5;a:do if((h|0)==5){j=d+20|0;i=f[j>>2]|0;e=i;if((g-i|0)>>>0>>0){e=Ea[f[d+36>>2]&7](d,a,c)|0;break}b:do if((b[d+75>>0]|0)>-1){i=c;while(1){if(!i){h=0;g=a;break b}g=i+-1|0;if((b[a+g>>0]|0)==10)break;else i=g}e=Ea[f[d+36>>2]&7](d,a,i)|0;if(e>>>0>>0)break a;h=i;g=a+i|0;c=c-i|0;e=f[j>>2]|0}else{h=0;g=a}while(0);kb(e|0,g|0,c|0)|0;f[j>>2]=(f[j>>2]|0)+c;e=h+c|0}while(0);return e|0}function Ab(a,c,d){a=a|0;c=c|0;d=d|0;do if(a){if(c>>>0<128){b[a>>0]=c;a=1;break}d=(ld()|0)+188|0;if(!(f[f[d>>2]>>2]|0))if((c&-128|0)==57216){b[a>>0]=c;a=1;break}else{a=jd()|0;f[a>>2]=84;a=-1;break}if(c>>>0<2048){b[a>>0]=c>>>6|192;b[a+1>>0]=c&63|128;a=2;break}if(c>>>0<55296|(c&-8192|0)==57344){b[a>>0]=c>>>12|224;b[a+1>>0]=c>>>6&63|128;b[a+2>>0]=c&63|128;a=3;break}if((c+-65536|0)>>>0<1048576){b[a>>0]=c>>>18|240;b[a+1>>0]=c>>>12&63|128;b[a+2>>0]=c>>>6&63|128;b[a+3>>0]=c&63|128;a=4;break}else{a=jd()|0;f[a>>2]=84;a=-1;break}}else a=1;while(0);return a|0}function Bb(){var a=0,b=0,c=0,d=0,e=0,g=0,h=0,i=0;e=u;u=u+48|0;h=e+32|0;c=e+24|0;i=e+16|0;g=e;e=e+36|0;a=rc()|0;if(a|0?(d=f[a>>2]|0,d|0):0){a=d+48|0;b=f[a>>2]|0;a=f[a+4>>2]|0;if(!((b&-256|0)==1126902528&(a|0)==1129074247)){f[c>>2]=4168;Ac(4118,c)}if((b|0)==1126902529&(a|0)==1129074247)a=f[d+44>>2]|0;else a=d+80|0;f[e>>2]=a;d=f[d>>2]|0;a=f[d+4>>2]|0;if(Ea[f[(f[2]|0)+16>>2]&7](8,d,e)|0){i=f[e>>2]|0;i=Ha[f[(f[i>>2]|0)+8>>2]&1](i)|0;f[g>>2]=4168;f[g+4>>2]=a;f[g+8>>2]=i;Ac(4032,g)}else{f[i>>2]=4168;f[i+4>>2]=a;Ac(4077,i)}}Ac(4156,h)}function Cb(a){a=a|0;var c=0,d=0,e=0,g=0,h=0;h=u;u=u+544|0;g=h+16|0;d=h;e=h+32|0;c=f[a+20>>2]|0;do if(c|0){sb(c);if(!(c&7)){Nb(c,0,0,1,0)|0;break}else{f[d>>2]=866;f[d+4>>2]=2506;f[d+8>>2]=1232;vc(e,812,d)|0;Ub(e)|0;break}}while(0);c=a+4|0;d=f[c>>2]|0;if(!d){g=a+16|0;b[g>>0]=0;u=h;return}if(!(d&7))Nb(d,0,0,1,0)|0;else{f[g>>2]=866;f[g+4>>2]=2506;f[g+8>>2]=1232;vc(e,812,g)|0;Ub(e)|0}f[c>>2]=0;f[a+8>>2]=0;f[a+12>>2]=0;g=a+16|0;b[g>>0]=0;u=h;return}function Db(a,b){a=a|0;b=b|0;var c=0,d=0,e=0,g=0,h=0,i=0,j=0;j=u;u=u+560|0;i=j+32|0;h=j+16|0;c=j;g=j+48|0;e=j+44|0;d=a+3&-4;d=d|0?d:4;if(d>>>0>2147418112){f[c>>2]=866;f[c+4>>2]=2506;f[c+8>>2]=1103;vc(g,812,c)|0;Ub(g)|0;i=0;u=j;return i|0}f[e>>2]=d;a=Nb(0,d,e,1,0)|0;c=f[e>>2]|0;if(b|0)f[b>>2]=c;if(!((a|0)==0|c>>>0>>0)){if(a&7){f[i>>2]=866;f[i+4>>2]=2533;f[i+8>>2]=1156;vc(g,812,i)|0;Ub(g)|0}}else{f[h>>2]=866;f[h+4>>2]=2506;f[h+8>>2]=1129;vc(g,812,h)|0;Ub(g)|0;a=0}i=a;u=j;return i|0}function Eb(a){a=a|0;var c=0,d=0,e=0,g=0,h=0,i=0;i=u;u=u+544|0;h=i+16|0;e=i;g=i+32|0;f[a>>2]=0;c=a+4|0;d=f[c>>2]|0;if(d|0){if(!(d&7))Nb(d,0,0,1,0)|0;else{f[e>>2]=866;f[e+4>>2]=2506;f[e+8>>2]=1232;vc(g,812,e)|0;Ub(g)|0}f[c>>2]=0;f[a+8>>2]=0;f[a+12>>2]=0}b[a+16>>0]=0;a=a+20|0;c=f[a>>2]|0;if(!c){u=i;return}sb(c);if(!(c&7))Nb(c,0,0,1,0)|0;else{f[h>>2]=866;f[h+4>>2]=2506;f[h+8>>2]=1232;vc(g,812,h)|0;Ub(g)|0}f[a>>2]=0;u=i;return}function Fb(a,c,d,e){a=a|0;c=c|0;d=d|0;e=e|0;var g=0,h=0,i=0,j=0,k=0,l=0,m=0;m=u;u=u+128|0;g=m+124|0;l=m;h=l;i=604;j=h+124|0;do{f[h>>2]=f[i>>2];h=h+4|0;i=i+4|0}while((h|0)<(j|0));if((c+-1|0)>>>0>2147483646)if(!c){a=g;c=1;k=4}else{c=jd()|0;f[c>>2]=75;c=-1}else k=4;if((k|0)==4){k=-2-a|0;k=c>>>0>k>>>0?k:c;f[l+48>>2]=k;g=l+20|0;f[g>>2]=a;f[l+44>>2]=a;c=a+k|0;a=l+16|0;f[a>>2]=c;f[l+28>>2]=c;c=ob(l,d,e)|0;if(k){l=f[g>>2]|0;b[l+(((l|0)==(f[a>>2]|0))<<31>>31)>>0]=0}}u=m;return c|0}function Gb(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;var e=0,g=0,h=0,i=0,j=0,k=0;k=u;u=u+560|0;j=k+32|0;g=k+16|0;e=k;h=k+48|0;i=k+44|0;if(a&7|0){f[e>>2]=866;f[e+4>>2]=2506;f[e+8>>2]=1210;vc(h,812,e)|0;Ub(h)|0;j=0;u=k;return j|0}if(b>>>0>2147418112){f[g>>2]=866;f[g+4>>2]=2506;f[g+8>>2]=1103;vc(h,812,g)|0;Ub(h)|0;j=0;u=k;return j|0}f[i>>2]=b;a=Nb(a,b,i,d,0)|0;if(c|0)f[c>>2]=f[i>>2];if(a&7|0){f[j>>2]=866;f[j+4>>2]=2558;f[j+8>>2]=1156;vc(h,812,j)|0;Ub(h)|0}j=a;u=k;return j|0}function Hb(a,c,d,e,g){a=a|0;c=c|0;d=d|0;e=e|0;g=g|0;var h=0;do if(!(Sc(a,f[c+8>>2]|0,g)|0)){if(Sc(a,f[c>>2]|0,g)|0){a=c+32|0;if((f[c+16>>2]|0)!=(d|0)?(h=c+20|0,(f[h>>2]|0)!=(d|0)):0){f[a>>2]=e;f[h>>2]=d;e=c+40|0;f[e>>2]=(f[e>>2]|0)+1;if((f[c+36>>2]|0)==1?(f[c+24>>2]|0)==2:0)b[c+54>>0]=1;f[c+44>>2]=4;break}if((e|0)==1)f[a>>2]=1}}else jc(0,c,d,e);while(0);return}function Ib(a,c,d){a=a|0;c=c|0;d=d|0;var e=0,g=0,h=0,i=0;h=a+d|0;c=c&255;if((d|0)>=67){while(a&3){b[a>>0]=c;a=a+1|0}e=h&-4|0;g=e-64|0;i=c|c<<8|c<<16|c<<24;while((a|0)<=(g|0)){f[a>>2]=i;f[a+4>>2]=i;f[a+8>>2]=i;f[a+12>>2]=i;f[a+16>>2]=i;f[a+20>>2]=i;f[a+24>>2]=i;f[a+28>>2]=i;f[a+32>>2]=i;f[a+36>>2]=i;f[a+40>>2]=i;f[a+44>>2]=i;f[a+48>>2]=i;f[a+52>>2]=i;f[a+56>>2]=i;f[a+60>>2]=i;a=a+64|0}while((a|0)<(e|0)){f[a>>2]=i;a=a+4|0}}while((a|0)<(h|0)){b[a>>0]=c;a=a+1|0}return h-d|0}function Jb(a,c,d,e,g){a=a|0;c=c|0;d=d|0;e=e|0;g=g|0;var h=0,i=0,j=0,k=0;b[c+53>>0]=1;do if((f[c+4>>2]|0)==(e|0)){b[c+52>>0]=1;e=c+16|0;h=f[e>>2]|0;j=c+54|0;k=c+48|0;i=c+24|0;a=c+36|0;if(!h){f[e>>2]=d;f[i>>2]=g;f[a>>2]=1;if(!((f[k>>2]|0)==1&(g|0)==1))break;b[j>>0]=1;break}if((h|0)!=(d|0)){f[a>>2]=(f[a>>2]|0)+1;b[j>>0]=1;break}a=f[i>>2]|0;if((a|0)==2){f[i>>2]=g;a=g}if((f[k>>2]|0)==1&(a|0)==1)b[j>>0]=1}while(0);return}function Kb(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0,g=0,h=0;h=u;u=u+64|0;e=h;if(!(Sc(a,b,0)|0))if((b|0)!=0?(g=pb(b,32,16,0)|0,(g|0)!=0):0){b=e+4|0;d=b+52|0;do{f[b>>2]=0;b=b+4|0}while((b|0)<(d|0));f[e>>2]=g;f[e+8>>2]=a;f[e+12>>2]=-1;f[e+48>>2]=1;La[f[(f[g>>2]|0)+28>>2]&3](g,e,f[c>>2]|0,1);if((f[e+24>>2]|0)==1){f[c>>2]=f[e+16>>2];b=1}else b=0}else b=0;else b=1;u=h;return b|0}function Lb(a,c){a=a|0;c=c|0;var d=0,e=0,g=0,i=0,j=0,k=0,l=0;l=u;u=u+16|0;j=l;k=c&255;b[j>>0]=k;e=a+16|0;g=f[e>>2]|0;if(!g)if(!(Zb(a)|0)){g=f[e>>2]|0;i=4}else d=-1;else i=4;do if((i|0)==4){i=a+20|0;e=f[i>>2]|0;if(e>>>0>>0?(d=c&255,(d|0)!=(b[a+75>>0]|0)):0){f[i>>2]=e+1;b[e>>0]=k;break}if((Ea[f[a+36>>2]&7](a,j,1)|0)==1)d=h[j>>0]|0;else d=-1}while(0);u=l;return d|0}function Mb(a,c){a=a|0;c=c|0;var d=0,e=0,g=0,h=0,i=0,j=0,k=0;j=a&255;d=a&255;if((f[c+76>>2]|0)>=0?(td(c)|0)!=0:0){if((d|0)!=(b[c+75>>0]|0)?(h=c+20|0,i=f[h>>2]|0,i>>>0<(f[c+16>>2]|0)>>>0):0){f[h>>2]=i+1;b[i>>0]=j}else d=Lb(c,a)|0;sd(c)}else k=3;do if((k|0)==3){if((d|0)!=(b[c+75>>0]|0)?(e=c+20|0,g=f[e>>2]|0,g>>>0<(f[c+16>>2]|0)>>>0):0){f[e>>2]=g+1;b[g>>0]=j;break}d=Lb(c,a)|0}while(0);return d|0}function Nb(a,b,c,d,e){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;do if(!a){b=Ma(b)|0;if(c){if(!b)a=0;else a=uc(b)|0;f[c>>2]=a}}else{if(!b){Ta(a);if(!c){b=0;break}f[c>>2]=0;b=0;break}if(d){b=Sb(a,b)|0;a=(b|0)==0?a:b}else b=0;if(c){e=uc(a)|0;f[c>>2]=e}}while(0);return b|0}function Ob(a){a=a|0;var c=0,d=0,e=0;e=a;a:do if(!(e&3))d=4;else{c=e;while(1){if(!(b[a>>0]|0)){a=c;break a}a=a+1|0;c=a;if(!(c&3)){d=4;break}}}while(0);if((d|0)==4){while(1){c=f[a>>2]|0;if(!((c&-2139062144^-2139062144)&c+-16843009))a=a+4|0;else break}if((c&255)<<24>>24)do a=a+1|0;while((b[a>>0]|0)!=0)}return a-e|0}function Pb(a,b){a=+a;b=b|0;var c=0,d=0,e=0;p[s>>3]=a;c=f[s>>2]|0;d=f[s+4>>2]|0;e=zc(c|0,d|0,52)|0;switch(e&2047){case 0:{if(a!=0.0){a=+Pb(a*18446744073709551616.0,b);c=(f[b>>2]|0)+-64|0}else c=0;f[b>>2]=c;break}case 2047:break;default:{f[b>>2]=(e&2047)+-1022;f[s>>2]=c;f[s+4>>2]=d&-2146435073|1071644672;a=+p[s>>3]}}return +a}function Qb(a,c){a=a|0;c=c|0;var d=0,e=0;e=0;while(1){if((h[2140+e>>0]|0)==(a|0)){a=2;break}d=e+1|0;if((d|0)==87){d=2228;e=87;a=5;break}else e=d}if((a|0)==2)if(!e)d=2228;else{d=2228;a=5}if((a|0)==5)while(1){do{a=d;d=d+1|0}while((b[a>>0]|0)!=0);e=e+-1|0;if(!e)break;else a=5}return ed(d,f[c+20>>2]|0)|0}function Rb(a,c,d){a=a|0;c=c|0;d=d|0;var e=0;if(c>>>0>0|(c|0)==0&a>>>0>4294967295){while(1){e=mc(a|0,c|0,10,0)|0;d=d+-1|0;b[d>>0]=e&255|48;e=a;a=Uc(a|0,c|0,10,0)|0;if(!(c>>>0>9|(c|0)==9&e>>>0>4294967295))break;else c=I}c=a}else c=a;if(c)while(1){d=d+-1|0;b[d>>0]=(c>>>0)%10|0|48;if(c>>>0<10)break;else c=(c>>>0)/10|0}return d|0}function Sb(a,b){a=a|0;b=b|0;var c=0,d=0;if(!a){b=Ma(b)|0;return b|0}if(b>>>0>4294967231){b=jd()|0;f[b>>2]=12;b=0;return b|0}c=_a(a+-8|0,b>>>0<11?16:b+11&-8)|0;if(c|0){b=c+8|0;return b|0}c=Ma(b)|0;if(!c){b=0;return b|0}d=f[a+-4>>2]|0;d=(d&-8)-((d&3|0)==0?8:4)|0;kb(c|0,a|0,(d>>>0>>0?d:b)|0)|0;Ta(a);b=c;return b|0}function Tb(a,c,d,e){a=a|0;c=c|0;d=d|0;e=e|0;var g=0,h=0,i=0;a=c+16|0;g=f[a>>2]|0;h=c+36|0;i=c+24|0;do if(g){if((g|0)!=(d|0)){f[h>>2]=(f[h>>2]|0)+1;f[i>>2]=2;b[c+54>>0]=1;break}if((f[i>>2]|0)==2)f[i>>2]=e}else{f[a>>2]=d;f[i>>2]=e;f[h>>2]=1}while(0);return}function Ub(a){a=a|0;var c=0,d=0,e=0,g=0;e=f[119]|0;if((f[e+76>>2]|0)>-1)g=td(e)|0;else g=0;do if((Mc(a,e)|0)<0)a=1;else{if((b[e+75>>0]|0)!=10?(c=e+20|0,d=f[c>>2]|0,d>>>0<(f[e+16>>2]|0)>>>0):0){f[c>>2]=d+1;b[d>>0]=10;a=0;break}a=(Lb(e,10)|0)<0}while(0);if(g|0)sd(e);return a<<31>>31|0}function Vb(a,b,c,d,e,g){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;g=g|0;if(Sc(a,f[b+8>>2]|0,g)|0)Jb(0,b,c,d,e);else{a=f[a+8>>2]|0;Ka[f[(f[a>>2]|0)+20>>2]&3](a,b,c,d,e,g)}return}function Wb(a,b,c,d,e){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;var f=0,g=0;g=u;u=u+256|0;f=g;if((c|0)>(d|0)&(e&73728|0)==0){e=c-d|0;Ib(f|0,b|0,(e>>>0<256?e:256)|0)|0;if(e>>>0>255){b=c-d|0;do{Nc(a,f,256);e=e+-256|0}while(e>>>0>255);e=b&255}Nc(a,f,e)}u=g;return}function Xb(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;if(Sc(a,f[b+8>>2]|0,0)|0)Tb(0,b,c,d);else{a=f[a+8>>2]|0;La[f[(f[a>>2]|0)+28>>2]&3](a,b,c,d)}return}function Yb(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0,g=0;e=u;u=u+32|0;g=e;d=e+20|0;f[g>>2]=f[a+60>>2];f[g+4>>2]=0;f[g+8>>2]=b;f[g+12>>2]=d;f[g+16>>2]=c;if((Ic(xa(140,g|0)|0)|0)<0){f[d>>2]=-1;a=-1}else a=f[d>>2]|0;u=e;return a|0}function Zb(a){a=a|0;var c=0,d=0;c=a+74|0;d=b[c>>0]|0;b[c>>0]=d+255|d;c=f[a>>2]|0;if(!(c&8)){f[a+8>>2]=0;f[a+4>>2]=0;d=f[a+44>>2]|0;f[a+28>>2]=d;f[a+20>>2]=d;f[a+16>>2]=d+(f[a+48>>2]|0);a=0}else{f[a>>2]=c|32;a=-1}return a|0}function _b(a,c){a=a|0;c=c|0;var d=0,e=0;d=b[a>>0]|0;e=b[c>>0]|0;if(d<<24>>24==0?1:d<<24>>24!=e<<24>>24)a=e;else{do{a=a+1|0;c=c+1|0;d=b[a>>0]|0;e=b[c>>0]|0}while(!(d<<24>>24==0?1:d<<24>>24!=e<<24>>24));a=e}return (d&255)-(a&255)|0}function $b(a,c,d){a=a|0;c=c|0;d=d|0;var e=0,g=0;g=u;u=u+32|0;e=g;f[a+36>>2]=1;if((f[a>>2]&64|0)==0?(f[e>>2]=f[a+60>>2],f[e+4>>2]=21523,f[e+8>>2]=g+16,na(54,e|0)|0):0)b[a+75>>0]=-1;e=mb(a,c,d)|0;u=g;return e|0}function ac(a){a=a|0;var b=0,c=0;c=a+15&-16|0;b=f[r>>2]|0;a=b+c|0;if((c|0)>0&(a|0)<(b|0)|(a|0)<0){da()|0;ra(12);return -1}f[r>>2]=a;if((a|0)>(ca()|0)?(ba()|0)==0:0){f[r>>2]=b;ra(12);return -1}return b|0}function bc(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;var e=0,g=0;e=X(c,b)|0;c=(b|0)==0?0:c;if((f[d+76>>2]|0)>-1){g=(td(d)|0)==0;a=zb(a,e,d)|0;if(!g)sd(d)}else a=zb(a,e,d)|0;if((a|0)!=(e|0))c=(a>>>0)/(b>>>0)|0;return c|0}function cc(a,b,c,d,e,g){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;g=g|0;if(Sc(a,f[b+8>>2]|0,g)|0)Jb(0,b,c,d,e);return}function dc(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;if(Sc(a,f[b+8>>2]|0,0)|0)Tb(0,b,c,d);return}function ec(a){a=a|0;var c=0,d=0,e=0;d=f[a>>2]|0;e=(b[d>>0]|0)+-48|0;if(e>>>0<10){c=0;do{c=e+(c*10|0)|0;d=d+1|0;f[a>>2]=d;e=(b[d>>0]|0)+-48|0}while(e>>>0<10)}else c=0;return c|0}function fc(){var a=0,b=0;a=rc()|0;if((a|0?(b=f[a>>2]|0,b|0):0)?(a=b+48|0,(f[a>>2]&-256|0)==1126902528?(f[a+4>>2]|0)==1129074247:0):0)Jc(f[b+12>>2]|0);Jc($c()|0)}function gc(a,c,d,e){a=a|0;c=c|0;d=d|0;e=e|0;if(!((a|0)==0&(c|0)==0))do{d=d+-1|0;b[d>>0]=h[2122+(a&15)>>0]|0|e;a=zc(a|0,c|0,4)|0;c=I}while(!((a|0)==0&(c|0)==0));return d|0}function hc(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0;e=u;u=u+16|0;d=e;f[d>>2]=f[c>>2];a=Ea[f[(f[a>>2]|0)+16>>2]&7](a,b,d)|0;if(a)f[c>>2]=f[d>>2];u=e;return a&1|0}function ic(a){a=a|0;var c=0;c=b[w+(a&255)>>0]|0;if((c|0)<8)return c|0;c=b[w+(a>>8&255)>>0]|0;if((c|0)<8)return c+8|0;c=b[w+(a>>16&255)>>0]|0;if((c|0)<8)return c+16|0;return (b[w+(a>>>24)>>0]|0)+24|0}function jc(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;var e=0;if((f[b+4>>2]|0)==(c|0)?(e=b+28|0,(f[e>>2]|0)!=1):0)f[e>>2]=d;return}function kc(a,c,d){a=a|0;c=c|0;d=d|0;if(!((a|0)==0&(c|0)==0))do{d=d+-1|0;b[d>>0]=a&7|48;a=zc(a|0,c|0,3)|0;c=I}while(!((a|0)==0&(c|0)==0));return d|0}function lc(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0;d=a+20|0;e=f[d>>2]|0;a=(f[a+16>>2]|0)-e|0;a=a>>>0>c>>>0?c:a;kb(e|0,b|0,a|0)|0;f[d>>2]=(f[d>>2]|0)+a;return c|0}function mc(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;var e=0,g=0;g=u;u=u+16|0;e=g|0;Za(a,b,c,d,e)|0;u=g;return (I=f[e+4>>2]|0,f[e>>2]|0)|0}function nc(a,b){a=a|0;b=b|0;var c=0,d=0;d=u;u=u+48|0;c=d;f[c>>2]=40;tb(a,b,c)|0;u=d;return f[c+32>>2]|0}function oc(a,b){a=a|0;b=b|0;var c=0,d=0;d=u;u=u+48|0;c=d;f[c>>2]=40;tb(a,b,c)|0;u=d;return f[c+12>>2]|0}function pc(a,b){a=a|0;b=b|0;var c=0,d=0;d=u;u=u+48|0;c=d;f[c>>2]=40;tb(a,b,c)|0;u=d;return f[c+8>>2]|0}function qc(a,b){a=a|0;b=b|0;var c=0,d=0;d=u;u=u+48|0;c=d;f[c>>2]=40;tb(a,b,c)|0;u=d;return f[c+4>>2]|0}function rc(){var a=0,b=0;a=u;u=u+16|0;if(!(ua(5136,2)|0)){b=ma(f[1285]|0)|0;u=a;return b|0}else Ac(4307,a);return 0}function sc(a){a=a|0;var b=0,c=0;b=u;u=u+16|0;c=b;a=pd(f[a+60>>2]|0)|0;f[c>>2]=a;a=Ic(qa(6,c|0)|0)|0;u=b;return a|0}function tc(a){a=a|0;var b=0;b=u;u=u+16|0;Ta(a);if(!(oa(f[1285]|0,0)|0)){u=b;return}else Ac(4406,b)}function uc(a){a=a|0;var b=0;if(!a)return 0;else{b=f[a+-4>>2]|0;a=b&3;return ((a|0)==1?0:(b&-8)-((a|0)==0?8:4)|0)|0}return 0}function vc(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0;d=u;u=u+16|0;e=d;f[e>>2]=c;c=Yc(a,b,e)|0;u=d;return c|0}function wc(a,b,c,d,e,f,g){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;g=g|0;Ka[a&3](b|0,c|0,d|0,e|0,f|0,g|0)}function xc(){var a=0;a=u;u=u+16|0;if(!(wa(5140,6)|0)){u=a;return}else Ac(4356,a)}function yc(a,b,c){a=a|0;b=b|0;c=c|0;if((c|0)<32){I=b<>>32-c;return a<>>c;return a>>>c|(b&(1<>>c-32|0}function Ac(a,b){a=a|0;b=b|0;var c=0;c=u;u=u+16|0;f[c>>2]=b;b=f[26]|0;ob(b,a,c)|0;Mb(10,b)|0;sa()}function Bc(){}function Cc(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;d=b-d-(c>>>0>a>>>0|0)>>>0;return (I=d,a-c>>>0|0)|0}function Dc(a,b){a=a|0;b=b|0;if(!b)b=0;else b=rb(f[b>>2]|0,f[b+4>>2]|0,a)|0;return (b|0?b:a)|0}function Ec(a,b,c,d,e,f){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;Fa[a&3](b|0,c|0,d|0,e|0,f|0)}function Fc(a){a=+a;var b=0;p[s>>3]=a;b=f[s>>2]|0;I=f[s+4>>2]|0;return b|0}function Gc(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;c=a+c>>>0;return (I=b+d+(c>>>0>>0|0)>>>0,c|0)|0}function Hc(a,b,c,d,e){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;La[a&3](b|0,c|0,d|0,e|0)}function Ic(a){a=a|0;var b=0;if(a>>>0>4294963200){b=jd()|0;f[b>>2]=0-a;a=-1}return a|0}function Jc(a){a=a|0;var b=0;b=u;u=u+16|0;Ja[a&3]();Ac(4459,b)}function Kc(a){a=a|0;if(!a)a=0;else a=(pb(a,32,88,0)|0)!=0;return a&1|0}function Lc(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;return Ea[a&7](b|0,c|0,d|0)|0}function Mc(a,b){a=a|0;b=b|0;var c=0;c=Ob(a)|0;return ((bc(a,1,c,b)|0)!=(c|0))<<31>>31|0}function Nc(a,b,c){a=a|0;b=b|0;c=c|0;if(!(f[a>>2]&32))zb(b,c,a)|0;return}function Oc(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;Ia[a&0](b|0,c|0,d|0)}function Pc(a){a=a|0;var b=0;b=u;u=u+a|0;u=u+15&-16;return b|0}function Qc(a){a=a|0;var b=0;b=(ld()|0)+188|0;return Qb(a,f[b>>2]|0)|0}function Rc(a,b){a=a|0;b=b|0;if(!a)a=0;else a=Ab(a,b,0)|0;return a|0}function Sc(a,b,c){a=a|0;b=b|0;c=c|0;return (a|0)==(b|0)|0}function Tc(a,b){a=a|0;b=b|0;var c=0;c=Vc(a|0)|0;return ((b|0)==0?a:c)|0}function Uc(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;return Za(a,b,c,d,0)|0}function Vc(a){a=a|0;return (a&255)<<24|(a>>8&255)<<16|(a>>16&255)<<8|a>>>24|0}function Wc(a,b,c,d,e,f){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;$(6)}function Xc(a,b){a=a|0;b=b|0;if(!x){x=a;y=b}}function Yc(a,b,c){a=a|0;b=b|0;c=c|0;return Fb(a,2147483647,b,c)|0}function Zc(a,b,c,d,e){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;$(1)}function _c(a){a=a|0;sd(a);nd(a);return}function $c(){var a=0;a=f[182]|0;f[182]=a+0;return a|0}function ad(a){a=a|0;ta(a|0)|0;fc()}function bd(a,b){a=a|0;b=b|0;return Ha[a&1](b|0)|0}function cd(a,b){a=a|0;b=b|0;u=a;v=b}function dd(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;$(7)}function ed(a,b){a=a|0;b=b|0;return Dc(a,b)|0}function fd(a,b){a=a|0;b=b|0;Ga[a&7](b|0)}function gd(a,b,c){a=a|0;b=b|0;c=c|0;$(0);return 0}function hd(a,b){a=+a;b=b|0;return +(+Pb(a,b))}function id(a,b,c){a=a|0;b=b|0;c=c|0;$(4)}function jd(){return (ld()|0)+64|0}function kd(a){a=a|0;Ja[a&3]()}function ld(){return xd()|0}function md(a){a=a|0;u=a}function nd(a){a=a|0;Ta(a);return}function od(a){a=a|0;I=a}function pd(a){a=a|0;return a|0}function qd(){return 5072}function rd(a){a=a|0;$(3);return 0}function sd(a){a=a|0;return}function td(a){a=a|0;return 0}function ud(){return I|0}function vd(){return u|0}function wd(a){a=a|0;$(2)}function xd(){return 232}function yd(){$(5)} - -// EMSCRIPTEN_END_FUNCS -var Ea=[gd,mb,Yb,$b,lc,Kb,gd,gd];var Fa=[Zc,Hb,nb,Zc];var Ga=[wd,sd,_c,sd,sd,_c,tc,wd];var Ha=[rd,sc];var Ia=[id];var Ja=[yd,Bb,xc,yd];var Ka=[Wc,cc,Vb,Wc];var La=[dd,dc,Xb,dd];return{stackSave:vd,_i64Subtract:Cc,_crn_get_bytes_per_block:ib,setThrew:Xc,dynCall_viii:Oc,_bitshift64Lshr:zc,_bitshift64Shl:yc,dynCall_viiii:Hc,setTempRet0:od,_crn_decompress:$a,_memset:Ib,_sbrk:ac,_memcpy:kb,stackAlloc:Pc,_crn_get_height:pc,dynCall_vi:fd,getTempRet0:ud,_crn_get_levels:oc,_crn_get_uncompressed_size:hb,_i64Add:Gc,dynCall_iiii:Lc,_emscripten_get_global_libc:qd,dynCall_ii:bd,___udivdi3:Uc,_llvm_bswap_i32:Vc,dynCall_viiiii:Ec,___cxa_can_catch:hc,_free:Ta,runPostSets:Bc,dynCall_viiiiii:wc,establishStackSpace:cd,___uremdi3:mc,___cxa_is_pointer_type:Kc,stackRestore:md,_malloc:Ma,_emscripten_replace_memory:Da,dynCall_v:kd,_crn_get_width:qc,_crn_get_dxt_format:nc}}) - - -// EMSCRIPTEN_END_ASM -(Module.asmGlobalArg,Module.asmLibraryArg,buffer);var stackSave=Module["stackSave"]=asm["stackSave"];var getTempRet0=Module["getTempRet0"]=asm["getTempRet0"];var _memset=Module["_memset"]=asm["_memset"];var setThrew=Module["setThrew"]=asm["setThrew"];var _bitshift64Lshr=Module["_bitshift64Lshr"]=asm["_bitshift64Lshr"];var _bitshift64Shl=Module["_bitshift64Shl"]=asm["_bitshift64Shl"];var setTempRet0=Module["setTempRet0"]=asm["setTempRet0"];var _crn_decompress=Module["_crn_decompress"]=asm["_crn_decompress"];var _crn_get_bytes_per_block=Module["_crn_get_bytes_per_block"]=asm["_crn_get_bytes_per_block"];var _sbrk=Module["_sbrk"]=asm["_sbrk"];var _memcpy=Module["_memcpy"]=asm["_memcpy"];var stackAlloc=Module["stackAlloc"]=asm["stackAlloc"];var _crn_get_height=Module["_crn_get_height"]=asm["_crn_get_height"];var _i64Subtract=Module["_i64Subtract"]=asm["_i64Subtract"];var _crn_get_levels=Module["_crn_get_levels"]=asm["_crn_get_levels"];var _crn_get_uncompressed_size=Module["_crn_get_uncompressed_size"]=asm["_crn_get_uncompressed_size"];var _i64Add=Module["_i64Add"]=asm["_i64Add"];var _emscripten_get_global_libc=Module["_emscripten_get_global_libc"]=asm["_emscripten_get_global_libc"];var ___udivdi3=Module["___udivdi3"]=asm["___udivdi3"];var _llvm_bswap_i32=Module["_llvm_bswap_i32"]=asm["_llvm_bswap_i32"];var ___cxa_can_catch=Module["___cxa_can_catch"]=asm["___cxa_can_catch"];var _free=Module["_free"]=asm["_free"];var runPostSets=Module["runPostSets"]=asm["runPostSets"];var establishStackSpace=Module["establishStackSpace"]=asm["establishStackSpace"];var ___uremdi3=Module["___uremdi3"]=asm["___uremdi3"];var ___cxa_is_pointer_type=Module["___cxa_is_pointer_type"]=asm["___cxa_is_pointer_type"];var stackRestore=Module["stackRestore"]=asm["stackRestore"];var _malloc=Module["_malloc"]=asm["_malloc"];var _emscripten_replace_memory=Module["_emscripten_replace_memory"]=asm["_emscripten_replace_memory"];var _crn_get_width=Module["_crn_get_width"]=asm["_crn_get_width"];var _crn_get_dxt_format=Module["_crn_get_dxt_format"]=asm["_crn_get_dxt_format"];var dynCall_iiii=Module["dynCall_iiii"]=asm["dynCall_iiii"];var dynCall_viiiii=Module["dynCall_viiiii"]=asm["dynCall_viiiii"];var dynCall_vi=Module["dynCall_vi"]=asm["dynCall_vi"];var dynCall_ii=Module["dynCall_ii"]=asm["dynCall_ii"];var dynCall_viii=Module["dynCall_viii"]=asm["dynCall_viii"];var dynCall_v=Module["dynCall_v"]=asm["dynCall_v"];var dynCall_viiiiii=Module["dynCall_viiiiii"]=asm["dynCall_viiiiii"];var dynCall_viiii=Module["dynCall_viiii"]=asm["dynCall_viiii"];Runtime.stackAlloc=Module["stackAlloc"];Runtime.stackSave=Module["stackSave"];Runtime.stackRestore=Module["stackRestore"];Runtime.establishStackSpace=Module["establishStackSpace"];Runtime.setTempRet0=Module["setTempRet0"];Runtime.getTempRet0=Module["getTempRet0"];Module["asm"]=asm;function ExitStatus(status){this.name="ExitStatus";this.message="Program terminated with exit("+status+")";this.status=status}ExitStatus.prototype=new Error;ExitStatus.prototype.constructor=ExitStatus;var initialStackTop;var preloadStartTime=null;var calledMain=false;dependenciesFulfilled=function runCaller(){if(!Module["calledRun"])run();if(!Module["calledRun"])dependenciesFulfilled=runCaller};Module["callMain"]=Module.callMain=function callMain(args){args=args||[];ensureInitRuntime();var argc=args.length+1;function pad(){for(var i=0;i<4-1;i++){argv.push(0)}}var argv=[allocate(intArrayFromString(Module["thisProgram"]),"i8",ALLOC_NORMAL)];pad();for(var i=0;i0){return}preRun();if(runDependencies>0)return;if(Module["calledRun"])return;function doRun(){if(Module["calledRun"])return;Module["calledRun"]=true;if(ABORT)return;ensureInitRuntime();preMain();if(Module["onRuntimeInitialized"])Module["onRuntimeInitialized"]();if(Module["_main"]&&shouldRunNow)Module["callMain"](args);postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout((function(){setTimeout((function(){Module["setStatus"]("")}),1);doRun()}),1)}else{doRun()}}Module["run"]=Module.run=run;function exit(status,implicit){if(implicit&&Module["noExitRuntime"]){return}if(Module["noExitRuntime"]){}else{ABORT=true;EXITSTATUS=status;STACKTOP=initialStackTop;exitRuntime();if(Module["onExit"])Module["onExit"](status)}if(ENVIRONMENT_IS_NODE){process["exit"](status)}Module["quit"](status,new ExitStatus(status))}Module["exit"]=Module.exit=exit;var abortDecorators=[];function abort(what){if(Module["onAbort"]){Module["onAbort"](what)}if(what!==undefined){Module.print(what);Module.printErr(what);what=JSON.stringify(what)}else{what=""}ABORT=true;EXITSTATUS=1;var extra="\nIf this abort() is unexpected, build with -s ASSERTIONS=1 which can give more information.";var output="abort("+what+") at "+stackTrace()+extra;if(abortDecorators){abortDecorators.forEach((function(decorator){output=decorator(output,what)}))}throw output}Module["abort"]=Module.abort=abort;if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}var shouldRunNow=true;if(Module["noInitialRun"]){shouldRunNow=false}Module["noExitRuntime"]=true;run() - -export default Module; diff --git a/Source/WorkersES6/transcodeCRNToDXT.js b/Source/WorkersES6/transcodeCRNToDXT.js deleted file mode 100644 index a6b756ffe48e..000000000000 --- a/Source/WorkersES6/transcodeCRNToDXT.js +++ /dev/null @@ -1,140 +0,0 @@ -import CompressedTextureBuffer from "../Core/CompressedTextureBuffer.js"; -import defined from "../Core/defined.js"; -import PixelFormat from "../Core/PixelFormat.js"; -import RuntimeError from "../Core/RuntimeError.js"; -import crunch from "../ThirdParty/crunch.js"; -import createTaskProcessorWorker from "./createTaskProcessorWorker.js"; - -// Modified from texture-tester -// See: -// https://github.com/toji/texture-tester/blob/master/js/webgl-texture-util.js -// http://toji.github.io/texture-tester/ - -/** - * @license - * - * Copyright (c) 2014, Brandon Jones. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -// Taken from crnlib.h -var CRN_FORMAT = { - cCRNFmtInvalid: -1, - - cCRNFmtDXT1: 0, - // cCRNFmtDXT3 is not currently supported when writing to CRN - only DDS. - cCRNFmtDXT3: 1, - cCRNFmtDXT5: 2, - - // Crunch supports more formats than this, but we can't use them here. -}; - -// Mapping of Crunch formats to DXT formats. -var DXT_FORMAT_MAP = {}; -DXT_FORMAT_MAP[CRN_FORMAT.cCRNFmtDXT1] = PixelFormat.RGB_DXT1; -DXT_FORMAT_MAP[CRN_FORMAT.cCRNFmtDXT3] = PixelFormat.RGBA_DXT3; -DXT_FORMAT_MAP[CRN_FORMAT.cCRNFmtDXT5] = PixelFormat.RGBA_DXT5; - -var dst; -var dxtData; -var cachedDstSize = 0; - -// Copy an array of bytes into or out of the emscripten heap. -function arrayBufferCopy(src, dst, dstByteOffset, numBytes) { - var i; - var dst32Offset = dstByteOffset / 4; - var tail = numBytes % 4; - var src32 = new Uint32Array(src.buffer, 0, (numBytes - tail) / 4); - var dst32 = new Uint32Array(dst.buffer); - for (i = 0; i < src32.length; i++) { - dst32[dst32Offset + i] = src32[i]; - } - for (i = numBytes - tail; i < numBytes; i++) { - dst[dstByteOffset + i] = src[i]; - } -} - -/** - * @private - */ -function transcodeCRNToDXT(arrayBuffer, transferableObjects) { - // Copy the contents of the arrayBuffer into emscriptens heap. - var srcSize = arrayBuffer.byteLength; - var bytes = new Uint8Array(arrayBuffer); - var src = crunch._malloc(srcSize); - arrayBufferCopy(bytes, crunch.HEAPU8, src, srcSize); - - // Determine what type of compressed data the file contains. - var crnFormat = crunch._crn_get_dxt_format(src, srcSize); - var format = DXT_FORMAT_MAP[crnFormat]; - if (!defined(format)) { - throw new RuntimeError("Unsupported compressed format."); - } - - // Gather basic metrics about the DXT data. - var levels = crunch._crn_get_levels(src, srcSize); - var width = crunch._crn_get_width(src, srcSize); - var height = crunch._crn_get_height(src, srcSize); - - // Determine the size of the decoded DXT data. - var dstSize = 0; - var i; - for (i = 0; i < levels; ++i) { - dstSize += PixelFormat.compressedTextureSizeInBytes( - format, - width >> i, - height >> i - ); - } - - // Allocate enough space on the emscripten heap to hold the decoded DXT data - // or reuse the existing allocation if a previous call to this function has - // already acquired a large enough buffer. - if (cachedDstSize < dstSize) { - if (defined(dst)) { - crunch._free(dst); - } - dst = crunch._malloc(dstSize); - dxtData = new Uint8Array(crunch.HEAPU8.buffer, dst, dstSize); - cachedDstSize = dstSize; - } - - // Decompress the DXT data from the Crunch file into the allocated space. - crunch._crn_decompress(src, srcSize, dst, dstSize, 0, levels); - - // Release the crunch file data from the emscripten heap. - crunch._free(src); - - // Mipmaps are unsupported, so copy the level 0 texture - // When mipmaps are supported, a copy will still be necessary as dxtData is a view on the heap. - var length = PixelFormat.compressedTextureSizeInBytes(format, width, height); - - // Get a copy of the 0th mip level. dxtData will exceed length when there are more mip levels. - // Equivalent to dxtData.slice(0, length), which is not supported in IE11 - var level0DXTDataView = dxtData.subarray(0, length); - var level0DXTData = new Uint8Array(length); - level0DXTData.set(level0DXTDataView, 0); - - transferableObjects.push(level0DXTData.buffer); - return new CompressedTextureBuffer(format, width, height, level0DXTData); -} -export default createTaskProcessorWorker(transcodeCRNToDXT); diff --git a/Source/WorkersES6/transcodeKTX2.js b/Source/WorkersES6/transcodeKTX2.js new file mode 100644 index 000000000000..19ea502f1065 --- /dev/null +++ b/Source/WorkersES6/transcodeKTX2.js @@ -0,0 +1,52 @@ +/* global require */ +import defined from "../Core/defined.js"; +import parseKTX2 from "../Core/parseKTX2.js"; + +import createTaskProcessorWorker from "./createTaskProcessorWorker.js"; + +var transcoderModule; + +function transcode(parameters, transferableObjects) { + var ktx2Buffer = parameters.ktx2Buffer; + var supportedTargetFormats = parameters.supportedTargetFormats; + return parseKTX2( + ktx2Buffer, + supportedTargetFormats, + transcoderModule, + transferableObjects + ); +} + +function initWorker(compiledModule) { + transcoderModule = compiledModule; + transcoderModule.initializeBasis(); + + self.onmessage = createTaskProcessorWorker(transcode); + self.postMessage(true); +} + +function transcodeKTX2(event) { + var data = event.data; + + // Expect the first message to be to load a web assembly module + var wasmConfig = data.webAssemblyConfig; + if (defined(wasmConfig)) { + // Require and compile WebAssembly module, or use fallback if not supported + return require([wasmConfig.modulePath], function (mscBasisTranscoder) { + if (defined(wasmConfig.wasmBinaryFile)) { + if (!defined(mscBasisTranscoder)) { + mscBasisTranscoder = self.MSC_TRANSCODER; + } + + mscBasisTranscoder(wasmConfig).then(function (compiledModule) { + initWorker(compiledModule); + }); + } else { + return mscBasisTranscoder().then(function (transcoder) { + initWorker(transcoder); + }); + } + }); + } +} +export default transcodeKTX2; diff --git a/Specs/Core/loadCRNSpec.js b/Specs/Core/loadCRNSpec.js deleted file mode 100644 index f06ff27dfe94..000000000000 --- a/Specs/Core/loadCRNSpec.js +++ /dev/null @@ -1,538 +0,0 @@ -import { loadCRN } from "../../Source/Cesium.js"; -import { PixelFormat } from "../../Source/Cesium.js"; -import { Request } from "../../Source/Cesium.js"; -import { RequestErrorEvent } from "../../Source/Cesium.js"; -import { RequestScheduler } from "../../Source/Cesium.js"; -import { Resource } from "../../Source/Cesium.js"; - -describe("Core/loadCRN", function () { - var validCompressed = new Uint8Array([ - 72, - 120, - 0, - 74, - 227, - 123, - 0, - 0, - 0, - 138, - 92, - 167, - 0, - 4, - 0, - 4, - 1, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 74, - 0, - 0, - 22, - 0, - 1, - 0, - 0, - 96, - 0, - 0, - 12, - 0, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 29, - 0, - 0, - 108, - 0, - 0, - 0, - 137, - 0, - 10, - 96, - 0, - 0, - 0, - 0, - 0, - 0, - 16, - 4, - 9, - 130, - 0, - 0, - 0, - 0, - 0, - 0, - 109, - 4, - 0, - 0, - 198, - 96, - 128, - 0, - 0, - 0, - 0, - 0, - 26, - 80, - 0, - 0, - 6, - 96, - 0, - 0, - 0, - 0, - 0, - 0, - 16, - 0, - 51, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 128, - 1, - 152, - 0, - 0, - 0, - 0, - 0, - 0, - 4, - 0, - ]); - var validCompressedMipmap = new Uint8Array([ - 72, - 120, - 0, - 82, - 183, - 141, - 0, - 0, - 0, - 148, - 151, - 24, - 0, - 4, - 0, - 4, - 3, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 82, - 0, - 0, - 22, - 0, - 1, - 0, - 0, - 104, - 0, - 0, - 12, - 0, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 29, - 0, - 0, - 116, - 0, - 0, - 0, - 145, - 0, - 0, - 0, - 146, - 0, - 0, - 0, - 147, - 0, - 130, - 97, - 0, - 0, - 0, - 0, - 0, - 4, - 35, - 37, - 0, - 3, - 48, - 0, - 0, - 0, - 0, - 0, - 0, - 8, - 200, - 0, - 198, - 96, - 128, - 0, - 0, - 0, - 0, - 0, - 26, - 80, - 0, - 0, - 6, - 96, - 0, - 0, - 0, - 0, - 0, - 0, - 16, - 0, - 51, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 128, - 1, - 152, - 0, - 0, - 0, - 0, - 0, - 0, - 4, - 0, - 0, - 0, - ]); - var fakeXHR; - - beforeEach(function () { - fakeXHR = jasmine.createSpyObj("XMLHttpRequest", [ - "send", - "open", - "setRequestHeader", - "abort", - "getAllResponseHeaders", - ]); - fakeXHR.simulateLoad = function (response) { - fakeXHR.simulateHttpResponse(200, response); - }; - fakeXHR.simulateError = function () { - fakeXHR.response = ""; - if (typeof fakeXHR.onerror === "function") { - fakeXHR.onerror(); - } - }; - fakeXHR.simulateHttpResponse = function (statusCode, response) { - fakeXHR.status = statusCode; - fakeXHR.response = response; - if (typeof fakeXHR.onload === "function") { - fakeXHR.onload(); - } - }; - - spyOn(window, "XMLHttpRequest").and.returnValue(fakeXHR); - }); - - it("throws with no url", function () { - expect(function () { - loadCRN(); - }).toThrowDeveloperError(); - }); - - it("creates and sends request without any custom headers", function () { - var testUrl = "http://example.invalid/testuri"; - loadCRN(testUrl); - - expect(fakeXHR.open).toHaveBeenCalledWith("GET", testUrl, true); - expect(fakeXHR.setRequestHeader).not.toHaveBeenCalled(); - expect(fakeXHR.send).toHaveBeenCalled(); - }); - - it("creates and sends request with custom headers with Resource", function () { - var testUrl = "http://example.invalid/testuri"; - var resource = new Resource({ - url: testUrl, - headers: { - Accept: "application/json", - "Cache-Control": "no-cache", - }, - }); - - loadCRN(resource); - - expect(fakeXHR.open).toHaveBeenCalledWith("GET", testUrl, true); - expect(fakeXHR.setRequestHeader.calls.count()).toEqual(2); - expect(fakeXHR.setRequestHeader).toHaveBeenCalledWith( - "Accept", - "application/json" - ); - expect(fakeXHR.setRequestHeader).toHaveBeenCalledWith( - "Cache-Control", - "no-cache" - ); - expect(fakeXHR.send).toHaveBeenCalled(); - }); - - it("returns a promise that rejects when the request errors", function () { - var testUrl = "http://example.invalid/testuri"; - var promise = loadCRN(testUrl); - - expect(promise).toBeDefined(); - - var resolvedValue; - var rejectedError; - promise.then( - function (value) { - resolvedValue = value; - }, - function (error) { - rejectedError = error; - } - ); - - expect(resolvedValue).toBeUndefined(); - expect(rejectedError).toBeUndefined(); - - fakeXHR.simulateError(); - expect(resolvedValue).toBeUndefined(); - expect(rejectedError).toBeInstanceOf(RequestErrorEvent); - expect(rejectedError.statusCode).toBeUndefined(); - expect(rejectedError.response).toBeUndefined(); - }); - - it("returns a promise that rejects when the request results in an HTTP error code", function () { - var testUrl = "http://example.invalid/testuri"; - var promise = loadCRN(testUrl); - - expect(promise).toBeDefined(); - - var resolvedValue; - var rejectedError; - promise.then( - function (value) { - resolvedValue = value; - }, - function (error) { - rejectedError = error; - } - ); - - expect(resolvedValue).toBeUndefined(); - expect(rejectedError).toBeUndefined(); - - var error = "some error"; - fakeXHR.simulateHttpResponse(404, error); - expect(resolvedValue).toBeUndefined(); - expect(rejectedError).toBeInstanceOf(RequestErrorEvent); - expect(rejectedError.statusCode).toEqual(404); - expect(rejectedError.response).toEqual(error); - }); - - it("returns a promise that resolves with undefined when statusCode is 204", function () { - var testUrl = "http://example.invalid/testuri"; - var promise = loadCRN(testUrl); - - expect(promise).toBeDefined(); - - var resolved = false; - var resolvedValue; - var rejectedError; - promise.then( - function (value) { - resolved = true; - resolvedValue = value; - }, - function (error) { - rejectedError = error; - } - ); - - expect(resolvedValue).toBeUndefined(); - expect(rejectedError).toBeUndefined(); - - fakeXHR.simulateHttpResponse(204); - expect(resolved).toBe(true); - expect(resolvedValue).toBeUndefined(); - expect(rejectedError).toBeUndefined(); - }); - - it("returns a promise that resolves to a compressed texture when the request loads", function () { - var testUrl = "http://example.invalid/testuri"; - var promise = loadCRN(testUrl); - - expect(promise).toBeDefined(); - - var resolvedValue; - var rejectedError; - var newPromise = promise.then( - function (value) { - resolvedValue = value; - }, - function (error) { - rejectedError = error; - } - ); - - expect(resolvedValue).toBeUndefined(); - expect(rejectedError).toBeUndefined(); - - var response = validCompressed.buffer; - fakeXHR.simulateLoad(response); - - return newPromise.then(function () { - expect(resolvedValue).toBeDefined(); - expect(resolvedValue.width).toEqual(4); - expect(resolvedValue.height).toEqual(4); - expect( - PixelFormat.isCompressedFormat(resolvedValue.internalFormat) - ).toEqual(true); - expect(resolvedValue.bufferView).toBeDefined(); - expect(rejectedError).toBeUndefined(); - }); - }); - - it("returns a promise that resolves to a compressed texture containing the first mip level of the original texture", function () { - var testUrl = "http://example.invalid/testuri"; - var promise = loadCRN(testUrl); - - expect(promise).toBeDefined(); - - var resolvedValue; - var rejectedError; - var newPromise = promise.then( - function (value) { - resolvedValue = value; - }, - function (error) { - rejectedError = error; - } - ); - - expect(resolvedValue).toBeUndefined(); - expect(rejectedError).toBeUndefined(); - - var response = validCompressedMipmap.buffer; - fakeXHR.simulateLoad(response); - - return newPromise.then(function () { - expect(resolvedValue).toBeDefined(); - expect(resolvedValue.width).toEqual(4); - expect(resolvedValue.height).toEqual(4); - expect( - PixelFormat.isCompressedFormat(resolvedValue.internalFormat) - ).toEqual(true); - expect(resolvedValue.bufferView).toBeDefined(); - expect(rejectedError).toBeUndefined(); - }); - }); - - it("returns undefined if the request is throttled", function () { - var oldMaximumRequests = RequestScheduler.maximumRequests; - RequestScheduler.maximumRequests = 0; - - var promise = loadCRN( - new Resource({ - url: "http://example.invalid/testuri", - request: new Request({ - throttle: true, - }), - }) - ); - expect(promise).toBeUndefined(); - - RequestScheduler.maximumRequests = oldMaximumRequests; - }); -}); diff --git a/Specs/Core/loadKTX2Spec.js b/Specs/Core/loadKTX2Spec.js new file mode 100644 index 000000000000..a69102774534 --- /dev/null +++ b/Specs/Core/loadKTX2Spec.js @@ -0,0 +1,295 @@ +import { loadKTX2 } from "../../Source/Cesium.js"; +import { KTX2Transcoder } from "../../Source/Cesium.js"; +import { PixelFormat } from "../../Source/Cesium.js"; +import { Resource } from "../../Source/Cesium.js"; +import { RuntimeError } from "../../Source/Cesium.js"; + +describe("Core/loadKTX2", function () { + it("throws with no url", function () { + expect(function () { + loadKTX2(); + }).toThrowDeveloperError(); + }); + + it("throws with unknown supported formats", function () { + expect(function () { + KTX2Transcoder.transcode(new Uint8Array()); + }).toThrowDeveloperError(); + }); + + it("throws if loadKTX2 is called with invalid url", function () { + var testUrl = "http://example.invalid/testuri"; + var promise = loadKTX2(testUrl); + return promise + .then(function (value) { + fail(); + }) + .otherwise(function (error) { + expect(error).toBeDefined(); + }); + }); + + function expectKTX2TranscodeResult( + url, + supportedFormats, + width, + height, + isCompressed + ) { + var resource = Resource.createIfNeeded(url); + var loadPromise = resource.fetchArrayBuffer(); + return loadPromise.then(function (buffer) { + var promise = KTX2Transcoder.transcode(buffer, supportedFormats); + return promise.then(function (result) { + expect(result).toBeDefined(); + expect(result.width).toEqual(width); + expect(result.height).toEqual(height); + expect(PixelFormat.isCompressedFormat(result.internalFormat)).toEqual( + isCompressed + ); + expect(result.bufferView).toBeDefined(); + }); + }); + } + + it("transcodes ETC1S ktx2 to etc", function () { + return expectKTX2TranscodeResult( + "./Data/Images/Green4x4_ETC1S.ktx2", + { etc: true }, + 4, + 4, + true + ); + }); + + it("transcodes UASTC ktx2 to etc", function () { + return expectKTX2TranscodeResult( + "./Data/Images/Logo32x32_UASTC_Zstd.ktx2", + { etc: true }, + 32, + 32, + true + ); + }); + + it("transcodes ETC1S ktx2 to etc1", function () { + return expectKTX2TranscodeResult( + "./Data/Images/Green4x4_ETC1S.ktx2", + { etc1: true }, + 4, + 4, + true + ); + }); + + it("transcodes UASTC ktx2 to etc1", function () { + return expectKTX2TranscodeResult( + "./Data/Images/Logo32x32_UASTC_Zstd.ktx2", + { etc1: true }, + 32, + 32, + true + ); + }); + + it("transcodes ETC1S ktx2 to astc", function () { + return expectKTX2TranscodeResult( + "./Data/Images/Green4x4_ETC1S.ktx2", + { astc: true }, + 4, + 4, + true + ); + }); + + it("transcodes UASTC ktx2 to astc", function () { + return expectKTX2TranscodeResult( + "./Data/Images/Logo32x32_UASTC_Zstd.ktx2", + { astc: true }, + 32, + 32, + true + ); + }); + + it("transcodes ETC1S ktx2 to pvrtc", function () { + return expectKTX2TranscodeResult( + "./Data/Images/Green4x4_ETC1S.ktx2", + { pvrtc: true }, + 4, + 4, + true + ); + }); + + it("transcodes UASTC ktx2 to pvrtc", function () { + return expectKTX2TranscodeResult( + "./Data/Images/Logo32x32_UASTC_Zstd.ktx2", + { pvrtc: true }, + 32, + 32, + true + ); + }); + + it("transcodes ETC1S ktx2 to s3tc", function () { + return expectKTX2TranscodeResult( + "./Data/Images/Green4x4_ETC1S.ktx2", + { s3tc: true }, + 4, + 4, + true + ); + }); + + it("transcodes UASTC ktx2 to s3tc", function () { + return expectKTX2TranscodeResult( + "./Data/Images/Logo32x32_UASTC_Zstd.ktx2", + { s3tc: true }, + 32, + 32, + true + ); + }); + + it("transcodes ETC1S ktx2 to bc7", function () { + return expectKTX2TranscodeResult( + "./Data/Images/Green4x4_ETC1S.ktx2", + { bc7: true }, + 4, + 4, + true + ); + }); + + it("transcodes UASTC ktx2 to bc7", function () { + return expectKTX2TranscodeResult( + "./Data/Images/Logo32x32_UASTC_Zstd.ktx2", + { bc7: true }, + 32, + 32, + true + ); + }); + + it("returns a promise that resolves to an uncompressed texture", function () { + return expectKTX2TranscodeResult( + "./Data/Images/Green4x4.ktx2", + { s3tc: true }, + 4, + 4, + false + ); + }); + + it("returns a promise that resolves to an uncompressed texture containing all mip levels of the original texture", function () { + var resource = Resource.createIfNeeded("./Data/Images/Green4x4Mipmap.ktx2"); + var loadPromise = resource.fetchArrayBuffer(); + return loadPromise.then(function (buffer) { + var promise = KTX2Transcoder.transcode(buffer, {}); + return promise.then(function (resolvedValue) { + expect(resolvedValue).toBeDefined(); + expect(resolvedValue.length).toEqual(3); + var dims = [4, 2, 1]; + for (var i = 0; i < resolvedValue.length; ++i) { + expect(resolvedValue[i].width).toEqual(dims[i]); + expect(resolvedValue[i].height).toEqual(dims[i]); + expect( + PixelFormat.isCompressedFormat(resolvedValue[i].internalFormat) + ).toEqual(false); + expect(resolvedValue[i].bufferView).toBeDefined(); + } + }); + }); + }); + + it("returns a promise that resolves to a compressed texture containing all mip levels of the original texture", function () { + var resource = Resource.createIfNeeded( + "./Data/Images/Green4x4Mipmap_ETC1S.ktx2" + ); + var loadPromise = resource.fetchArrayBuffer(); + return loadPromise.then(function (buffer) { + var promise = KTX2Transcoder.transcode(buffer, { etc1: true }); + return promise.then(function (resolvedValue) { + expect(resolvedValue).toBeDefined(); + expect(resolvedValue.length).toEqual(3); + var dims = [4, 2, 1]; + for (var i = 0; i < resolvedValue.length; ++i) { + expect(resolvedValue[i].width).toEqual(dims[i]); + expect(resolvedValue[i].height).toEqual(dims[i]); + expect( + PixelFormat.isCompressedFormat(resolvedValue[i].internalFormat) + ).toEqual(true); + expect(resolvedValue[i].bufferView).toBeDefined(); + } + }); + }); + }); + + it("cannot parse invalid KTX2 buffer", function () { + var invalidKTX = new Uint8Array([0, 1, 2, 3, 4, 5]); + var resolvedValue; + var rejectedError; + var promise = loadKTX2(invalidKTX.buffer); + return promise + .then(function (value) { + fail(); + }) + .otherwise(function (error) { + rejectedError = error; + expect(resolvedValue).toBeUndefined(); + expect(rejectedError).toBeInstanceOf(RuntimeError); + expect(rejectedError.message).toEqual("Invalid KTX2 file."); + }); + }); + + it("3D textures are unsupported", function () { + var resource = Resource.createIfNeeded("./Data/Images/Green4x4.ktx2"); + var loadPromise = resource.fetchArrayBuffer(); + return loadPromise.then(function (buffer) { + var invalidKTX = new Uint32Array(buffer); + invalidKTX[7] = 2; // Uint32 pixelDepth + + var resolvedValue; + var rejectedError; + var promise = loadKTX2(invalidKTX.buffer); + return promise + .then(function (value) { + fail(); + }) + .otherwise(function (error) { + rejectedError = error; + expect(resolvedValue).toBeUndefined(); + expect(rejectedError).toBeInstanceOf(RuntimeError); + expect(rejectedError.message).toEqual( + "KTX2 3D textures are unsupported." + ); + }); + }); + }); + + it("texture arrays are unsupported", function () { + var resource = Resource.createIfNeeded("./Data/Images/Green4x4.ktx2"); + var loadPromise = resource.fetchArrayBuffer(); + return loadPromise.then(function (buffer) { + var invalidKTX = new Uint32Array(buffer); + invalidKTX[8] = 15; // Uint32 layerCount + + var resolvedValue; + var rejectedError; + var promise = loadKTX2(invalidKTX.buffer); + return promise + .then(function (value) { + fail(); + }) + .otherwise(function (error) { + rejectedError = error; + expect(resolvedValue).toBeUndefined(); + expect(rejectedError).toBeInstanceOf(RuntimeError); + expect(rejectedError.message).toEqual( + "KTX2 texture arrays are not supported." + ); + }); + }); + }); +}); diff --git a/Specs/Core/loadKTXSpec.js b/Specs/Core/loadKTXSpec.js deleted file mode 100644 index 661bc66bab23..000000000000 --- a/Specs/Core/loadKTXSpec.js +++ /dev/null @@ -1,1080 +0,0 @@ -import { loadKTX } from "../../Source/Cesium.js"; -import { PixelFormat } from "../../Source/Cesium.js"; -import { Request } from "../../Source/Cesium.js"; -import { RequestErrorEvent } from "../../Source/Cesium.js"; -import { RequestScheduler } from "../../Source/Cesium.js"; -import { Resource } from "../../Source/Cesium.js"; -import { RuntimeError } from "../../Source/Cesium.js"; - -describe("Core/loadKTX", function () { - var validCompressed = new Uint8Array([ - 171, - 75, - 84, - 88, - 32, - 49, - 49, - 187, - 13, - 10, - 26, - 10, - 1, - 2, - 3, - 4, - 0, - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 241, - 131, - 0, - 0, - 8, - 25, - 0, - 0, - 4, - 0, - 0, - 0, - 4, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 8, - 0, - 0, - 0, - 224, - 7, - 224, - 7, - 0, - 0, - 0, - 0, - ]); - var validCompressedMipmap = new Uint8Array([ - 171, - 75, - 84, - 88, - 32, - 49, - 49, - 187, - 13, - 10, - 26, - 10, - 1, - 2, - 3, - 4, - 0, - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 100, - 141, - 0, - 0, - 7, - 25, - 0, - 0, - 4, - 0, - 0, - 0, - 4, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 3, - 0, - 0, - 0, - 52, - 0, - 0, - 0, - 19, - 0, - 0, - 0, - 67, - 82, - 78, - 76, - 73, - 66, - 95, - 70, - 79, - 85, - 82, - 67, - 67, - 0, - 69, - 84, - 67, - 49, - 0, - 0, - 23, - 0, - 0, - 0, - 75, - 84, - 88, - 111, - 114, - 105, - 101, - 110, - 116, - 97, - 116, - 105, - 111, - 110, - 0, - 83, - 61, - 114, - 44, - 84, - 61, - 100, - 0, - 0, - 8, - 0, - 0, - 0, - 255, - 0, - 0, - 0, - 255, - 255, - 0, - 0, - 8, - 0, - 0, - 0, - 255, - 0, - 0, - 0, - 255, - 255, - 0, - 0, - 8, - 0, - 0, - 0, - 255, - 0, - 0, - 0, - 255, - 255, - 0, - 0, - ]); - var validUncompressed = new Uint8Array([ - 171, - 75, - 84, - 88, - 32, - 49, - 49, - 187, - 13, - 10, - 26, - 10, - 1, - 2, - 3, - 4, - 1, - 20, - 0, - 0, - 1, - 0, - 0, - 0, - 8, - 25, - 0, - 0, - 88, - 128, - 0, - 0, - 8, - 25, - 0, - 0, - 4, - 0, - 0, - 0, - 4, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 32, - 0, - 0, - 0, - 27, - 0, - 0, - 0, - 75, - 84, - 88, - 79, - 114, - 105, - 101, - 110, - 116, - 97, - 116, - 105, - 111, - 110, - 0, - 83, - 61, - 114, - 44, - 84, - 61, - 100, - 44, - 82, - 61, - 105, - 0, - 0, - 64, - 0, - 0, - 0, - 0, - 255, - 0, - 255, - 0, - 255, - 0, - 255, - 0, - 255, - 0, - 255, - 0, - 255, - 0, - 255, - 0, - 255, - 0, - 255, - 0, - 255, - 0, - 255, - 0, - 255, - 0, - 255, - 0, - 255, - 0, - 255, - 0, - 255, - 0, - 255, - 0, - 255, - 0, - 255, - 0, - 255, - 0, - 255, - 0, - 255, - 0, - 255, - 0, - 255, - 0, - 255, - 0, - 255, - 0, - 255, - 0, - 255, - 0, - 255, - 0, - 255, - 0, - 255, - ]); - var validUncompressedMipmap = new Uint8Array([ - 171, - 75, - 84, - 88, - 32, - 49, - 49, - 187, - 13, - 10, - 26, - 10, - 1, - 2, - 3, - 4, - 1, - 20, - 0, - 0, - 1, - 0, - 0, - 0, - 7, - 25, - 0, - 0, - 81, - 128, - 0, - 0, - 7, - 25, - 0, - 0, - 4, - 0, - 0, - 0, - 4, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 3, - 0, - 0, - 0, - 52, - 0, - 0, - 0, - 19, - 0, - 0, - 0, - 67, - 82, - 78, - 76, - 73, - 66, - 95, - 70, - 79, - 85, - 82, - 67, - 67, - 0, - 82, - 71, - 66, - 120, - 0, - 0, - 23, - 0, - 0, - 0, - 75, - 84, - 88, - 111, - 114, - 105, - 101, - 110, - 116, - 97, - 116, - 105, - 111, - 110, - 0, - 83, - 61, - 114, - 44, - 84, - 61, - 100, - 0, - 0, - 48, - 0, - 0, - 0, - 255, - 0, - 0, - 255, - 0, - 0, - 255, - 0, - 0, - 255, - 0, - 0, - 255, - 0, - 0, - 255, - 0, - 0, - 255, - 0, - 0, - 255, - 0, - 0, - 255, - 0, - 0, - 255, - 0, - 0, - 255, - 0, - 0, - 255, - 0, - 0, - 255, - 0, - 0, - 255, - 0, - 0, - 255, - 0, - 0, - 255, - 0, - 0, - 12, - 0, - 0, - 0, - 255, - 0, - 0, - 255, - 0, - 0, - 255, - 0, - 0, - 255, - 0, - 0, - 3, - 0, - 0, - 0, - 255, - 0, - 0, - 0, - ]); - - var fakeXHR; - - beforeEach(function () { - fakeXHR = jasmine.createSpyObj("XMLHttpRequest", [ - "send", - "open", - "setRequestHeader", - "abort", - "getAllResponseHeaders", - ]); - fakeXHR.simulateLoad = function (response) { - fakeXHR.simulateHttpResponse(200, response); - }; - fakeXHR.simulateError = function () { - fakeXHR.response = ""; - if (typeof fakeXHR.onerror === "function") { - fakeXHR.onerror(); - } - }; - fakeXHR.simulateHttpResponse = function (statusCode, response) { - fakeXHR.status = statusCode; - fakeXHR.response = response; - if (typeof fakeXHR.onload === "function") { - fakeXHR.onload(); - } - }; - - spyOn(window, "XMLHttpRequest").and.returnValue(fakeXHR); - }); - - it("throws with no url", function () { - expect(function () { - loadKTX(); - }).toThrowDeveloperError(); - }); - - it("creates and sends request without any custom headers", function () { - var testUrl = "http://example.invalid/testuri"; - loadKTX(testUrl); - - expect(fakeXHR.open).toHaveBeenCalledWith("GET", testUrl, true); - expect(fakeXHR.setRequestHeader).not.toHaveBeenCalled(); - expect(fakeXHR.send).toHaveBeenCalled(); - }); - - it("returns a promise that rejects when the request errors", function () { - var testUrl = "http://example.invalid/testuri"; - var promise = loadKTX(testUrl); - - expect(promise).toBeDefined(); - - var resolvedValue; - var rejectedError; - promise.then( - function (value) { - resolvedValue = value; - }, - function (error) { - rejectedError = error; - } - ); - - expect(resolvedValue).toBeUndefined(); - expect(rejectedError).toBeUndefined(); - - fakeXHR.simulateError(); - expect(resolvedValue).toBeUndefined(); - expect(rejectedError).toBeInstanceOf(RequestErrorEvent); - expect(rejectedError.statusCode).toBeUndefined(); - expect(rejectedError.response).toBeUndefined(); - }); - - it("returns a promise that rejects when the request results in an HTTP error code", function () { - var testUrl = "http://example.invalid/testuri"; - var promise = loadKTX(testUrl); - - expect(promise).toBeDefined(); - - var resolvedValue; - var rejectedError; - promise.then( - function (value) { - resolvedValue = value; - }, - function (error) { - rejectedError = error; - } - ); - - expect(resolvedValue).toBeUndefined(); - expect(rejectedError).toBeUndefined(); - - var error = "some error"; - fakeXHR.simulateHttpResponse(404, error); - expect(resolvedValue).toBeUndefined(); - expect(rejectedError).toBeInstanceOf(RequestErrorEvent); - expect(rejectedError.statusCode).toEqual(404); - expect(rejectedError.response).toEqual(error); - }); - - it("returns a promise that resolves with undefined when the status code is 204", function () { - var testUrl = "http://example.invalid/testuri"; - var promise = loadKTX(testUrl); - - expect(promise).toBeDefined(); - - var resolved = false; - var resolvedValue; - var rejectedError; - promise.then( - function (value) { - resolved = true; - resolvedValue = value; - }, - function (error) { - rejectedError = error; - } - ); - - expect(resolvedValue).toBeUndefined(); - expect(rejectedError).toBeUndefined(); - - fakeXHR.simulateHttpResponse(204); - expect(resolved).toBe(true); - expect(resolvedValue).toBeUndefined(); - expect(rejectedError).toBeUndefined(); - }); - - it("returns a promise that resolves to an uncompressed texture when the request loads", function () { - var testUrl = "http://example.invalid/testuri"; - var promise = loadKTX(testUrl); - - expect(promise).toBeDefined(); - - var resolvedValue; - var rejectedError; - promise.then( - function (value) { - resolvedValue = value; - }, - function (error) { - rejectedError = error; - } - ); - - expect(resolvedValue).toBeUndefined(); - expect(rejectedError).toBeUndefined(); - - var response = validUncompressed.buffer; - fakeXHR.simulateLoad(response); - expect(resolvedValue).toBeDefined(); - expect(resolvedValue.width).toEqual(4); - expect(resolvedValue.height).toEqual(4); - expect( - PixelFormat.isCompressedFormat(resolvedValue.internalFormat) - ).toEqual(false); - expect(resolvedValue.bufferView).toBeDefined(); - expect(rejectedError).toBeUndefined(); - }); - - it("returns a promise that resolves to an uncompressed texture containing all mip levels of the original texture", function () { - var testUrl = "http://example.invalid/testuri"; - var promise = loadKTX(testUrl); - - expect(promise).toBeDefined(); - - var resolvedValue; - var rejectedError; - promise.then( - function (value) { - resolvedValue = value; - }, - function (error) { - rejectedError = error; - } - ); - - expect(resolvedValue).toBeUndefined(); - expect(rejectedError).toBeUndefined(); - - var response = validUncompressedMipmap.buffer; - fakeXHR.simulateLoad(response); - expect(resolvedValue).toBeDefined(); - expect(resolvedValue.length).toEqual(3); - expect(resolvedValue[0].width).toEqual(4); - expect(resolvedValue[0].height).toEqual(4); - expect( - PixelFormat.isCompressedFormat(resolvedValue[0].internalFormat) - ).toEqual(false); - expect(resolvedValue[0].bufferView).toBeDefined(); - expect(rejectedError).toBeUndefined(); - }); - - it("returns a promise that resolves to a compressed texture when the request loads", function () { - var testUrl = "http://example.invalid/testuri"; - var promise = loadKTX(testUrl); - - expect(promise).toBeDefined(); - - var resolvedValue; - var rejectedError; - promise.then( - function (value) { - resolvedValue = value; - }, - function (error) { - rejectedError = error; - } - ); - - expect(resolvedValue).toBeUndefined(); - expect(rejectedError).toBeUndefined(); - - var response = validCompressed.buffer; - fakeXHR.simulateLoad(response); - expect(resolvedValue).toBeDefined(); - expect(resolvedValue.width).toEqual(4); - expect(resolvedValue.height).toEqual(4); - expect( - PixelFormat.isCompressedFormat(resolvedValue.internalFormat) - ).toEqual(true); - expect(resolvedValue.bufferView).toBeDefined(); - expect(rejectedError).toBeUndefined(); - }); - - it("returns a promise that resolves to a compressed texture containing the all mip levels of the original texture", function () { - var testUrl = "http://example.invalid/testuri"; - var promise = loadKTX(testUrl); - - expect(promise).toBeDefined(); - - var resolvedValue; - var rejectedError; - promise.then( - function (value) { - resolvedValue = value; - }, - function (error) { - rejectedError = error; - } - ); - - expect(resolvedValue).toBeUndefined(); - expect(rejectedError).toBeUndefined(); - - var response = validCompressedMipmap.buffer; - fakeXHR.simulateLoad(response); - expect(resolvedValue).toBeDefined(); - expect(resolvedValue.length).toEqual(3); - expect(resolvedValue[0].width).toEqual(4); - expect(resolvedValue[0].height).toEqual(4); - expect( - PixelFormat.isCompressedFormat(resolvedValue[0].internalFormat) - ).toEqual(true); - expect(resolvedValue[0].bufferView).toBeDefined(); - expect(rejectedError).toBeUndefined(); - }); - - it("cannot parse invalid KTX buffer", function () { - var invalidKTX = new Uint8Array(validCompressed); - invalidKTX[0] = 0; - - var promise = loadKTX(invalidKTX.buffer); - - var resolvedValue; - var rejectedError; - promise.then( - function (value) { - resolvedValue = value; - }, - function (error) { - rejectedError = error; - } - ); - - expect(resolvedValue).toBeUndefined(); - expect(rejectedError).toBeInstanceOf(RuntimeError); - expect(rejectedError.message).toEqual("Invalid KTX file."); - }); - - it("cannot parse KTX buffer with invalid endianness", function () { - var reinterprestBuffer = new Uint32Array(validCompressed.buffer); - var invalidKTX = new Uint32Array(reinterprestBuffer); - invalidKTX[3] = 0x01020304; - - var promise = loadKTX(invalidKTX.buffer); - - var resolvedValue; - var rejectedError; - promise.then( - function (value) { - resolvedValue = value; - }, - function (error) { - rejectedError = error; - } - ); - - expect(resolvedValue).toBeUndefined(); - expect(rejectedError).toBeInstanceOf(RuntimeError); - expect(rejectedError.message).toEqual("File is the wrong endianness."); - }); - - it("cannot parse KTX buffer with invalid internal format", function () { - var reinterprestBuffer = new Uint32Array(validCompressed.buffer); - var invalidKTX = new Uint32Array(reinterprestBuffer); - invalidKTX[7] = 0; - - var promise = loadKTX(invalidKTX.buffer); - - var resolvedValue; - var rejectedError; - promise.then( - function (value) { - resolvedValue = value; - }, - function (error) { - rejectedError = error; - } - ); - - expect(resolvedValue).toBeUndefined(); - expect(rejectedError).toBeInstanceOf(RuntimeError); - expect(rejectedError.message).toEqual( - "glInternalFormat is not a valid format." - ); - }); - - it("cannot parse KTX buffer with compressed texture and invalid type", function () { - var reinterprestBuffer = new Uint32Array(validCompressed.buffer); - var invalidKTX = new Uint32Array(reinterprestBuffer); - invalidKTX[4] = 15; - - var promise = loadKTX(invalidKTX.buffer); - - var resolvedValue; - var rejectedError; - promise.then( - function (value) { - resolvedValue = value; - }, - function (error) { - rejectedError = error; - } - ); - - expect(resolvedValue).toBeUndefined(); - expect(rejectedError).toBeInstanceOf(RuntimeError); - expect(rejectedError.message).toEqual( - "glType must be zero when the texture is compressed." - ); - }); - - it("cannot parse KTX buffer with compressed texture and invalid type size", function () { - var reinterprestBuffer = new Uint32Array(validCompressed.buffer); - var invalidKTX = new Uint32Array(reinterprestBuffer); - invalidKTX[5] = 15; - - var promise = loadKTX(invalidKTX.buffer); - - var resolvedValue; - var rejectedError; - promise.then( - function (value) { - resolvedValue = value; - }, - function (error) { - rejectedError = error; - } - ); - - expect(resolvedValue).toBeUndefined(); - expect(rejectedError).toBeInstanceOf(RuntimeError); - expect(rejectedError.message).toEqual( - "The type size for compressed textures must be 1." - ); - }); - - it("cannot parse KTX buffer with uncompressed texture and base format is not the same as format", function () { - var reinterprestBuffer = new Uint32Array(validUncompressed.buffer); - var invalidKTX = new Uint32Array(reinterprestBuffer); - invalidKTX[8] = invalidKTX[6] + 1; - - var promise = loadKTX(invalidKTX.buffer); - - var resolvedValue; - var rejectedError; - promise.then( - function (value) { - resolvedValue = value; - }, - function (error) { - rejectedError = error; - } - ); - - expect(resolvedValue).toBeUndefined(); - expect(rejectedError).toBeInstanceOf(RuntimeError); - expect(rejectedError.message).toEqual( - "The base internal format must be the same as the format for uncompressed textures." - ); - }); - - it("3D textures are unsupported", function () { - var reinterprestBuffer = new Uint32Array(validUncompressed.buffer); - var invalidKTX = new Uint32Array(reinterprestBuffer); - invalidKTX[11] = 15; - - var promise = loadKTX(invalidKTX.buffer); - - var resolvedValue; - var rejectedError; - promise.then( - function (value) { - resolvedValue = value; - }, - function (error) { - rejectedError = error; - } - ); - - expect(resolvedValue).toBeUndefined(); - expect(rejectedError).toBeInstanceOf(RuntimeError); - expect(rejectedError.message).toEqual("3D textures are unsupported."); - }); - - it("texture arrays are unsupported", function () { - var reinterprestBuffer = new Uint32Array(validUncompressed.buffer); - var invalidKTX = new Uint32Array(reinterprestBuffer); - invalidKTX[12] = 15; - - var promise = loadKTX(invalidKTX.buffer); - - var resolvedValue; - var rejectedError; - promise.then( - function (value) { - resolvedValue = value; - }, - function (error) { - rejectedError = error; - } - ); - - expect(resolvedValue).toBeUndefined(); - expect(rejectedError).toBeInstanceOf(RuntimeError); - expect(rejectedError.message).toEqual("Texture arrays are unsupported."); - }); - - it("cubemaps are supported", function () { - var reinterprestBuffer = new Uint32Array(validUncompressed.buffer); - var cubemapKTX = new Uint32Array(reinterprestBuffer); - cubemapKTX[13] = 6; - - var promise = loadKTX(cubemapKTX.buffer); - - promise.then(function (value) { - expect(value).toBeDefined(); - }); - }); - - it("returns undefined if the request is throttled", function () { - var oldMaximumRequests = RequestScheduler.maximumRequests; - RequestScheduler.maximumRequests = 0; - - var promise = loadKTX( - new Resource({ - url: "http://example.invalid/testuri", - request: new Request({ - throttle: true, - }), - }) - ); - expect(promise).toBeUndefined(); - - RequestScheduler.maximumRequests = oldMaximumRequests; - }); -}); diff --git a/Specs/Data/EnvironmentMap/kiara_6_afternoon_2k_ibl.ktx b/Specs/Data/EnvironmentMap/kiara_6_afternoon_2k_ibl.ktx deleted file mode 100644 index 7a8880d04115..000000000000 Binary files a/Specs/Data/EnvironmentMap/kiara_6_afternoon_2k_ibl.ktx and /dev/null differ diff --git a/Specs/Data/EnvironmentMap/kiara_6_afternoon_2k_ibl.ktx2 b/Specs/Data/EnvironmentMap/kiara_6_afternoon_2k_ibl.ktx2 new file mode 100644 index 000000000000..ac10d770d05d Binary files /dev/null and b/Specs/Data/EnvironmentMap/kiara_6_afternoon_2k_ibl.ktx2 differ diff --git a/Specs/Data/Images/Green4x4.crn b/Specs/Data/Images/Green4x4.crn deleted file mode 100644 index d32561e1af30..000000000000 Binary files a/Specs/Data/Images/Green4x4.crn and /dev/null differ diff --git a/Specs/Data/Images/Green4x4.ktx b/Specs/Data/Images/Green4x4.ktx deleted file mode 100644 index b251f62c3f5e..000000000000 Binary files a/Specs/Data/Images/Green4x4.ktx and /dev/null differ diff --git a/Specs/Data/Images/Green4x4.ktx2 b/Specs/Data/Images/Green4x4.ktx2 new file mode 100644 index 000000000000..84ea605d76f7 Binary files /dev/null and b/Specs/Data/Images/Green4x4.ktx2 differ diff --git a/Specs/Data/Images/Green4x4DXT1.ktx b/Specs/Data/Images/Green4x4DXT1.ktx deleted file mode 100644 index 7d013e8d2e94..000000000000 Binary files a/Specs/Data/Images/Green4x4DXT1.ktx and /dev/null differ diff --git a/Specs/Data/Images/Green4x4ETC1.ktx b/Specs/Data/Images/Green4x4ETC1.ktx deleted file mode 100644 index d3d1123c0906..000000000000 Binary files a/Specs/Data/Images/Green4x4ETC1.ktx and /dev/null differ diff --git a/Specs/Data/Images/Green4x4Mipmap.ktx2 b/Specs/Data/Images/Green4x4Mipmap.ktx2 new file mode 100644 index 000000000000..fcd642886068 Binary files /dev/null and b/Specs/Data/Images/Green4x4Mipmap.ktx2 differ diff --git a/Specs/Data/Images/Green4x4Mipmap_ETC1S.ktx2 b/Specs/Data/Images/Green4x4Mipmap_ETC1S.ktx2 new file mode 100644 index 000000000000..7a53dacc0992 Binary files /dev/null and b/Specs/Data/Images/Green4x4Mipmap_ETC1S.ktx2 differ diff --git a/Specs/Data/Images/Green4x4PVR.ktx b/Specs/Data/Images/Green4x4PVR.ktx deleted file mode 100644 index c6fe6296866f..000000000000 Binary files a/Specs/Data/Images/Green4x4PVR.ktx and /dev/null differ diff --git a/Specs/Data/Images/Green4x4_ETC1S.ktx2 b/Specs/Data/Images/Green4x4_ETC1S.ktx2 new file mode 100644 index 000000000000..41f3bc467413 Binary files /dev/null and b/Specs/Data/Images/Green4x4_ETC1S.ktx2 differ diff --git a/Specs/Data/Images/Logo32x32_UASTC_Zstd.ktx2 b/Specs/Data/Images/Logo32x32_UASTC_Zstd.ktx2 new file mode 100644 index 000000000000..6a27bbc914e5 Binary files /dev/null and b/Specs/Data/Images/Logo32x32_UASTC_Zstd.ktx2 differ diff --git a/Specs/Data/Models/Box-Textured-CRN-Binary/CesiumTexturedBoxTest.glb b/Specs/Data/Models/Box-Textured-CRN-Binary/CesiumTexturedBoxTest.glb deleted file mode 100644 index 7e988e8b0210..000000000000 Binary files a/Specs/Data/Models/Box-Textured-CRN-Binary/CesiumTexturedBoxTest.glb and /dev/null differ diff --git a/Specs/Data/Models/Box-Textured-CRN-Embedded/CesiumTexturedBoxTest.gltf b/Specs/Data/Models/Box-Textured-CRN-Embedded/CesiumTexturedBoxTest.gltf deleted file mode 100644 index fa3a353d192c..000000000000 --- a/Specs/Data/Models/Box-Textured-CRN-Embedded/CesiumTexturedBoxTest.gltf +++ /dev/null @@ -1,276 +0,0 @@ -{ - "accessors": { - "accessor_21": { - "bufferView": "bufferView_1", - "byteOffset": 0, - "byteStride": 0, - "componentType": 5123, - "count": 36, - "type": "SCALAR" - }, - "accessor_23": { - "bufferView": "bufferView_0", - "byteOffset": 0, - "byteStride": 0, - "componentType": 5126, - "count": 24, - "max": [ - 0.5, - 0.5, - 0.5 - ], - "min": [ - -0.5, - -0.5, - -0.5 - ], - "type": "VEC3" - }, - "accessor_25": { - "bufferView": "bufferView_0", - "byteOffset": 288, - "byteStride": 0, - "componentType": 5126, - "count": 24, - "max": [ - 1, - 1, - 1 - ], - "min": [ - -1, - -1, - -1 - ], - "type": "VEC3" - }, - "accessor_27": { - "bufferView": "bufferView_0", - "byteOffset": 576, - "byteStride": 0, - "componentType": 5126, - "count": 24, - "max": [ - 6, - 1 - ], - "min": [ - 0, - 0 - ], - "type": "VEC2" - } - }, - "animations": {}, - "asset": { - "generator": "collada2gltf@", - "premultipliedAlpha": true, - "profile": { - "api": "WebGL", - "version": "1.0.2" - }, - "version": "1.0" - }, - "bufferViews": { - "bufferView_0": { - "buffer": "CesiumTexturedBoxTest", - "byteLength": 768, - "byteOffset": 0, - "target": 34962 - }, - "bufferView_1": { - "buffer": "CesiumTexturedBoxTest", - "byteLength": 72, - "byteOffset": 768, - "target": 34963 - } - }, - "buffers": { - "CesiumTexturedBoxTest": { - "type": "arraybuffer", - "byteLength": 840, - "uri": "data:application/octet-stream;base64,AAAAvwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAvwAAAD8AAAC/AAAAPwAAAD8AAAC/AAAAPwAAAD8AAAC/AAAAPwAAAD8AAAA/AAAAPwAAAL8AAAC/AAAAPwAAAL8AAAA/AAAAvwAAAD8AAAC/AAAAPwAAAD8AAAC/AAAAvwAAAL8AAAC/AAAAPwAAAL8AAAC/AAAAPwAAAD8AAAA/AAAAvwAAAD8AAAA/AAAAPwAAAL8AAAA/AAAAvwAAAL8AAAA/AAAAvwAAAD8AAAA/AAAAvwAAAD8AAAC/AAAAvwAAAL8AAAA/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAA/AAAAvwAAAL8AAAC/AAAAPwAAAL8AAAA/AAAAPwAAAL8AAAC/AAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAADAQAAAAAAAAKBAAAAAAAAAwED+/38/AACgQP7/fz8AAIBAAAAAAAAAoEAAAAAAAACAQAAAgD8AAKBAAACAPwAAAEAAAAAAAACAPwAAAAAAAABAAACAPwAAgD8AAIA/AABAQAAAAAAAAIBAAAAAAAAAQEAAAIA/AACAQAAAgD8AAEBAAAAAAAAAAEAAAAAAAABAQAAAgD8AAABAAACAPwAAAAAAAAAAAAAAAP7/fz8AAIA/AAAAAAAAgD/+/38/AAABAAIAAwACAAEABAAFAAYABwAGAAUACAAJAAoACwAKAAkADAANAA4ADwAOAA0AEAARABIAEwASABEAFAAVABYAFwAWABUA" - } - }, - "images": { - "Image0001": { - "name": "Image0001", - "uri": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+ip1sAAAAASUVORK5CYII=", - "extras": { - "compressedImage3DTiles": { - "crunch": { - "uri": "data:image/crn;base64,SHgASvv9AAAFlRpEAIAAgAEBAAAAAAAAAAAAAAAAAAAAAABKAAC4AE8AAQIAASsAdAAAAAAAAAAAAAAAAAAAAAAAfQACLQAAAqoAgnAA0wxAxABM1vqhQR4PUQKytgIE4wGEEIIKAL7+GiFANAMaDWRm8ENz89/XXoAAISoXJZtVe3l4rbbF7curHPHoJCSQ0CIAAAEBY0beiq4JVXxed+SQIAAACxESaN1oA9c9CS3aVe2qkwrehDP/ze+bpWAFYklTaqqCb0KqBA7+55nw0ZYedBoAABoAIbauOQlkKCAQAAAAAsMsP/OPmOZ2z0mW5s+abbQAZppmemfv989/372AAMZsANtQQQUAUCt8JR7jEnnvtIma6DnKZIAEAWBgEoCAgA2I8sRAWMZ4DI9A9MPeNheAVzYPjtAb2D0Bz5sG0BAEAAWAsFtC3dTu6uFXBRdhbp4eWAjYCUoK0BYNNWG9Sgb8gVkgVjZTRCgwC6BSjSzkJkyIiItYldwXRaPWBh0I5Z9RsEAbchXcDPgHAKaFOFjHv+r1rWtZ/vIEz+oD+fu8Dt/a6a1rWLB1AOQLmr1rWqsBGBlIwbYGEcs47rFP004GOFHx2gO1gEBYg7LWPmeUCYgWEIbFd6EGOX146KId3s6WwEeg63YM9QFZ1DAGGgooAsU6ACwFuXy9PCkeOYwwCGzeT0hCwhS3LBoFKcXwDIVfa6vl9T7jqeA449vxfs+/+7Pzx+JW9AAG3m1QwgxRQABeX6Qhl7InpDEQRAEFdBCGglO4iAFGIwQhgIgudQl0qcq8qMqCoCfEChpBCDADfcB3CBMzKys2na1WzVtTZ8ywPkBTg/4B0mBREm2AAABfSDC8bnWouLmguCitlpS3qpduH5nYo/AuZvlVte5cnZc9c5SRCGa8AAPgAOBRaFjsvQc/o5XPe+EHC5rr8+5HdjNk52uhsy9LwAAAAAAKgAiuKMqubSqaZX00/owxhoAFhs9+jAm7F0fd5pyO2WKeQAAANAB10e5qr7y2uI9GGgAAAAgACWDHgzWzerutty7vAC8B0Zsyrvbd39M2wu+ILDhI8mNJXJ3QAAAABxAlVfs8fxh2YjqnTxgAI7nb3epejAAAAAAB1k8vTem//1Zky9Vm5a64wsI19t+p9aNkKdNFLRq7X4cGlS54qxPXAKx+yCc636HiVrHISRhYTyKXfN6drc8AysbVW0MgOF3218sP4Q2yzRFVT/3Ox4r4aEMunXywVobH/QQ81Hpnq3/x8MWjk93Ba1gAAAhYc5qsPn02EPNqx8z8Ps4bP5OrP/zQ44N0fEgs+aedyHL9fezU8m52bYNABsijLD2LBbetzfp1l6LvFhtvO4dmXVz8/ch2wA5Xe6l3FLupd9tveFEln5btr6m9Dr/tyenLQzxgHlGVyy1S1tPd/Oat/e+HPv17yHL3ZGKLnSTUoaKs0sbqpr3eHHhtdAvdnDbwYO9eHlr70evJokZVMNvltY++zm3VPjBP31EGdalm9i0vv+5te/XpqV/tRZMAH7IpoprMibLvbkk59P7QT1VEGdnR+8tHDQneIUdDsfPN6TJTxZLWmKn1zgAAADzBk10anTk8fyfZjtq/XXdfPbT6Z7WmFtqeKZA9RwSan9aGFn3wgBv9oInjk4uL25FNEkwuW3MgmY+GHMal4vZ/1E/QAAAAAUrbmeEU3f49vrq44xIB0qhkuU6OTY3nDWAAAAAAAABwAC2kcmpPVVPqjBeAAH3RTsliMqWYPNMMxBUAAAAACTAkb/GXY35+jg9qv4HXgoAIAAdKoZLn5E46f4bN+SaTgj5ZZ12ayJ7SYADwROsUGBZ6n+VelzR+nwkjF+8AAAAAHgAAGrngJavn/MB9K8HIe8+XlYpl1fkxDb0E5Y4CgAAAAA==" - } - } - } - } - }, - "materials": { - "Effect-Texture": { - "name": "Texture", - "technique": "technique0", - "values": { - "diffuse": "texture_Image0001", - "shininess": 256, - "specular": [ - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224, - 1 - ] - } - } - }, - "meshes": { - "Geometry-mesh002": { - "name": "Mesh", - "primitives": [ - { - "attributes": { - "NORMAL": "accessor_25", - "POSITION": "accessor_23", - "TEXCOORD_0": "accessor_27" - }, - "indices": "accessor_21", - "material": "Effect-Texture", - "mode": 4 - } - ] - } - }, - "nodes": { - "rootNode": { - "children": [], - "meshes": [ - "Geometry-mesh002" - ], - "matrix": [ - 1, - 0, - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 0, - 1 - ] - } - }, - "programs": { - "program_0": { - "attributes": [ - "a_normal", - "a_position", - "a_texcoord0" - ], - "fragmentShader": "CesiumTexturedBoxTest0FS", - "vertexShader": "CesiumTexturedBoxTest0VS" - } - }, - "samplers": { - "sampler_0": { - "magFilter": 9729, - "minFilter": 9729, - "wrapS": 10497, - "wrapT": 10497 - } - }, - "scene": "defaultScene", - "scenes": { - "defaultScene": { - "nodes": [ - "rootNode" - ] - } - }, - "shaders": { - "CesiumTexturedBoxTest0FS": { - "type": 35632, - "uri": "data:text/plain;base64,cHJlY2lzaW9uIGhpZ2hwIGZsb2F0Ow0KdmFyeWluZyB2ZWMzIHZfbm9ybWFsOw0KdmFyeWluZyB2ZWMyIHZfdGV4Y29vcmQwOw0KdW5pZm9ybSBzYW1wbGVyMkQgdV9kaWZmdXNlOw0KdW5pZm9ybSB2ZWM0IHVfc3BlY3VsYXI7DQp1bmlmb3JtIGZsb2F0IHVfc2hpbmluZXNzOw0Kdm9pZCBtYWluKHZvaWQpIHsNCnZlYzMgbm9ybWFsID0gbm9ybWFsaXplKHZfbm9ybWFsKTsNCnZlYzQgY29sb3IgPSB2ZWM0KDAuLCAwLiwgMC4sIDAuKTsNCnZlYzQgZGlmZnVzZSA9IHZlYzQoMC4sIDAuLCAwLiwgMS4pOw0KdmVjNCBzcGVjdWxhcjsNCmRpZmZ1c2UgPSB0ZXh0dXJlMkQodV9kaWZmdXNlLCB2X3RleGNvb3JkMCk7DQpzcGVjdWxhciA9IHVfc3BlY3VsYXI7DQpkaWZmdXNlLnh5eiAqPSBtYXgoZG90KG5vcm1hbCx2ZWMzKDAuLDAuLDEuKSksIDAuKTsNCmNvbG9yLnh5eiArPSBkaWZmdXNlLnh5ejsNCmNvbG9yID0gdmVjNChjb2xvci5yZ2IgKiBkaWZmdXNlLmEsIGRpZmZ1c2UuYSk7DQpnbF9GcmFnQ29sb3IgPSBjb2xvcjsNCn0NCg==" - }, - "CesiumTexturedBoxTest0VS": { - "type": 35633, - "uri": "data:text/plain;base64,cHJlY2lzaW9uIGhpZ2hwIGZsb2F0Ow0KYXR0cmlidXRlIHZlYzMgYV9wb3NpdGlvbjsNCmF0dHJpYnV0ZSB2ZWMzIGFfbm9ybWFsOw0KdmFyeWluZyB2ZWMzIHZfbm9ybWFsOw0KdW5pZm9ybSBtYXQzIHVfbm9ybWFsTWF0cml4Ow0KdW5pZm9ybSBtYXQ0IHVfbW9kZWxWaWV3TWF0cml4Ow0KdW5pZm9ybSBtYXQ0IHVfcHJvamVjdGlvbk1hdHJpeDsNCmF0dHJpYnV0ZSB2ZWMyIGFfdGV4Y29vcmQwOw0KdmFyeWluZyB2ZWMyIHZfdGV4Y29vcmQwOw0Kdm9pZCBtYWluKHZvaWQpIHsNCnZlYzQgcG9zID0gdV9tb2RlbFZpZXdNYXRyaXggKiB2ZWM0KGFfcG9zaXRpb24sMS4wKTsNCnZfbm9ybWFsID0gdV9ub3JtYWxNYXRyaXggKiBhX25vcm1hbDsNCnZfdGV4Y29vcmQwID0gYV90ZXhjb29yZDA7DQpnbF9Qb3NpdGlvbiA9IHVfcHJvamVjdGlvbk1hdHJpeCAqIHBvczsNCn0NCg==" - } - }, - "skins": {}, - "techniques": { - "technique0": { - "attributes": { - "a_normal": "normal", - "a_position": "position", - "a_texcoord0": "texcoord0" - }, - "parameters": { - "diffuse": { - "type": 35678 - }, - "modelViewMatrix": { - "semantic": "MODELVIEW", - "type": 35676 - }, - "normal": { - "semantic": "NORMAL", - "type": 35665 - }, - "normalMatrix": { - "semantic": "MODELVIEWINVERSETRANSPOSE", - "type": 35675 - }, - "position": { - "semantic": "POSITION", - "type": 35665 - }, - "projectionMatrix": { - "semantic": "PROJECTION", - "type": 35676 - }, - "shininess": { - "type": 5126 - }, - "specular": { - "type": 35666 - }, - "texcoord0": { - "semantic": "TEXCOORD_0", - "type": 35664 - } - }, - "program": "program_0", - "states": { - "enable": [ - 2929, - 2884 - ] - }, - "uniforms": { - "u_diffuse": "diffuse", - "u_modelViewMatrix": "modelViewMatrix", - "u_normalMatrix": "normalMatrix", - "u_projectionMatrix": "projectionMatrix", - "u_shininess": "shininess", - "u_specular": "specular" - } - } - }, - "textures": { - "texture_Image0001": { - "format": 6408, - "internalFormat": 6408, - "sampler": "sampler_0", - "source": "Image0001", - "target": 3553, - "type": 5121 - } - }, - "cameras": {}, - "extensionsUsed": [] -} diff --git a/Specs/Data/Models/Box-Textured-CRN/CesiumTexturedBoxTest.gltf b/Specs/Data/Models/Box-Textured-CRN/CesiumTexturedBoxTest.gltf deleted file mode 100644 index 23be67a6fefb..000000000000 --- a/Specs/Data/Models/Box-Textured-CRN/CesiumTexturedBoxTest.gltf +++ /dev/null @@ -1,276 +0,0 @@ -{ - "accessors": { - "accessor_21": { - "bufferView": "bufferView_1", - "byteOffset": 0, - "byteStride": 0, - "componentType": 5123, - "count": 36, - "type": "SCALAR" - }, - "accessor_23": { - "bufferView": "bufferView_0", - "byteOffset": 0, - "byteStride": 0, - "componentType": 5126, - "count": 24, - "max": [ - 0.5, - 0.5, - 0.5 - ], - "min": [ - -0.5, - -0.5, - -0.5 - ], - "type": "VEC3" - }, - "accessor_25": { - "bufferView": "bufferView_0", - "byteOffset": 288, - "byteStride": 0, - "componentType": 5126, - "count": 24, - "max": [ - 1, - 1, - 1 - ], - "min": [ - -1, - -1, - -1 - ], - "type": "VEC3" - }, - "accessor_27": { - "bufferView": "bufferView_0", - "byteOffset": 576, - "byteStride": 0, - "componentType": 5126, - "count": 24, - "max": [ - 6, - 1 - ], - "min": [ - 0, - 0 - ], - "type": "VEC2" - } - }, - "animations": {}, - "asset": { - "generator": "collada2gltf@", - "premultipliedAlpha": true, - "profile": { - "api": "WebGL", - "version": "1.0.2" - }, - "version": "1.0" - }, - "bufferViews": { - "bufferView_0": { - "buffer": "CesiumTexturedBoxTest", - "byteLength": 768, - "byteOffset": 0, - "target": 34962 - }, - "bufferView_1": { - "buffer": "CesiumTexturedBoxTest", - "byteLength": 72, - "byteOffset": 768, - "target": 34963 - } - }, - "buffers": { - "CesiumTexturedBoxTest": { - "type": "arraybuffer", - "byteLength": 840, - "uri": "data:application/octet-stream;base64,AAAAvwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAvwAAAD8AAAC/AAAAPwAAAD8AAAC/AAAAPwAAAD8AAAC/AAAAPwAAAD8AAAA/AAAAPwAAAL8AAAC/AAAAPwAAAL8AAAA/AAAAvwAAAD8AAAC/AAAAPwAAAD8AAAC/AAAAvwAAAL8AAAC/AAAAPwAAAL8AAAC/AAAAPwAAAD8AAAA/AAAAvwAAAD8AAAA/AAAAPwAAAL8AAAA/AAAAvwAAAL8AAAA/AAAAvwAAAD8AAAA/AAAAvwAAAD8AAAC/AAAAvwAAAL8AAAA/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAA/AAAAvwAAAL8AAAC/AAAAPwAAAL8AAAA/AAAAPwAAAL8AAAC/AAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAADAQAAAAAAAAKBAAAAAAAAAwED+/38/AACgQP7/fz8AAIBAAAAAAAAAoEAAAAAAAACAQAAAgD8AAKBAAACAPwAAAEAAAAAAAACAPwAAAAAAAABAAACAPwAAgD8AAIA/AABAQAAAAAAAAIBAAAAAAAAAQEAAAIA/AACAQAAAgD8AAEBAAAAAAAAAAEAAAAAAAABAQAAAgD8AAABAAACAPwAAAAAAAAAAAAAAAP7/fz8AAIA/AAAAAAAAgD/+/38/AAABAAIAAwACAAEABAAFAAYABwAGAAUACAAJAAoACwAKAAkADAANAA4ADwAOAA0AEAARABIAEwASABEAFAAVABYAFwAWABUA" - } - }, - "images": { - "Image0001": { - "name": "Image0001", - "uri": "Image0001.png", - "extras": { - "compressedImage3DTiles": { - "crunch": { - "uri": "Image0001-crunch.crn" - } - } - } - } - }, - "materials": { - "Effect-Texture": { - "name": "Texture", - "technique": "technique0", - "values": { - "diffuse": "texture_Image0001", - "shininess": 256, - "specular": [ - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224, - 1 - ] - } - } - }, - "meshes": { - "Geometry-mesh002": { - "name": "Mesh", - "primitives": [ - { - "attributes": { - "NORMAL": "accessor_25", - "POSITION": "accessor_23", - "TEXCOORD_0": "accessor_27" - }, - "indices": "accessor_21", - "material": "Effect-Texture", - "mode": 4 - } - ] - } - }, - "nodes": { - "rootNode": { - "children": [], - "meshes": [ - "Geometry-mesh002" - ], - "matrix": [ - 1, - 0, - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 0, - 1 - ] - } - }, - "programs": { - "program_0": { - "attributes": [ - "a_normal", - "a_position", - "a_texcoord0" - ], - "fragmentShader": "CesiumTexturedBoxTest0FS", - "vertexShader": "CesiumTexturedBoxTest0VS" - } - }, - "samplers": { - "sampler_0": { - "magFilter": 9729, - "minFilter": 9729, - "wrapS": 10497, - "wrapT": 10497 - } - }, - "scene": "defaultScene", - "scenes": { - "defaultScene": { - "nodes": [ - "rootNode" - ] - } - }, - "shaders": { - "CesiumTexturedBoxTest0FS": { - "type": 35632, - "uri": "data:text/plain;base64,cHJlY2lzaW9uIGhpZ2hwIGZsb2F0Ow0KdmFyeWluZyB2ZWMzIHZfbm9ybWFsOw0KdmFyeWluZyB2ZWMyIHZfdGV4Y29vcmQwOw0KdW5pZm9ybSBzYW1wbGVyMkQgdV9kaWZmdXNlOw0KdW5pZm9ybSB2ZWM0IHVfc3BlY3VsYXI7DQp1bmlmb3JtIGZsb2F0IHVfc2hpbmluZXNzOw0Kdm9pZCBtYWluKHZvaWQpIHsNCnZlYzMgbm9ybWFsID0gbm9ybWFsaXplKHZfbm9ybWFsKTsNCnZlYzQgY29sb3IgPSB2ZWM0KDAuLCAwLiwgMC4sIDAuKTsNCnZlYzQgZGlmZnVzZSA9IHZlYzQoMC4sIDAuLCAwLiwgMS4pOw0KdmVjNCBzcGVjdWxhcjsNCmRpZmZ1c2UgPSB0ZXh0dXJlMkQodV9kaWZmdXNlLCB2X3RleGNvb3JkMCk7DQpzcGVjdWxhciA9IHVfc3BlY3VsYXI7DQpkaWZmdXNlLnh5eiAqPSBtYXgoZG90KG5vcm1hbCx2ZWMzKDAuLDAuLDEuKSksIDAuKTsNCmNvbG9yLnh5eiArPSBkaWZmdXNlLnh5ejsNCmNvbG9yID0gdmVjNChjb2xvci5yZ2IgKiBkaWZmdXNlLmEsIGRpZmZ1c2UuYSk7DQpnbF9GcmFnQ29sb3IgPSBjb2xvcjsNCn0NCg==" - }, - "CesiumTexturedBoxTest0VS": { - "type": 35633, - "uri": "data:text/plain;base64,cHJlY2lzaW9uIGhpZ2hwIGZsb2F0Ow0KYXR0cmlidXRlIHZlYzMgYV9wb3NpdGlvbjsNCmF0dHJpYnV0ZSB2ZWMzIGFfbm9ybWFsOw0KdmFyeWluZyB2ZWMzIHZfbm9ybWFsOw0KdW5pZm9ybSBtYXQzIHVfbm9ybWFsTWF0cml4Ow0KdW5pZm9ybSBtYXQ0IHVfbW9kZWxWaWV3TWF0cml4Ow0KdW5pZm9ybSBtYXQ0IHVfcHJvamVjdGlvbk1hdHJpeDsNCmF0dHJpYnV0ZSB2ZWMyIGFfdGV4Y29vcmQwOw0KdmFyeWluZyB2ZWMyIHZfdGV4Y29vcmQwOw0Kdm9pZCBtYWluKHZvaWQpIHsNCnZlYzQgcG9zID0gdV9tb2RlbFZpZXdNYXRyaXggKiB2ZWM0KGFfcG9zaXRpb24sMS4wKTsNCnZfbm9ybWFsID0gdV9ub3JtYWxNYXRyaXggKiBhX25vcm1hbDsNCnZfdGV4Y29vcmQwID0gYV90ZXhjb29yZDA7DQpnbF9Qb3NpdGlvbiA9IHVfcHJvamVjdGlvbk1hdHJpeCAqIHBvczsNCn0NCg==" - } - }, - "skins": {}, - "techniques": { - "technique0": { - "attributes": { - "a_normal": "normal", - "a_position": "position", - "a_texcoord0": "texcoord0" - }, - "parameters": { - "diffuse": { - "type": 35678 - }, - "modelViewMatrix": { - "semantic": "MODELVIEW", - "type": 35676 - }, - "normal": { - "semantic": "NORMAL", - "type": 35665 - }, - "normalMatrix": { - "semantic": "MODELVIEWINVERSETRANSPOSE", - "type": 35675 - }, - "position": { - "semantic": "POSITION", - "type": 35665 - }, - "projectionMatrix": { - "semantic": "PROJECTION", - "type": 35676 - }, - "shininess": { - "type": 5126 - }, - "specular": { - "type": 35666 - }, - "texcoord0": { - "semantic": "TEXCOORD_0", - "type": 35664 - } - }, - "program": "program_0", - "states": { - "enable": [ - 2929, - 2884 - ] - }, - "uniforms": { - "u_diffuse": "diffuse", - "u_modelViewMatrix": "modelViewMatrix", - "u_normalMatrix": "normalMatrix", - "u_projectionMatrix": "projectionMatrix", - "u_shininess": "shininess", - "u_specular": "specular" - } - } - }, - "textures": { - "texture_Image0001": { - "format": 6408, - "internalFormat": 6408, - "sampler": "sampler_0", - "source": "Image0001", - "target": 3553, - "type": 5121 - } - }, - "cameras": {}, - "extensionsUsed": [] -} diff --git a/Specs/Data/Models/Box-Textured-CRN/Image0001-crunch.crn b/Specs/Data/Models/Box-Textured-CRN/Image0001-crunch.crn deleted file mode 100644 index ff524c5fb28c..000000000000 Binary files a/Specs/Data/Models/Box-Textured-CRN/Image0001-crunch.crn and /dev/null differ diff --git a/Specs/Data/Models/Box-Textured-CRN/Image0001.png b/Specs/Data/Models/Box-Textured-CRN/Image0001.png deleted file mode 100644 index 073fcf40a183..000000000000 Binary files a/Specs/Data/Models/Box-Textured-CRN/Image0001.png and /dev/null differ diff --git a/Specs/Data/Models/Box-Textured-KTX-Binary/CesiumTexturedBoxTest.glb b/Specs/Data/Models/Box-Textured-KTX-Binary/CesiumTexturedBoxTest.glb deleted file mode 100644 index ec4774259c3b..000000000000 Binary files a/Specs/Data/Models/Box-Textured-KTX-Binary/CesiumTexturedBoxTest.glb and /dev/null differ diff --git a/Specs/Data/Models/Box-Textured-KTX-Embedded/CesiumTexturedBoxTest.gltf b/Specs/Data/Models/Box-Textured-KTX-Embedded/CesiumTexturedBoxTest.gltf deleted file mode 100644 index 1b59277eb682..000000000000 --- a/Specs/Data/Models/Box-Textured-KTX-Embedded/CesiumTexturedBoxTest.gltf +++ /dev/null @@ -1,282 +0,0 @@ -{ - "accessors": { - "accessor_21": { - "bufferView": "bufferView_1", - "byteOffset": 0, - "byteStride": 0, - "componentType": 5123, - "count": 36, - "type": "SCALAR" - }, - "accessor_23": { - "bufferView": "bufferView_0", - "byteOffset": 0, - "byteStride": 0, - "componentType": 5126, - "count": 24, - "max": [ - 0.5, - 0.5, - 0.5 - ], - "min": [ - -0.5, - -0.5, - -0.5 - ], - "type": "VEC3" - }, - "accessor_25": { - "bufferView": "bufferView_0", - "byteOffset": 288, - "byteStride": 0, - "componentType": 5126, - "count": 24, - "max": [ - 1, - 1, - 1 - ], - "min": [ - -1, - -1, - -1 - ], - "type": "VEC3" - }, - "accessor_27": { - "bufferView": "bufferView_0", - "byteOffset": 576, - "byteStride": 0, - "componentType": 5126, - "count": 24, - "max": [ - 6, - 1 - ], - "min": [ - 0, - 0 - ], - "type": "VEC2" - } - }, - "animations": {}, - "asset": { - "generator": "collada2gltf@", - "premultipliedAlpha": true, - "profile": { - "api": "WebGL", - "version": "1.0.2" - }, - "version": "1.0" - }, - "bufferViews": { - "bufferView_0": { - "buffer": "CesiumTexturedBoxTest", - "byteLength": 768, - "byteOffset": 0, - "target": 34962 - }, - "bufferView_1": { - "buffer": "CesiumTexturedBoxTest", - "byteLength": 72, - "byteOffset": 768, - "target": 34963 - } - }, - "buffers": { - "CesiumTexturedBoxTest": { - "type": "arraybuffer", - "byteLength": 840, - "uri": "data:application/octet-stream;base64,AAAAvwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAvwAAAD8AAAC/AAAAPwAAAD8AAAC/AAAAPwAAAD8AAAC/AAAAPwAAAD8AAAA/AAAAPwAAAL8AAAC/AAAAPwAAAL8AAAA/AAAAvwAAAD8AAAC/AAAAPwAAAD8AAAC/AAAAvwAAAL8AAAC/AAAAPwAAAL8AAAC/AAAAPwAAAD8AAAA/AAAAvwAAAD8AAAA/AAAAPwAAAL8AAAA/AAAAvwAAAL8AAAA/AAAAvwAAAD8AAAA/AAAAvwAAAD8AAAC/AAAAvwAAAL8AAAA/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAA/AAAAvwAAAL8AAAC/AAAAPwAAAL8AAAA/AAAAPwAAAL8AAAC/AAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAADAQAAAAAAAAKBAAAAAAAAAwED+/38/AACgQP7/fz8AAIBAAAAAAAAAoEAAAAAAAACAQAAAgD8AAKBAAACAPwAAAEAAAAAAAACAPwAAAAAAAABAAACAPwAAgD8AAIA/AABAQAAAAAAAAIBAAAAAAAAAQEAAAIA/AACAQAAAgD8AAEBAAAAAAAAAAEAAAAAAAABAQAAAgD8AAABAAACAPwAAAAAAAAAAAAAAAP7/fz8AAIA/AAAAAAAAgD/+/38/AAABAAIAAwACAAEABAAFAAYABwAGAAUACAAJAAoACwAKAAkADAANAA4ADwAOAA0AEAARABIAEwASABEAFAAVABYAFwAWABUA" - } - }, - "images": { - "Image0001": { - "name": "Image0001", - "uri": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+ip1sAAAAASUVORK5CYII=", - "extras": { - "compressedImage3DTiles": { - "s3tc": { - "uri": "data:image/ktx;base64,q0tUWCAxMbsNChoKAQIDBAAAAAABAAAAAAAAAPCDAAAHGQAAgAAAAIAAAAAAAAAAAAAAAAEAAAABAAAANAAAABMAAABDUk5MSUJfRk9VUkNDAERYVDEAABcAAABLVFhvcmllbnRhdGlvbgBTPXIsVD1kAAAAIAAAHOd4xqqqqqoc53jGqqqqqhzneMaqqqqqHOd4xqqqqqoc53jGqqqqqhzneMaqqqqqHOd4xqqqqqoc53jGqqqqqhzneMaqqqqqHOd4xqqqqqoc53jGqqqqqhzneMaqqqqqHOd4xqqqqqr73rvWqqqqqvvmu8aqqqqq++bb1v///6r75rvGqqqqqtvm28aqqqqq++bb1v////8c53jGqqqqqhzneMaqqqqqHOd4xqqqqqoc53jGqqqqqhzneMaqqqqqHOd4xqqqqqoc53jGqqqqqhzneMaqqqqqHOd4xqqqqqoc53jGqqqqqhzneMaqqqqqHOd4xqqqqqoc53jGqqqqqhzneMaqqqqqHOd4xqqqqqoc53jGqqqqqhzneMaqqqqqHOd4xqqqqqoc53jGqqqqqhzneMaqqqqqHOd4xqqqqqoc53jGqqqqqvveutaqqqqq+ubb1v///7/b3vuVAAAAeNvWe20AAOhV2957bQCoVVXb1lttAP9VVbvOe20AVVVVu857dQBVVVXb1nttAP9VVdvee20AKlVV29Z7bQAAK1Xb3vuVAAAALfveutaqqqqgHOd4xqqqqqoc53jGqqqqqhzneMaqqqqqHOd4xqqqqqoc53jGqqqqqhzneMaqqqqqHOd4xqqqqqoc53jGqqqqqhzneMaqqqqqHOd4xqqqqqoc53jGqqqqqhzneMaqqqqqHOd4xqqqqqoc53jGqqqqqhzneMaqqqqqHOd4xqqqqqoc53jGqqqqqtve+9aqqiryeuYb1//////b3nttAADgXvvee22AXlVVu4VbZVz9//97bXx1qAAAAFt1e21f9VVVe3V7bX1XVVVbdXttVdVVVXttW20Aqqqqe21bbaoqqqqdbVpt7////3tte3UogAAAu4VbZTV////b3nttArVVVfveW2UAAAu1+97b3v//l1vb3hvXqqiqqhzneMaqqqqqHOd4xqqqqqoc53jGqqqqqhzneMaqqqqqHOd4xqqqqqoc53jGqqqqqhzneMaqqqqqHOd4xqqqqqoc53jGqqqqqhzneMaqqqqqHOd4xqqqqqoc53jGqqqqqhzneMaqqqqq29771qqqior73nttAACAcHttu9aVCQAAe2V7dZCmqqpadXttVVdVVbxt2WyqqqqqvG3ZbKqqqqq8bdlsqqqqqrxt2WyqqqqqvG3ZbKqqqqq8bdlsqqqqqrxt2WyqqqqqvG3ZbKqqqqq8bdlsqqqqqrxt2WyqqqqqO2Wbdaqqqqp7bVtl8AAIANvWe20DJVVV2957dQAAAg3a3vzWqqoKq/zm2tb/////HOd4xqqqqqoc53jGqqqqqhzneMaqqqqqHOd4xqqqqqoc53jGqqqqqhzneMaqqqqqHOd4xqqqqqoc53jGqqqqqhzneMaqqqqq+9661qqqqqr75rvGqqqqqvvee20AgHBcm757bVxVVVV7bVptAAgAALxt2WyqqqqqvG3ZbKqqqqq8bdlsqqqqqrxt2WyqqqqqvG3ZbKqqqqq8bdlsqqqqqrxt2WyqqqqqvG3ZbKqqqqq8bdlsqqqqqrxt2WyqqqqqvG3ZbKqqqqq8bdlsqqqqqrxt2WyqqqqqvG3ZbKqqqqp7bVttKIqiinu+e201VVVV29ZbZQACCTXb3vvWoKOKiNre/NaqqqoqHOd4xqqqqqoc53jGqqqqqhzneMaqqqqqHOd4xqqqqqoc53jGqqqqqhzneMaqqqqqHOd4xqqqqqoc53jGqqqqqvrevNaqqqqq29ZbZQDAcFy7hVtl9P3f/3ttW22qqqqqvG3ZbKqqqqq8bdlsqqqqqrxt2WyqqqqqvG3ZbKqqqqq8bdlsqqqqqrxt2WyqqqqqvG3ZbKqqqqq8bdlsqqqqqrxt2WyqqqqqvG3ZbKqqqqq8bdlsqqqqqrxt2WyqqqqqvG3ZbKqqqqq8bdlsqqqqqrxt2WyqqqqqvG3ZbKqqqqq8bdlsqqqqqruFW2Uff///29ZbZQADDTXa3vzWsIKLqBzneMaqqqqqHOd4xqqqqqoc53jGqqqqqhzneMaqqqqqHOd4xqqqqqoc53jGqqqqqhzneMaqqqqq++a6xqqqqqrb3ltlAMBgWLuFW2X0/f/3WnV7bVVXVVV8bXttV1VVVbxt2WyqqqqqvG3ZbKqqqqq8bdlsqqqqqrxt2WyqqqqqvG3ZbKqqqqq8bdlsqqqqqrxt2WyqqqqqvG3ZbKqqqqq8bdlsqqqqqrxt2WyqqqqqvG3ZbKqqqqq8bdlsqqqqqnt1e21VVVXVe3V7bVVVVVW8bdlsqqqqqrxt2WyqqqqqvG3ZbKqqqqr73nttVVVVVbuFW2Uff///2957bQADDSXa3vzWqqqqqhzneMaqqqqqHOd4xqqqqqoc53jGqqqqqhzneMaqqqqqHOd4xqqqqqra3vzWqqqqitvem3UAAMBgm8Z7bVRXVVVadXtt9VVVVbxt2WyqqqqqvG3ZbKqqqqq8bdlsqqqqqrxt2WyqqqqqvG3ZbKqqqqq8bdlsqqqqqrxt2WyqqqqqvG3ZbKqqqqq8bdlsqqqqqrxt2WyqqqqqvG3ZbKqqqqq8bdlsqqqqqrxt2Wyqqqqqe2373gAAAIC/93ttVVUJAP//e21VVXiAe218ZQAAAiB7dXttVVVXVbxt2WyqqqqqvG3ZbKqqqqpadXtt1VVVVbzGe20V1VVV+96bdQAAAwnb3vvWqqiqqhzneMaqqqqqHOd4xqqqqqoc53jGqqqqqhzneMaqqqqq+9661qqqqiq71nttcFhUV1p1e21d1VVVe21bZQAAAAC8bdlsqqqqqrxt2WyqqqqqvG3ZbKqqqqq8bdlsqqqqqrxt2WyqqqqqvG3ZbKqqqqq8bdlsqqqqqrxt2WyqqqqqvG3ZbKqqqqq8bdlsqqqqqrxt2WyqqqqqvG3ZbKqqqqqbdXttVVXV1f//W2U1JQ0N///e96wKCAD//973KoAAAN/3e21WXFhQe21abQAAAAC8bdlsqqqqqrxt2WyqqqqqvG3ZbKqqqqp7bVttKqqqqrvWe20NJRXV+ubb1v///v775rrGqqqqqhzneMaqqqqqHOd4xqqqqqra3vzWqqqqqtvee22AwGBwe208TQACAAC8bdlsqqqqqrxt2WyqqqqqvG3ZbKqqqqq8bdlsqqqqqrxt2WyqqqqqvG3ZbKqqqqq8bdlsqqqqqrxt2WyqqqqqvG3ZbKqqqqq8bdlsqqqqqrxt2WyqqqqqvG3ZbKqqqqq8bdlsqqqqqrxt2Wyqqqqqm3V7bZXVVVVbZd/3WFhQYP//3vcAAAIq///f9wAAgDh7bb73BQUJAXttfGUAAAAAvG3ZbKqqqqq8bdlsqqqqqrxt2Wyqqqqqe3V7bVXVVVV7bVtlgsAAANvee20CAwkN29771qqqqqoc53jGqqqqqhzneMaqqqqq+9661qqqqirb1nttUFhcVnttW22oiqKqvG3ZbKqqqqq8bdlsqqqqqrxt2WyqqqqqvG3ZbKqqqqq8bdlsqqqqqnxte21VVVXV3/d7bVVVVVV7bVptAAAAAHttXG0AAACgWnV7bVVVVVX73nttVVVVVbxt2WyqqqqqvG3ZbKqqqqq8bdlsqqqqqrxt2Wyqqqqq/sZ7bRVVVVX//3ttAAP1Vd/3e20AYFdV/I17bVRVVVV8bXttVVdVVbxt2WyqqqqqvG3ZbKqqqqpadXttVVVVVXttW22qqqqK29Z7bVVVVVXb1nttBSUVlfrm29b////+HOd4xqqqqqoc53jGqqqqqtveG6YAgMBA+517bVRXVVW8bdlsqqqqqrxt2WyqqqqqvG3ZbKqqqqq8bdlsqqqqqrxt2WyqqqqqvG3ZbKqqqqpbZXttVVVVhf//e21VVfUL//97bVVVqgD//1ttVVV+gF2u+kz////8e21bbaKqqKK8bdlsqqqqqrxt2WyqqqqqvG3ZbKqqqqq8bdlsqqqqqrxt2Wyqqqqqe217daAAAAB7bXt1AgAAAHxte21XVVVVvG3ZbKqqqqq8bdlsqqqqqrxt2WyqqqqqXa76TP////+bdTtlqqrqGr/3W21VVbUC//97bdVVqgC+93nO//3//BzneMaqqqqqHOd4xqqqqqrb1ltlwEBgYHttPF0CAAAAvG3ZbKqqqqq8bdlsqqqqqrxt2WyqqqqqvG3ZbKqqqqq8bdlsqqqqqr2+e21VVVUV//9bbbUNAgD//97/gAAAAP//3/eCAAAA///f9woAAAD//3tteMAAAHtt//8AAAIJe21bbaKILKK8bdlsqqqqqrxt2WyqqqqqvG3ZbKqqqqq8bdlsqqqqqrxt2WyqqqqqvG3ZbKqqqqq8bdlsqqqqqrxt2WyqqqqqvG3ZbKqqqqp7bVttKioqql7Xe21VVVUV//97bTUJAgD//9/3gAAAAP//3/eqAIAA///b3lRcXFgc53jGqqqqqvvmusaqqqqq+957bXBQWFh7dXttVVdXV7xt2WyqqqqqvG3ZbKqqqqq8bdlsqqqqqrxt2Wyqqqqqe21bXQAAAED//3ttNQ0JAv//3v8qIAAA//+97wAAAEj//y+NAAAAV///Vb4AAAAJ///f96AAAAD//1tlcMCAAP3Oe21VVVVUvG3ZbKqqqqq8bdlsqqqqqrxt2WyqqqqqvG3ZbKqqqqq8bdlsqqqqqrxt2WyqqqqqvG3ZbKqqqqq8bdlsqqqqqrxt2WyqqqqqW2V7dapqGmr//1tlJQ0DAv//vfcCAAAA//8a1wAAAMD//y6NAAAAV///2tZQcHBhvvd5zv/////b3vvWqqqqqvvee21YXFxce3V7bVVVV1e8bdlsqqqqqrxt2WyqqqqqvG3ZbKqqqqqcdXttVVXV1d/3e23VNQUJ///f9wAICoL//973gIAgSP//A1TgWFRXR2QATFUAqqr//wJULZVVVf//LY0AAAIB///e94CAAgD//3ttXHBAgHttO10AAAADvG3ZbKqqqqq8bdlsqqqqqrxt2WyqqqqqvG3ZbKqqqqq8bdlsqqqqqrxt2WyqqqqqvG3ZbKqqqqp7bVttqqoigt/3e22VNQ0B///e9wgrAAD//3znAAAASP//4ktgWFZVR2QATFUAqqriS/veWGBgYNve+taiqqio++a7xqqqqqq71nttXFxcXPvee21VVVVVvG3ZbKqqqqp8bXttVVVVVXttW22qqqoqvvd7bVXVFSX//32uAQAAAP//3vcCAIAg3vcDVIBgUFxHZABMoaioqiVcJFyqqqqqiWQDXL////++9wJUCSUV1f//vfcCAggD///f9yAAgADf93ttVlxQYHt1e21VVVdfe21bbaqqqqq8bdlsqqqqqrxt2WyqqqqqvG3ZbKqqqqq8bdlsqqqqqpxte21VVVVdvvd7bVWVNQX//x7PAQAAAP//vfcAAIAA3vcDVMBgWFRHZABUoaiqqiVcJFyoqKqqudYkXDU1NRX73rrWqqqoqr73ec7/////29Z7bVxcXFx8bXttVVdXV7xt2WyqqqqqWnV7bdXVVVUdz3ttVVVVFd/3O10JAwAA///e/wIAAALe9yNcAIBAcLGdoEP0/f//ZWTES6qqqqplZMRLqqqqqmVkxEuqqqqqZ2TgS0oqqqre9wNUAwkFNf//3vcCAAIIe23//5VVVVXf93ttVVdUWHxte21XVVVffG17bVVVVVW8bdlsqqqqqrxt2Wyqqqqq+957bVVVVVWe73ttVVXVFf//W2UJAgAA///e/woKgqDe9wNUAMBgUO2E4Uv0/f//ZWTES6qqqqplZMRLqqqqqpnOJFwVNTU1+9661qqoqqob53vGqqqqqtvee21cXFhYe21bbaKioqq8bdlsqqqqqnttW2WAAIBA3/dbbSUNAQL//97/AAAAAP//DIUAAIBA//8CVFxWVVUlXCRcqqqqqmVkxEuqqqqqZWTES6qqqqplZMRLqqqqqmVkxEuqqqqqkJ2gQx9////e9wJUAAIBDf//3/cAAAAA//87XWDAAAA913ttVVVVVFp1e21VX1VdvG3ZbKqqqqpadXttVdVVVZt9O1Wqquo6//87ZSUJAwD//9/3AgACAv//RGQAAIBgXOfjU1xWVVUlXCRcqqqqqmVkxEuqqqqqZWTES6qqqqoCVPveYGBgYPveutaqqqqr+9661qqqqqrb3nttWFBwcHttW22oqqqonG17bVVVVdXf93ttlTUFCf//3veIAAAA//+99wCAKEi+9+JTYFhUV0hsI1T+////ZWTES6qqqqplZMRLqqqqqmVkxEuqqqqqZWTES6qqqqplZMRLqqqqqoZsBFT///////8DVDWVVVX//+t8AAACAf//3veoAAAA//97bVhwQIB7bVtlAAACA7xt2Wyqqqqqm31bZf//v3/f93ttlSUNAf//3vcIAAAA//863wAAAEDf/wJUcFxWVUVcJFz4////ZWTES6qqqqplZMRLqqqqqkVcJVz//7+//N4DVCUlBQ383rjWqqqqqvveutaqqqqq2957bWBgQAA8phtV///9/P//W2VV1TUL//+9vgEAAAD//773AACAIP//AlTAYFhcR2QBVKGoqqqGbARU/////2VkxEuqqqqqZWTES6qqqqplZMRLqqqqqmVkxEuqqqqqZWTES6qqqqpFXARcqqqqqkhsI1S/////3vcCVA0lFdX//3vnAAAAA///3/8ooAIC//97bVZccIA8pnttVVVVVv//e21VlSUL//9e3wEAAAD//773AACAIP//AlTAcFhWSGwjVPn+//9lZMRLqqqqqmVkxEuqqqqqZWTES6qqqqpHZAFUqiqqatrWAVQJCQED29761qioqqoc53jGqqqqqn33ms4///////893/gAAgP//9/3IyiAAP//vvcAAACA//9FZACAYFBwlaBD9P3//0VcBFyqqqqqZWTES6qqqqplZMRLqqqqqmVkxEuqqqqqZWTES6qqqqplZMRLqqqqqmVkxEuqqqqqZWTES6qqqqqGbARU/////2dk4EtKKqqq3/8CVAMJJTXe9///VVVWWf//3/cggAAA//9+594AAAD//973IAoAAP//vvcAAACA//8CVADAYFiqdAJU9P3//yVkRUyqqqqqZWTES6qqqqplZMRLqqqqqmVkxEuqqqqqT43AQ3//vx9wlfveVFZVVRzneMaqqqqqHOd4xqqqqqr73rrWqqqqqv//+94BCQ0l///e9wAAoMD//wJUAABgXlznA1RcV1VVBWxEVP////9lZMRLqqqqqmVkxEuqqqqqZWTES6qqqqplZMRLqqqqqmVkxEuqqqqqZWTES6qqqqplZMRLqqqqqmVkxEuqqqqqZWTES6qqqqpIbCNU/////+6E4Esff///3vcDVAADJdX//xnXAAAAAf//AlQAAAAA//++9wAACED//+JLAIBgXvjWJVxUVVVVRVwEXKqqqqplZMRLqqqqqmVkxEuqqqqqRVwEXKqqqqpFXARcqqqqqtveA1SVNSUF/Oba1v7///8c53jGqqqqqhzneMaqqqqqHOd4xqqqqqqf/y+NCmrqqjvf4kvgV1VXR2QAVIWiqqplZMRLqqqqqmVkxEuqqqqqZWTES6qqqqplZMRLqqqqqmVkxEuqqqqqZWTES6qqqqplZMRLqqqqqmVkxEuqqqqqZWTES6qqqqplZMRLqqqqqmVkxEuqqqqqZWTES6qqqqplZMRLqqqqqkdkAExKKqqq/N4DVC1VVVWd7wNUAP1VVfnW4kvgV1VVR2QAVIWoqqpIbCNU/////2VkxEuqqqqqZWTES6qqqqplZMRLqqqqqoRU5WOqqqqqR2QAVKqqSioiVNrWWFRWVdve+taqqKiqHOd4xqqqqqoc53jGqqqqqhzneMaqqqqq/Oba1r/////83gJUVlxYcEhsI1T////+ZWTES6qqqqplZMRLqqqqqmVkxEuqqqqqZWTES6qqqqplZMRLqqqqqmVkxEuqqqqqZWTES6qqqqplZMRLqqqqqmVkxEuqqqqqZWTES6qqqqplZMRLqqqqqmVkxEuqqqqqZWTES6qqqqolXCRc+qqqqoVb5FyqqqqqRVwlXO////+EVOVjqqqqqoZsBFT/////ZWTES6qqqqplZMRLqqqqqmVkxEuqqqqqZWTES6qqqqpIbCNU////v9rWA1SVNSUN+9661qioqqoa33zeqqqqqhzneMaqqqqqHOd4xqqqqqoc53jGqqqqqtve+tYiqqqq296IbECAAADa1iJUVVVWXEdkAFSqqqqqZWTES6qqqqplZMRLqqqqqmVkxEuqqqqqZWTES6qqqqplZMRLqqqqqmVkxEuqqqqqZWTES6qqqqplZMRLqqqqqmVkxEuqqqqqZWTES6qqqqplZMRLqqqqqmVkxEuqqqqqZWTES6qqqqplZMRLqqqqqmVkxEuqqqqqZWTES6qqqqplZMRLqqqqqmVkxEuqqqqqZWTES6qqqqplZMRLqqqqqoVb5Fyqqqqqmc4DVFVV1TX73mZkCQIAALjm/Nb/////HOd4xqqqqqoc53jGqqqqqhzneMaqqqqqHOd4xqqqqqoc53jGqqqqqvzm2tb/////295EXFBggABwlcBL///99CVcJFyqqqqqZWTES6qqqqplZMRLqqqqqmVkxEuqqqqqZWTES6qqqqplZMRLqqqqqmVkxEuqqqqqZWTES6qqqqplZMRLqqqqqmVkxEuqqqqqZWTES6qqqqplZMRLqqqqqmVkxEuqqqqqZWTES6qqqqplZMRLqqqqqmVkxEuqqqqqZWTES6qqqqplZMRLqqqqqmVkxEuqqqqqRVwEXKqqqqovjeBL//9/H9veIlwlCQIAut4816qqqqr85trW/////xzneMaqqqqqHOd4xqqqqqoc53jGqqqqqhzneMaqqqqqHOd4xqqqqqrb3vrWqqqqqrjm/Nb/////A1T73gkllVVwlcBD///99EdkAEyqqqqqZWTES6qqqqplZMRLqqqqqmVkxEuqqqqqZWTES6qqqqplZMRLqqqqqmVkxEuqqqqqZWTES6qqqqplZMRLqqqqqmVkxEuqqqqqZWTES6qqqqplZMRLqqqqqmVkxEuqqqqqZWTES6qqqqplZMRLqqqqqmVkxEuqqqqqZWTES6qqqqpEXCVc////ew6F4Uv//38f294DVDUNAwDb3hrXgoIoqhzneMaqqqqqHOd4xqqqqqoc53jGqqqqqhzneMaqqqqqHOd4xqqqqqoc53jGqqqqqhzneMaqqqqqHOd4xqqqqqr85trW//////revNaqoqqq294jXFhgAACZzgNUVVVXWEZcJFz////+RVwlXP////9lZMRLqqqqqmVkxEuqqqqqZWTES6qqqqplZMRLqqqqqmVkxEuqqqqqZWTES6qqqqplZMRLqqqqqmVkxEuqqqqqZWTES6qqqqplZMRLqqqqqmVkxEuqqqqqRlwkXP////+EVOVjqqqqqkhsI1T///+/V8YDVFVV1SX73iNcJQkCANve+taiqKqqHOd4xqqqqqoc53jGqqqqqhzneMaqqqqqHOd4xqqqqqoc53jGqqqqqhzneMaqqqqqHOd4xqqqqqoc53jGqqqqqhzneMaqqqqqHOd4xqqqqqoc53jGqqqqqvveutaqqqqq296IbGAAAAD83gNUVVd4gIlsAlT///u0SGwjVP////9lZMRLqqqqqmVkxEuqqqqqZWTES6qqqqplZMRLqqqqqmVkxEuqqqqqZWTES6qqqqplZMRLqqqqqmVkxEuqqqqqZWTES6qqqqplZMRLqqqqqoZsBFT///+/R2QBVKqqihrb3gNUVdUtAtveRmQJAAAA+t681qqqqqoc53jGqqqqqhzneMaqqqqqHOd4xqqqqqoc53jGqqqqqhzneMaqqqqqHOd4xqqqqqoc53jGqqqqqhzneMaqqqqqHOd4xqqqqqoc53jGqqqqqhzneMaqqqqqHOd4xqqqqqoc53jGqqqqqrveOteqqqqqPOe61r/////b3sBDeIAAANrWA1RVV3gAcZ3AQ////XhHZAFUqqqqDUhsI1T////6RVwEXKqqqqplZMRLqqqqqmVkxEuqqqqqSGwjVP////9FXCVc////q0dkAFSqqqpicJWgQ///fy+61gNUVdUtAANU295gVlVV/Oba1v7////b3vrWKqqqqrjm/Nb/////HOd4xqqqqqoc53jGqqqqqhzneMaqqqqqHOd4xqqqqqoc53jGqqqqqhzneMaqqqqqHOd4xqqqqqoc53jGqqqqqhzneMaqqqqqHOd4xqqqqqoc53jGqqqqqhzneMaqqqqqHOd4xqqqqqoc53jGqqqqqtve+taqKqqqfOYa1//////85trWv/////ve0qVgAAAA294CVF+gAADb3iNUVV+AANveI1xVVeoA+94DVFVV/wDb3gNUVVX/AAJUHecAAKpV294jXFX1AgDb3uFL9QoAALKl+95YVVVV+9661qiqqqp85hrX//////zm2tb/////HOd4xqqqqqoc53jGqqqqqhzneMaqqqqqHOd4xqqqqqoc53jGqqqqqhzneMaqqqqqHOd4xqqqqqoc53jGqqqqqhzneMaqqqqqHOd4xqqqqqoc53jGqqqqqhzneMaqqqqqHOd4xqqqqqoc53jGqqqqqhzneMaqqqqqHOd4xqqqqqoc53jGqqqqqhzneMaqqqqqHOd4xqqqqqoc53jGqqqqqtve+taqqqqquOb81v/////73rrWuqqqqtve+taogqqqfOYa1//////85trW//////veutaqqqqq/Oba1v////8c53jGqqqqqhzneMaqqqqqHOd4xqqqqqoc53jGqqqqqhzneMaqqqqqHOd4xqqqqqoc53jGqqqqqhzneMaqqqqqHOd4xqqqqqoc53jGqqqqqhzneMaqqqqqHOd4xqqqqqo=" - }, - "etc1": { - "uri": "data:image/ktx;base64,q0tUWCAxMbsNChoKAQIDBAAAAAABAAAAAAAAAGSNAAAHGQAAgAAAAIAAAAAAAAAAAAAAAAEAAAABAAAAAAAAAAAgAADY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AAN3f2Au7s4AA2NvdCfu7AETG2t0hIiIiRKbK3YEiIgAAnMXYp+7uAACcxdin7u4AAKbK3YEiIgAAxtrdISIiRCLY290Ju79EAN3f2As7uwAI2NjYA///AADY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgD//8AANrc3Qn7s4jEpsrdQTIgIhV3qNgCEe4AAWaq3QAAAAAAZqrdAQAAAABmqt0BAAAAAGaq3QEAAAAAZqrdAQAAAABmqt0BAAAAAGaq3QEAAAAAZqrdAQAAAABpqNgC7iEQAKbK3UECI1Ei2dzdCTu/TIjY2NgC//8AANjY2AP//wAA2NjYAv//AADY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AANze2A/7M4AApsrdQTIgIhVmqt0BAAAAAWaq3QEAAAAAZqrdAAAAAABmqt0AAAAAAGaq3QAAAAAAZqrdAAAAAABmqt0AAAAAAGaq3QAAAAAAZqrdAAAAAABmqt0AAAAAAGaq3QAAAAAAZqrdAAAAAABmqt0AAAAAAGaq3QAAABAApsrdQQIjUSLc3tgPM78ACNjY2AL//wAA2NjYAv//AADY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AANjY2AL//wAAzNbYK+yA6Ex+t9hDf+YAAWaq3QAAAAAAZqrdAAAAAABmqt0AAAAAAGaq3QAAAAAAZqrdAAAAAABmqt0AAAAAAGaq3QAAAAAAZqrdAAAAAABmqt0AAAAAAGaq3QAAAAAAZqrdAAAAAABmqt0AAAAAAGaq3QAAAAAAZqrdAAAAAABmqt0AAAAAAGaq3QAAAAAAfrfYQ+a7EADM1tgrCM7EjtjY2AL//wAA2NjYAv//AADY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AANjY2AL//wAA2NjYAv//AADE1dhL/IDoTGio2APfnAABZqrdAAAAAABmqt0AAAAAAGaq3QAAAAAAZqrdAAAAAABmqt0AAAAAAGaq3QAAAAAAZqrdAAAAAABmqt0AAAAAAGaq3QAAAAAAZqrdAAAAAABmqt0AAAAAAGaq3QAAAAAAZqrdAAAAAABmqt0AAAAAAGaq3QAAAAAAZqrdAAAAAABmqt0AAAAAAGaq3QAAAAAAZqrdIQAAEADE1dhLCO/EjtjY2AP//wAA2NjYAv//AADY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AAMzW2CrsgNuAaKjYA/HeAAFmqt0BAAAAAGaq3QAAAAAAZqrdAAAAAABmqt0AAAAAAGaq3QAAAAAAZqrdAAAAAABmqt0AAAAAAGaq3QAAAAAAZqrdAAAAAABmqt0AAAAAAGaq3QAAAAAAZqrdAAAAAABmqt0AAAAAAGaq3QAAAAAAZqrdAAAAAABmqt0AAAAAAGaq3QAAAAAAZqrdAAAAAABmqt0AAAAAAGaq3QAAAAAAZqrdIQAAEACrwthKCM4AvdjY2AL//wAA2NjYAv//AADY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AANjY2AP//wAA3d7YD/szoAB+t9hDd3gAAWaq3QEAAAAAZqrdAAAAAABmqt0AAAAAAGaq3QAAAAAAZqrdAAAAAABmqt0AAAAAAGaq3QAAAAAAZqrdAAAAAABmqt0AAAAAAGaq3QAAAAAAZqrdAAAAAABmqt0AAAAAAGaq3QAAAAAAZqrdAAAAAABpqNgHTsyAAH2u3hEVd6qEbK3eLUQATIpmqt0AAAAACGaq3QAAAAAAZqrdAAAAAABmqt0AAAAAAGaq3QEAAAAAaqnYCs8QEADW3tgPM78ACtjY2AL//wAA2NjYAv//AADY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgD//8AAKbK3UQA6AHDZqrdAAAAAABmqt0AAAAAAGaq3QAAAAAAZqrdAAAAAABmqt0AAAAAAGaq3QAAAAAAZqrdAAAAAABmqt0AAAAAAGaq3QAAAAAAZqrdAAAAAABmqt0AAAAAAGaq3QAAAAAAZqrdAAAAAABmqt0AAAAAAGaq3QAAAAAAfr7fbAM/4QD4+PgDE/MAAPj4+AMQEQAAxtrtYAAxCD5mqt0AAAAAAGaq3QAAAAAAZqrdAAAAAABmqt0AAAAAAGaq3QAAAAAAaqzdKI4APBDY2NgD//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AANjY2AP//wAA2tzdCOj/wwBmqt0BAAAAAWaq3QAAAAAAZqrdAAAAAABmqt0AAAAAAGaq3QAAAAAAZqrdAAAAAABmqt0AAAAAAGaq3QAAAAAAZqrdAAAAAABmqt0AAAAAAGaq3QAAAAAAZqrdAAAAAABmqt0AAAAAAGaq3QAAAAAAZqrdAAAAAABmqt0AAAAAAH6+3ywMz3m/+Pj4AojMAAD4+PgDiAgAANbq7WAA4AHHZqrdAAAAAABmqt0AAAAAAGaq3QAAAAAAZqrdAAAAAABmqt0BAAAAAGaq3QAAABAArc3dYP+OAAzY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgD//8AAKbK3UAA4AHDZqrdAQAAAABmqt0AAAAAAGaq3QAAAAAAZqrdAAAAAABmqt0AAAAAAGaq3QAAAAAAZqrdAAAAAABmqt0AAAAAAGaq3QEAAAAAZqrdAAAAAABmqt0AAAAAAGaq3QEAAAAAZqrdAAAAAABmqt0AAAAAAGaq3QAAAAAAZqrdAAAAAAB2ut1hIzMQAOfr/U2I7hET1+r9haoIIVVmqt0hAAAAAWaq3QEAAAAAZqrdAAAAAABmqt0AAAAAAGaq3QAAAAAAZqrdAQAAAABmqt0AAAAAAGqs3QgOADwQ2NjYAv//AADY2NgC//8AANjY2AL//wAA19/YC/MzoAB3qNgiAPwAAWaq3QAAAAAAZqrdAAAAAABmqt0AAAAAAGaq3QAAAAAAZqrdAAAAAABmqt0AAAAAAGaq3QAAAIAAaqzeDQRMiMRurt8JRESIjGyt3g1EREyIaajYB953AAhmqt0gAAAAAGaq3QAAAAAAZqrdAAAAAABmqt0AAAAAAGaq3QAAAAAAZqrdAAAAAABmqt0AAAAAAGaq3QAAAAAAZqrdAAAAAABmqt0AAAAAAGaq3QAAAAAAZqrdAAAAAABmqt0AAAAAAGio2AJZ5oAAa63eEURMiER+rt8tR3eQiNjY2CL/8wAI2NjYAv//AADY2NgC//8AANnb3Qjw/8MAZqrdAQAAAABmqt0AAAAAAGaq3QAAAAAAZqrdAAAAAABmqt0AAAAAAGaq3QAAAAAAaanYC37MgACuz+9tARfyF/j4+AMAAAAA+Pj4AwAAAAD4+PgCAAAAAM/f72VxABMjlMXnovdzAAhmqt0AAAAAAGaq3QAAAAAAZqrdAAAAAABmqt0AAAAAAGaq3QAAAAAAZqrdAAAAAABmqt0AAAAAAGaq3QAAAAAAZqrdAAAAAABmqt0AAAAAAGaq3QAAAAAAZ6vdDH8AgAC/3+9pARcyF/j4+AIAAAAA+Pj4AxEQAADt7e0g/3AAHtjY2AL//wAA2NjYAv//AADH2t0goOABgGaq3QAAAAAAZqrdAAAAAABmqt0AAAAAAGaq3QAAAAAAZqrdAAAAAABmqt0AAACAAJ7P79ABNwGA+Pj4AoERAAD4+P8SgMwAAPz8+hGIiMzE6vHqgkyIAAj4+PgDEQAAANPj8Y9xADDvdrrdYAD3AAhmqt0AAAAAAGaq3QAAAAAAZqrdAAAAAABmqt0AAAAAAGaq3QAAAAAAZqrdAAAAAABmqt0AAAAAAGaq3QAAAAAAZqrdAAAAAABoqNgCcACAALvT6nYBN/zX+Pj4AyERAAD/+P8WgOQAAPv8+hGIiEzE7f3tYPGIDA/Y2NgD//8AANjY2AL//wAAtsrdIADwAO9mqt0BAAAAAGaq3QAAAAAAZqrdAAAAAABmqt0AAAAAAGaq3QEAAAAAfL3ebBN/64D4+PgjxMkAAPj4+AL4gIAAt8mklO7IAdtYgCgDAAAAAJaoYuWO/1AA/f78FwAOzEj4+PgCMAwAAOn8/vRzEAwAZqrdAAAAAAhmqt0AAAAAAGaq3QAAAAAAZqrdAAAAAABmqt0AAAAAAGaq3QAAAAAAZqrdAAAAAABmqt0AAAAAAGaq3QEAAAAAjb7edBM/yYD4+PgDAzMAAP/4/wqAhIAApsmUkf/oMhdYgCgCAAAAAGuMOkwO7w4Q2NjYA///AADY2NgC//8AAKbK3YAA8AAAZqrdAAAAAABmqt0AAAAAAGaq3QAAAAAAZqrdAAAAAAB5rN45B/6gAOrx+GIXAQCB+Pj4AvcVAADM3LSS/IDtv1iAKAIAAAAAWIAoAgAAAABYgCgDAAAAAIObW16M7zH/+Pj/BwAZgAj4+PgD+YAAAMfb7Yz3MQicZqrdAAAAAABmqt0AAAAAAGaq3QAAAAAAZqrdAAAAAABmqt0AAAAAAGaq3QAAAAAAZqrdAAAAAAB7s9lXF//oAPHx+KMABQAA+Pj4A9AIAAC81KSS/MDtt1iAIQMAAAAAWIAoAwAAAABZiygYD4AAANjY2AP//wAA2NjYAv//AACmyt2AAPAAAGaq3QAAAAAAZqrdAAAAAABmqt0AAAAAAGqp2A8t3oAAz9/vgN8TAOn4+PgCAAsAAOv86vHoAMjMZ483YgD+AAFYgCgCAAAAAFiAKAIAAAAAWIAoAgAAAABYgCgCAAAQAKO7k5IIz/ve+Pj4A4KPAAD+//8MEHyQAHur2Tf/cQAOZqrdAAAAAABmqt0AAAAAAGaq3QAAAAAAZqrdAAAAAABmqt0AAAAAAGuq2RMe3IAA2+rxpwAXIwn4+PgDfvoAAPr7+dDogNsAZ48oIzMyAAFYgCgCAAAAAFiAKAIAAAAAWYsoGA8AAADY2NgD//8AANjY2AL//wAAtsrdIADwAH9mqt0AAAAAAGaq3QAAAAAAZqrdAQAAgACz0+J6ATf8l/j4+AIAAAAA/f78F+MwgMyEpVTD/+jMzViAKAIAAAAAWIAoAgAAAABYgCgCAAAAAFiAKAIAAAAAWIAoAgAAAABnjzdDIzMQAOz03PcAjsSM+Pj4AgAAAAD8/f4QMfSeAHa63WAA9wAIZqrdAAAAAABmqt0AAAAAAGaq3QAAAAAAZqrdBQAAgACvz+9oARcB2/j4+AMADwAA/f78GekApMx8nUyjMzAABViAKAIAAAAAWIAoAgAAAABYgCgCAAAAAFuLKQgPAPcA2NjYA///AADY2NgC//8AANfa3QTw/wgwZqrdAAAAAABmqt0AAAAAAHy93nATP+mA+Pj4AhARAAD4+P8GgMCRAJy8fPb+yAATWIAoAgAAAABYgCgCAAAAAFiAKAIAAAAAWIAoAgAAAABYgCgCAAAAAFiAKAIAAAAAWIAoAgAAAACEpVTHjv8QAN/v36DiDAB7+Pj4AwEAAADp/P50cxAMHmaq3QEAAAAIZqrdAAAAAABmqt0AAAAAAI2+35ATP+mA+Pj4AhARAAD///4ZoAEAAKa4g4T+6AHbWIAoAwAAAABYgCgCAAAAAFiAKAIAAAAAWIAoAgAAAABsjTwEBx8DgNjY2AL//wAA2NjYAv//AADa3N0Icf/4AHeo2CLAdwAIg7PaVxd/6ADv///hSI0AAPj4+APIQAAAxNyskvyA7bdYgCgDAAAAAFiAKAMAAAAAWIAoAgAAAABYgCgCAAAAAFiAKAIAAAAAWIAoAgAAAABYgCgCAAAAAFiAKAIAAAAAWIAoAgAAAAB7m1u6jO8xAPj4/w8ACAAA+Pj4AxIcAACNvu+19xBAjmmo2AdsxgAIe73ebRd/6ETx+PiiEQEAAPj4+APIgAAAvNScsv7A7bdYgCgCAAAAAFiAKAIAAAAAWIAoAgAAAABYgCgCAAAAAFiAKAMAAAAAja1tYP8PAMfY2NgD//8AANjY2AL//wAA2NjYA4//EADw8fEOERwA6vj4+CJCAQAA+Pj4AtljAADr7Op16ADpX2ePN0MzMgABWIAoAgAAAABYgCgCAAAAAFiAKAIAAAAAWIAoAgAAAABYgCgCAAAAAFiAKAIAAAAAWIAoAgAAAABYgCgCAAAAAFiAKAIAAAAAWIAoAwAAAACjs4uSCM973vj4+AKIjwAA+Pj4AhGMAAD/+PhGERHJAPj4+AIDMwAA+Pj4A4iAAADq++hw6IDbg2ePKCIA/gABWIAoAwAAAABYgCgCAAAAAFiAKAIAAAAAWIAoAgAAAABZgSkLDMyAAMrKw2L/AwAB2NjYAv//AADY2NgC//8AANjY2AL//wAA7+/vIAzPCJ74+PgDyAiAAPr7+FHogOhMdZ1MozMiAAFYgCgDAAAAAFiAKAIAAAAAWIAoAgAAAABYgCgCAAAAAFiAKAIAAAAAWIAoAgAAAABYgCgCAAAAAFiAKAIAAAAAWIAoAgAAAABYgCgCAAAAAFiAKAIAAAAAZ48oIyMzEADE3KyTiM573v///hkAKgAA+Pj4AwAAAAD4+PgCiACAAOn75/HogMhEZZhCgTMyAAFYgCgCAAAAAFiAKAIAAAAAWIAoAgAAAABYgCgCAAAAAFiAKAIAAAAAWospDAcA44DY2NgD//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AANzc2wxg/3EAhaZcru7uARFYgCgDAAAAAFiAKAIAAAAAWIAoAgAAAABYgCgCAAAAAFiAKAIAAAAAWIAoAgAAAABYgCgCAAAAAFiAKAIAAAAAWIAoAgAAAABYgCgCAAAAAFiAKAIAAAAAWIAoAgAAAABYgCgCAAAAAFiAKAIAAAAAWIAoAwAAAABiiisy7u8REKW4kuEiYgEAfZ5Uru7uARFYgCgDAAAAAFiAKAIAAAAAWIAoAgAAAABYgCgCAAAAAFiAKAIAAAAAWIAoAgAAAABYgCgDAACAAK29jYD/FwCD2NjYA///AADY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AAJy0fHL3MAC+WIAoAwAAAABYgCgCAAAAAFiAKAIAAAAAWIAoAgAAAABYgCgCAAAAAFiAKAIAAAAAWIAoAgAAAABYgCgCAAAAAFiAKAIAAAAAWIAoAgAAAABYgCgCAAAAAFiAKAIAAAAAWIAoAgAAAABYgCgCAAAAAFiAKAIAAAAAWIAoAgAAAABYgCgCAAAAAFiAKAIAAAAAWIAoAwAAAABYgCgCAAAAAFiAKAIAAAAAWIAoAgAAAABYgCgCAAAAAFiAKAMAAAAAaos5LBN/y4DY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AANjY2AL//wAA2NjYAv//AADd3twSMP8QAHWdTIIA8wAIWIAoAgAAAABYgCgCAAAAAFiAKAIAAAAAWIAoAgAAAABYgCgCAAAAAFiAKAIAAAAAWIAoAgAAAABYgCgCAAAAAFiAKAIAAAAAWIAoAgAAAABYgCgCAAAAAFiAKAIAAAAAWIAoAgAAAABYgCgCAAAAAFiAKAIAAAAAWIAoAgAAAABYgCgCAAAAAFiAKAIAAAAAWIAoAgAAAABYgCgCAAAAAFiAKAIAAAAAWIAoAwAAAABXiSQQPwCAAMPKu4PM3wAF2NjYAv//AADY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AANjY2AL//wAA2NjYAv//AADa29gsMf+9EFmBKQvMxAAIWIAoAgAAAABYgCgCAAAAAFiAKAIAAAAAWIAoAgAAAABYgCgCAAAAAFiAKAIAAAAAWIAoAgAAAABYgCgCAAAAAFiAKAIAAAAAWIAoAgAAAABYgCgCAAAAAFiAKAIAAAAAWIAoAgAAAABYgCgCAAAAAFiAKAIAAAAAWIAoAgAAAABYgCgCAAAAAFiAKAIAAAAAWIAoAgAAAABYgCgCAAAAAFmBKQp/AIAAnb2NZPc3AdvY2NgD//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AANjY2AL//wAA2NjYA///AADE1LRucxC9EFmBKQvMxAAIWIAoAgAAAABYgCgCAAAAAFiAKAIAAAAAWIAoAgAAAABYgCgCAAAAAFiAKAIAAAAAWIAoAgAAAABYgCgCAAAAAFiAKAIAAAAAWIAoAgAAAABYgCgCAAAAAFiAKAIAAAAAWIAoAgAAAABYgCgCAAAAAFiAKAIAAAAAWIAoAgAAAABYgCgCAAAAAFiAKAIAAAAAWYEpCn8AgACcrHxtATcyF9jY2AL//wAA2NjYAv//AADY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AANjY2AL//wAA2NjYA///AADM1MROMRC9EFeJJBHNRAAIWIAoAgAAAABYgCgCAAAAAFiAKAIAAAAAWIAoAgAAAABYgCgCAAAAAFiAKAIAAAAAWIAoAgAAAABYgCgCAAAAAFiAKAIAAAAAWIAoAgAAAABYgCgCAAAAAFiAKAIAAAAAWIAoAgAAAABYgCgCAAAAAFiAKAMAAAAAWIAoAgAAAABXiSQRReyAAJ29jWXN3zIX2NjYAv//AADY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AANjY2AL//wAA2NjYAv//AADd3twSEf8QEGuLOU33MUSOWI8oAgD3AAhYgCgCAAAAAFiAKAIAAAAAWIAoAgAAAABYgCgCAAAAAFiAKAIAAAAAWIAoAgAAAABYgCgCAAAAAFiAKAIAAAAAWIAoAgAAAABYgCgCAAAAAFiAKAIAAAAAWIAoAwAAAABYgSgDTMyAAGqLOS0Tf+hEvc29gczdAAHY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AALO7q4sxEBEAa4s6LXdxTIpujz5iAHcACFiAKAIAAAAAWIAoAwAAAABYgCgCAAAAAFiAKAIAAAAAWIAoAgAAAABYgCgCAAAAAFiAKAIAAAAAWIAoAgAAAABZgSoOdwCAAGuLKi0Xd6jEs7uriwETABHY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgD//8AANjY2AL//wAA3t/eChH/EBCdrX1h3d0TMm2NPEV90UACW4wqCUREzMhaiykZREQAAFqLKRlERAAAW4wqCUREjMxtjTwlXV8gRJ2tfWHd3SMRytHJQv8RAQHY2NgD//8AANjY2AP//wAA2NjYAv//AADY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AANjY2AP//wAA2NjYA///AADY2NgD//8AANjY2AP//wAA2NjYA///AADY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AANjY2AL//wAA2NjYAv//AADY2NgC//8AAA==" - }, - "pvrtc1": { - "uri": "data:image/ktx;base64,q0tUWCAxMbsNChoKAQIDBAAAAAABAAAAAAAAAAGMAAAHGQAAgAAAAIAAAAAAAAAAAAAAAAEAAAABAAAAIAAAABsAAABLVFhPcmllbnRhdGlvbgBTPXIsVD1kLFI9aQAAABAAAP/v/19673vv9/e/93rve+//36/teu9773///99673vv/f///3rve+/3f///eu977////39673vv3+//93rve+//+f+/eu977+v/9/9673vv/v//73vve+/+//z/e+977/7v//9773vvzv//+3vve+/+/+v/e+t87/7//z+7tnvv/+39v3rve+/v//f/eu977/////9673vv7f3//3rve++/9///eu977/7///9773vv7v/W/3vvfO/+//8/u7Z67+776f9773vv/j9/D7u2e+8uCwMAu7J77wAAQFS9stu+HgcHAb2ye+8CAAAAvbJb30CQ8PC7tru28PDw9Lu2u7b/9/v/eu977/7///9773vv/////3rve+/+//8/3b577/7/vx+7tnvzCgEAAL2yeu8eAQAAvbZ77wAAUJS9sru2/v///3vve+/+bwsAvbJ77/77//9773vv/gAAAL2ye+8AAOD0u7a8tvD0wv+7tru2AADv/7u2vLb+///8u7a7tgAAoOS9sru2MDTE+bu2u7YABc/wu7a7tvLw/w+7tru2+P7/87u2u7b+///zu7a7tg4Pzw+7tru2Pg///7u2u7by8B8Pu7a7tj4P3wC7tru2zv/8wLu2u7bw8D8Au7a7tjAA/wC7tru2AAAPD7u2u7YAAM8Au7a7tgAAAAC7tru2zv/z/Hvve+/+/+//e+977z4fPw+9tnvzDgcLA7uye+/+++r/e+987/7+/n77xnrvAgADAL2ye+8AAAAAu7b7ygBA4PC7try28PDA8Lu2u7bw/T/7u7a7tvr///+7tru28PDA8Lu2u7bA9PD0u7a7tv7/D/+7tru2/v//H7u2u7b+Pv4+vbZ7734/Pi+7tnvvABCQ8L22u7bg8ODwu7a8tj4fPx+7tnvvPh8/D7u2e+/AwKAgvba7tiDA4GC7tru2wD3N/7u2u7ay//tfu7a7tjIMMw+7tru2Lh8uALu2vLYyAAQPu7a7th4LLwC7try2AMDA4Luy///Q9PD8u7b///7//PC7tru2/P///7u2u7b+///wu7a7tv7z//+7tru2/v/AH7u2u7Y+Dy8Au7a8tv3+/wC6tru2AACg/7uy//8+DP/Pu7a7tj7///y7tru2AAAP/7u2u7b+/8//u7a7tm///wC6tru2AAACD7u2///////wura7tuDgoAC7try2QNDg+Luy///0/fz/u7b///7//////////v//DwOu///+//////v///4/Px8Frv//CgICACWu//8AABAABa4lrn5///+9tv///v///xHX//8AAAICvbL//wYHDw+9tv//+Pjw8AWu///AwAAABa7//z4///+7tv///v///937///+////e+977/8AAAC6tnvv///7/3rve+/+/ZAAvbJ77wAAoPO9tru2zMD/P7u2u7YAAC8Pu7a8tj4j/Py7tru2/v///3vve+/+///+27p77/7///9773vvf/+//3rve+/QgAAAvbZ77wAAPx+9sru2/v/8+L22e+/QwAAAu7Z77/7/Mw+7tru2Dg/w8Lu2u7b+///wu7a7tvDw/z+7tru28PA/QLu2u7ZwEAAAu7a7tgz/DAC7tru2AAAAQL22HM8+b8z/u7a7tv78P/+7tru2AAA7D7uyu7Y+H3xgu7a7tvz/MAC7tru2AAB8/7u2//9+v89Qu7a7thBUQAC7ttu+//f/8nrve+/+P///e+977//ff/9673vv9/t+/3rve+9/jw//eu977/7//v27unvv/v///3vve+/+////e+977//r//9673vv/////3rve+////f6eu977//3//d673vv/v8//3vve+/+///+e+977//v//9673vv/f///3rve+/w8MDAu7Z77wAAAQG9tty+/u9f/3vve+/+//z8u7Z77xQEPwy7tru2Ph45BLu2u7bw8MDAu7Z784AAAAC6tlzf/v8//3vve+/+////e+977/d/999673vv97///3rve+/+////e+977/7//f+9snvv/s//z3vve+/+////e+977wAAMA+7tru2Pg88D7u2u7aAwMDAurb//8DAwMC7tv//Pg8zH7u2u7Y6H/70u7a7tgAAAAC7tn7fAADP/7u2u7b+//////////7/////////AgADA7u2//8CAwMAu7b///4/FAC7tv//AAD/v7q2u7YAAAAAvbIdxwBQD/+7tru28PDA8Lu2u7bw8PDwu7a7tv78/w+7tru2PA//D7u2u7bgoKAAu7bctgAAAwO7sv//Dg/KBLu2u7YAAAAAu7a7uv7/PwC7tru2MAD/8Lu2u7b+z7zwu7a7tvDw/x+7tru28PD/w7u2u7b8/HAcu7a7tj4PDwa7tru2LgYqALu2vLYwYMDwu7a7tsDwwPC7tru2AAAHC7u2vLY+Cz8Pu7a8tvDwxLW7tru2NA4AD7u2u7Y6Dz8Gu7a7thQAFQC9trq+/Pzw9Luye/Pg8MDAu7Z77/7/3/9773vvzs8PH3vve++AwABAu7Z77wAApP+7tv//bv/vmnvve+9KlkaVe+//+z4PHw+7try2KAopALu2vLZA4OD4u7b///j+/f+7tv//AMDA4Lu2///g9PT8vbb///7///+78////j8/DwWu///+//////////7//w8Fsv//QpBDknvv//9Wl5urd+f//wYBAQAFrv//AAAwEAOqBa7o/PT8Ja577/T89PwFrnzvPh8/H7u2e+8+Hz8vvbJ773AQIAC7try2MAAgBLu2vLY+Pz8/vbJ7774/v7+9tnvvIAQgAL22u7YAQEDQu7b//wAAAIC7tp7ngMDA8Lu2///8////u7b///7//z9pvv//8Pz8/7u2///+////fd///34vLw8lrv//DgMDAAWu//++qwsLe++99woLP69773vv/v///733///8//z+e+///77//v9773vv/v/z/3vve+++Aw8LBaq99y4PPz8Frnzv/r//PyWu//8+CwsABa7//wAAAAADqozCAEDw8AWuBK4AAFBQBa4kspCQkAADrgWu8PTB/AWuBK7O/wbwBa4Erh4LCwMFrv//AgAAACWq//8gELCwBa4ErvDw8DAFrgSuAABQkCWuBbJQkJDwBa4krvD09v0FrgSu/v/P8wWuBK4AABoKBa4lsi4PDw8FrgSu/P78/AWu///w8MDABa7//z4PDw8FrgSuDh8/DwWuBK5AgAAABa7//wAAPA8FrgSucDAABAWuBK4ADc/zBa4ErsLwwAAFrgSuMAA//wWuBK7+//zzBa4Erv7//P8FrgSu/v/P/wWuBK7O/w8PBa4Erj4PADAFrgSu8PDf/wWuBK48AwADBa4ErgIPfx8FrgSu/v///wWuBK7+/wDwBa4Ern5/D/8FrgSu/v/wPwWuBK7+///8e+977/7//+9773vvf////yaye+/+/+//e+97777///9773vv9/3//3rve+/+////e+977/7/z/9773vvAAABAAWueesCAw8PBa5778DwAAAFrgSuAAAAAAWuBK4+P///Ba577/7/2fN773vvAAAAAAWuz84CAx8fBa577//9/f9673vv/f//v3rve+/+v///e+977/+/f/9673vv9//n/3rve+//////eu9779///99673vv/////3rve+/+////e+977/7/8/9773vvf////ySye+/+/9//e+977/7///9773vv///f/Xrve+/+////e+977//3//9673vv/v8AAAWuBK4AAMwJBa4Erg4PAAAFrgSuMAA/AAWuBK4wADDwBa4ErvDw8AAErgSuwAAAAwWuBK7////wBK4ErsDwwPAFrgSuwPMAAAWuBK7+////Ba4Erv7/APAFrgSuMAAA8AWuBK7A8P/wBa4ErvDw8P8FrgSu/v//PwWuBK4AAAMLJa577z6///8FrnzvAAAAAAWuBK4AAAcLBa577/7/7v9773vv7v//83vve+/+////r8p87/7///9773vvwPDwxAWuBK4wEEAABa4krv7/z/8FrgSu//78AASuBK4AC///Ba577/7/7vd773vvAABW/wWum+///57/eu977w4PPz+7tv//vn///722///w8JAAu7a8sgAAAAG8sr7v/////ka2///8/PD0Ba7//wIDDw+9sv//Lh9/v72y//8ODwkJu7a7tjAEMAC7try2AAAAwL2y3/eA4NDwu7b//yAAEAC7try2AICA4Lu2///w/Pz/u7b///7///+f6///0NCAwCWu//8AAAAABa5puv7/z////////v/89AWq//8ABQwPBa4ErjIf8/8FrgSugAAAAAWqmOsAAP//Ba4Ervr///+/9////v/////////+f78vBa7//y4LBwAjrv//bgAAAAWu3vsAAP//BK4ErgAAkKQFrgWu0PT//AWuBK78////u7b///7//z8Fsv//HgcLAgWu//8CAAAAJa7d+34fLwsjrv//DgMDAAWu//8AAJBgBa4kqtDwMGAFrgSuMAAwAAWuBK4wAAAABa4ErvD89PwFrnvv9Pz0/AWue+8ABAIPBa4ErhIEEAAFrgWu+Pz8/AWue+/8//z/Ba577wAAAAAlrmm+AFDg8AWuJa4AEAAJBa4ErgQJOw8FrgSu8PTO/wWuBK7OP88fBa4Erj4APw8FrgSuPg8jAAWuBK4AAABABa6MwgDAQMAFqnvv/P///2vCe+/+/7//e+9778Dw0PAlrnvv8Pz4/QWqfO/u76/ve+987+7///9773vv/v///wWuBK7O/wD/Ba4Erv7///8FrgSu/v/AzwWuBK7y////Ba4Erv7/D/8FrgSuzv8D/wWuBK7+//D/Ba4Erv7///8FrgSuPv8/DwWuBK7+////Ba4Erv7/wGAFrgSuPg/A/wWuBK4O/w8fBa4ErnATAA8FrgSuHx8fAASuBK7+//P/Ba4Erv/v/wAErgSuPg8PHwWuBK4YChkABa4FrgAAVf8Frnzv/v+q/3vve+8B9P7/Ba577/7/6v9773vvJAsaACWuBa4AAID0Ba577wBAgPAFrnvv9P///wWufO/8////rcp87/7/Ps9773vv/v+fr3vve+8O/8//e+977w4PDw8FrgSuPg8vAQWuBa4AAADAJa5X54Dg0PQFrnzvAAAAQAWujMKA4OD8Ba577/T9/f8Frnvv/v+vr3vvfO/8////Ba587/7/n+9773zv/v/P/3vve+/+//3Pe+977+7/P/9773vv/v/+/3vve+/+/z/ze+977//3//9673vv/P///wWyfO/+/+//e+97767///9773vv/v/7P3vve+////z+eu977/4///9773vv///933rve+////n7eu977///v79673vv//+z/3rve+//99//eu9779+//vd673vv/////3rve+/f+t//eu977/////9673vv/////3rve+8=" - } - } - } - } - }, - "materials": { - "Effect-Texture": { - "name": "Texture", - "technique": "technique0", - "values": { - "diffuse": "texture_Image0001", - "shininess": 256, - "specular": [ - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224, - 1 - ] - } - } - }, - "meshes": { - "Geometry-mesh002": { - "name": "Mesh", - "primitives": [ - { - "attributes": { - "NORMAL": "accessor_25", - "POSITION": "accessor_23", - "TEXCOORD_0": "accessor_27" - }, - "indices": "accessor_21", - "material": "Effect-Texture", - "mode": 4 - } - ] - } - }, - "nodes": { - "rootNode": { - "children": [], - "meshes": [ - "Geometry-mesh002" - ], - "matrix": [ - 1, - 0, - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 0, - 1 - ] - } - }, - "programs": { - "program_0": { - "attributes": [ - "a_normal", - "a_position", - "a_texcoord0" - ], - "fragmentShader": "CesiumTexturedBoxTest0FS", - "vertexShader": "CesiumTexturedBoxTest0VS" - } - }, - "samplers": { - "sampler_0": { - "magFilter": 9729, - "minFilter": 9729, - "wrapS": 10497, - "wrapT": 10497 - } - }, - "scene": "defaultScene", - "scenes": { - "defaultScene": { - "nodes": [ - "rootNode" - ] - } - }, - "shaders": { - "CesiumTexturedBoxTest0FS": { - "type": 35632, - "uri": "data:text/plain;base64,cHJlY2lzaW9uIGhpZ2hwIGZsb2F0Ow0KdmFyeWluZyB2ZWMzIHZfbm9ybWFsOw0KdmFyeWluZyB2ZWMyIHZfdGV4Y29vcmQwOw0KdW5pZm9ybSBzYW1wbGVyMkQgdV9kaWZmdXNlOw0KdW5pZm9ybSB2ZWM0IHVfc3BlY3VsYXI7DQp1bmlmb3JtIGZsb2F0IHVfc2hpbmluZXNzOw0Kdm9pZCBtYWluKHZvaWQpIHsNCnZlYzMgbm9ybWFsID0gbm9ybWFsaXplKHZfbm9ybWFsKTsNCnZlYzQgY29sb3IgPSB2ZWM0KDAuLCAwLiwgMC4sIDAuKTsNCnZlYzQgZGlmZnVzZSA9IHZlYzQoMC4sIDAuLCAwLiwgMS4pOw0KdmVjNCBzcGVjdWxhcjsNCmRpZmZ1c2UgPSB0ZXh0dXJlMkQodV9kaWZmdXNlLCB2X3RleGNvb3JkMCk7DQpzcGVjdWxhciA9IHVfc3BlY3VsYXI7DQpkaWZmdXNlLnh5eiAqPSBtYXgoZG90KG5vcm1hbCx2ZWMzKDAuLDAuLDEuKSksIDAuKTsNCmNvbG9yLnh5eiArPSBkaWZmdXNlLnh5ejsNCmNvbG9yID0gdmVjNChjb2xvci5yZ2IgKiBkaWZmdXNlLmEsIGRpZmZ1c2UuYSk7DQpnbF9GcmFnQ29sb3IgPSBjb2xvcjsNCn0NCg==" - }, - "CesiumTexturedBoxTest0VS": { - "type": 35633, - "uri": "data:text/plain;base64,cHJlY2lzaW9uIGhpZ2hwIGZsb2F0Ow0KYXR0cmlidXRlIHZlYzMgYV9wb3NpdGlvbjsNCmF0dHJpYnV0ZSB2ZWMzIGFfbm9ybWFsOw0KdmFyeWluZyB2ZWMzIHZfbm9ybWFsOw0KdW5pZm9ybSBtYXQzIHVfbm9ybWFsTWF0cml4Ow0KdW5pZm9ybSBtYXQ0IHVfbW9kZWxWaWV3TWF0cml4Ow0KdW5pZm9ybSBtYXQ0IHVfcHJvamVjdGlvbk1hdHJpeDsNCmF0dHJpYnV0ZSB2ZWMyIGFfdGV4Y29vcmQwOw0KdmFyeWluZyB2ZWMyIHZfdGV4Y29vcmQwOw0Kdm9pZCBtYWluKHZvaWQpIHsNCnZlYzQgcG9zID0gdV9tb2RlbFZpZXdNYXRyaXggKiB2ZWM0KGFfcG9zaXRpb24sMS4wKTsNCnZfbm9ybWFsID0gdV9ub3JtYWxNYXRyaXggKiBhX25vcm1hbDsNCnZfdGV4Y29vcmQwID0gYV90ZXhjb29yZDA7DQpnbF9Qb3NpdGlvbiA9IHVfcHJvamVjdGlvbk1hdHJpeCAqIHBvczsNCn0NCg==" - } - }, - "skins": {}, - "techniques": { - "technique0": { - "attributes": { - "a_normal": "normal", - "a_position": "position", - "a_texcoord0": "texcoord0" - }, - "parameters": { - "diffuse": { - "type": 35678 - }, - "modelViewMatrix": { - "semantic": "MODELVIEW", - "type": 35676 - }, - "normal": { - "semantic": "NORMAL", - "type": 35665 - }, - "normalMatrix": { - "semantic": "MODELVIEWINVERSETRANSPOSE", - "type": 35675 - }, - "position": { - "semantic": "POSITION", - "type": 35665 - }, - "projectionMatrix": { - "semantic": "PROJECTION", - "type": 35676 - }, - "shininess": { - "type": 5126 - }, - "specular": { - "type": 35666 - }, - "texcoord0": { - "semantic": "TEXCOORD_0", - "type": 35664 - } - }, - "program": "program_0", - "states": { - "enable": [ - 2929, - 2884 - ] - }, - "uniforms": { - "u_diffuse": "diffuse", - "u_modelViewMatrix": "modelViewMatrix", - "u_normalMatrix": "normalMatrix", - "u_projectionMatrix": "projectionMatrix", - "u_shininess": "shininess", - "u_specular": "specular" - } - } - }, - "textures": { - "texture_Image0001": { - "format": 6408, - "internalFormat": 6408, - "sampler": "sampler_0", - "source": "Image0001", - "target": 3553, - "type": 5121 - } - }, - "cameras": {}, - "extensionsUsed": [] -} diff --git a/Specs/Data/Models/Box-Textured-KTX/CesiumTexturedBoxTest.gltf b/Specs/Data/Models/Box-Textured-KTX/CesiumTexturedBoxTest.gltf deleted file mode 100644 index bc2dae588970..000000000000 --- a/Specs/Data/Models/Box-Textured-KTX/CesiumTexturedBoxTest.gltf +++ /dev/null @@ -1,282 +0,0 @@ -{ - "accessors": { - "accessor_21": { - "bufferView": "bufferView_1", - "byteOffset": 0, - "byteStride": 0, - "componentType": 5123, - "count": 36, - "type": "SCALAR" - }, - "accessor_23": { - "bufferView": "bufferView_0", - "byteOffset": 0, - "byteStride": 0, - "componentType": 5126, - "count": 24, - "max": [ - 0.5, - 0.5, - 0.5 - ], - "min": [ - -0.5, - -0.5, - -0.5 - ], - "type": "VEC3" - }, - "accessor_25": { - "bufferView": "bufferView_0", - "byteOffset": 288, - "byteStride": 0, - "componentType": 5126, - "count": 24, - "max": [ - 1, - 1, - 1 - ], - "min": [ - -1, - -1, - -1 - ], - "type": "VEC3" - }, - "accessor_27": { - "bufferView": "bufferView_0", - "byteOffset": 576, - "byteStride": 0, - "componentType": 5126, - "count": 24, - "max": [ - 6, - 1 - ], - "min": [ - 0, - 0 - ], - "type": "VEC2" - } - }, - "animations": {}, - "asset": { - "generator": "collada2gltf@", - "premultipliedAlpha": true, - "profile": { - "api": "WebGL", - "version": "1.0.2" - }, - "version": "1.0" - }, - "bufferViews": { - "bufferView_0": { - "buffer": "CesiumTexturedBoxTest", - "byteLength": 768, - "byteOffset": 0, - "target": 34962 - }, - "bufferView_1": { - "buffer": "CesiumTexturedBoxTest", - "byteLength": 72, - "byteOffset": 768, - "target": 34963 - } - }, - "buffers": { - "CesiumTexturedBoxTest": { - "type": "arraybuffer", - "byteLength": 840, - "uri": "data:application/octet-stream;base64,AAAAvwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAvwAAAD8AAAC/AAAAPwAAAD8AAAC/AAAAPwAAAD8AAAC/AAAAPwAAAD8AAAA/AAAAPwAAAL8AAAC/AAAAPwAAAL8AAAA/AAAAvwAAAD8AAAC/AAAAPwAAAD8AAAC/AAAAvwAAAL8AAAC/AAAAPwAAAL8AAAC/AAAAPwAAAD8AAAA/AAAAvwAAAD8AAAA/AAAAPwAAAL8AAAA/AAAAvwAAAL8AAAA/AAAAvwAAAD8AAAA/AAAAvwAAAD8AAAC/AAAAvwAAAL8AAAA/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAA/AAAAvwAAAL8AAAC/AAAAPwAAAL8AAAA/AAAAPwAAAL8AAAC/AAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAADAQAAAAAAAAKBAAAAAAAAAwED+/38/AACgQP7/fz8AAIBAAAAAAAAAoEAAAAAAAACAQAAAgD8AAKBAAACAPwAAAEAAAAAAAACAPwAAAAAAAABAAACAPwAAgD8AAIA/AABAQAAAAAAAAIBAAAAAAAAAQEAAAIA/AACAQAAAgD8AAEBAAAAAAAAAAEAAAAAAAABAQAAAgD8AAABAAACAPwAAAAAAAAAAAAAAAP7/fz8AAIA/AAAAAAAAgD/+/38/AAABAAIAAwACAAEABAAFAAYABwAGAAUACAAJAAoACwAKAAkADAANAA4ADwAOAA0AEAARABIAEwASABEAFAAVABYAFwAWABUA" - } - }, - "images": { - "Image0001": { - "name": "Image0001", - "uri": "Image0001.png", - "extras": { - "compressedImage3DTiles": { - "s3tc": { - "uri": "Image0001-s3tc.ktx" - }, - "etc1": { - "uri": "Image0001-etc1.ktx" - }, - "pvrtc1": { - "uri": "Image0001-pvrtc1.ktx" - } - } - } - } - }, - "materials": { - "Effect-Texture": { - "name": "Texture", - "technique": "technique0", - "values": { - "diffuse": "texture_Image0001", - "shininess": 256, - "specular": [ - 0.20000000298023224, - 0.20000000298023224, - 0.20000000298023224, - 1 - ] - } - } - }, - "meshes": { - "Geometry-mesh002": { - "name": "Mesh", - "primitives": [ - { - "attributes": { - "NORMAL": "accessor_25", - "POSITION": "accessor_23", - "TEXCOORD_0": "accessor_27" - }, - "indices": "accessor_21", - "material": "Effect-Texture", - "mode": 4 - } - ] - } - }, - "nodes": { - "rootNode": { - "children": [], - "meshes": [ - "Geometry-mesh002" - ], - "matrix": [ - 1, - 0, - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 0, - 1 - ] - } - }, - "programs": { - "program_0": { - "attributes": [ - "a_normal", - "a_position", - "a_texcoord0" - ], - "fragmentShader": "CesiumTexturedBoxTest0FS", - "vertexShader": "CesiumTexturedBoxTest0VS" - } - }, - "samplers": { - "sampler_0": { - "magFilter": 9729, - "minFilter": 9729, - "wrapS": 10497, - "wrapT": 10497 - } - }, - "scene": "defaultScene", - "scenes": { - "defaultScene": { - "nodes": [ - "rootNode" - ] - } - }, - "shaders": { - "CesiumTexturedBoxTest0FS": { - "type": 35632, - "uri": "data:text/plain;base64,cHJlY2lzaW9uIGhpZ2hwIGZsb2F0Ow0KdmFyeWluZyB2ZWMzIHZfbm9ybWFsOw0KdmFyeWluZyB2ZWMyIHZfdGV4Y29vcmQwOw0KdW5pZm9ybSBzYW1wbGVyMkQgdV9kaWZmdXNlOw0KdW5pZm9ybSB2ZWM0IHVfc3BlY3VsYXI7DQp1bmlmb3JtIGZsb2F0IHVfc2hpbmluZXNzOw0Kdm9pZCBtYWluKHZvaWQpIHsNCnZlYzMgbm9ybWFsID0gbm9ybWFsaXplKHZfbm9ybWFsKTsNCnZlYzQgY29sb3IgPSB2ZWM0KDAuLCAwLiwgMC4sIDAuKTsNCnZlYzQgZGlmZnVzZSA9IHZlYzQoMC4sIDAuLCAwLiwgMS4pOw0KdmVjNCBzcGVjdWxhcjsNCmRpZmZ1c2UgPSB0ZXh0dXJlMkQodV9kaWZmdXNlLCB2X3RleGNvb3JkMCk7DQpzcGVjdWxhciA9IHVfc3BlY3VsYXI7DQpkaWZmdXNlLnh5eiAqPSBtYXgoZG90KG5vcm1hbCx2ZWMzKDAuLDAuLDEuKSksIDAuKTsNCmNvbG9yLnh5eiArPSBkaWZmdXNlLnh5ejsNCmNvbG9yID0gdmVjNChjb2xvci5yZ2IgKiBkaWZmdXNlLmEsIGRpZmZ1c2UuYSk7DQpnbF9GcmFnQ29sb3IgPSBjb2xvcjsNCn0NCg==" - }, - "CesiumTexturedBoxTest0VS": { - "type": 35633, - "uri": "data:text/plain;base64,cHJlY2lzaW9uIGhpZ2hwIGZsb2F0Ow0KYXR0cmlidXRlIHZlYzMgYV9wb3NpdGlvbjsNCmF0dHJpYnV0ZSB2ZWMzIGFfbm9ybWFsOw0KdmFyeWluZyB2ZWMzIHZfbm9ybWFsOw0KdW5pZm9ybSBtYXQzIHVfbm9ybWFsTWF0cml4Ow0KdW5pZm9ybSBtYXQ0IHVfbW9kZWxWaWV3TWF0cml4Ow0KdW5pZm9ybSBtYXQ0IHVfcHJvamVjdGlvbk1hdHJpeDsNCmF0dHJpYnV0ZSB2ZWMyIGFfdGV4Y29vcmQwOw0KdmFyeWluZyB2ZWMyIHZfdGV4Y29vcmQwOw0Kdm9pZCBtYWluKHZvaWQpIHsNCnZlYzQgcG9zID0gdV9tb2RlbFZpZXdNYXRyaXggKiB2ZWM0KGFfcG9zaXRpb24sMS4wKTsNCnZfbm9ybWFsID0gdV9ub3JtYWxNYXRyaXggKiBhX25vcm1hbDsNCnZfdGV4Y29vcmQwID0gYV90ZXhjb29yZDA7DQpnbF9Qb3NpdGlvbiA9IHVfcHJvamVjdGlvbk1hdHJpeCAqIHBvczsNCn0NCg==" - } - }, - "skins": {}, - "techniques": { - "technique0": { - "attributes": { - "a_normal": "normal", - "a_position": "position", - "a_texcoord0": "texcoord0" - }, - "parameters": { - "diffuse": { - "type": 35678 - }, - "modelViewMatrix": { - "semantic": "MODELVIEW", - "type": 35676 - }, - "normal": { - "semantic": "NORMAL", - "type": 35665 - }, - "normalMatrix": { - "semantic": "MODELVIEWINVERSETRANSPOSE", - "type": 35675 - }, - "position": { - "semantic": "POSITION", - "type": 35665 - }, - "projectionMatrix": { - "semantic": "PROJECTION", - "type": 35676 - }, - "shininess": { - "type": 5126 - }, - "specular": { - "type": 35666 - }, - "texcoord0": { - "semantic": "TEXCOORD_0", - "type": 35664 - } - }, - "program": "program_0", - "states": { - "enable": [ - 2929, - 2884 - ] - }, - "uniforms": { - "u_diffuse": "diffuse", - "u_modelViewMatrix": "modelViewMatrix", - "u_normalMatrix": "normalMatrix", - "u_projectionMatrix": "projectionMatrix", - "u_shininess": "shininess", - "u_specular": "specular" - } - } - }, - "textures": { - "texture_Image0001": { - "format": 6408, - "internalFormat": 6408, - "sampler": "sampler_0", - "source": "Image0001", - "target": 3553, - "type": 5121 - } - }, - "cameras": {}, - "extensionsUsed": [] -} diff --git a/Specs/Data/Models/Box-Textured-KTX/Image0001-etc1.ktx b/Specs/Data/Models/Box-Textured-KTX/Image0001-etc1.ktx deleted file mode 100644 index b5672fe60686..000000000000 Binary files a/Specs/Data/Models/Box-Textured-KTX/Image0001-etc1.ktx and /dev/null differ diff --git a/Specs/Data/Models/Box-Textured-KTX/Image0001-pvrtc1.ktx b/Specs/Data/Models/Box-Textured-KTX/Image0001-pvrtc1.ktx deleted file mode 100644 index f67b26e49312..000000000000 Binary files a/Specs/Data/Models/Box-Textured-KTX/Image0001-pvrtc1.ktx and /dev/null differ diff --git a/Specs/Data/Models/Box-Textured-KTX/Image0001-s3tc.ktx b/Specs/Data/Models/Box-Textured-KTX/Image0001-s3tc.ktx deleted file mode 100644 index ae4d0f4eebc6..000000000000 Binary files a/Specs/Data/Models/Box-Textured-KTX/Image0001-s3tc.ktx and /dev/null differ diff --git a/Specs/Data/Models/Box-Textured-KTX/Image0001.png b/Specs/Data/Models/Box-Textured-KTX/Image0001.png deleted file mode 100644 index 073fcf40a183..000000000000 Binary files a/Specs/Data/Models/Box-Textured-KTX/Image0001.png and /dev/null differ diff --git a/Specs/Data/Models/Box-Textured-KTX2-Basis/CesiumTexturedBoxTest.gltf b/Specs/Data/Models/Box-Textured-KTX2-Basis/CesiumTexturedBoxTest.gltf new file mode 100644 index 000000000000..ace71e649673 --- /dev/null +++ b/Specs/Data/Models/Box-Textured-KTX2-Basis/CesiumTexturedBoxTest.gltf @@ -0,0 +1,205 @@ +{ + "asset": { + "generator": "COLLADA2GLTF", + "version": "2.0" + }, + "extensionsUsed": [ + "KHR_texture_basisu" + ], + "extensionsRequired": [ + "KHR_texture_basisu" + ], + "scene": 0, + "scenes": [ + { + "nodes": [ + 0 + ] + } + ], + "nodes": [ + { + "children": [ + 1 + ], + "matrix": [ + 1, + 0, + 0, + 0, + 0, + 0, + -1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1 + ] + }, + { + "mesh": 0 + } + ], + "meshes": [ + { + "primitives": [ + { + "attributes": { + "NORMAL": 1, + "POSITION": 2, + "TEXCOORD_0": 3 + }, + "indices": 0, + "mode": 4, + "material": 0 + } + ], + "name": "Mesh" + } + ], + "accessors": [ + { + "bufferView": 0, + "byteOffset": 0, + "componentType": 5123, + "count": 36, + "max": [ + 23 + ], + "min": [ + 0 + ], + "type": "SCALAR" + }, + { + "bufferView": 1, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [ + 1, + 1, + 1 + ], + "min": [ + -1, + -1, + -1 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 288, + "componentType": 5126, + "count": 24, + "max": [ + 0.5, + 0.5, + 0.5 + ], + "min": [ + -0.5, + -0.5, + -0.5 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [ + 6, + 1 + ], + "min": [ + 0, + 0 + ], + "type": "VEC2" + } + ], + "materials": [ + { + "pbrMetallicRoughness": { + "baseColorTexture": { + "index": 0, + "texCoord": 0 + }, + "metallicFactor": 0, + "baseColorFactor": [ + 1, + 1, + 1, + 1 + ], + "roughnessFactor": 1 + }, + "name": "Texture", + "emissiveFactor": [ + 0, + 0, + 0 + ], + "alphaMode": "OPAQUE", + "doubleSided": false + } + ], + "textures": [ + { + "extensions": { + "KHR_texture_basisu": { + "source": 0 + } + } + } + ], + "images": [ + { + "mimeType": "image/ktx2", + "name": "cesium_logo", + "bufferView": 3 + } + ], + "bufferViews": [ + { + "buffer": 0, + "byteOffset": 0, + "byteLength": 72, + "target": 34963 + }, + { + "buffer": 0, + "byteOffset": 72, + "byteLength": 576, + "byteStride": 12, + "target": 34962 + }, + { + "buffer": 0, + "byteOffset": 648, + "byteLength": 192, + "byteStride": 8, + "target": 34962 + }, + { + "buffer": 0, + "byteOffset": 840, + "byteLength": 3559 + } + ], + "buffers": [ + { + "name": "box-textured-separate", + "byteLength": 4400, + "uri": "data:application/octet-stream;base64,AAABAAIAAwACAAEABAAFAAYABwAGAAUACAAJAAoACwAKAAkADAANAA4ADwAOAA0AEAARABIAEwASABEAFAAVABYAFwAWABUAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAvwAAAL8AAAA/AAAAPwAAAL8AAAA/AAAAvwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAL8AAAA/AAAAPwAAAD8AAAC/AAAAPwAAAL8AAAC/AAAAvwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAvwAAAD8AAAC/AAAAPwAAAD8AAAC/AAAAPwAAAL8AAAA/AAAAvwAAAL8AAAA/AAAAPwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAA/AAAAvwAAAD8AAAA/AAAAvwAAAL8AAAC/AAAAvwAAAD8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAD8AAAC/AAAAPwAAAL8AAAC/AAAAPwAAAD8AAAC/AADAQAAAAAAAAKBAAAAAAAAAwED+/38/AACgQP7/fz8AAIBAAAAAAAAAoEAAAAAAAACAQAAAgD8AAKBAAACAPwAAAEAAAAAAAACAPwAAAAAAAABAAACAPwAAgD8AAIA/AABAQAAAAAAAAIBAAAAAAAAAQEAAAIA/AACAQAAAgD8AAEBAAAAAAAAAAEAAAAAAAABAQAAAgD8AAABAAACAPwAAAAAAAAAAAAAAAP7/fz8AAIA/AAAAAAAAgD/+/38/q0tUWCAyMLsNChoKAAAAAAEAAAAAAQAAAAEAAAAAAAAAAAAAAQAAAAEAAAABAAAAaAAAACwAAACUAAAAfAAAABABAAAAAAAA/wUAAAAAAAAPBwAAAAAAANgGAAAAAAAAAAAAAAAAAAAsAAAAAAAAAAIAKACjAQIAAwMAAAAAAAAAAAAAAAA/AAAAAAAAAAAA/////xIAAABLVFhvcmllbnRhdGlvbgBydQAAAD0AAABLVFh3cml0ZXIAdG9rdHggdjQuMC4wLXJjMX42IC8gbGlia3R4IHY0LjAuMC1yYzEtNC1nMDI2NTIzMDMAAAAAGQAAAEtUWHdyaXRlclNjUGFyYW1zAC0tYmNtcAAAAACRAMwBXAEAAHsDAAAAAQAAAAAAAAAAAAAAAAAA2AYAAAAAAAAAAAAAH8AbAAEAgGBZEQe1cAICPAAgBkEQyCNIIm7tWrdVp4AAESC6QRAGoD8J6vo2V1pFkSNBACIAAAAACIHiwT3CjnU1NNwv0BLUfSgQh9cQArgiYGJKMRKFiCRAhChiieA2r/fq739fBfNrx7+8d96Z2Jg5Akc0I8aa9DhLUKW3pgSE2/CxShdT9+E8YYjSa7irKPfwAgIg31ZTGx5CHsKX6GZb/ifJ3wMQsiny4HJpdHvqMmSGSo9fPm3JjCj/WuPvfqJwVbcm0yv1v215e8ZUqXkq+mbho/7hSnm473n+XM8xI3MeAM40xohh0NPPrPUyjbR13Kf8QiQIm1SM2g8oQbW6am4R+r12lB3iRJd9Mpuv5+gYh95no1AGMkLPENZIPobnImVAQnDAY1YT0pDgivBSSidCEBmYgSm+/Xhd08w1TksxKMjh+8p91rfu2q/6Ftu/W6lsqtiYT0EHAAjmDojeZx0A8M/3eZ73zXvn75Jf2ivE2iHDFYyI/mKhRLzhe2kztAR8qTnQ7dXJweHALG6P7W0uF3VQcIjSpSrUQaRChieWgmCsWdwV/QOuf0FVVVNJUVSomDBNBUKUAgJpwOgDGAwGgYGCNzCwoIPBgku6IQf38S6K6hjUjgUdFQs+YLys64M8409TX8YTMCZDR2Ia6PqPTler4K13fLOak/fvovHCikSByoQCAhEqKAg0bBBYMFAxIbGQ6JDoDMhAgWBdqI1yhXMkOmbs0GGwoCNxgezINPfuJnayj4RkWOg3WQwM/YJrOnoFlc/2sKhwAIP6BfzUAM1TpcaUlde5BhUHtKquEShXsCkiVq3F3l4rDYtqfZXECR5BR3KrEzPnW6M/fz5/dbebWZDjCky4Pxw+HvZf4ZPj7tVvJz985+1AmETDyqI1FczK+gaup5ixhkc8oJ/vdw4z593Nm1s3DtPKAvNKSywb82GjbTabTQkt2ChBQCPALAIazngFBicrsY8ZGVLDLCEeo9GS9l00AoUgNBGtUQoqbuA/PEBsyRW23MM6xZQaHj2WS+UhuUR0oO6wsyrjrWK+H/r1dWgcbaz3grJeoxImUfYRyCQbEi2JpKAFSokrpcSX8D98+YSvWPH/e9rtVANvpr2lJ4mto7McF84emrnYwSHN3raBZhH9Yg6sOcAbJAIPEvcYWxbW+xiQZmlPMtNmJHOyRVykV7GFJLHFEcTs5cNZ4BS/J2xzX9tumjKLF683cZfsmJHkjCMkCcFYSZjhi8y3kq1Bh+TmbCxm5EVm5jxnsrXVn8/nOMx8T57kLFpgxosQMeF6ExE0tBI0EhHEmgUNDookFtzYMDX2mlCKEg4p31L2loAmhNvMtBtfe+F6Wf2xRTt5F2eJYb/JyUxLZoNFINhNmqNDh9p8kG9utxd/fj8jRbTVHfPjrzPF6Us11Ge/ZlkmtRaUikuWhcxpvNensVLdOebThT5ekyw8ebKKk/6Pp08Vnr7Op5cLf/9GOahTPTDC1b9ZEPXZuOtymvj4xDGGfzqu13wMPjeoFf+yt3htH8uC7W63++st60xx8VBc/PfntNs4IX62lhny378o5eru6Fe//f7x8Mv7sYp6dT9+o//hdy/92PmHH31w7+3z72FlumxLXX7wzId3qtP4Tl2fxl9+8slHOw8BAUEcAXEqCMDwF8YixcCbn1xkxSKNMBewFUvJDXYKeWVKy72FR0jaQQQDeThHsNz2Leq+ZnD+SOARwCYRRNH+P8OwULa7i0ANHkyqqSeJIakhEjzYqKEHtalNvBhjy80DlpQGI5YKy3a7szP/NQjvoPfrAY7P/ctvJmo5MiIPIXLMPIAQyjF3RcoVfrTMkXueQZ5C7iZHHkGYq80DmGFyTfIscs0oR55CHsAfjo2VI5mHMPII5ggb8gDCkDthCGseQrnzAHLP5hhhzjyH9+vz/vb79Fu/frXafr+K1q/8fiq6lF+qza8XEPBQghAEgeg+FlhENM3xGEjT0m6nTxAIAIcXTTmTPrV3sBjgERkgbNaHnh0UhhHnGHTf41mj6x+XXjmmag8zy15vua8Jm8O71aH79yyS1lp+3coQeFRIXFCaG7S/Gq0x9/407/aun5swWRsd2cHFvdO4lm0LsDCJLbb6bG6yLNdLQ1wSJv3ND0kXTWv72RvrXK4fWV1PXYyjsKguIzvgzbwTcu6wDx6jwRoGxrQlKyMena6OrNQ5YKKAjUm65SAc+nHFmWpeFIejWawdA20yHbuEwzxP1Ougac6NvhhgI4A+qyI3Cw14x27f8rWYiOcEMCvezDzgRv6ysxLQ5445sh/wiWHYOz+HQGIBHP9HIRZ8B/HhGQS1yZzeMfx/xw+OYT9gKcwcWP06apbfAOHVDswEI0sjtjvueIZGgXwB0UGG1e0j/jGASRHL/KgtbJ5Twmqtdr5XhoTFV7OMR4HZ5zsfNjuuh5H8xCNt2dkqKbwIztyO1jWNGAdN2FJD+ubPzWwbdVTY41NH0Fjt/YnOu3yLN6xjjrCaRje0uzkxw2FpXWYQDUcb/Hqg9EKZe7GiDtmS381F64rsbRUiZZ16dQMlcHtMW7Kq5d8lSATtw87/QhVVwMqmBzUXH5dJAPVDouj9vXu+AgpApDZmuy+Zg7blrs2U30Hk95sYcAJrs+nSWwqRatWdOb+vTMRhFh1WoA3wdUaylm5NWeq4C9ZU33qCAkHK/LqXqIsEnjDpduTcP20MRIaKjfnz2q3SXquvZYoUEuVdbukugRbgy1hk1OKVZXJmvEq/CZcf8tCwYInGW0kvIOIDCxbPk51lWU7dzkQKTx6qPtDY9cjqf1eSAaRA4yCf7GUgyqOdNoTSZAB6ixo0m/jTJEC6d/jMxYukgMSorUMRBInSyrbx0ppADTTXP74RcXt092mFSJRg9EoV5k0MpDEVdJ0lm0ySQQSH+RW9gsATPEZJELmMvmelILfqxyU0i8v9UkBiuSsl1ASJ1o1EpUsFdA512GhHp+wgiwSxzxTivwIyxLeeLxMiiezLval0r4AKfnMZahwRiPOOglCrhnNSPPwysYJS2HSTXkCkRo50/5yCmi22EEnZGdpWQbjq5IQ+fz7hRAEVxEwcZK6FVyD37+mGLBYF1EBv18QP0ySo4n3AZ/FCIAW0wC3kHEQAIq1n+h5OpgKCJU4hwk1BjlJb9yWFfPS6XEpB7jzZeJIMIjhcmnEKCp7ksCVBJNrel4J4Njahj1kU0AC3a04KxLpFidoNSAEV3UY7xqcCkfHaSYUIpwqYWdytv6uKNyAV/DQ315sUkH4UFJFWQdPwHM5JUb5JrCCqNog7hYgPXiyPrKBnS5gdIik7w3SlEIlTEDrfx0nelQIaoLExnF6KKIn5GtqSLEaHaye3z548CKR7J5/HvGQDMJj8CtnZR5Ao8S7XSgdGgpw5g04uYmaXzwBNFFr7ZQPSUgnTScPncv3BqBAJR5iytwqWFLZESLrr7YI34rvwU5oBiWy3xz4rA1AcLgmNBInmuZeA67eeonN7pUBafhyYC4c+YOUSk9ZeE3hLkKhnuwXsXrCdxUNPOwMi3uNdzwpK7D99GgV19RwpjwzWcSCkBtVT67oUIn2oLCEFdA77dN/GT5UUULHWkHmBPAdg47MP+VxNayQDiHw6PFEBcauCzt6c+F9TIXJSyXjhfHmwNddXZoHIbaZCpIjjiwJ6i4hHmhpEz5WT2b5M/u7VLPNMfmUfFQ5OMen3+5pzjvrs34rM6AVQDc49gkE8UPvBiJO40J9lW8+vA5Xwv6k8SLziVQd+0CP2EYqZCgMW3W94KEHN76qf2IEj2+AC85iKmd+4a0WPquwZoBZLYPVZAS94DbFWZwbjSUE5Z/plm1egA6hnP0pZNwqocVzwNpjiNvNnFCL6mMtAwSvmUgWtYFOhkZiwGmrU6n5SILLFJ127AwWg+/UPpQIK5EC+wIgqOUEJiup4oTwqaK1fnK6gE9zcZ+UIGK3iVcD/k9an6BFlvkO+AgVgcfufsZEH9OA9mtxgcrH0KpKKHqfz+R48gbmAp8zUjgV8YRjqsDbp5WEXLIAY2ZLgwxbGOQBPAniSHXX+E7hiV4f9zZ0VGKwB/nICbzYt/gbYCIc7dnB6AeeE1zqsK3IHgC0Oc30ahhwVTM6dPnFxAfbCYvLO9MUWWOGREaPaxcz+PesSFBixoF15OP0a2OFV2czFAzgKk5Ym2oaH37QbHnnGpHZ3RaaP3YUB4IJJ7yimP0KDYGn90Obijj7AVdgUnbwXnTWw86d/9E+v/82I9yIe3uSWLrBbv/0xl1/SHzGbrTAo8IeNd5WYeg/sabf4J5M9CgT5cT7yKh6XAcI7AAA=" + } + ] +} diff --git a/Specs/Data/Models/Box-Textured-KTX2-Mipmap/CheckerboardTexturedBoxTest.gltf b/Specs/Data/Models/Box-Textured-KTX2-Mipmap/CheckerboardTexturedBoxTest.gltf new file mode 100644 index 000000000000..c0f6db8afd10 --- /dev/null +++ b/Specs/Data/Models/Box-Textured-KTX2-Mipmap/CheckerboardTexturedBoxTest.gltf @@ -0,0 +1,205 @@ +{ + "asset": { + "generator": "COLLADA2GLTF", + "version": "2.0" + }, + "extensionsUsed": [ + "KHR_texture_basisu" + ], + "extensionsRequired": [ + "KHR_texture_basisu" + ], + "scene": 0, + "scenes": [ + { + "nodes": [ + 0 + ] + } + ], + "nodes": [ + { + "children": [ + 1 + ], + "matrix": [ + 1, + 0, + 0, + 0, + 0, + 0, + -1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1 + ] + }, + { + "mesh": 0 + } + ], + "meshes": [ + { + "primitives": [ + { + "attributes": { + "NORMAL": 1, + "POSITION": 2, + "TEXCOORD_0": 3 + }, + "indices": 0, + "mode": 4, + "material": 0 + } + ], + "name": "Mesh" + } + ], + "accessors": [ + { + "bufferView": 0, + "byteOffset": 0, + "componentType": 5123, + "count": 36, + "max": [ + 23 + ], + "min": [ + 0 + ], + "type": "SCALAR" + }, + { + "bufferView": 1, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [ + 1, + 1, + 1 + ], + "min": [ + -1, + -1, + -1 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 288, + "componentType": 5126, + "count": 24, + "max": [ + 0.5, + 0.5, + 0.5 + ], + "min": [ + -0.5, + -0.5, + -0.5 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [ + 6, + 1 + ], + "min": [ + 0, + 0 + ], + "type": "VEC2" + } + ], + "materials": [ + { + "pbrMetallicRoughness": { + "baseColorTexture": { + "index": 0, + "texCoord": 0 + }, + "metallicFactor": 0, + "baseColorFactor": [ + 1, + 1, + 1, + 1 + ], + "roughnessFactor": 1 + }, + "name": "Texture", + "emissiveFactor": [ + 0, + 0, + 0 + ], + "alphaMode": "OPAQUE", + "doubleSided": false + } + ], + "textures": [ + { + "extensions": { + "KHR_texture_basisu": { + "source": 0 + } + } + } + ], + "images": [ + { + "name": "checkerboard", + "bufferView": 3, + "mimeType": "image/ktx2" + } + ], + "bufferViews": [ + { + "buffer": 0, + "byteOffset": 0, + "byteLength": 72, + "target": 34963 + }, + { + "buffer": 0, + "byteOffset": 72, + "byteLength": 576, + "byteStride": 12, + "target": 34962 + }, + { + "buffer": 0, + "byteOffset": 648, + "byteLength": 192, + "byteStride": 8, + "target": 34962 + }, + { + "buffer": 0, + "byteOffset": 840, + "byteLength": 2647 + } + ], + "buffers": [ + { + "name": "BoxTextured0", + "byteLength": 3488, + "uri": "data:application/octet-stream;base64,AAABAAIAAwACAAEABAAFAAYABwAGAAUACAAJAAoACwAKAAkADAANAA4ADwAOAA0AEAARABIAEwASABEAFAAVABYAFwAWABUAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAvwAAAL8AAAA/AAAAPwAAAL8AAAA/AAAAvwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAL8AAAA/AAAAPwAAAD8AAAC/AAAAPwAAAL8AAAC/AAAAvwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAvwAAAD8AAAC/AAAAPwAAAD8AAAC/AAAAPwAAAL8AAAA/AAAAvwAAAL8AAAA/AAAAPwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAA/AAAAvwAAAD8AAAA/AAAAvwAAAL8AAAC/AAAAvwAAAD8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAD8AAAC/AAAAPwAAAL8AAAC/AAAAPwAAAD8AAAC/AADAQAAAAAAAAKBAAAAAAAAAwED+/38/AACgQP7/fz8AAIBAAAAAAAAAoEAAAAAAAACAQAAAgD8AAKBAAACAPwAAAEAAAAAAAACAPwAAAAAAAABAAACAPwAAgD8AAIA/AABAQAAAAAAAAIBAAAAAAAAAQEAAAIA/AACAQAAAgD8AAEBAAAAAAAAAAEAAAAAAAABAQAAAgD8AAABAAACAPwAAAAAAAAAAAAAAAP7/fz8AAIA/AAAAAAAAgD/+/38/q0tUWCAyMLsNChoKAAAAAAEAAAAAAQAAAAEAAAAAAAAAAAAAAQAAAAkAAAABAAAAKAEAACwAAABUAQAAfAAAANABAAAAAAAA9wEAAAAAAABeBwAAAAAAAPkCAAAAAAAAAAAAAAAAAACYBAAAAAAAAMYCAAAAAAAAAAAAAAAAAAD/AwAAAAAAAJkAAAAAAAAAAAAAAAAAAADqAwAAAAAAABUAAAAAAAAAAAAAAAAAAADXAwAAAAAAABMAAAAAAAAAAAAAAAAAAADQAwAAAAAAAAcAAAAAAAAAAAAAAAAAAADNAwAAAAAAAAMAAAAAAAAAAAAAAAAAAADKAwAAAAAAAAMAAAAAAAAAAAAAAAAAAADHAwAAAAAAAAMAAAAAAAAAAAAAAAAAAAAsAAAAAAAAAAIAKACjAQIAAwMAAAAAAAAAAAAAAAA/AAAAAAAAAAAA/////xIAAABLVFhvcmllbnRhdGlvbgByZAAAAD0AAABLVFh3cml0ZXIAdG9rdHggdjQuMC4wLXJjMX42IC8gbGlia3R4IHY0LjAuMC1yYzEtNC1nMDI2NTIzMDMAAAAAGQAAAEtUWHdyaXRlclNjUGFyYW1zAC0tYmNtcAAAAAANACgANgAAAJMAAABmAAAAAAAAAAAAAAAAAAAA+QIAAAAAAAAAAAAAAAAAAAAAAADGAgAAAAAAAAAAAAAAAAAAAAAAAJkAAAAAAAAAAAAAAAAAAAAAAAAAFQAAAAAAAAAAAAAAAAAAAAAAAAATAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAAAAAAAAAAACDAlAAAAAAAEMQNkw9AFAABAAAASGH7AKIGCAAAAINY2weCQQQgAoAAAAAQiNxmfrYhSzVpCAAIogYMwkAUQN/vAYIEUhI6QCsIihk+Sc2hOgI5R3cgXALiREUNBInAgOoIF9gEicQ3zDDPMJezMgVEgSIUQQFADIiBuBnftgpSVcPBffL5qW89sJMkkXoAySgR33p9pBDyPFhr7QHQGKMYY3oA6I0xEmPUcx2zzK/81588T/7L+X4N70un2i2O2l1fMm2yrHHOOQHBlABwxAqgKHpAYcl938lEQFUsTVTURZWEFBUFrIeuizUxvwGIACAAAjAM0gcFzTRg1jVJmlYFGA4P+BPwhIrgEfN6n86K7k42pqmYCjZnSChYgi75BrcLMCUAAAAAAAQRvCMQAN99B999B999B6c//P0/+CO//vzj79383W9v/92++uPjzd8Jv74//cZXH324/uQf9/3AD/yN/qQA38/399f/9p9+e0c/86u++KUvfumLX/ril774Xf6yf/+LX7z/5PX19fX19fX19T8+/Nen9+uHOz5dH1w38Df8/AYAfvnhV7c3dwBg+MkNALx+mNubOwAwvN4AwOuHub25AwDD6w0AvH6Y25s7ADC83gDA64e5vbkDAMPrDQC8fpjbmysA+G34wb/9+a9/8/Xb58fj8Xg8Hvc9f70/+v/u4d/+9+kfv334s+fp5189fD5PP/n48Pk8ffr08Pk8ffr08Pk8ffr08Pk8ffr006c/3D9/v+/+1T/9sl/N/7w28/WnZj5/aOZ+b+Z+b+Z+b/71xb/sB/ve39/1Z//7f/v/b7s/fez++L77cu2es3vO/sOv5/GYeTxmHo+Zx2Pm8Zh5PGYej5nH++G3u3Ou2j1n95zdc3bP2T1n95zd57nfvD5mHo+Zx2Pm8Zh5PGYej5nHY+bxmK9fvO1s965zds/ZPWf3nN1zds/ZPWd/+nnePs88HjOPx8zjMfN4zDweM4/HzOPT4ce7c67aPWf3nN1zds/ZPWf3nN3nubcPbzP3x8x1n3HN3Mwwwwzz+cXbznbv+mz3ftu9brvssssu+/J5Xq6Zc2bOmTln5pyZc2bOmTlvh5fddbtql1122WWXXXaf7u3tZeY6M+fMnDNzzsw5M+fMnDP3F2+7b/eu27V7s8suu+yyy77c5+U+c66Z65q5rpnrmrmumeuaud4OL7uX21W757bLLrvsssvu0729XTPnzJwzc87MOTPnzJwzc87cX7ztvt27btfuzS677LLLLvtyn5f7zLlmrmvmumaua+a6Zq5r5no7vOxeblftntsuu+yyyy67T/f2ds2cM3POzDkz58ycM3POzDlzf/G2+3bvul27N7vssssuu+zLfV7uM+eaua6Z65q5rpnrmrmumevt8LJ7uV21e2677LLLLrvsPt3b2zVzzsw5M+fMnDNzzsw5M+fM/cXb7tu963bt3uyyyy677LIv93m5z5xr5rpmrmvmumaua+a6Zq63w8vu5XbV7rntsssuu+yy+3Rvb9fMOTPnzJwzc87MOTPnzJwz95+87b7dr9u13a+b7X6x3S+2+8V2v9juF//vy/3i+f7u8/n+7vP5/u7z+f7u8/n+7vP5/u7z+f7u8/n+fAPn/dE3vvp4+uG3vvp4/PjB5fTxg8tRnMRRnMRRnMRRnMRRnMRRnISIiIiIiIiISCKRSCQSiUQikUgkEomEiIiIiIiIiKiDiYmJiYmJiYmJiYmJiYkJEREREREREZFEIpFIJBKJRCKRSCQSCRERERERERFRBxMTExMTExMTExMTExMTEyIiIiIiIiIiiUQikUgkEolEIpFIJBIiIiIiIiIiog4mJiYmJiYmJiYmJiYmJiZERERERERERBKJRCKRSCQSiUQikUgkREREREREREQdTExMTExMTExMTExMTExMiIiIiIiIiIgkEolEIpFIJBKJRCKRSIiIiIiIiIiIOpiYmJiYmJiYmJiYmJiYmBARERERERERSSQSiUQikUgkEolEIpEQEREREREREXUwMTExMTExMTExMTExMTEhIiIiIiIiIpJIJBKJRCKRSCQSiUQiISIiIiIiIiLqYGJiYmJiYmJiYmJiYmJiQkREREREREQkkUgkEolEIpFIJBKJREJERERERERE1MHExMTExMTExMTExMTExISIiIiIiIiISCKRSCQSiUQikUgkEomEiIiIiIiIiKiDiYmJiYmJiYmJiYmJiYkJEREREREREZFEIpFIJBKJRCKRSCQSCRERERERERFRBxMTExMTExMTExMTExMTEyIiIiIiIiIiiUQikUgkEolEIpFIJBIiIiIiIiIiog4mJiYmJiYmJiYmJiYmJiZERERERERERBKJRCKRSCQSiUQikUgkREREREREREQdTExMTExMTExMTExMTExMiIiIiIiIiIgkEolEIpFIJBKJRCKRSIiIiIiIiIiIOpiYmJiYmJiYmJiYmJiYmBARERERERERSSQSiUQikUgkEolEIpEQEREREREREXUwMTExMTExMTExMTExMTEhIiIiIiIiIpJIJBKJRCKRSCQSiUQiISIiIiIiIiLqYGJiYmJiYmJiYmJiYmJiQkREREREREQkkUgkEolEIpFIJBKJREJEREREREREBAA=" + } + ] +} diff --git a/Specs/Data/Models/GltfLoader/BoxTexturedKtx2Basis/glTF-Binary/BoxTexturedKtx2Basis.glb b/Specs/Data/Models/GltfLoader/BoxTexturedKtx2Basis/glTF-Binary/BoxTexturedKtx2Basis.glb new file mode 100644 index 000000000000..210b8319826a Binary files /dev/null and b/Specs/Data/Models/GltfLoader/BoxTexturedKtx2Basis/glTF-Binary/BoxTexturedKtx2Basis.glb differ diff --git a/Specs/Data/Models/GltfLoader/BoxTexturedKtx2Basis/glTF/BoxTexturedKtx2Basis.bin b/Specs/Data/Models/GltfLoader/BoxTexturedKtx2Basis/glTF/BoxTexturedKtx2Basis.bin new file mode 100644 index 000000000000..46ac386f3e05 Binary files /dev/null and b/Specs/Data/Models/GltfLoader/BoxTexturedKtx2Basis/glTF/BoxTexturedKtx2Basis.bin differ diff --git a/Specs/Data/Models/GltfLoader/BoxTexturedKtx2Basis/glTF/BoxTexturedKtx2Basis.gltf b/Specs/Data/Models/GltfLoader/BoxTexturedKtx2Basis/glTF/BoxTexturedKtx2Basis.gltf new file mode 100644 index 000000000000..a9a86a1cd652 --- /dev/null +++ b/Specs/Data/Models/GltfLoader/BoxTexturedKtx2Basis/glTF/BoxTexturedKtx2Basis.gltf @@ -0,0 +1,200 @@ +{ + "asset": { + "generator": "COLLADA2GLTF", + "version": "2.0" + }, + "extensionsUsed": [ + "KHR_texture_basisu" + ], + "extensionsRequired": [ + "KHR_texture_basisu" + ], + "scene": 0, + "scenes": [ + { + "nodes": [ + 0 + ] + } + ], + "nodes": [ + { + "children": [ + 1 + ], + "matrix": [ + 1, + 0, + 0, + 0, + 0, + 0, + -1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1 + ] + }, + { + "mesh": 0 + } + ], + "meshes": [ + { + "primitives": [ + { + "attributes": { + "NORMAL": 1, + "POSITION": 2, + "TEXCOORD_0": 3 + }, + "indices": 0, + "mode": 4, + "material": 0 + } + ], + "name": "Mesh" + } + ], + "accessors": [ + { + "bufferView": 0, + "byteOffset": 0, + "componentType": 5123, + "count": 36, + "max": [ + 23 + ], + "min": [ + 0 + ], + "type": "SCALAR" + }, + { + "bufferView": 1, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [ + 1, + 1, + 1 + ], + "min": [ + -1, + -1, + -1 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 288, + "componentType": 5126, + "count": 24, + "max": [ + 0.5, + 0.5, + 0.5 + ], + "min": [ + -0.5, + -0.5, + -0.5 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [ + 6, + 1 + ], + "min": [ + 0, + 0 + ], + "type": "VEC2" + } + ], + "materials": [ + { + "pbrMetallicRoughness": { + "baseColorTexture": { + "index": 0, + "texCoord": 0 + }, + "metallicFactor": 0, + "baseColorFactor": [ + 1, + 1, + 1, + 1 + ], + "roughnessFactor": 1 + }, + "name": "Texture", + "emissiveFactor": [ + 0, + 0, + 0 + ], + "alphaMode": "OPAQUE", + "doubleSided": false + } + ], + "textures": [ + { + "extensions": { + "KHR_texture_basisu": { + "source": 0 + } + } + } + ], + "images": [ + { + "mimeType": "image/ktx2", + "name": "cesium_logo", + "uri": "cesium_logo.ktx2" + } + ], + "bufferViews": [ + { + "buffer": 0, + "byteOffset": 0, + "byteLength": 72, + "target": 34963 + }, + { + "buffer": 0, + "byteOffset": 72, + "byteLength": 576, + "byteStride": 12, + "target": 34962 + }, + { + "buffer": 0, + "byteOffset": 648, + "byteLength": 192, + "byteStride": 8, + "target": 34962 + } + ], + "buffers": [ + { + "name": "BoxTexturedKtx2Basis", + "byteLength": 840, + "uri": "BoxTexturedKtx2Basis.bin" + } + ] +} diff --git a/Specs/Data/Models/GltfLoader/BoxTexturedKtx2Basis/glTF/cesium_logo.ktx2 b/Specs/Data/Models/GltfLoader/BoxTexturedKtx2Basis/glTF/cesium_logo.ktx2 new file mode 100644 index 000000000000..1c44a7e3925b Binary files /dev/null and b/Specs/Data/Models/GltfLoader/BoxTexturedKtx2Basis/glTF/cesium_logo.ktx2 differ diff --git a/Specs/Renderer/TextureSpec.js b/Specs/Renderer/TextureSpec.js index c717c5eebef1..a7dcd2302507 100644 --- a/Specs/Renderer/TextureSpec.js +++ b/Specs/Renderer/TextureSpec.js @@ -1,6 +1,7 @@ import { Cartesian2 } from "../../Source/Cesium.js"; import { Color } from "../../Source/Cesium.js"; -import { loadKTX } from "../../Source/Cesium.js"; +import { loadKTX2 } from "../../Source/Cesium.js"; +import { KTX2Transcoder } from "../../Source/Cesium.js"; import { PixelFormat } from "../../Source/Cesium.js"; import { Resource } from "../../Source/Cesium.js"; import { ClearCommand } from "../../Source/Cesium.js"; @@ -25,9 +26,8 @@ describe( var blueOverRedFlippedImage; var red16x16Image; - var greenDXTImage; - var greenPVRImage; - var greenETC1Image; + var greenKTX2Image; + var greenBasisKTX2Image; var fs = "uniform sampler2D u_texture;" + @@ -85,22 +85,26 @@ describe( red16x16Image = image; }) ); + + var resource = Resource.createIfNeeded("./Data/Images/Green4x4.ktx2"); + var loadPromise = resource.fetchArrayBuffer(); promises.push( - loadKTX("./Data/Images/Green4x4DXT1.ktx").then(function (image) { - greenDXTImage = image; - }) - ); - promises.push( - loadKTX("./Data/Images/Green4x4PVR.ktx").then(function (image) { - greenPVRImage = image; - }) - ); - promises.push( - loadKTX("./Data/Images/Green4x4ETC1.ktx").then(function (image) { - greenETC1Image = image; + loadPromise.then(function (buffer) { + var promise = KTX2Transcoder.transcode(buffer, {}); + return promise.then(function (result) { + greenKTX2Image = result; + }); }) ); + if (context.supportsBasis) { + promises.push( + loadKTX2("./Data/Images/Green4x4_ETC1S.ktx2").then(function (image) { + greenBasisKTX2Image = image; + }) + ); + } + return when.all(promises); }); @@ -432,18 +436,18 @@ describe( } }); - it("draws the expected DXT compressed texture color", function () { - if (!context.s3tc) { + it("draws the expected Basis compressed texture color", function () { + if (!context.supportsBasis) { return; } texture = new Texture({ context: context, - pixelFormat: greenDXTImage.internalFormat, + pixelFormat: greenBasisKTX2Image.internalFormat, source: { - width: greenDXTImage.width, - height: greenDXTImage.height, - arrayBufferView: greenDXTImage.bufferView, + width: greenBasisKTX2Image.width, + height: greenBasisKTX2Image.height, + arrayBufferView: greenBasisKTX2Image.bufferView, }, }); @@ -453,55 +457,31 @@ describe( context: context, fragmentShader: fs, uniformMap: uniformMap, - }).contextToRender([0, 255, 0, 255]); - }); - - it("draws the expected PVR compressed texture color", function () { - if (!context.pvrtc) { - return; - } - - texture = new Texture({ - context: context, - pixelFormat: greenPVRImage.internalFormat, - source: { - width: greenPVRImage.width, - height: greenPVRImage.height, - arrayBufferView: greenPVRImage.bufferView, - }, + }).contextToRenderAndCall(function (color) { + return expect(color).toEqualEpsilon([2, 255, 2, 255], 2); }); - - expect(texture.sizeInBytes).toBe(32); - - expect({ - context: context, - fragmentShader: fs, - uniformMap: uniformMap, - }).contextToRender([0, 255, 0, 255]); }); - it("draws the expected ETC1 compressed texture color", function () { - if (!context.etc1) { - return; - } - + it("draws the expected KTX2 uncompressed texture color", function () { texture = new Texture({ context: context, - pixelFormat: greenETC1Image.internalFormat, + pixelFormat: greenKTX2Image.internalFormat, source: { - width: greenETC1Image.width, - height: greenETC1Image.height, - arrayBufferView: greenETC1Image.bufferView, + width: greenKTX2Image.width, + height: greenKTX2Image.height, + arrayBufferView: greenKTX2Image.bufferView, }, }); - expect(texture.sizeInBytes).toBe(8); + expect(texture.sizeInBytes).toBe(48); expect({ context: context, fragmentShader: fs, uniformMap: uniformMap, - }).contextToRender([0, 253, 0, 255]); + }).contextToRenderAndCall(function (color) { + return expect(color).toEqualEpsilon([0, 255, 24, 255], 2); + }); }); it("renders with premultiplied alpha", function () { @@ -1129,70 +1109,6 @@ describe( }).toThrowDeveloperError(); }); - it("throws when creating compressed texture when s3tc is unsupported", function () { - if (!context.s3tc) { - expect(function () { - texture = new Texture({ - context: context, - width: greenDXTImage.width, - height: greenDXTImage.height, - pixelFormat: greenDXTImage.internalFormat, - source: { - arrayBufferView: greenDXTImage.bufferView, - }, - }); - }).toThrowDeveloperError(); - } - }); - - it("throws when creating compressed texture when pvrtc is unsupported", function () { - if (!context.pvrtc) { - expect(function () { - texture = new Texture({ - context: context, - width: greenPVRImage.width, - height: greenPVRImage.height, - pixelFormat: greenPVRImage.internalFormat, - source: { - arrayBufferView: greenPVRImage.bufferView, - }, - }); - }).toThrowDeveloperError(); - } - }); - - it("throws when creating compressed texture when etc1 is unsupported", function () { - if (!context.etc1) { - expect(function () { - texture = new Texture({ - context: context, - width: greenETC1Image.width, - height: greenETC1Image.height, - pixelFormat: greenETC1Image.internalFormat, - source: { - arrayBufferView: greenETC1Image.bufferView, - }, - }); - }).toThrowDeveloperError(); - } - }); - - it("throws when creating compressed texture and the array buffer is not the right length", function () { - if (context.s3tc) { - expect(function () { - texture = new Texture({ - context: context, - width: greenDXTImage.width + 1, - height: greenDXTImage.height, - pixelFormat: greenDXTImage.internalFormat, - source: { - arrayBufferView: greenDXTImage.bufferView, - }, - }); - }).toThrowDeveloperError(); - } - }); - it("throws when creating from the framebuffer with an invalid pixel format", function () { expect(function () { texture = Texture.fromFramebuffer({ @@ -1274,14 +1190,14 @@ describe( }); it("throws when copying to a texture from the framebuffer with a compressed pixel format", function () { - if (context.s3tc) { + if (context.supportsBasis) { texture = new Texture({ context: context, - width: greenDXTImage.width, - height: greenDXTImage.height, - pixelFormat: greenDXTImage.internalFormat, + width: greenBasisKTX2Image.width, + height: greenBasisKTX2Image.height, + pixelFormat: greenBasisKTX2Image.internalFormat, source: { - arrayBufferView: greenDXTImage.bufferView, + arrayBufferView: greenBasisKTX2Image.bufferView, }, }); @@ -1496,14 +1412,14 @@ describe( }); it("throws when copyFrom is given a source with a compressed pixel format", function () { - if (context.s3tc) { + if (context.supportsBasis) { texture = new Texture({ context: context, - width: greenDXTImage.width, - height: greenDXTImage.height, - pixelFormat: greenDXTImage.internalFormat, + width: greenBasisKTX2Image.width, + height: greenBasisKTX2Image.height, + pixelFormat: greenBasisKTX2Image.internalFormat, source: { - arrayBufferView: greenDXTImage.bufferView, + arrayBufferView: greenBasisKTX2Image.bufferView, }, }); @@ -1533,14 +1449,14 @@ describe( }); it("throws when generating mipmaps with a compressed pixel format", function () { - if (context.s3tc) { + if (context.supportsBasis) { texture = new Texture({ context: context, - width: greenDXTImage.width, - height: greenDXTImage.height, - pixelFormat: greenDXTImage.internalFormat, + width: greenBasisKTX2Image.width, + height: greenBasisKTX2Image.height, + pixelFormat: greenBasisKTX2Image.internalFormat, source: { - arrayBufferView: greenDXTImage.bufferView, + arrayBufferView: greenBasisKTX2Image.bufferView, }, }); diff --git a/Specs/Scene/GltfImageLoaderSpec.js b/Specs/Scene/GltfImageLoaderSpec.js index abc0926e693f..4cfab9fade60 100644 --- a/Specs/Scene/GltfImageLoaderSpec.js +++ b/Specs/Scene/GltfImageLoaderSpec.js @@ -1,13 +1,15 @@ import { + BufferLoader, clone, + CompressedTextureBuffer, GltfBufferViewLoader, GltfImageLoader, FeatureDetection, Resource, ResourceCache, - SupportedImageFormats, when, } from "../../Source/Cesium.js"; +import createContext from "../createContext.js"; import dataUriToBuffer from "../dataUriToBuffer.js"; import pollToPromise from "../pollToPromise.js"; @@ -31,6 +33,9 @@ describe("Scene/GltfImageLoader", function () { "data:image/gif;base64,R0lGODdhBAAEAIAAAP///////ywAAAAABAAEAAACBISPCQUAOw==" ); + var ktx2BasisBuffer; + var ktx2BasisMipmapBuffer; + var gltfUri = "https://example.com/model.glb"; var gltfResource = new Resource({ url: gltfUri, @@ -58,9 +63,18 @@ describe("Scene/GltfImageLoader", function () { { uri: "image.png", }, + { + mimeType: "image/ktx2", + bufferView: 0, + }, + { + uri: "image.ktx2", + }, ], }; + var context; + function getGltf(imageBuffer) { var clonedGltf = clone(gltf, true); clonedGltf.buffers[0].byteLength = imageBuffer.byteLength; @@ -68,6 +82,26 @@ describe("Scene/GltfImageLoader", function () { return clonedGltf; } + beforeAll(function () { + context = createContext(); + var ktx2BasisBufferPromise = Resource.fetchArrayBuffer({ + url: "./Data/Images/Green4x4_ETC1S.ktx2", + }).then(function (arrayBuffer) { + ktx2BasisBuffer = new Uint8Array(arrayBuffer); + }); + var ktx2BasisMipmapBufferPromise = Resource.fetchArrayBuffer({ + url: "./Data/Images/Green4x4Mipmap_ETC1S.ktx2", + }).then(function (arrayBuffer) { + ktx2BasisMipmapBuffer = new Uint8Array(arrayBuffer); + }); + + return when.all([ktx2BasisBufferPromise, ktx2BasisMipmapBufferPromise]); + }); + + afterAll(function () { + context.destroyForSpecs(); + }); + afterEach(function () { ResourceCache.clearForSpecs(); }); @@ -80,7 +114,6 @@ describe("Scene/GltfImageLoader", function () { imageId: 0, gltfResource: gltfResource, baseResource: gltfResource, - supportedImageFormats: new SupportedImageFormats(), }); }).toThrowDeveloperError(); }); @@ -93,7 +126,6 @@ describe("Scene/GltfImageLoader", function () { imageId: 0, gltfResource: gltfResource, baseResource: gltfResource, - supportedImageFormats: new SupportedImageFormats(), }); }).toThrowDeveloperError(); }); @@ -106,7 +138,6 @@ describe("Scene/GltfImageLoader", function () { imageId: undefined, gltfResource: gltfResource, baseResource: gltfResource, - supportedImageFormats: new SupportedImageFormats(), }); }).toThrowDeveloperError(); }); @@ -119,7 +150,6 @@ describe("Scene/GltfImageLoader", function () { imageId: 0, gltfResource: undefined, baseResource: gltfResource, - supportedImageFormats: new SupportedImageFormats(), }); }).toThrowDeveloperError(); }); @@ -132,20 +162,6 @@ describe("Scene/GltfImageLoader", function () { imageId: 0, gltfResource: gltfResource, baseResource: undefined, - supportedImageFormats: new SupportedImageFormats(), - }); - }).toThrowDeveloperError(); - }); - - it("throws if supportedImageFormats is undefined", function () { - expect(function () { - return new GltfImageLoader({ - resourceCache: ResourceCache, - gltf: gltf, - imageId: 0, - gltfResource: gltfResource, - baseResource: gltfResource, - supportedImageFormats: undefined, }); }).toThrowDeveloperError(); }); @@ -162,7 +178,6 @@ describe("Scene/GltfImageLoader", function () { imageId: 0, gltfResource: gltfResource, baseResource: gltfResource, - supportedImageFormats: new SupportedImageFormats(), }); imageLoader.load(); @@ -189,7 +204,6 @@ describe("Scene/GltfImageLoader", function () { imageId: 0, gltfResource: gltfResource, baseResource: gltfResource, - supportedImageFormats: new SupportedImageFormats(), }); imageLoader.load(); @@ -215,7 +229,6 @@ describe("Scene/GltfImageLoader", function () { imageId: 1, gltfResource: gltfResource, baseResource: gltfResource, - supportedImageFormats: new SupportedImageFormats(), }); imageLoader.load(); @@ -242,7 +255,6 @@ describe("Scene/GltfImageLoader", function () { imageId: 0, gltfResource: gltfResource, baseResource: gltfResource, - supportedImageFormats: new SupportedImageFormats(), }); imageLoader.load(); @@ -273,6 +285,60 @@ describe("Scene/GltfImageLoader", function () { }); }); + it("loads KTX2/Basis from buffer view", function () { + if (!context.supportsBasis) { + return; + } + + spyOn(BufferLoader, "_fetchArrayBuffer").and.returnValue( + when.resolve(ktx2BasisBuffer) + ); + + var imageLoader = new GltfImageLoader({ + resourceCache: ResourceCache, + gltf: getGltf(ktx2BasisBuffer), + imageId: 2, + gltfResource: gltfResource, + baseResource: gltfResource, + }); + + imageLoader.load(); + + return imageLoader.promise.then(function (imageLoader) { + expect(imageLoader.image instanceof CompressedTextureBuffer).toBe(true); + expect(imageLoader.image.width).toBe(4); + expect(imageLoader.image.height).toBe(4); + expect(imageLoader.mipLevels).toBeUndefined(); + }); + }); + + it("loads KTX2/Basis with mipmap from buffer view", function () { + if (!context.supportsBasis) { + return; + } + + spyOn(BufferLoader, "_fetchArrayBuffer").and.returnValue( + when.resolve(ktx2BasisMipmapBuffer) + ); + + var imageLoader = new GltfImageLoader({ + resourceCache: ResourceCache, + gltf: getGltf(ktx2BasisMipmapBuffer), + imageId: 2, + gltfResource: gltfResource, + baseResource: gltfResource, + }); + + imageLoader.load(); + + return imageLoader.promise.then(function (imageLoader) { + expect(imageLoader.image instanceof CompressedTextureBuffer).toBe(true); + expect(imageLoader.image.width).toBe(4); + expect(imageLoader.image.height).toBe(4); + expect(imageLoader.mipLevels.length).toBe(2); + }); + }); + it("loads from uri", function () { spyOn(Resource.prototype, "fetchImage").and.returnValue( when.resolve(image) @@ -280,11 +346,10 @@ describe("Scene/GltfImageLoader", function () { var imageLoader = new GltfImageLoader({ resourceCache: ResourceCache, - gltf: getGltf(pngBuffer), + gltf: clone(gltf, true), imageId: 1, gltfResource: gltfResource, baseResource: gltfResource, - supportedImageFormats: new SupportedImageFormats(), }); imageLoader.load(); @@ -295,6 +360,36 @@ describe("Scene/GltfImageLoader", function () { }); }); + it("loads KTX2/Basis from uri ", function () { + if (!context.supportsBasis) { + return; + } + + var baseResource = new Resource({ + url: "./Data/Images/", + }); + + var clonedGltf = clone(gltf, true); + clonedGltf.images[3].uri = "Green4x4_ETC1S.ktx2"; + + var imageLoader = new GltfImageLoader({ + resourceCache: ResourceCache, + gltf: clonedGltf, + imageId: 3, + gltfResource: gltfResource, + baseResource: baseResource, + }); + + imageLoader.load(); + + return imageLoader.promise.then(function (imageLoader) { + expect(imageLoader.image instanceof CompressedTextureBuffer).toBe(true); + expect(imageLoader.image.width).toBe(4); + expect(imageLoader.image.height).toBe(4); + expect(imageLoader.mipLevels).toBeUndefined(); + }); + }); + it("destroys image loader", function () { spyOn(Resource.prototype, "fetchArrayBuffer").and.returnValue( when.resolve(pngBuffer) @@ -311,7 +406,6 @@ describe("Scene/GltfImageLoader", function () { imageId: 0, gltfResource: gltfResource, baseResource: gltfResource, - supportedImageFormats: new SupportedImageFormats(), }); expect(imageLoader.image).not.toBeDefined(); @@ -350,7 +444,6 @@ describe("Scene/GltfImageLoader", function () { imageId: 0, gltfResource: gltfResource, baseResource: gltfResource, - supportedImageFormats: new SupportedImageFormats(), }); expect(imageLoader.image).not.toBeDefined(); @@ -403,7 +496,6 @@ describe("Scene/GltfImageLoader", function () { imageId: 0, gltfResource: gltfResource, baseResource: gltfResource, - supportedImageFormats: new SupportedImageFormats(), }); expect(imageLoader.image).not.toBeDefined(); @@ -443,7 +535,6 @@ describe("Scene/GltfImageLoader", function () { imageId: 1, gltfResource: gltfResource, baseResource: gltfResource, - supportedImageFormats: new SupportedImageFormats(), }); expect(imageLoader.image).not.toBeDefined(); diff --git a/Specs/Scene/GltfLoaderSpec.js b/Specs/Scene/GltfLoaderSpec.js index 5f5fdaa2fee6..bdb8ac879271 100644 --- a/Specs/Scene/GltfLoaderSpec.js +++ b/Specs/Scene/GltfLoaderSpec.js @@ -44,6 +44,10 @@ describe( "./Data/Models/GltfLoader/BoxTextured/glTF-Binary/BoxTextured.glb"; var boxTexturedEmbedded = "./Data/Models/GltfLoader/BoxTextured/glTF-Embedded/BoxTextured.gltf"; + var boxTexturedKtx2Basis = + "./Data/Models/GltfLoader/BoxTexturedKtx2Basis/glTF/BoxTexturedKtx2Basis.gltf"; + var boxTexturedKtx2BasisBinary = + "./Data/Models/GltfLoader/BoxTexturedKtx2Basis/glTF-Binary/BoxTexturedKtx2Basis.glb"; var boxVertexColors = "./Data/Models/GltfLoader/BoxVertexColors/glTF/BoxVertexColors.gltf"; var simpleMorph = @@ -359,6 +363,47 @@ describe( ); }); + function loadsBoxTexturedKtx2Basis(gltfPath) { + return loadGltf(gltfPath).then(function (gltfLoader) { + var components = gltfLoader.components; + var scene = components.scene; + var rootNode = scene.nodes[0]; + var childNode = rootNode.children[0]; + var primitive = childNode.primitives[0]; + var material = primitive.material; + var metallicRoughness = material.metallicRoughness; + + var texture = metallicRoughness.baseColorTexture.texture; + var sampler = texture.sampler; + + expect(texture.width).toBe(256); + expect(texture.height).toBe(256); + + expect(sampler.wrapS).toBe(TextureWrap.REPEAT); + expect(sampler.wrapT).toBe(TextureWrap.REPEAT); + expect(sampler.magnificationFilter).toBe( + TextureMagnificationFilter.LINEAR + ); + expect(sampler.minificationFilter).toBe( + TextureMinificationFilter.LINEAR + ); + }); + } + + it("loads BoxTexturedKtx2Basis", function () { + if (!scene.context.supportsBasis) { + return; + } + return loadsBoxTexturedKtx2Basis(boxTexturedKtx2Basis); + }); + + it("loads BoxTexturedKtx2BasisBinary", function () { + if (!scene.context.supportsBasis) { + return; + } + return loadsBoxTexturedKtx2Basis(boxTexturedKtx2BasisBinary); + }); + it("loads BoxVertexColors", function () { return loadGltf(boxVertexColors).then(function (gltfLoader) { var components = gltfLoader.components; diff --git a/Specs/Scene/GltfLoaderUtilSpec.js b/Specs/Scene/GltfLoaderUtilSpec.js index bbaf98393f3c..33f2b55963e8 100644 --- a/Specs/Scene/GltfLoaderUtilSpec.js +++ b/Specs/Scene/GltfLoaderUtilSpec.js @@ -24,6 +24,9 @@ describe("Scene/GltfLoaderUtil", function () { { uri: "image.webp", }, + { + uri: "image.ktx2", + }, ], textures: [ { @@ -37,6 +40,14 @@ describe("Scene/GltfLoaderUtil", function () { }, }, }, + { + source: 0, + extensions: { + KHR_texture_basisu: { + source: 3, + }, + }, + }, ], }; @@ -101,6 +112,28 @@ describe("Scene/GltfLoaderUtil", function () { expect(imageId).toBe(0); }); + it("getImageIdFromTexture gets KTX2 image when KHR_texture_basisu extension is supported", function () { + var imageId = GltfLoaderUtil.getImageIdFromTexture({ + gltf: gltfWithTextures, + textureId: 2, + supportedImageFormats: new SupportedImageFormats({ + basis: true, + }), + }); + expect(imageId).toBe(3); + }); + + it("getImageIdFromTexture gets default image when KHR_texture_basisu extension is not supported", function () { + var imageId = GltfLoaderUtil.getImageIdFromTexture({ + gltf: gltfWithTextures, + textureId: 2, + supportedImageFormats: new SupportedImageFormats({ + basis: false, + }), + }); + expect(imageId).toBe(0); + }); + it("createSampler throws if gltf is undefined", function () { expect(function () { GltfLoaderUtil.getImageIdFromTexture({ @@ -112,7 +145,7 @@ describe("Scene/GltfLoaderUtil", function () { }).toThrowDeveloperError(); }); - it("createSampler throws if gltf is undefined", function () { + it("createSampler throws if textureInfo is undefined", function () { expect(function () { GltfLoaderUtil.getImageIdFromTexture({ gltf: gltfWithTextures, @@ -140,6 +173,64 @@ describe("Scene/GltfLoaderUtil", function () { expect(sampler.magnificationFilter).toBe(TextureMagnificationFilter.LINEAR); }); + it("createSampler uses NEAREST when compressedTextureNoMipmap is true and the minFilter uses nearest mipmap filtering", function () { + var sampler = GltfLoaderUtil.createSampler({ + gltf: { + textures: [ + { + source: 0, + sampler: 0, + }, + ], + samplers: [ + { + magFilter: 9729, + minFilter: 9986, + wrapS: 10497, + wrapT: 10497, + }, + ], + }, + textureInfo: { + index: 0, + }, + compressedTextureNoMipmap: true, + }); + expect(sampler.wrapS).toBe(TextureWrap.REPEAT); + expect(sampler.wrapT).toBe(TextureWrap.REPEAT); + expect(sampler.minificationFilter).toBe(TextureMinificationFilter.NEAREST); + expect(sampler.magnificationFilter).toBe(TextureMagnificationFilter.LINEAR); + }); + + it("createSampler uses LINEAR when compressedTextureNoMipmap is true and the minFilter uses linear mipmap filtering", function () { + var sampler = GltfLoaderUtil.createSampler({ + gltf: { + textures: [ + { + source: 0, + sampler: 0, + }, + ], + samplers: [ + { + magFilter: 9729, + minFilter: 9987, + wrapS: 10497, + wrapT: 10497, + }, + ], + }, + textureInfo: { + index: 0, + }, + compressedTextureNoMipmap: true, + }); + expect(sampler.wrapS).toBe(TextureWrap.REPEAT); + expect(sampler.wrapT).toBe(TextureWrap.REPEAT); + expect(sampler.minificationFilter).toBe(TextureMinificationFilter.LINEAR); + expect(sampler.magnificationFilter).toBe(TextureMagnificationFilter.LINEAR); + }); + function createSampler(options) { var gltf = { textures: [ diff --git a/Specs/Scene/GltfTextureLoaderSpec.js b/Specs/Scene/GltfTextureLoaderSpec.js index 04301cc8d977..faefc3d80eda 100644 --- a/Specs/Scene/GltfTextureLoaderSpec.js +++ b/Specs/Scene/GltfTextureLoaderSpec.js @@ -1,11 +1,14 @@ import { + clone, GltfImageLoader, GltfTextureLoader, + GltfLoaderUtil, JobScheduler, Resource, ResourceCache, SupportedImageFormats, Texture, + TextureMinificationFilter, when, } from "../../Source/Cesium.js"; import createScene from "../createScene.js"; @@ -75,6 +78,68 @@ describe( ], }; + var gltfKtx2BaseResource = new Resource({ + url: "./Data/Images/", + }); + + var gltfKtx2 = { + images: [ + { + uri: "image.png", + }, + { + uri: "Green4x4_ETC1S.ktx2", + }, + { + uri: "Green4x4Mipmap_ETC1S.ktx2", + }, + ], + textures: [ + { + source: 0, + sampler: 0, + extensions: { + KHR_texture_basisu: { + source: 1, + }, + }, + }, + { + source: 0, + sampler: 1, + extensions: { + KHR_texture_basisu: { + source: 2, + }, + }, + }, + ], + materials: [ + { + emissiveTexture: { + index: 0, + }, + occlusionTexture: { + index: 1, + }, + }, + ], + samplers: [ + { + magFilter: 9728, // NEAREST + minFilter: 9728, // NEAREST + wrapS: 10497, // REPEAT + wrapT: 10497, // REPEAT + }, + { + magFilter: 9728, // NEAREST + minFilter: 9984, // NEAREST_MIPMAP_NEAREST + wrapS: 33071, // CLAMP_TO_EDGE + wrapT: 33071, // CLAMP_TO_EDGE + }, + ], + }; + var scene; beforeAll(function () { @@ -263,6 +328,105 @@ describe( }); }); + it("loads KTX2/Basis texture", function () { + if (!scene.context.supportsBasis) { + return; + } + + var gl = scene.context._gl; + spyOn(gl, "compressedTexImage2D").and.callThrough(); + + var textureLoader = new GltfTextureLoader({ + resourceCache: ResourceCache, + gltf: gltfKtx2, + textureInfo: gltf.materials[0].emissiveTexture, + gltfResource: gltfResource, + baseResource: gltfKtx2BaseResource, + supportedImageFormats: new SupportedImageFormats({ + basis: true, + }), + }); + + textureLoader.load(); + + return waitForLoaderProcess(textureLoader, scene).then(function ( + textureLoader + ) { + expect(textureLoader.texture.width).toBe(4); + expect(textureLoader.texture.height).toBe(4); + expect(gl.compressedTexImage2D.calls.count()).toEqual(1); + }); + }); + + it("loads KTX2/Basis texture with mipmap", function () { + if (!scene.context.supportsBasis) { + return; + } + + var gl = scene.context._gl; + spyOn(gl, "compressedTexImage2D").and.callThrough(); + + var textureLoader = new GltfTextureLoader({ + resourceCache: ResourceCache, + gltf: gltfKtx2, + textureInfo: gltf.materials[0].occlusionTexture, + gltfResource: gltfResource, + baseResource: gltfKtx2BaseResource, + supportedImageFormats: new SupportedImageFormats({ + basis: true, + }), + }); + + textureLoader.load(); + + return waitForLoaderProcess(textureLoader, scene).then(function ( + textureLoader + ) { + expect(textureLoader.texture.width).toBe(4); + expect(textureLoader.texture.height).toBe(4); + expect(gl.compressedTexImage2D.calls.count()).toEqual(3); + }); + }); + + it("loads KTX2/Basis texture with incompatible mipmap sampler", function () { + if (!scene.context.supportsBasis) { + return; + } + + spyOn(GltfLoaderUtil, "createSampler").and.callThrough(); + + var gltfKtx2MissingMipmap = clone(gltfKtx2, true); + gltfKtx2MissingMipmap.samplers[0].minFilter = + TextureMinificationFilter.NEAREST_MIPMAP_NEAREST; + + var textureLoader = new GltfTextureLoader({ + resourceCache: ResourceCache, + gltf: gltfKtx2MissingMipmap, + textureInfo: gltfKtx2MissingMipmap.materials[0].emissiveTexture, + gltfResource: gltfResource, + baseResource: gltfKtx2BaseResource, + supportedImageFormats: new SupportedImageFormats({ + basis: true, + }), + asynchronous: false, + }); + + textureLoader.load(); + + return waitForLoaderProcess(textureLoader, scene).then(function ( + textureLoader + ) { + expect(GltfLoaderUtil.createSampler).toHaveBeenCalledWith({ + gltf: gltfKtx2MissingMipmap, + textureInfo: gltf.materials[0].emissiveTexture, + compressedTextureNoMipmap: true, + }); + expect(textureLoader.texture.sampler.minificationFilter).toBe( + TextureMinificationFilter.NEAREST + ); + }); + }); + it("generates mipmap if sampler requires it", function () { spyOn(Resource.prototype, "fetchImage").and.returnValue( when.resolve(image) @@ -397,7 +561,6 @@ describe( imageId: 0, gltfResource: gltfResource, baseResource: gltfResource, - supportedImageFormats: new SupportedImageFormats(), }); var textureLoader = new GltfTextureLoader({ diff --git a/Specs/Scene/MaterialSpec.js b/Specs/Scene/MaterialSpec.js index 5ac0984a7d3b..63abff825c82 100644 --- a/Specs/Scene/MaterialSpec.js +++ b/Specs/Scene/MaterialSpec.js @@ -10,6 +10,7 @@ import { Resource } from "../../Source/Cesium.js"; import { Material } from "../../Source/Cesium.js"; import { MaterialAppearance } from "../../Source/Cesium.js"; import { PolylineCollection } from "../../Source/Cesium.js"; +import { FeatureDetection } from "../../Source/Cesium.js"; import { Primitive } from "../../Source/Cesium.js"; import { TextureMagnificationFilter } from "../../Source/Cesium.js"; import { TextureMinificationFilter } from "../../Source/Cesium.js"; @@ -367,15 +368,10 @@ describe( renderMaterial(material); }); - it("creates a material with an ktx compressed image uniform", function () { + it("creates a material with an KTX2 compressed image uniform", function () { var compressedUrl; - var context = scene.context; - if (context.s3tc) { - compressedUrl = "./Data/Images/Green4x4DXT1.ktx"; - } else if (context.etc1) { - compressedUrl = "./Data/Images/Green4x4ETC1.ktx"; - } else if (context.pvrtc) { - compressedUrl = "./Data/Images/Green4x4PVR.ktx"; + if (FeatureDetection.supportsBasis(scene)) { + compressedUrl = "./Data/Images/Green4x4.ktx2"; } else { return; } @@ -392,25 +388,6 @@ describe( renderMaterial(material); }); - it("creates a material with an crn compressed image uniform", function () { - var context = scene.context; - if (!context.s3tc) { - return; - } - - var compressedUrl = "./Data/Images/Green4x4.crn"; - var material = new Material({ - strict: true, - fabric: { - type: "DiffuseMap", - uniforms: { - image: compressedUrl, - }, - }, - }); - renderMaterial(material); - }); - it("creates a material with a cube map uniform", function () { var material = new Material({ strict: true, diff --git a/Specs/Scene/ModelSpec.js b/Specs/Scene/ModelSpec.js index bd014fbf47eb..89406a71f3df 100644 --- a/Specs/Scene/ModelSpec.js +++ b/Specs/Scene/ModelSpec.js @@ -50,18 +50,10 @@ describe( "./Data/Models/Box-Textured-Separate/CesiumTexturedBoxTest.gltf"; var texturedBoxBasePathUrl = "./Data/Models/Box-Textured-BasePath/CesiumTexturedBoxTest.gltf"; - var texturedBoxKTXUrl = - "./Data/Models/Box-Textured-KTX/CesiumTexturedBoxTest.gltf"; - var texturedBoxKTXBinaryUrl = - "./Data/Models/Box-Textured-KTX-Binary/CesiumTexturedBoxTest.glb"; - var texturedBoxKTXEmbeddedUrl = - "./Data/Models/Box-Textured-KTX-Embedded/CesiumTexturedBoxTest.gltf"; - var texturedBoxCRNUrl = - "./Data/Models/Box-Textured-CRN/CesiumTexturedBoxTest.gltf"; - var texturedBoxCRNBinaryUrl = - "./Data/Models/Box-Textured-CRN-Binary/CesiumTexturedBoxTest.glb"; - var texturedBoxCRNEmbeddedUrl = - "./Data/Models/Box-Textured-CRN-Embedded/CesiumTexturedBoxTest.gltf"; + var texturedBoxKTX2Url = + "./Data/Models/Box-Textured-KTX2-Basis/CesiumTexturedBoxTest.gltf"; + var texturedBoxKTX2MipmapUrl = + "./Data/Models/Box-Textured-KTX2-Mipmap/CheckerboardTexturedBoxTest.gltf"; var texturedBoxCustomUrl = "./Data/Models/Box-Textured-Custom/CesiumTexturedBoxTest.gltf"; var texturedBoxKhrBinaryUrl = @@ -807,7 +799,7 @@ describe( return loadModel(boomBoxUrl).then(function (m) { m.scale = 20.0; // Source model is very small, so scale up a bit m.specularEnvironmentMaps = - "./Data/EnvironmentMap/kiara_6_afternoon_2k_ibl.ktx"; + "./Data/EnvironmentMap/kiara_6_afternoon_2k_ibl.ktx2"; return pollToPromise(function () { scene.highDynamicRange = true; @@ -1380,54 +1372,11 @@ describe( }); }); - it("renders textured box with external KTX texture", function () { - return loadModel(texturedBoxKTXUrl, { - incrementallyLoadTextures: false, - }).then(function (m) { - verifyRender(m); - expect(Object.keys(m._rendererResources.textures).length).toBe(1); - primitives.remove(m); - }); - }); - - it("renders textured box with embedded binary KTX texture", function () { - return loadModel(texturedBoxKTXBinaryUrl, { - incrementallyLoadTextures: false, - }).then(function (m) { - verifyRender(m); - expect(Object.keys(m._rendererResources.textures).length).toBe(1); - primitives.remove(m); - }); - }); - - it("renders textured box with embedded base64 encoded KTX texture", function () { - return loadModel(texturedBoxKTXEmbeddedUrl, { - incrementallyLoadTextures: false, - }).then(function (m) { - verifyRender(m); - expect(Object.keys(m._rendererResources.textures).length).toBe(1); - primitives.remove(m); - }); - }); - - it("renders textured box with external CRN texture", function () { - if (!scene.context.s3tc) { - return; - } - return loadModel(texturedBoxCRNUrl, { - incrementallyLoadTextures: false, - }).then(function (m) { - verifyRender(m); - expect(Object.keys(m._rendererResources.textures).length).toBe(1); - primitives.remove(m); - }); - }); - - it("renders textured box with embedded binary CRN texture", function () { - if (!scene.context.s3tc) { + it("renders textured box with embedded KTX2 texture", function () { + if (!scene.context.supportsBasis) { return; } - return loadModel(texturedBoxCRNBinaryUrl, { + return loadModel(texturedBoxKTX2Url, { incrementallyLoadTextures: false, }).then(function (m) { verifyRender(m); @@ -1436,14 +1385,17 @@ describe( }); }); - it("renders textured box with embedded base64 encoded CRN texture", function () { - if (!scene.context.s3tc) { + it("renders textured box with embedded KTX2 texture with mipmap", function () { + if (!scene.context.supportsBasis) { return; } - return loadModel(texturedBoxCRNEmbeddedUrl, { + var gl = scene.context._gl; + spyOn(gl, "compressedTexImage2D").and.callThrough(); + return loadModel(texturedBoxKTX2MipmapUrl, { incrementallyLoadTextures: false, }).then(function (m) { verifyRender(m); + expect(gl.compressedTexImage2D.calls.count()).toEqual(9); expect(Object.keys(m._rendererResources.textures).length).toBe(1); primitives.remove(m); }); diff --git a/Specs/Scene/OctahedralProjectedCubeMapSpec.js b/Specs/Scene/OctahedralProjectedCubeMapSpec.js index 95a2c6fb4a95..98173ce414da 100644 --- a/Specs/Scene/OctahedralProjectedCubeMapSpec.js +++ b/Specs/Scene/OctahedralProjectedCubeMapSpec.js @@ -14,7 +14,7 @@ describe( var octahedralMap; var environmentMapUrl = - "./Data/EnvironmentMap/kiara_6_afternoon_2k_ibl.ktx"; + "./Data/EnvironmentMap/kiara_6_afternoon_2k_ibl.ktx2"; var fsOctahedralMap = "uniform sampler2D projectedMap;" + "uniform vec2 textureSize;" + @@ -30,10 +30,8 @@ describe( "uniform samplerCube cubeMap;" + "uniform vec3 direction;" + "void main() {" + - " vec4 rgbm = textureCube(cubeMap, direction);" + - " float m = rgbm.a * 16.0;" + - " vec3 r = rgbm.rgb * m;" + - " gl_FragColor = vec4(r * r, 1.0);" + + " vec4 rgba = textureCube(cubeMap, direction);" + + " gl_FragColor = vec4(rgba.rgb, 1.0);" + "}"; beforeAll(function () { @@ -113,7 +111,7 @@ describe( sampleOctahedralMap(octahedralMap, directionFlipY, lod, function ( octahedralMapColor ) { - return expect(cubeMapColor).toEqualEpsilon(octahedralMapColor, 5); + return expect(cubeMapColor).toEqualEpsilon(octahedralMapColor, 6); }); }); } diff --git a/Specs/Scene/ResourceCacheKeySpec.js b/Specs/Scene/ResourceCacheKeySpec.js index d32370dde8d2..19ff0a4009a9 100644 --- a/Specs/Scene/ResourceCacheKeySpec.js +++ b/Specs/Scene/ResourceCacheKeySpec.js @@ -197,6 +197,9 @@ describe("ResourceCacheKey", function () { { uri: "image.webp", }, + { + uri: "image.ktx2", + }, ], textures: [ { @@ -215,6 +218,14 @@ describe("ResourceCacheKey", function () { }, }, }, + { + source: 0, + extensions: { + KHR_texture_basisu: { + source: 3, + }, + }, + }, ], samplers: [ { @@ -622,7 +633,6 @@ describe("ResourceCacheKey", function () { imageId: 0, gltfResource: gltfResource, baseResource: baseResource, - supportedImageFormats: new SupportedImageFormats(), }); expect(cacheKey).toBe("image:https://example.com/resources/image.png"); @@ -634,7 +644,6 @@ describe("ResourceCacheKey", function () { imageId: 1, gltfResource: gltfResource, baseResource: baseResource, - supportedImageFormats: new SupportedImageFormats(), }); expect(cacheKey).toBe( @@ -649,7 +658,6 @@ describe("ResourceCacheKey", function () { imageId: 0, gltfResource: gltfResource, baseResource: baseResource, - supportedImageFormats: new SupportedImageFormats(), }); }).toThrowDeveloperError(); }); @@ -661,7 +669,6 @@ describe("ResourceCacheKey", function () { imageId: undefined, gltfResource: gltfResource, baseResource: baseResource, - supportedImageFormats: new SupportedImageFormats(), }); }).toThrowDeveloperError(); }); @@ -673,7 +680,6 @@ describe("ResourceCacheKey", function () { imageId: 0, gltfResource: undefined, baseResource: baseResource, - supportedImageFormats: new SupportedImageFormats(), }); }).toThrowDeveloperError(); }); @@ -685,19 +691,6 @@ describe("ResourceCacheKey", function () { imageId: 0, gltfResource: gltfResource, baseResource: undefined, - supportedImageFormats: new SupportedImageFormats(), - }); - }).toThrowDeveloperError(); - }); - - it("getImageCacheKey throws if supportedImageFormats is undefined", function () { - expect(function () { - ResourceCacheKey.getImageCacheKey({ - gltf: gltfWithTextures, - imageId: 0, - gltfResource: gltfResource, - baseResource: baseResource, - supportedImageFormats: undefined, }); }).toThrowDeveloperError(); }); @@ -772,6 +765,42 @@ describe("ResourceCacheKey", function () { ); }); + it("getTextureCacheKey works with KHR_texture_basisu extension", function () { + var cacheKey = ResourceCacheKey.getTextureCacheKey({ + gltf: gltfWithTextures, + textureInfo: { + index: 3, + texCoord: 0, + }, + gltfResource: gltfResource, + baseResource: baseResource, + supportedImageFormats: new SupportedImageFormats({ + basis: true, + }), + }); + + expect(cacheKey).toBe( + "texture:https://example.com/resources/image.ktx2-sampler-10497-10497-9729-9729" + ); + }); + + it("getTextureCacheKey ignores KHR_texture_basisu extension if Basis is not supported", function () { + var cacheKey = ResourceCacheKey.getTextureCacheKey({ + gltf: gltfWithTextures, + textureInfo: { + index: 3, + texCoord: 0, + }, + gltfResource: gltfResource, + baseResource: baseResource, + supportedImageFormats: new SupportedImageFormats(), + }); + + expect(cacheKey).toBe( + "texture:https://example.com/resources/image.png-sampler-10497-10497-9729-9729" + ); + }); + it("getTextureCacheKey throws if gltf is undefined", function () { expect(function () { ResourceCacheKey.getTextureCacheKey({ diff --git a/Specs/Scene/ResourceCacheSpec.js b/Specs/Scene/ResourceCacheSpec.js index 45d627a88124..4df03602319d 100644 --- a/Specs/Scene/ResourceCacheSpec.js +++ b/Specs/Scene/ResourceCacheSpec.js @@ -1150,14 +1150,12 @@ describe( imageId: 0, gltfResource: gltfResource, baseResource: gltfResource, - supportedImageFormats: new SupportedImageFormats(), }); var imageLoader = ResourceCache.loadImage({ gltf: gltfWithTextures, imageId: 0, gltfResource: gltfResource, baseResource: gltfResource, - supportedImageFormats: new SupportedImageFormats(), }); var cacheEntry = ResourceCache.cacheEntries[expectedCacheKey]; expect(imageLoader.cacheKey).toBe(expectedCacheKey); @@ -1170,7 +1168,6 @@ describe( imageId: 0, gltfResource: gltfResource, baseResource: gltfResource, - supportedImageFormats: new SupportedImageFormats(), }) ).toBe(imageLoader); @@ -1183,60 +1180,44 @@ describe( it("loadImage throws if gltf is undefined", function () { expect(function () { - ResourceCache.loadIndexBuffer({ + ResourceCache.loadImage({ gltf: undefined, imageId: 0, gltfResource: gltfResource, baseResource: gltfResource, - supportedImageFormats: new SupportedImageFormats(), }); }).toThrowDeveloperError(); }); it("loadImage throws if imageId is undefined", function () { expect(function () { - ResourceCache.loadIndexBuffer({ + ResourceCache.loadImage({ gltf: gltfWithTextures, imageId: undefined, gltfResource: gltfResource, baseResource: gltfResource, - supportedImageFormats: new SupportedImageFormats(), }); }).toThrowDeveloperError(); }); it("loadImage throws if gltfResource is undefined", function () { expect(function () { - ResourceCache.loadIndexBuffer({ + ResourceCache.loadImage({ gltf: gltfWithTextures, imageId: 0, gltfResource: undefined, baseResource: gltfResource, - supportedImageFormats: new SupportedImageFormats(), }); }).toThrowDeveloperError(); }); it("loadImage throws if baseResource is undefined", function () { expect(function () { - ResourceCache.loadIndexBuffer({ + ResourceCache.loadImage({ gltf: gltfWithTextures, imageId: 0, gltfResource: gltfResource, baseResource: undefined, - supportedImageFormats: new SupportedImageFormats(), - }); - }).toThrowDeveloperError(); - }); - - it("loadImage throws if supportedImageFormats is undefined", function () { - expect(function () { - ResourceCache.loadIndexBuffer({ - gltf: gltfWithTextures, - imageId: 0, - gltfResource: gltfResource, - baseResource: gltfResource, - supportedImageFormats: undefined, }); }).toThrowDeveloperError(); }); @@ -1286,7 +1267,7 @@ describe( it("loadTexture throws if gltf is undefined", function () { expect(function () { - ResourceCache.loadIndexBuffer({ + ResourceCache.loadTexture({ gltf: undefined, textureInfo: gltfWithTextures.materials[0].emissiveTexture, gltfResource: gltfResource, @@ -1298,7 +1279,7 @@ describe( it("loadTexture throws if textureInfo is undefined", function () { expect(function () { - ResourceCache.loadIndexBuffer({ + ResourceCache.loadTexture({ gltf: gltfWithTextures, textureInfo: undefined, gltfResource: gltfResource, @@ -1310,7 +1291,7 @@ describe( it("loadTexture throws if gltfResource is undefined", function () { expect(function () { - ResourceCache.loadIndexBuffer({ + ResourceCache.loadTexture({ gltf: gltfWithTextures, textureInfo: gltfWithTextures.materials[0].emissiveTexture, gltfResource: undefined, @@ -1322,7 +1303,7 @@ describe( it("loadTexture throws if baseResource is undefined", function () { expect(function () { - ResourceCache.loadIndexBuffer({ + ResourceCache.loadTexture({ gltf: gltfWithTextures, textureInfo: gltfWithTextures.materials[0].emissiveTexture, gltfResource: gltfResource, @@ -1334,7 +1315,7 @@ describe( it("loadTexture throws if supportedImageFormats is undefined", function () { expect(function () { - ResourceCache.loadIndexBuffer({ + ResourceCache.loadTexture({ gltf: gltfWithTextures, textureInfo: gltfWithTextures.materials[0].emissiveTexture, gltfResource: gltfResource, diff --git a/Specs/Scene/SupportedImageFormatsSpec.js b/Specs/Scene/SupportedImageFormatsSpec.js index a558e201a937..3f9c75469917 100644 --- a/Specs/Scene/SupportedImageFormatsSpec.js +++ b/Specs/Scene/SupportedImageFormatsSpec.js @@ -4,21 +4,15 @@ describe("Scene/SupportedImageFormats", function () { it("constructs with options", function () { var supportedImageFormats = new SupportedImageFormats({ webp: true, - s3tc: false, - pvrtc: true, - etc1: false, + basis: false, }); expect(supportedImageFormats.webp).toBe(true); - expect(supportedImageFormats.s3tc).toBe(false); - expect(supportedImageFormats.pvrtc).toBe(true); - expect(supportedImageFormats.etc1).toBe(false); + expect(supportedImageFormats.basis).toBe(false); }); it("constructs with default values", function () { var supportedImageFormats = new SupportedImageFormats({}); expect(supportedImageFormats.webp).toBe(false); - expect(supportedImageFormats.s3tc).toBe(false); - expect(supportedImageFormats.pvrtc).toBe(false); - expect(supportedImageFormats.etc1).toBe(false); + expect(supportedImageFormats.basis).toBe(false); }); }); diff --git a/gulpfile.cjs b/gulpfile.cjs index 3c265ef865b7..7377604408fc 100644 --- a/gulpfile.cjs +++ b/gulpfile.cjs @@ -74,7 +74,6 @@ const sourceFiles = [ "!Source/ThirdParty/Workers/**", "!Source/ThirdParty/google-earth-dbroot-parser.js", "!Source/ThirdParty/pako_inflate.js", - "!Source/ThirdParty/crunch.js", ]; const watchedFiles = [ @@ -126,7 +125,7 @@ function rollupWarning(message) { // Ignore eval warnings in third-party code we don't have control over if ( message.code === "EVAL" && - /(protobuf-minimal|crunch)\.js$/.test(message.loc.file) + /protobuf-minimal\.js$/.test(message.loc.file) ) { return; } @@ -737,7 +736,7 @@ function getMimeType(filename) { return { type: "text/plain", compress: true }; } else if (/\.(czml|topojson)$/i.test(filename)) { return { type: "application/json", compress: true }; - } else if (/\.(crn|tgz)$/i.test(filename)) { + } else if (/\.tgz$/i.test(filename)) { return { type: "application/octet-stream", compress: false }; } diff --git a/server.cjs b/server.cjs index 2ded8466d84f..1b0623c0b6ab 100644 --- a/server.cjs +++ b/server.cjs @@ -48,8 +48,7 @@ { "application/json": ["czml", "json", "geojson", "topojson"], "application/wasm": ["wasm"], - "image/crn": ["crn"], - "image/ktx": ["ktx"], + "image/ktx2": ["ktx2"], "model/gltf+json": ["gltf"], "model/gltf-binary": ["bgltf", "glb"], "application/octet-stream": [ diff --git a/web.config b/web.config index 9330dbc8efce..29f8221b1420 100644 --- a/web.config +++ b/web.config @@ -40,10 +40,8 @@ - - - - + +