babylonjs-serializers 8.9.0 → 8.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"babylon.glTF2Serializer.min.js","mappings":"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","sources":["webpack://SERIALIZERS/webpack/universalModuleDefinition","webpack://SERIALIZERS/webpack/runtime/create fake namespace object","webpack://SERIALIZERS/external umd {\"root\":\"BABYLON\",\"commonjs\":\"babylonjs\",\"commonjs2\":\"babylonjs\",\"amd\":\"babylonjs\"}","webpack://SERIALIZERS/webpack/bootstrap","webpack://SERIALIZERS/webpack/runtime/define property getters","webpack://SERIALIZERS/webpack/runtime/global","webpack://SERIALIZERS/webpack/runtime/hasOwnProperty shorthand","webpack://SERIALIZERS/webpack/runtime/make namespace object","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/glTFFileExporter.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/glTFData.ts","webpack://SERIALIZERS/../../../../node_modules/tslib/tslib.es6.mjs","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/glTFMaterialExporter.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/glTFUtilities.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/dataWriter.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/bufferManager.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/glTFAnimation.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/glTFMorphTargetsUtilities.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/glTFExporter.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/glTFSerializer.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_draco_mesh_compression.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_lights_punctual.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_anisotropy.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_clearcoat.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_dispersion.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_emissive_strength.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_ior.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_iridescence.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_sheen.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_specular.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_transmission.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_unlit.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_volume.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/EXT_materials_diffuse_roughness.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_texture_transform.ts","webpack://SERIALIZERS/../../../lts/serializers/src/legacy/legacy-glTF2Serializer.ts","webpack://SERIALIZERS/./src/glTF2.ts"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory(require(\"babylonjs\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine(\"babylonjs-serializers\", [\"babylonjs\"], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"babylonjs-serializers\"] = factory(require(\"babylonjs\"));\n\telse\n\t\troot[\"SERIALIZERS\"] = factory(root[\"BABYLON\"]);\n})((typeof self !== \"undefined\" ? self : typeof global !== \"undefined\" ? global : this), (__WEBPACK_EXTERNAL_MODULE__597__) => {\nreturn ","var getProto = Object.getPrototypeOf ? (obj) => (Object.getPrototypeOf(obj)) : (obj) => (obj.__proto__);\nvar leafPrototypes;\n// create a fake namespace object\n// mode & 1: value is a module id, require it\n// mode & 2: merge all properties of value into the ns\n// mode & 4: return value when already ns object\n// mode & 16: return value when it's Promise-like\n// mode & 8|1: behave like require\n__webpack_require__.t = function(value, mode) {\n\tif(mode & 1) value = this(value);\n\tif(mode & 8) return value;\n\tif(typeof value === 'object' && value) {\n\t\tif((mode & 4) && value.__esModule) return value;\n\t\tif((mode & 16) && typeof value.then === 'function') return value;\n\t}\n\tvar ns = Object.create(null);\n\t__webpack_require__.r(ns);\n\tvar def = {};\n\tleafPrototypes = leafPrototypes || [null, getProto({}), getProto([]), getProto(getProto)];\n\tfor(var current = mode & 2 && value; typeof current == 'object' && !~leafPrototypes.indexOf(current); current = getProto(current)) {\n\t\tObject.getOwnPropertyNames(current).forEach((key) => (def[key] = () => (value[key])));\n\t}\n\tdef['default'] = () => (value);\n\t__webpack_require__.d(ns, def);\n\treturn ns;\n};","module.exports = __WEBPACK_EXTERNAL_MODULE__597__;","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.g = (function() {\n\tif (typeof globalThis === 'object') return globalThis;\n\ttry {\n\t\treturn this || new Function('return this')();\n\t} catch (e) {\n\t\tif (typeof window === 'object') return window;\n\t}\n})();","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","/** @internal */\r\n// eslint-disable-next-line no-var, @typescript-eslint/naming-convention\r\nexport var __IGLTFExporterExtension = 0; // I am here to allow dts to be created\r\n\r\n/**\r\n * Interface for extending the exporter\r\n * @internal\r\n */\r\nexport interface IGLTFExporterExtension {\r\n /**\r\n * The name of this extension\r\n */\r\n readonly name: string;\r\n /**\r\n * Defines whether this extension is enabled\r\n */\r\n enabled: boolean;\r\n\r\n /**\r\n * Defines whether this extension is required\r\n */\r\n required: boolean;\r\n}\r\n","import { GetMimeType } from \"core/Misc/fileTools\";\r\nimport { Tools } from \"core/Misc/tools\";\r\n\r\n/**\r\n * Class for holding and downloading glTF file data\r\n */\r\nexport class GLTFData {\r\n /**\r\n * Object which contains the file name as the key and its data as the value\r\n */\r\n public readonly files: { [fileName: string]: string | Blob } = {};\r\n\r\n /**\r\n * @deprecated Use files instead\r\n */\r\n public get glTFFiles() {\r\n return this.files;\r\n }\r\n\r\n /**\r\n * Downloads the glTF data as files based on their names and data\r\n */\r\n public downloadFiles(): void {\r\n for (const key in this.files) {\r\n const value = this.files[key];\r\n const blob = new Blob([value], { type: GetMimeType(key) });\r\n Tools.Download(blob, key);\r\n }\r\n }\r\n}\r\n","/******************************************************************************\nCopyright (c) Microsoft Corporation.\n\nPermission to use, copy, modify, and/or distribute this software for any\npurpose with or without fee is hereby granted.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\nPERFORMANCE OF THIS SOFTWARE.\n***************************************************************************** */\n/* global Reflect, Promise, SuppressedError, Symbol, Iterator */\n\nvar extendStatics = function(d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n};\n\nexport function __extends(d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n}\n\nexport var __assign = function() {\n __assign = Object.assign || function __assign(t) {\n for (var s, i = 1, n = arguments.length; i < n; i++) {\n s = arguments[i];\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\n }\n return t;\n }\n return __assign.apply(this, arguments);\n}\n\nexport function __rest(s, e) {\n var t = {};\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\n t[p] = s[p];\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\n t[p[i]] = s[p[i]];\n }\n return t;\n}\n\nexport function __decorate(decorators, target, key, desc) {\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\n return c > 3 && r && Object.defineProperty(target, key, r), r;\n}\n\nexport function __param(paramIndex, decorator) {\n return function (target, key) { decorator(target, key, paramIndex); }\n}\n\nexport function __esDecorate(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {\n function accept(f) { if (f !== void 0 && typeof f !== \"function\") throw new TypeError(\"Function expected\"); return f; }\n var kind = contextIn.kind, key = kind === \"getter\" ? \"get\" : kind === \"setter\" ? \"set\" : \"value\";\n var target = !descriptorIn && ctor ? contextIn[\"static\"] ? ctor : ctor.prototype : null;\n var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});\n var _, done = false;\n for (var i = decorators.length - 1; i >= 0; i--) {\n var context = {};\n for (var p in contextIn) context[p] = p === \"access\" ? {} : contextIn[p];\n for (var p in contextIn.access) context.access[p] = contextIn.access[p];\n context.addInitializer = function (f) { if (done) throw new TypeError(\"Cannot add initializers after decoration has completed\"); extraInitializers.push(accept(f || null)); };\n var result = (0, decorators[i])(kind === \"accessor\" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);\n if (kind === \"accessor\") {\n if (result === void 0) continue;\n if (result === null || typeof result !== \"object\") throw new TypeError(\"Object expected\");\n if (_ = accept(result.get)) descriptor.get = _;\n if (_ = accept(result.set)) descriptor.set = _;\n if (_ = accept(result.init)) initializers.unshift(_);\n }\n else if (_ = accept(result)) {\n if (kind === \"field\") initializers.unshift(_);\n else descriptor[key] = _;\n }\n }\n if (target) Object.defineProperty(target, contextIn.name, descriptor);\n done = true;\n};\n\nexport function __runInitializers(thisArg, initializers, value) {\n var useValue = arguments.length > 2;\n for (var i = 0; i < initializers.length; i++) {\n value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);\n }\n return useValue ? value : void 0;\n};\n\nexport function __propKey(x) {\n return typeof x === \"symbol\" ? x : \"\".concat(x);\n};\n\nexport function __setFunctionName(f, name, prefix) {\n if (typeof name === \"symbol\") name = name.description ? \"[\".concat(name.description, \"]\") : \"\";\n return Object.defineProperty(f, \"name\", { configurable: true, value: prefix ? \"\".concat(prefix, \" \", name) : name });\n};\n\nexport function __metadata(metadataKey, metadataValue) {\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\n}\n\nexport function __awaiter(thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n}\n\nexport function __generator(thisArg, body) {\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === \"function\" ? Iterator : Object).prototype);\n return g.next = verb(0), g[\"throw\"] = verb(1), g[\"return\"] = verb(2), typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\n function verb(n) { return function (v) { return step([n, v]); }; }\n function step(op) {\n if (f) throw new TypeError(\"Generator is already executing.\");\n while (g && (g = 0, op[0] && (_ = 0)), _) try {\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\n if (y = 0, t) op = [op[0] & 2, t.value];\n switch (op[0]) {\n case 0: case 1: t = op; break;\n case 4: _.label++; return { value: op[1], done: false };\n case 5: _.label++; y = op[1]; op = [0]; continue;\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\n default:\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\n if (t[2]) _.ops.pop();\n _.trys.pop(); continue;\n }\n op = body.call(thisArg, _);\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\n }\n}\n\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() { return m[k]; } };\n }\n Object.defineProperty(o, k2, desc);\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n});\n\nexport function __exportStar(m, o) {\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\n}\n\nexport function __values(o) {\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\n if (m) return m.call(o);\n if (o && typeof o.length === \"number\") return {\n next: function () {\n if (o && i >= o.length) o = void 0;\n return { value: o && o[i++], done: !o };\n }\n };\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\n}\n\nexport function __read(o, n) {\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\n if (!m) return o;\n var i = m.call(o), r, ar = [], e;\n try {\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\n }\n catch (error) { e = { error: error }; }\n finally {\n try {\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\n }\n finally { if (e) throw e.error; }\n }\n return ar;\n}\n\n/** @deprecated */\nexport function __spread() {\n for (var ar = [], i = 0; i < arguments.length; i++)\n ar = ar.concat(__read(arguments[i]));\n return ar;\n}\n\n/** @deprecated */\nexport function __spreadArrays() {\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\n r[k] = a[j];\n return r;\n}\n\nexport function __spreadArray(to, from, pack) {\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\n if (ar || !(i in from)) {\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\n ar[i] = from[i];\n }\n }\n return to.concat(ar || Array.prototype.slice.call(from));\n}\n\nexport function __await(v) {\n return this instanceof __await ? (this.v = v, this) : new __await(v);\n}\n\nexport function __asyncGenerator(thisArg, _arguments, generator) {\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\n return i = Object.create((typeof AsyncIterator === \"function\" ? AsyncIterator : Object).prototype), verb(\"next\"), verb(\"throw\"), verb(\"return\", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i;\n function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; }\n function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } }\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\n function fulfill(value) { resume(\"next\", value); }\n function reject(value) { resume(\"throw\", value); }\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\n}\n\nexport function __asyncDelegator(o) {\n var i, p;\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: false } : f ? f(v) : v; } : f; }\n}\n\nexport function __asyncValues(o) {\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n var m = o[Symbol.asyncIterator], i;\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\n}\n\nexport function __makeTemplateObject(cooked, raw) {\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\n return cooked;\n};\n\nvar __setModuleDefault = Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n};\n\nvar ownKeys = function(o) {\n ownKeys = Object.getOwnPropertyNames || function (o) {\n var ar = [];\n for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;\n return ar;\n };\n return ownKeys(o);\n};\n\nexport function __importStar(mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== \"default\") __createBinding(result, mod, k[i]);\n __setModuleDefault(result, mod);\n return result;\n}\n\nexport function __importDefault(mod) {\n return (mod && mod.__esModule) ? mod : { default: mod };\n}\n\nexport function __classPrivateFieldGet(receiver, state, kind, f) {\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\n}\n\nexport function __classPrivateFieldSet(receiver, state, value, kind, f) {\n if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\n return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\n}\n\nexport function __classPrivateFieldIn(state, receiver) {\n if (receiver === null || (typeof receiver !== \"object\" && typeof receiver !== \"function\")) throw new TypeError(\"Cannot use 'in' operator on non-object\");\n return typeof state === \"function\" ? receiver === state : state.has(receiver);\n}\n\nexport function __addDisposableResource(env, value, async) {\n if (value !== null && value !== void 0) {\n if (typeof value !== \"object\" && typeof value !== \"function\") throw new TypeError(\"Object expected.\");\n var dispose, inner;\n if (async) {\n if (!Symbol.asyncDispose) throw new TypeError(\"Symbol.asyncDispose is not defined.\");\n dispose = value[Symbol.asyncDispose];\n }\n if (dispose === void 0) {\n if (!Symbol.dispose) throw new TypeError(\"Symbol.dispose is not defined.\");\n dispose = value[Symbol.dispose];\n if (async) inner = dispose;\n }\n if (typeof dispose !== \"function\") throw new TypeError(\"Object not disposable.\");\n if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };\n env.stack.push({ value: value, dispose: dispose, async: async });\n }\n else if (async) {\n env.stack.push({ async: true });\n }\n return value;\n}\n\nvar _SuppressedError = typeof SuppressedError === \"function\" ? SuppressedError : function (error, suppressed, message) {\n var e = new Error(message);\n return e.name = \"SuppressedError\", e.error = error, e.suppressed = suppressed, e;\n};\n\nexport function __disposeResources(env) {\n function fail(e) {\n env.error = env.hasError ? new _SuppressedError(e, env.error, \"An error was suppressed during disposal.\") : e;\n env.hasError = true;\n }\n var r, s = 0;\n function next() {\n while (r = env.stack.pop()) {\n try {\n if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);\n if (r.dispose) {\n var result = r.dispose.call(r.value);\n if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });\n }\n else s |= 1;\n }\n catch (e) {\n fail(e);\n }\n }\n if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();\n if (env.hasError) throw env.error;\n }\n return next();\n}\n\nexport function __rewriteRelativeImportExtension(path, preserveJsx) {\n if (typeof path === \"string\" && /^\\.\\.?\\//.test(path)) {\n return path.replace(/\\.(tsx)$|((?:\\.d)?)((?:\\.[^./]+?)?)\\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {\n return tsx ? preserveJsx ? \".jsx\" : \".js\" : d && (!ext || !cm) ? m : (d + ext + \".\" + cm.toLowerCase() + \"js\");\n });\n }\n return path;\n}\n\nexport default {\n __extends,\n __assign,\n __rest,\n __decorate,\n __param,\n __esDecorate,\n __runInitializers,\n __propKey,\n __setFunctionName,\n __metadata,\n __awaiter,\n __generator,\n __createBinding,\n __exportStar,\n __values,\n __read,\n __spread,\n __spreadArrays,\n __spreadArray,\n __await,\n __asyncGenerator,\n __asyncDelegator,\n __asyncValues,\n __makeTemplateObject,\n __importStar,\n __importDefault,\n __classPrivateFieldGet,\n __classPrivateFieldSet,\n __classPrivateFieldIn,\n __addDisposableResource,\n __disposeResources,\n __rewriteRelativeImportExtension,\n};\n","/* eslint-disable @typescript-eslint/prefer-promise-reject-errors */\r\n/* eslint-disable github/no-then */\r\n/* eslint-disable babylonjs/available */\r\n\r\nimport type { ITextureInfo, IMaterial, IMaterialPbrMetallicRoughness, IMaterialOcclusionTextureInfo, ISampler, IImage } from \"babylonjs-gltf2interface\";\r\nimport { ImageMimeType, MaterialAlphaMode, TextureMagFilter, TextureMinFilter, TextureWrapMode } from \"babylonjs-gltf2interface\";\r\n\r\nimport type { Nullable } from \"core/types\";\r\nimport { Color3 } from \"core/Maths/math.color\";\r\nimport { Scalar } from \"core/Maths/math.scalar\";\r\nimport { Tools } from \"core/Misc/tools\";\r\nimport { GetTextureDataAsync, TextureTools } from \"core/Misc/textureTools\";\r\nimport type { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\nimport { Texture } from \"core/Materials/Textures/texture\";\r\nimport { RawTexture } from \"core/Materials/Textures/rawTexture\";\r\n\r\nimport type { Scene } from \"core/scene\";\r\n\r\nimport type { GLTFExporter } from \"./glTFExporter\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { DumpTools } from \"core/Misc/dumpTools\";\r\n\r\nimport type { Material } from \"core/Materials/material\";\r\nimport type { StandardMaterial } from \"core/Materials/standardMaterial\";\r\nimport type { PBRBaseMaterial } from \"core/Materials/PBR/pbrBaseMaterial\";\r\nimport { SpecularPowerToRoughness } from \"core/Helpers/materialConversionHelper\";\r\n\r\nconst Epsilon = 1e-6;\r\nconst DielectricSpecular = new Color3(0.04, 0.04, 0.04);\r\nconst MaxSpecularPower = 1024;\r\nconst White = Color3.White();\r\nconst Black = Color3.Black();\r\n\r\n/**\r\n * Interface for storing specular glossiness factors\r\n * @internal\r\n */\r\ninterface IPBRSpecularGlossiness {\r\n /**\r\n * Represents the linear diffuse factors of the material\r\n */\r\n diffuseColor: Color3;\r\n specularColor: Color3;\r\n glossiness: number;\r\n}\r\n\r\ninterface IPBRMetallicRoughness {\r\n baseColor: Color3;\r\n metallic: Nullable<number>;\r\n roughness: Nullable<number>;\r\n metallicRoughnessTextureData?: Nullable<ArrayBuffer>;\r\n baseColorTextureData?: Nullable<ArrayBuffer>;\r\n}\r\n\r\nfunction GetFileExtensionFromMimeType(mimeType: ImageMimeType): string {\r\n switch (mimeType) {\r\n case ImageMimeType.JPEG:\r\n return \".jpg\";\r\n case ImageMimeType.PNG:\r\n return \".png\";\r\n case ImageMimeType.WEBP:\r\n return \".webp\";\r\n case ImageMimeType.AVIF:\r\n return \".avif\";\r\n }\r\n}\r\n\r\nfunction IsCompressedTextureFormat(format: number): boolean {\r\n switch (format) {\r\n case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_BPTC_UNORM:\r\n case Constants.TEXTUREFORMAT_COMPRESSED_SRGB_ALPHA_BPTC_UNORM:\r\n case Constants.TEXTUREFORMAT_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT:\r\n case Constants.TEXTUREFORMAT_COMPRESSED_RGB_BPTC_SIGNED_FLOAT:\r\n case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_S3TC_DXT5:\r\n case Constants.TEXTUREFORMAT_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:\r\n case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_S3TC_DXT3:\r\n case Constants.TEXTUREFORMAT_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:\r\n case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_S3TC_DXT1:\r\n case Constants.TEXTUREFORMAT_COMPRESSED_RGB_S3TC_DXT1:\r\n case Constants.TEXTUREFORMAT_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:\r\n case Constants.TEXTUREFORMAT_COMPRESSED_SRGB_S3TC_DXT1_EXT:\r\n case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_4x4:\r\n case Constants.TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:\r\n case Constants.TEXTUREFORMAT_COMPRESSED_RGB_ETC1_WEBGL:\r\n case Constants.TEXTUREFORMAT_COMPRESSED_RGB8_ETC2:\r\n case Constants.TEXTUREFORMAT_COMPRESSED_SRGB8_ETC2:\r\n case Constants.TEXTUREFORMAT_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:\r\n case Constants.TEXTUREFORMAT_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:\r\n case Constants.TEXTUREFORMAT_COMPRESSED_RGBA8_ETC2_EAC:\r\n case Constants.TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:\r\n return true;\r\n default:\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Computes the metallic factor from specular glossiness values.\r\n * @param diffuse diffused value\r\n * @param specular specular value\r\n * @param oneMinusSpecularStrength one minus the specular strength\r\n * @returns metallic value\r\n * @internal\r\n */\r\nexport function _SolveMetallic(diffuse: number, specular: number, oneMinusSpecularStrength: number): number {\r\n if (specular < DielectricSpecular.r) {\r\n DielectricSpecular;\r\n return 0;\r\n }\r\n\r\n const a = DielectricSpecular.r;\r\n const b = (diffuse * oneMinusSpecularStrength) / (1.0 - DielectricSpecular.r) + specular - 2.0 * DielectricSpecular.r;\r\n const c = DielectricSpecular.r - specular;\r\n const d = b * b - 4.0 * a * c;\r\n return Scalar.Clamp((-b + Math.sqrt(d)) / (2.0 * a), 0, 1);\r\n}\r\n\r\n/**\r\n * Computes the metallic/roughness factors from a Standard Material.\r\n * @internal\r\n */\r\nexport function _ConvertToGLTFPBRMetallicRoughness(babylonStandardMaterial: StandardMaterial): IMaterialPbrMetallicRoughness {\r\n const diffuse = babylonStandardMaterial.diffuseColor.toLinearSpace(babylonStandardMaterial.getScene().getEngine().useExactSrgbConversions).scale(0.5);\r\n const opacity = babylonStandardMaterial.alpha;\r\n const specularPower = Scalar.Clamp(babylonStandardMaterial.specularPower, 0, MaxSpecularPower);\r\n\r\n const roughness = SpecularPowerToRoughness(specularPower);\r\n\r\n const glTFPbrMetallicRoughness: IMaterialPbrMetallicRoughness = {\r\n baseColorFactor: [diffuse.r, diffuse.g, diffuse.b, opacity],\r\n metallicFactor: 0,\r\n roughnessFactor: roughness,\r\n };\r\n\r\n return glTFPbrMetallicRoughness;\r\n}\r\n\r\n/**\r\n * Sets the glTF alpha mode to a glTF material from the Babylon Material\r\n * @param glTFMaterial glTF material\r\n * @param babylonMaterial Babylon material\r\n */\r\nfunction SetAlphaMode(glTFMaterial: IMaterial, babylonMaterial: Material & { alphaCutOff?: number }): void {\r\n if (babylonMaterial.needAlphaBlending()) {\r\n glTFMaterial.alphaMode = MaterialAlphaMode.BLEND;\r\n } else if (babylonMaterial.needAlphaTesting()) {\r\n glTFMaterial.alphaMode = MaterialAlphaMode.MASK;\r\n glTFMaterial.alphaCutoff = babylonMaterial.alphaCutOff;\r\n }\r\n}\r\n\r\nfunction CreateWhiteTexture(width: number, height: number, scene: Scene): Texture {\r\n const data = new Uint8Array(width * height * 4);\r\n\r\n for (let i = 0; i < data.length; i = i + 4) {\r\n data[i] = data[i + 1] = data[i + 2] = data[i + 3] = 0xff;\r\n }\r\n\r\n const rawTexture = RawTexture.CreateRGBATexture(data, width, height, scene);\r\n\r\n return rawTexture;\r\n}\r\n\r\nfunction ConvertPixelArrayToFloat32(pixels: ArrayBufferView): Float32Array {\r\n if (pixels instanceof Uint8Array) {\r\n const length = pixels.length;\r\n const buffer = new Float32Array(pixels.length);\r\n for (let i = 0; i < length; ++i) {\r\n buffer[i] = pixels[i] / 255;\r\n }\r\n return buffer;\r\n } else if (pixels instanceof Float32Array) {\r\n return pixels;\r\n } else {\r\n throw new Error(\"Unsupported pixel format!\");\r\n }\r\n}\r\n\r\n/**\r\n * Utility methods for working with glTF material conversion properties.\r\n * @internal\r\n */\r\nexport class GLTFMaterialExporter {\r\n // Mapping to store textures\r\n private _textureMap = new Map<BaseTexture, ITextureInfo>();\r\n\r\n // Mapping of internal textures to images to avoid exporting duplicate images\r\n private _internalTextureToImage: { [uniqueId: number]: { [mimeType: string]: Promise<number> } } = {};\r\n\r\n constructor(private readonly _exporter: GLTFExporter) {}\r\n\r\n public getTextureInfo(babylonTexture: Nullable<BaseTexture>): Nullable<ITextureInfo> {\r\n return babylonTexture ? (this._textureMap.get(babylonTexture) ?? null) : null;\r\n }\r\n\r\n public async exportStandardMaterialAsync(babylonStandardMaterial: StandardMaterial, mimeType: ImageMimeType, hasUVs: boolean): Promise<number> {\r\n const pbrMetallicRoughness = _ConvertToGLTFPBRMetallicRoughness(babylonStandardMaterial);\r\n\r\n const material: IMaterial = { name: babylonStandardMaterial.name };\r\n if (babylonStandardMaterial.backFaceCulling != null && !babylonStandardMaterial.backFaceCulling) {\r\n if (!babylonStandardMaterial.twoSidedLighting) {\r\n Tools.Warn(babylonStandardMaterial.name + \": Back-face culling disabled and two-sided lighting disabled is not supported in glTF.\");\r\n }\r\n material.doubleSided = true;\r\n }\r\n\r\n if (hasUVs) {\r\n const promises: Promise<void>[] = [];\r\n\r\n const diffuseTexture = babylonStandardMaterial.diffuseTexture;\r\n if (diffuseTexture) {\r\n promises.push(\r\n this.exportTextureAsync(diffuseTexture, mimeType).then((textureInfo) => {\r\n if (textureInfo) {\r\n pbrMetallicRoughness.baseColorTexture = textureInfo;\r\n }\r\n })\r\n );\r\n }\r\n\r\n const bumpTexture = babylonStandardMaterial.bumpTexture;\r\n if (bumpTexture) {\r\n promises.push(\r\n this.exportTextureAsync(bumpTexture, mimeType).then((textureInfo) => {\r\n if (textureInfo) {\r\n material.normalTexture = textureInfo;\r\n if (bumpTexture.level !== 1) {\r\n material.normalTexture.scale = bumpTexture.level;\r\n }\r\n }\r\n })\r\n );\r\n }\r\n\r\n const emissiveTexture = babylonStandardMaterial.emissiveTexture;\r\n if (emissiveTexture) {\r\n material.emissiveFactor = [1.0, 1.0, 1.0];\r\n\r\n promises.push(\r\n this.exportTextureAsync(emissiveTexture, mimeType).then((textureInfo) => {\r\n if (textureInfo) {\r\n material.emissiveTexture = textureInfo;\r\n }\r\n })\r\n );\r\n }\r\n\r\n const ambientTexture = babylonStandardMaterial.ambientTexture;\r\n if (ambientTexture) {\r\n promises.push(\r\n this.exportTextureAsync(ambientTexture, mimeType).then((textureInfo) => {\r\n if (textureInfo) {\r\n const occlusionTexture: IMaterialOcclusionTextureInfo = {\r\n index: textureInfo.index,\r\n };\r\n material.occlusionTexture = occlusionTexture;\r\n }\r\n })\r\n );\r\n }\r\n\r\n if (promises.length > 0) {\r\n this._exporter._materialNeedsUVsSet.add(babylonStandardMaterial);\r\n await Promise.all(promises);\r\n }\r\n }\r\n\r\n if (babylonStandardMaterial.alpha < 1.0 || babylonStandardMaterial.opacityTexture) {\r\n if (babylonStandardMaterial.alphaMode === Constants.ALPHA_COMBINE) {\r\n material.alphaMode = MaterialAlphaMode.BLEND;\r\n } else {\r\n Tools.Warn(babylonStandardMaterial.name + \": glTF 2.0 does not support alpha mode: \" + babylonStandardMaterial.alphaMode.toString());\r\n }\r\n }\r\n\r\n if (babylonStandardMaterial.emissiveColor && !babylonStandardMaterial.emissiveColor.equalsWithEpsilon(Black, Epsilon)) {\r\n material.emissiveFactor = babylonStandardMaterial.emissiveColor.asArray();\r\n }\r\n\r\n material.pbrMetallicRoughness = pbrMetallicRoughness;\r\n SetAlphaMode(material, babylonStandardMaterial);\r\n\r\n await this._finishMaterialAsync(material, babylonStandardMaterial, mimeType);\r\n\r\n const materials = this._exporter._materials;\r\n materials.push(material);\r\n return materials.length - 1;\r\n }\r\n\r\n private async _finishMaterialAsync(glTFMaterial: IMaterial, babylonMaterial: Material, mimeType: ImageMimeType): Promise<void> {\r\n const textures = this._exporter._extensionsPostExportMaterialAdditionalTextures(\"exportMaterial\", glTFMaterial, babylonMaterial);\r\n\r\n const promises: Array<Promise<Nullable<ITextureInfo>>> = [];\r\n\r\n for (const texture of textures) {\r\n promises.push(this.exportTextureAsync(texture, mimeType));\r\n }\r\n\r\n await Promise.all(promises);\r\n\r\n await this._exporter._extensionsPostExportMaterialAsync(\"exportMaterial\", glTFMaterial, babylonMaterial);\r\n }\r\n\r\n private async _getImageDataAsync(buffer: Uint8Array | Float32Array, width: number, height: number, mimeType: ImageMimeType): Promise<ArrayBuffer> {\r\n const textureType = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n\r\n const hostingScene = this._exporter._babylonScene;\r\n const engine = hostingScene.getEngine();\r\n\r\n // Create a temporary texture with the texture buffer data\r\n const tempTexture = engine.createRawTexture(buffer, width, height, Constants.TEXTUREFORMAT_RGBA, false, true, Texture.NEAREST_SAMPLINGMODE, null, textureType);\r\n\r\n engine.isWebGPU ? await import(\"core/ShadersWGSL/pass.fragment\") : await import(\"core/Shaders/pass.fragment\");\r\n await TextureTools.ApplyPostProcess(\"pass\", tempTexture, hostingScene, textureType, Constants.TEXTURE_NEAREST_SAMPLINGMODE, Constants.TEXTUREFORMAT_RGBA);\r\n\r\n const data = await engine._readTexturePixels(tempTexture, width, height);\r\n\r\n return (await DumpTools.DumpDataAsync(width, height, data, mimeType, undefined, true, true)) as ArrayBuffer;\r\n }\r\n\r\n /**\r\n * Resizes the two source textures to the same dimensions. If a texture is null, a default white texture is generated. If both textures are null, returns null\r\n * @param texture1 first texture to resize\r\n * @param texture2 second texture to resize\r\n * @param scene babylonjs scene\r\n * @returns resized textures or null\r\n */\r\n private _resizeTexturesToSameDimensions(texture1: Nullable<BaseTexture>, texture2: Nullable<BaseTexture>, scene: Scene): { texture1: BaseTexture; texture2: BaseTexture } {\r\n const texture1Size = texture1 ? texture1.getSize() : { width: 0, height: 0 };\r\n const texture2Size = texture2 ? texture2.getSize() : { width: 0, height: 0 };\r\n let resizedTexture1: BaseTexture;\r\n let resizedTexture2: BaseTexture;\r\n\r\n if (texture1Size.width < texture2Size.width) {\r\n if (texture1 && texture1 instanceof Texture) {\r\n resizedTexture1 = TextureTools.CreateResizedCopy(texture1, texture2Size.width, texture2Size.height, true);\r\n } else {\r\n resizedTexture1 = CreateWhiteTexture(texture2Size.width, texture2Size.height, scene);\r\n }\r\n resizedTexture2 = texture2!;\r\n } else if (texture1Size.width > texture2Size.width) {\r\n if (texture2 && texture2 instanceof Texture) {\r\n resizedTexture2 = TextureTools.CreateResizedCopy(texture2, texture1Size.width, texture1Size.height, true);\r\n } else {\r\n resizedTexture2 = CreateWhiteTexture(texture1Size.width, texture1Size.height, scene);\r\n }\r\n resizedTexture1 = texture1!;\r\n } else {\r\n resizedTexture1 = texture1!;\r\n resizedTexture2 = texture2!;\r\n }\r\n\r\n return {\r\n texture1: resizedTexture1!,\r\n texture2: resizedTexture2!,\r\n };\r\n }\r\n\r\n /**\r\n * Convert Specular Glossiness Textures to Metallic Roughness\r\n * See link below for info on the material conversions from PBR Metallic/Roughness and Specular/Glossiness\r\n * @see https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Archived/KHR_materials_pbrSpecularGlossiness/examples/convert-between-workflows-bjs/js/babylon.pbrUtilities.js\r\n * @param diffuseTexture texture used to store diffuse information\r\n * @param specularGlossinessTexture texture used to store specular and glossiness information\r\n * @param factors specular glossiness material factors\r\n * @param mimeType the mime type to use for the texture\r\n * @returns pbr metallic roughness interface or null\r\n */\r\n private async _convertSpecularGlossinessTexturesToMetallicRoughnessAsync(\r\n diffuseTexture: Nullable<BaseTexture>,\r\n specularGlossinessTexture: Nullable<BaseTexture>,\r\n factors: IPBRSpecularGlossiness,\r\n mimeType: ImageMimeType\r\n ): Promise<IPBRMetallicRoughness> {\r\n const promises = new Array<Promise<void>>();\r\n if (!(diffuseTexture || specularGlossinessTexture)) {\r\n return await Promise.reject(\"diffuse and specular glossiness textures are not defined!\");\r\n }\r\n\r\n const scene: Nullable<Scene> = diffuseTexture ? diffuseTexture.getScene() : specularGlossinessTexture ? specularGlossinessTexture.getScene() : null;\r\n if (scene) {\r\n const resizedTextures = this._resizeTexturesToSameDimensions(diffuseTexture, specularGlossinessTexture, scene);\r\n\r\n const diffuseSize = resizedTextures.texture1?.getSize();\r\n\r\n let diffuseBuffer: Float32Array;\r\n let specularGlossinessBuffer: Float32Array;\r\n\r\n const width = diffuseSize.width;\r\n const height = diffuseSize.height;\r\n\r\n const diffusePixels = await resizedTextures.texture1.readPixels();\r\n const specularPixels = await resizedTextures.texture2.readPixels();\r\n\r\n if (diffusePixels) {\r\n diffuseBuffer = ConvertPixelArrayToFloat32(diffusePixels);\r\n } else {\r\n return await Promise.reject(\"Failed to retrieve pixels from diffuse texture!\");\r\n }\r\n if (specularPixels) {\r\n specularGlossinessBuffer = ConvertPixelArrayToFloat32(specularPixels);\r\n } else {\r\n return await Promise.reject(\"Failed to retrieve pixels from specular glossiness texture!\");\r\n }\r\n\r\n const byteLength = specularGlossinessBuffer.byteLength;\r\n\r\n const metallicRoughnessBuffer = new Uint8Array(byteLength);\r\n const baseColorBuffer = new Uint8Array(byteLength);\r\n\r\n const strideSize = 4;\r\n const maxBaseColor = Black;\r\n let maxMetallic = 0;\r\n let maxRoughness = 0;\r\n\r\n for (let h = 0; h < height; ++h) {\r\n for (let w = 0; w < width; ++w) {\r\n const offset = (width * h + w) * strideSize;\r\n\r\n const diffuseColor = new Color3(diffuseBuffer[offset], diffuseBuffer[offset + 1], diffuseBuffer[offset + 2])\r\n .toLinearSpace(scene.getEngine().useExactSrgbConversions)\r\n .multiply(factors.diffuseColor);\r\n const specularColor = new Color3(specularGlossinessBuffer[offset], specularGlossinessBuffer[offset + 1], specularGlossinessBuffer[offset + 2])\r\n .toLinearSpace(scene.getEngine().useExactSrgbConversions)\r\n .multiply(factors.specularColor);\r\n const glossiness = specularGlossinessBuffer[offset + 3] * factors.glossiness;\r\n\r\n const specularGlossiness: IPBRSpecularGlossiness = {\r\n diffuseColor: diffuseColor,\r\n specularColor: specularColor,\r\n glossiness: glossiness,\r\n };\r\n\r\n const metallicRoughness = this._convertSpecularGlossinessToMetallicRoughness(specularGlossiness);\r\n maxBaseColor.r = Math.max(maxBaseColor.r, metallicRoughness.baseColor.r);\r\n maxBaseColor.g = Math.max(maxBaseColor.g, metallicRoughness.baseColor.g);\r\n maxBaseColor.b = Math.max(maxBaseColor.b, metallicRoughness.baseColor.b);\r\n maxMetallic = Math.max(maxMetallic, metallicRoughness.metallic!);\r\n maxRoughness = Math.max(maxRoughness, metallicRoughness.roughness!);\r\n\r\n baseColorBuffer[offset] = metallicRoughness.baseColor.r * 255;\r\n baseColorBuffer[offset + 1] = metallicRoughness.baseColor.g * 255;\r\n baseColorBuffer[offset + 2] = metallicRoughness.baseColor.b * 255;\r\n baseColorBuffer[offset + 3] = resizedTextures.texture1.hasAlpha ? diffuseBuffer[offset + 3] * 255 : 255;\r\n\r\n metallicRoughnessBuffer[offset] = 0;\r\n metallicRoughnessBuffer[offset + 1] = metallicRoughness.roughness! * 255;\r\n metallicRoughnessBuffer[offset + 2] = metallicRoughness.metallic! * 255;\r\n metallicRoughnessBuffer[offset + 3] = 255;\r\n }\r\n }\r\n\r\n // Retrieves the metallic roughness factors from the maximum texture values.\r\n const metallicRoughnessFactors: IPBRMetallicRoughness = {\r\n baseColor: maxBaseColor,\r\n metallic: maxMetallic,\r\n roughness: maxRoughness,\r\n };\r\n\r\n let writeOutMetallicRoughnessTexture = false;\r\n let writeOutBaseColorTexture = false;\r\n\r\n for (let h = 0; h < height; ++h) {\r\n for (let w = 0; w < width; ++w) {\r\n const destinationOffset = (width * h + w) * strideSize;\r\n\r\n baseColorBuffer[destinationOffset] /= metallicRoughnessFactors.baseColor.r > Epsilon ? metallicRoughnessFactors.baseColor.r : 1;\r\n baseColorBuffer[destinationOffset + 1] /= metallicRoughnessFactors.baseColor.g > Epsilon ? metallicRoughnessFactors.baseColor.g : 1;\r\n baseColorBuffer[destinationOffset + 2] /= metallicRoughnessFactors.baseColor.b > Epsilon ? metallicRoughnessFactors.baseColor.b : 1;\r\n\r\n const linearBaseColorPixel = Color3.FromInts(\r\n baseColorBuffer[destinationOffset],\r\n baseColorBuffer[destinationOffset + 1],\r\n baseColorBuffer[destinationOffset + 2]\r\n );\r\n const sRGBBaseColorPixel = linearBaseColorPixel.toGammaSpace(scene.getEngine().useExactSrgbConversions);\r\n baseColorBuffer[destinationOffset] = sRGBBaseColorPixel.r * 255;\r\n baseColorBuffer[destinationOffset + 1] = sRGBBaseColorPixel.g * 255;\r\n baseColorBuffer[destinationOffset + 2] = sRGBBaseColorPixel.b * 255;\r\n\r\n if (!sRGBBaseColorPixel.equalsWithEpsilon(White, Epsilon)) {\r\n writeOutBaseColorTexture = true;\r\n }\r\n\r\n metallicRoughnessBuffer[destinationOffset + 1] /= metallicRoughnessFactors.roughness! > Epsilon ? metallicRoughnessFactors.roughness! : 1;\r\n metallicRoughnessBuffer[destinationOffset + 2] /= metallicRoughnessFactors.metallic! > Epsilon ? metallicRoughnessFactors.metallic! : 1;\r\n\r\n const metallicRoughnessPixel = Color3.FromInts(255, metallicRoughnessBuffer[destinationOffset + 1], metallicRoughnessBuffer[destinationOffset + 2]);\r\n\r\n if (!metallicRoughnessPixel.equalsWithEpsilon(White, Epsilon)) {\r\n writeOutMetallicRoughnessTexture = true;\r\n }\r\n }\r\n }\r\n\r\n if (writeOutMetallicRoughnessTexture) {\r\n promises.push(\r\n this._getImageDataAsync(metallicRoughnessBuffer, width, height, mimeType).then((data) => {\r\n metallicRoughnessFactors.metallicRoughnessTextureData = data;\r\n })\r\n );\r\n }\r\n if (writeOutBaseColorTexture) {\r\n promises.push(\r\n this._getImageDataAsync(baseColorBuffer, width, height, mimeType).then((data) => {\r\n metallicRoughnessFactors.baseColorTextureData = data;\r\n })\r\n );\r\n }\r\n\r\n return await Promise.all(promises).then(() => {\r\n return metallicRoughnessFactors;\r\n });\r\n } else {\r\n return await Promise.reject(\"_ConvertSpecularGlossinessTexturesToMetallicRoughness: Scene from textures is missing!\");\r\n }\r\n }\r\n\r\n /**\r\n * Converts specular glossiness material properties to metallic roughness\r\n * @param specularGlossiness interface with specular glossiness material properties\r\n * @returns interface with metallic roughness material properties\r\n */\r\n private _convertSpecularGlossinessToMetallicRoughness(specularGlossiness: IPBRSpecularGlossiness): IPBRMetallicRoughness {\r\n const diffusePerceivedBrightness = this._getPerceivedBrightness(specularGlossiness.diffuseColor);\r\n const specularPerceivedBrightness = this._getPerceivedBrightness(specularGlossiness.specularColor);\r\n const oneMinusSpecularStrength = 1 - this._getMaxComponent(specularGlossiness.specularColor);\r\n const metallic = _SolveMetallic(diffusePerceivedBrightness, specularPerceivedBrightness, oneMinusSpecularStrength);\r\n const baseColorFromDiffuse = specularGlossiness.diffuseColor.scale(oneMinusSpecularStrength / (1.0 - DielectricSpecular.r) / Math.max(1 - metallic));\r\n const baseColorFromSpecular = specularGlossiness.specularColor.subtract(DielectricSpecular.scale(1 - metallic)).scale(1 / Math.max(metallic));\r\n let baseColor = Color3.Lerp(baseColorFromDiffuse, baseColorFromSpecular, metallic * metallic);\r\n baseColor = baseColor.clampToRef(0, 1, baseColor);\r\n\r\n const metallicRoughness: IPBRMetallicRoughness = {\r\n baseColor: baseColor,\r\n metallic: metallic,\r\n roughness: 1 - specularGlossiness.glossiness,\r\n };\r\n\r\n return metallicRoughness;\r\n }\r\n\r\n /**\r\n * Calculates the surface reflectance, independent of lighting conditions\r\n * @param color Color source to calculate brightness from\r\n * @returns number representing the perceived brightness, or zero if color is undefined\r\n */\r\n private _getPerceivedBrightness(color: Color3): number {\r\n if (color) {\r\n return Math.sqrt(0.299 * color.r * color.r + 0.587 * color.g * color.g + 0.114 * color.b * color.b);\r\n }\r\n return 0;\r\n }\r\n\r\n /**\r\n * Returns the maximum color component value\r\n * @param color\r\n * @returns maximum color component value, or zero if color is null or undefined\r\n */\r\n private _getMaxComponent(color: Color3): number {\r\n if (color) {\r\n return Math.max(color.r, Math.max(color.g, color.b));\r\n }\r\n return 0;\r\n }\r\n\r\n /**\r\n * Convert a PBRMaterial (Metallic/Roughness) to Metallic Roughness factors\r\n * @param babylonPBRMaterial BJS PBR Metallic Roughness Material\r\n * @param mimeType mime type to use for the textures\r\n * @param glTFPbrMetallicRoughness glTF PBR Metallic Roughness interface\r\n * @param hasUVs specifies if texture coordinates are present on the submesh to determine if textures should be applied\r\n * @returns glTF PBR Metallic Roughness factors\r\n */\r\n private async _convertMetalRoughFactorsToMetallicRoughnessAsync(\r\n babylonPBRMaterial: PBRBaseMaterial,\r\n mimeType: ImageMimeType,\r\n glTFPbrMetallicRoughness: IMaterialPbrMetallicRoughness,\r\n hasUVs: boolean\r\n ): Promise<IPBRMetallicRoughness> {\r\n const promises: Promise<void>[] = [];\r\n\r\n const metallicRoughness: IPBRMetallicRoughness = {\r\n baseColor: babylonPBRMaterial._albedoColor,\r\n metallic: babylonPBRMaterial._metallic,\r\n roughness: babylonPBRMaterial._roughness,\r\n };\r\n\r\n if (hasUVs) {\r\n const albedoTexture = babylonPBRMaterial._albedoTexture;\r\n if (albedoTexture) {\r\n promises.push(\r\n this.exportTextureAsync(babylonPBRMaterial._albedoTexture!, mimeType).then((glTFTexture) => {\r\n if (glTFTexture) {\r\n glTFPbrMetallicRoughness.baseColorTexture = glTFTexture;\r\n }\r\n })\r\n );\r\n }\r\n const metallicTexture = babylonPBRMaterial._metallicTexture;\r\n if (metallicTexture) {\r\n promises.push(\r\n this.exportTextureAsync(metallicTexture, mimeType).then((glTFTexture) => {\r\n if (glTFTexture) {\r\n glTFPbrMetallicRoughness.metallicRoughnessTexture = glTFTexture;\r\n }\r\n })\r\n );\r\n }\r\n }\r\n\r\n if (promises.length > 0) {\r\n this._exporter._materialNeedsUVsSet.add(babylonPBRMaterial);\r\n await Promise.all(promises);\r\n }\r\n\r\n return metallicRoughness;\r\n }\r\n\r\n private _getTextureSampler(texture: Nullable<BaseTexture>): ISampler {\r\n const sampler: ISampler = {};\r\n if (!texture || !(texture instanceof Texture)) {\r\n return sampler;\r\n }\r\n\r\n const wrapS = this._getGLTFTextureWrapMode(texture.wrapU);\r\n if (wrapS !== TextureWrapMode.REPEAT) {\r\n sampler.wrapS = wrapS;\r\n }\r\n\r\n const wrapT = this._getGLTFTextureWrapMode(texture.wrapV);\r\n if (wrapT !== TextureWrapMode.REPEAT) {\r\n sampler.wrapT = wrapT;\r\n }\r\n\r\n switch (texture.samplingMode) {\r\n case Texture.LINEAR_LINEAR: {\r\n sampler.magFilter = TextureMagFilter.LINEAR;\r\n sampler.minFilter = TextureMinFilter.LINEAR;\r\n break;\r\n }\r\n case Texture.LINEAR_NEAREST: {\r\n sampler.magFilter = TextureMagFilter.LINEAR;\r\n sampler.minFilter = TextureMinFilter.NEAREST;\r\n break;\r\n }\r\n case Texture.NEAREST_LINEAR: {\r\n sampler.magFilter = TextureMagFilter.NEAREST;\r\n sampler.minFilter = TextureMinFilter.LINEAR;\r\n break;\r\n }\r\n case Texture.NEAREST_LINEAR_MIPLINEAR: {\r\n sampler.magFilter = TextureMagFilter.NEAREST;\r\n sampler.minFilter = TextureMinFilter.LINEAR_MIPMAP_LINEAR;\r\n break;\r\n }\r\n case Texture.NEAREST_NEAREST: {\r\n sampler.magFilter = TextureMagFilter.NEAREST;\r\n sampler.minFilter = TextureMinFilter.NEAREST;\r\n break;\r\n }\r\n case Texture.NEAREST_LINEAR_MIPNEAREST: {\r\n sampler.magFilter = TextureMagFilter.NEAREST;\r\n sampler.minFilter = TextureMinFilter.LINEAR_MIPMAP_NEAREST;\r\n break;\r\n }\r\n case Texture.LINEAR_NEAREST_MIPNEAREST: {\r\n sampler.magFilter = TextureMagFilter.LINEAR;\r\n sampler.minFilter = TextureMinFilter.NEAREST_MIPMAP_NEAREST;\r\n break;\r\n }\r\n case Texture.LINEAR_NEAREST_MIPLINEAR: {\r\n sampler.magFilter = TextureMagFilter.LINEAR;\r\n sampler.minFilter = TextureMinFilter.NEAREST_MIPMAP_LINEAR;\r\n break;\r\n }\r\n case Texture.NEAREST_NEAREST_MIPLINEAR: {\r\n sampler.magFilter = TextureMagFilter.NEAREST;\r\n sampler.minFilter = TextureMinFilter.NEAREST_MIPMAP_LINEAR;\r\n break;\r\n }\r\n case Texture.LINEAR_LINEAR_MIPLINEAR: {\r\n sampler.magFilter = TextureMagFilter.LINEAR;\r\n sampler.minFilter = TextureMinFilter.LINEAR_MIPMAP_LINEAR;\r\n break;\r\n }\r\n case Texture.LINEAR_LINEAR_MIPNEAREST: {\r\n sampler.magFilter = TextureMagFilter.LINEAR;\r\n sampler.minFilter = TextureMinFilter.LINEAR_MIPMAP_NEAREST;\r\n break;\r\n }\r\n case Texture.NEAREST_NEAREST_MIPNEAREST: {\r\n sampler.magFilter = TextureMagFilter.NEAREST;\r\n sampler.minFilter = TextureMinFilter.NEAREST_MIPMAP_NEAREST;\r\n break;\r\n }\r\n }\r\n\r\n return sampler;\r\n }\r\n\r\n private _getGLTFTextureWrapMode(wrapMode: number): TextureWrapMode {\r\n switch (wrapMode) {\r\n case Texture.WRAP_ADDRESSMODE: {\r\n return TextureWrapMode.REPEAT;\r\n }\r\n case Texture.CLAMP_ADDRESSMODE: {\r\n return TextureWrapMode.CLAMP_TO_EDGE;\r\n }\r\n case Texture.MIRROR_ADDRESSMODE: {\r\n return TextureWrapMode.MIRRORED_REPEAT;\r\n }\r\n default: {\r\n Tools.Error(`Unsupported Texture Wrap Mode ${wrapMode}!`);\r\n return TextureWrapMode.REPEAT;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Convert a PBRMaterial (Specular/Glossiness) to Metallic Roughness factors\r\n * @param babylonPBRMaterial BJS PBR Metallic Roughness Material\r\n * @param mimeType mime type to use for the textures\r\n * @param pbrMetallicRoughness glTF PBR Metallic Roughness interface\r\n * @param hasUVs specifies if texture coordinates are present on the submesh to determine if textures should be applied\r\n * @returns glTF PBR Metallic Roughness factors\r\n */\r\n private async _convertSpecGlossFactorsToMetallicRoughnessAsync(\r\n babylonPBRMaterial: PBRBaseMaterial,\r\n mimeType: ImageMimeType,\r\n pbrMetallicRoughness: IMaterialPbrMetallicRoughness,\r\n hasUVs: boolean\r\n ): Promise<IPBRMetallicRoughness> {\r\n const specGloss: IPBRSpecularGlossiness = {\r\n diffuseColor: babylonPBRMaterial._albedoColor,\r\n specularColor: babylonPBRMaterial._reflectivityColor,\r\n glossiness: babylonPBRMaterial._microSurface,\r\n };\r\n\r\n const albedoTexture = babylonPBRMaterial._albedoTexture;\r\n const reflectivityTexture = babylonPBRMaterial._reflectivityTexture;\r\n const useMicrosurfaceFromReflectivityMapAlpha = babylonPBRMaterial._useMicroSurfaceFromReflectivityMapAlpha;\r\n if (reflectivityTexture && !useMicrosurfaceFromReflectivityMapAlpha) {\r\n return await Promise.reject(\"_ConvertPBRMaterial: Glossiness values not included in the reflectivity texture are currently not supported\");\r\n }\r\n\r\n if ((albedoTexture || reflectivityTexture) && hasUVs) {\r\n this._exporter._materialNeedsUVsSet.add(babylonPBRMaterial);\r\n\r\n const samplerIndex = this._exportTextureSampler(albedoTexture || reflectivityTexture);\r\n const metallicRoughnessFactors = await this._convertSpecularGlossinessTexturesToMetallicRoughnessAsync(albedoTexture, reflectivityTexture, specGloss, mimeType);\r\n\r\n const textures = this._exporter._textures;\r\n\r\n if (metallicRoughnessFactors.baseColorTextureData) {\r\n const imageIndex = this._exportImage(`baseColor${textures.length}`, mimeType, metallicRoughnessFactors.baseColorTextureData);\r\n pbrMetallicRoughness.baseColorTexture = this._exportTextureInfo(imageIndex, samplerIndex, albedoTexture?.coordinatesIndex);\r\n }\r\n\r\n if (metallicRoughnessFactors.metallicRoughnessTextureData) {\r\n const imageIndex = this._exportImage(`metallicRoughness${textures.length}`, mimeType, metallicRoughnessFactors.metallicRoughnessTextureData);\r\n pbrMetallicRoughness.metallicRoughnessTexture = this._exportTextureInfo(imageIndex, samplerIndex, reflectivityTexture?.coordinatesIndex);\r\n }\r\n\r\n return metallicRoughnessFactors;\r\n } else {\r\n return this._convertSpecularGlossinessToMetallicRoughness(specGloss);\r\n }\r\n }\r\n\r\n public async exportPBRMaterialAsync(babylonPBRMaterial: PBRBaseMaterial, mimeType: ImageMimeType, hasUVs: boolean): Promise<number> {\r\n const glTFPbrMetallicRoughness: IMaterialPbrMetallicRoughness = {};\r\n\r\n const glTFMaterial: IMaterial = {\r\n name: babylonPBRMaterial.name,\r\n };\r\n\r\n const useMetallicRoughness = babylonPBRMaterial.isMetallicWorkflow();\r\n\r\n if (useMetallicRoughness) {\r\n const albedoColor = babylonPBRMaterial._albedoColor;\r\n const alpha = babylonPBRMaterial.alpha;\r\n if (albedoColor) {\r\n glTFPbrMetallicRoughness.baseColorFactor = [albedoColor.r, albedoColor.g, albedoColor.b, alpha];\r\n }\r\n }\r\n\r\n const metallicRoughness = useMetallicRoughness\r\n ? await this._convertMetalRoughFactorsToMetallicRoughnessAsync(babylonPBRMaterial, mimeType, glTFPbrMetallicRoughness, hasUVs)\r\n : await this._convertSpecGlossFactorsToMetallicRoughnessAsync(babylonPBRMaterial, mimeType, glTFPbrMetallicRoughness, hasUVs);\r\n\r\n await this._setMetallicRoughnessPbrMaterialAsync(metallicRoughness, babylonPBRMaterial, glTFMaterial, glTFPbrMetallicRoughness, mimeType, hasUVs);\r\n await this._finishMaterialAsync(glTFMaterial, babylonPBRMaterial, mimeType);\r\n\r\n const materials = this._exporter._materials;\r\n materials.push(glTFMaterial);\r\n return materials.length - 1;\r\n }\r\n\r\n private async _setMetallicRoughnessPbrMaterialAsync(\r\n metallicRoughness: IPBRMetallicRoughness,\r\n babylonPBRMaterial: PBRBaseMaterial,\r\n glTFMaterial: IMaterial,\r\n glTFPbrMetallicRoughness: IMaterialPbrMetallicRoughness,\r\n mimeType: ImageMimeType,\r\n hasUVs: boolean\r\n ): Promise<void> {\r\n SetAlphaMode(glTFMaterial, babylonPBRMaterial);\r\n\r\n if (!metallicRoughness.baseColor.equalsWithEpsilon(White, Epsilon) || !Scalar.WithinEpsilon(babylonPBRMaterial.alpha, 1, Epsilon)) {\r\n glTFPbrMetallicRoughness.baseColorFactor = [metallicRoughness.baseColor.r, metallicRoughness.baseColor.g, metallicRoughness.baseColor.b, babylonPBRMaterial.alpha];\r\n }\r\n\r\n if (metallicRoughness.metallic != null && metallicRoughness.metallic !== 1) {\r\n glTFPbrMetallicRoughness.metallicFactor = metallicRoughness.metallic;\r\n }\r\n if (metallicRoughness.roughness != null && metallicRoughness.roughness !== 1) {\r\n glTFPbrMetallicRoughness.roughnessFactor = metallicRoughness.roughness;\r\n }\r\n\r\n if (babylonPBRMaterial.backFaceCulling != null && !babylonPBRMaterial.backFaceCulling) {\r\n if (!babylonPBRMaterial._twoSidedLighting) {\r\n Tools.Warn(babylonPBRMaterial.name + \": Back-face culling disabled and two-sided lighting disabled is not supported in glTF.\");\r\n }\r\n glTFMaterial.doubleSided = true;\r\n }\r\n\r\n if (hasUVs) {\r\n const promises: Promise<void>[] = [];\r\n\r\n const bumpTexture = babylonPBRMaterial._bumpTexture;\r\n if (bumpTexture) {\r\n promises.push(\r\n this.exportTextureAsync(bumpTexture, mimeType).then((glTFTexture) => {\r\n if (glTFTexture) {\r\n glTFMaterial.normalTexture = glTFTexture;\r\n if (bumpTexture.level !== 1) {\r\n glTFMaterial.normalTexture.scale = bumpTexture.level;\r\n }\r\n }\r\n })\r\n );\r\n }\r\n\r\n const ambientTexture = babylonPBRMaterial._ambientTexture;\r\n if (ambientTexture) {\r\n promises.push(\r\n this.exportTextureAsync(ambientTexture, mimeType).then((glTFTexture) => {\r\n if (glTFTexture) {\r\n const occlusionTexture: IMaterialOcclusionTextureInfo = {\r\n index: glTFTexture.index,\r\n texCoord: glTFTexture.texCoord,\r\n extensions: glTFTexture.extensions,\r\n };\r\n\r\n glTFMaterial.occlusionTexture = occlusionTexture;\r\n const ambientTextureStrength = babylonPBRMaterial._ambientTextureStrength;\r\n if (ambientTextureStrength) {\r\n occlusionTexture.strength = ambientTextureStrength;\r\n }\r\n }\r\n })\r\n );\r\n }\r\n\r\n const emissiveTexture = babylonPBRMaterial._emissiveTexture;\r\n if (emissiveTexture) {\r\n promises.push(\r\n this.exportTextureAsync(emissiveTexture, mimeType).then((glTFTexture) => {\r\n if (glTFTexture) {\r\n glTFMaterial.emissiveTexture = glTFTexture;\r\n }\r\n })\r\n );\r\n }\r\n\r\n if (promises.length > 0) {\r\n this._exporter._materialNeedsUVsSet.add(babylonPBRMaterial);\r\n await Promise.all(promises);\r\n }\r\n }\r\n\r\n const emissiveColor = babylonPBRMaterial._emissiveColor;\r\n if (!emissiveColor.equalsWithEpsilon(Black, Epsilon)) {\r\n glTFMaterial.emissiveFactor = emissiveColor.asArray();\r\n }\r\n\r\n glTFMaterial.pbrMetallicRoughness = glTFPbrMetallicRoughness;\r\n }\r\n\r\n /**\r\n * Get the RGBA pixel data from a texture\r\n * @param babylonTexture\r\n * @returns an array buffer promise containing the pixel data\r\n */\r\n // eslint-disable-next-line no-restricted-syntax, @typescript-eslint/promise-function-async\r\n private _getPixelsFromTextureAsync(babylonTexture: BaseTexture): Promise<Nullable<Uint8Array | Float32Array>> {\r\n // If the internal texture format is compressed, we cannot read the pixels directly.\r\n if (IsCompressedTextureFormat(babylonTexture.textureFormat)) {\r\n return GetTextureDataAsync(babylonTexture, babylonTexture._texture!.width, babylonTexture._texture!.height);\r\n }\r\n\r\n return babylonTexture.textureType === Constants.TEXTURETYPE_UNSIGNED_BYTE\r\n ? (babylonTexture.readPixels() as Promise<Uint8Array>)\r\n : (babylonTexture.readPixels() as Promise<Float32Array>);\r\n }\r\n\r\n public async exportTextureAsync(babylonTexture: BaseTexture, mimeType: ImageMimeType): Promise<Nullable<ITextureInfo>> {\r\n const extensionPromise = this._exporter._extensionsPreExportTextureAsync(\"exporter\", babylonTexture as Texture, mimeType);\r\n if (!extensionPromise) {\r\n return await this._exportTextureInfoAsync(babylonTexture, mimeType);\r\n }\r\n\r\n return await extensionPromise.then(async (texture) => {\r\n if (!texture) {\r\n return await this._exportTextureInfoAsync(babylonTexture, mimeType);\r\n }\r\n return await this._exportTextureInfoAsync(texture, mimeType);\r\n });\r\n }\r\n\r\n private async _exportTextureInfoAsync(babylonTexture: BaseTexture, mimeType: ImageMimeType): Promise<Nullable<ITextureInfo>> {\r\n let textureInfo = this._textureMap.get(babylonTexture);\r\n if (!textureInfo) {\r\n const pixels = await this._getPixelsFromTextureAsync(babylonTexture);\r\n if (!pixels) {\r\n return null;\r\n }\r\n\r\n const samplerIndex = this._exportTextureSampler(babylonTexture);\r\n\r\n // Preserve texture mime type if defined\r\n const textureMimeType = (babylonTexture as Texture).mimeType;\r\n if (textureMimeType) {\r\n switch (textureMimeType) {\r\n case \"image/jpeg\":\r\n case \"image/png\":\r\n case \"image/webp\":\r\n mimeType = textureMimeType as ImageMimeType;\r\n break;\r\n default:\r\n Tools.Warn(`Unsupported media type: ${textureMimeType}. Exporting texture as PNG.`);\r\n // Will later fallback to default mime type, image/png, from Canvas API\r\n break;\r\n }\r\n }\r\n\r\n const internalTextureToImage = this._internalTextureToImage;\r\n const internalTextureUniqueId = babylonTexture.getInternalTexture()!.uniqueId;\r\n internalTextureToImage[internalTextureUniqueId] ||= {};\r\n let imageIndexPromise = internalTextureToImage[internalTextureUniqueId][mimeType];\r\n if (imageIndexPromise === undefined) {\r\n const size = babylonTexture.getSize();\r\n imageIndexPromise = (async () => {\r\n const data = await this._getImageDataAsync(pixels, size.width, size.height, mimeType);\r\n return this._exportImage(babylonTexture.name, mimeType, data);\r\n })();\r\n internalTextureToImage[internalTextureUniqueId][mimeType] = imageIndexPromise;\r\n }\r\n\r\n textureInfo = this._exportTextureInfo(await imageIndexPromise, samplerIndex, babylonTexture.coordinatesIndex);\r\n this._textureMap.set(babylonTexture, textureInfo);\r\n this._exporter._extensionsPostExportTextures(\"exporter\", textureInfo, babylonTexture);\r\n }\r\n\r\n return textureInfo;\r\n }\r\n\r\n private _exportImage(name: string, mimeType: ImageMimeType, data: ArrayBuffer): number {\r\n const images = this._exporter._images;\r\n\r\n let image: IImage;\r\n if (this._exporter._shouldUseGlb) {\r\n image = {\r\n name: name,\r\n mimeType: mimeType,\r\n bufferView: undefined, // Will be updated later by BufferManager\r\n };\r\n const bufferView = this._exporter._bufferManager.createBufferView(new Uint8Array(data));\r\n this._exporter._bufferManager.setBufferView(image, bufferView);\r\n } else {\r\n // Build a unique URI\r\n const baseName = name.replace(/\\.\\/|\\/|\\.\\\\|\\\\/g, \"_\");\r\n const extension = GetFileExtensionFromMimeType(mimeType);\r\n let fileName = baseName + extension;\r\n if (images.some((image) => image.uri === fileName)) {\r\n fileName = `${baseName}_${Tools.RandomId()}${extension}`;\r\n }\r\n\r\n image = {\r\n name: name,\r\n uri: fileName,\r\n };\r\n this._exporter._imageData[fileName] = { data: data, mimeType: mimeType }; // Save image data to be written to file later\r\n }\r\n\r\n images.push(image);\r\n\r\n return images.length - 1;\r\n }\r\n\r\n private _exportTextureInfo(imageIndex: number, samplerIndex: number, coordinatesIndex?: number): ITextureInfo {\r\n const textures = this._exporter._textures;\r\n let textureIndex = textures.findIndex((t) => t.sampler == samplerIndex && t.source === imageIndex);\r\n if (textureIndex === -1) {\r\n textureIndex = textures.length;\r\n textures.push({\r\n source: imageIndex,\r\n sampler: samplerIndex,\r\n });\r\n }\r\n\r\n const textureInfo: ITextureInfo = { index: textureIndex };\r\n if (coordinatesIndex) {\r\n textureInfo.texCoord = coordinatesIndex;\r\n }\r\n return textureInfo;\r\n }\r\n\r\n private _exportTextureSampler(texture: Nullable<BaseTexture>): number {\r\n const sampler = this._getTextureSampler(texture);\r\n\r\n // if a pre-existing sampler with identical parameters exists, then reuse the previous sampler\r\n const samplers = this._exporter._samplers;\r\n const samplerIndex = samplers.findIndex(\r\n (s) => s.minFilter === sampler.minFilter && s.magFilter === sampler.magFilter && s.wrapS === sampler.wrapS && s.wrapT === sampler.wrapT\r\n );\r\n if (samplerIndex !== -1) {\r\n return samplerIndex;\r\n }\r\n\r\n samplers.push(sampler);\r\n return samplers.length - 1;\r\n }\r\n}\r\n","/* eslint-disable jsdoc/require-jsdoc */\r\n\r\nimport type { INode } from \"babylonjs-gltf2interface\";\r\nimport { AccessorType, MeshPrimitiveMode } from \"babylonjs-gltf2interface\";\r\nimport type { FloatArray, DataArray, IndicesArray } from \"core/types\";\r\nimport type { Vector4 } from \"core/Maths/math.vector\";\r\nimport { Quaternion, TmpVectors, Matrix, Vector3 } from \"core/Maths/math.vector\";\r\nimport { VertexBuffer } from \"core/Buffers/buffer\";\r\nimport { Material } from \"core/Materials/material\";\r\nimport { TransformNode } from \"core/Meshes/transformNode\";\r\nimport { AbstractMesh } from \"core/Meshes/abstractMesh\";\r\nimport { EnumerateFloatValues } from \"core/Buffers/bufferUtils\";\r\nimport type { Node } from \"core/node\";\r\n\r\n// Matrix that converts handedness on the X-axis. Can convert from LH to RH and vice versa.\r\nconst ConvertHandednessMatrix = Matrix.Compose(new Vector3(-1, 1, 1), Quaternion.Identity(), Vector3.Zero());\r\n\r\n// Default values for comparison.\r\nconst Epsilon = 1e-6;\r\nconst DefaultTranslation = Vector3.Zero();\r\nconst DefaultScale = Vector3.One();\r\n\r\n/**\r\n * Get the information necessary for enumerating a vertex buffer.\r\n * @param vertexBuffer the vertex buffer to enumerate\r\n * @param meshes the meshes that use the vertex buffer\r\n * @returns the information necessary to enumerate the vertex buffer\r\n */\r\nexport function GetVertexBufferInfo(vertexBuffer: VertexBuffer, meshes: AbstractMesh[]) {\r\n const { byteOffset, byteStride, type, normalized } = vertexBuffer;\r\n const componentCount = vertexBuffer.getSize();\r\n const totalVertices = meshes.reduce((max, current) => {\r\n return current.getTotalVertices() > max ? current.getTotalVertices() : max;\r\n }, -Number.MAX_VALUE); // Get the max total vertices count, to ensure we capture the full range of vertex data used by the meshes.\r\n const count = totalVertices * componentCount;\r\n const kind = vertexBuffer.getKind();\r\n\r\n return { byteOffset, byteStride, componentCount, type, count, normalized, totalVertices, kind };\r\n}\r\n\r\nexport function GetAccessorElementCount(accessorType: AccessorType): number {\r\n switch (accessorType) {\r\n case AccessorType.MAT2:\r\n return 4;\r\n case AccessorType.MAT3:\r\n return 9;\r\n case AccessorType.MAT4:\r\n return 16;\r\n case AccessorType.SCALAR:\r\n return 1;\r\n case AccessorType.VEC2:\r\n return 2;\r\n case AccessorType.VEC3:\r\n return 3;\r\n case AccessorType.VEC4:\r\n return 4;\r\n }\r\n}\r\n\r\nexport function FloatsNeed16BitInteger(floatArray: FloatArray): boolean {\r\n return floatArray.some((value) => value >= 256);\r\n}\r\n\r\nexport function IsStandardVertexAttribute(type: string): boolean {\r\n switch (type) {\r\n case VertexBuffer.PositionKind:\r\n case VertexBuffer.NormalKind:\r\n case VertexBuffer.TangentKind:\r\n case VertexBuffer.ColorKind:\r\n case VertexBuffer.MatricesIndicesKind:\r\n case VertexBuffer.MatricesIndicesExtraKind:\r\n case VertexBuffer.MatricesWeightsKind:\r\n case VertexBuffer.MatricesWeightsExtraKind:\r\n case VertexBuffer.UVKind:\r\n case VertexBuffer.UV2Kind:\r\n case VertexBuffer.UV3Kind:\r\n case VertexBuffer.UV4Kind:\r\n case VertexBuffer.UV5Kind:\r\n case VertexBuffer.UV6Kind:\r\n return true;\r\n }\r\n return false;\r\n}\r\n\r\nexport function GetAccessorType(kind: string, hasVertexColorAlpha: boolean): AccessorType {\r\n if (kind == VertexBuffer.ColorKind) {\r\n return hasVertexColorAlpha ? AccessorType.VEC4 : AccessorType.VEC3;\r\n }\r\n\r\n switch (kind) {\r\n case VertexBuffer.PositionKind:\r\n case VertexBuffer.NormalKind:\r\n return AccessorType.VEC3;\r\n case VertexBuffer.TangentKind:\r\n case VertexBuffer.MatricesIndicesKind:\r\n case VertexBuffer.MatricesIndicesExtraKind:\r\n case VertexBuffer.MatricesWeightsKind:\r\n case VertexBuffer.MatricesWeightsExtraKind:\r\n return AccessorType.VEC4;\r\n case VertexBuffer.UVKind:\r\n case VertexBuffer.UV2Kind:\r\n case VertexBuffer.UV3Kind:\r\n case VertexBuffer.UV4Kind:\r\n case VertexBuffer.UV5Kind:\r\n case VertexBuffer.UV6Kind:\r\n return AccessorType.VEC2;\r\n }\r\n\r\n throw new Error(`Unknown kind ${kind}`);\r\n}\r\n\r\nexport function GetAttributeType(kind: string): string {\r\n switch (kind) {\r\n case VertexBuffer.PositionKind:\r\n return \"POSITION\";\r\n case VertexBuffer.NormalKind:\r\n return \"NORMAL\";\r\n case VertexBuffer.TangentKind:\r\n return \"TANGENT\";\r\n case VertexBuffer.ColorKind:\r\n return \"COLOR_0\";\r\n case VertexBuffer.UVKind:\r\n return \"TEXCOORD_0\";\r\n case VertexBuffer.UV2Kind:\r\n return \"TEXCOORD_1\";\r\n case VertexBuffer.UV3Kind:\r\n return \"TEXCOORD_2\";\r\n case VertexBuffer.UV4Kind:\r\n return \"TEXCOORD_3\";\r\n case VertexBuffer.UV5Kind:\r\n return \"TEXCOORD_4\";\r\n case VertexBuffer.UV6Kind:\r\n return \"TEXCOORD_5\";\r\n case VertexBuffer.MatricesIndicesKind:\r\n return \"JOINTS_0\";\r\n case VertexBuffer.MatricesIndicesExtraKind:\r\n return \"JOINTS_1\";\r\n case VertexBuffer.MatricesWeightsKind:\r\n return \"WEIGHTS_0\";\r\n case VertexBuffer.MatricesWeightsExtraKind:\r\n return \"WEIGHTS_1\";\r\n }\r\n\r\n throw new Error(`Unknown kind: ${kind}`);\r\n}\r\n\r\nexport function GetPrimitiveMode(fillMode: number): MeshPrimitiveMode {\r\n switch (fillMode) {\r\n case Material.TriangleFillMode:\r\n return MeshPrimitiveMode.TRIANGLES;\r\n case Material.TriangleStripDrawMode:\r\n return MeshPrimitiveMode.TRIANGLE_STRIP;\r\n case Material.TriangleFanDrawMode:\r\n return MeshPrimitiveMode.TRIANGLE_FAN;\r\n case Material.PointListDrawMode:\r\n case Material.PointFillMode:\r\n return MeshPrimitiveMode.POINTS;\r\n case Material.LineLoopDrawMode:\r\n return MeshPrimitiveMode.LINE_LOOP;\r\n case Material.LineListDrawMode:\r\n return MeshPrimitiveMode.LINES;\r\n case Material.LineStripDrawMode:\r\n return MeshPrimitiveMode.LINE_STRIP;\r\n }\r\n\r\n throw new Error(`Unknown fill mode: ${fillMode}`);\r\n}\r\n\r\nexport function IsTriangleFillMode(fillMode: number): boolean {\r\n switch (fillMode) {\r\n case Material.TriangleFillMode:\r\n case Material.TriangleStripDrawMode:\r\n case Material.TriangleFanDrawMode:\r\n return true;\r\n }\r\n\r\n return false;\r\n}\r\n\r\nexport function NormalizeTangent(tangent: Vector4 | Vector3) {\r\n const length = Math.sqrt(tangent.x * tangent.x + tangent.y * tangent.y + tangent.z * tangent.z);\r\n if (length > 0) {\r\n tangent.x /= length;\r\n tangent.y /= length;\r\n tangent.z /= length;\r\n }\r\n}\r\n\r\nexport function ConvertToRightHandedPosition(value: Vector3): Vector3 {\r\n value.x *= -1;\r\n return value;\r\n}\r\n\r\n/**\r\n * Converts, in-place, a left-handed quaternion to a right-handed quaternion via a change of basis.\r\n * @param value the unit quaternion to convert\r\n * @returns the converted quaternion\r\n */\r\nexport function ConvertToRightHandedRotation(value: Quaternion): Quaternion {\r\n /**\r\n * This is the simplified version of the following equation:\r\n * q' = to_quaternion(M * to_matrix(q) * M^-1)\r\n * where M is the conversion matrix `convertHandednessMatrix`,\r\n * q is the input quaternion, and q' is the converted quaternion.\r\n * Reference: https://d3cw3dd2w32x2b.cloudfront.net/wp-content/uploads/2015/01/matrix-to-quat.pdf\r\n */\r\n if (value.x * value.x + value.y * value.y > 0.5) {\r\n const absX = Math.abs(value.x);\r\n const absY = Math.abs(value.y);\r\n if (absX > absY) {\r\n const sign = Math.sign(value.x);\r\n value.x = absX;\r\n value.y *= -sign;\r\n value.z *= -sign;\r\n value.w *= sign;\r\n } else {\r\n const sign = Math.sign(value.y);\r\n value.x *= -sign;\r\n value.y = absY;\r\n value.z *= sign;\r\n value.w *= -sign;\r\n }\r\n } else {\r\n const absZ = Math.abs(value.z);\r\n const absW = Math.abs(value.w);\r\n if (absZ > absW) {\r\n const sign = Math.sign(value.z);\r\n value.x *= -sign;\r\n value.y *= sign;\r\n value.z = absZ;\r\n value.w *= -sign;\r\n } else {\r\n const sign = Math.sign(value.w);\r\n value.x *= sign;\r\n value.y *= -sign;\r\n value.z *= -sign;\r\n value.w = absW;\r\n }\r\n }\r\n\r\n return value;\r\n}\r\n\r\nexport function ConvertToRightHandedNode(value: INode) {\r\n let translation = Vector3.FromArrayToRef(value.translation || [0, 0, 0], 0, TmpVectors.Vector3[0]);\r\n let rotation = Quaternion.FromArrayToRef(value.rotation || [0, 0, 0, 1], 0, TmpVectors.Quaternion[0]);\r\n\r\n translation = ConvertToRightHandedPosition(translation);\r\n rotation = ConvertToRightHandedRotation(rotation);\r\n\r\n if (translation.equalsWithEpsilon(DefaultTranslation, Epsilon)) {\r\n delete value.translation;\r\n } else {\r\n value.translation = translation.asArray();\r\n }\r\n\r\n if (Quaternion.IsIdentity(rotation)) {\r\n delete value.rotation;\r\n } else {\r\n value.rotation = rotation.asArray();\r\n }\r\n}\r\n\r\n/**\r\n * Pre-multiplies a 180-degree Y rotation to the quaternion, in order to match glTF's flipped forward direction for cameras.\r\n * @param rotation Target camera rotation.\r\n */\r\nexport function ConvertCameraRotationToGLTF(rotation: Quaternion): void {\r\n // Simplified from: rotation * (0, 1, 0, 0).\r\n rotation.copyFromFloats(-rotation.z, rotation.w, rotation.x, -rotation.y);\r\n}\r\n\r\nexport function RotateNode180Y(node: INode): void {\r\n Quaternion.FromArrayToRef(node.rotation || [0, 0, 0, 1], 0, TmpVectors.Quaternion[1]);\r\n ConvertCameraRotationToGLTF(TmpVectors.Quaternion[1]);\r\n node.rotation = TmpVectors.Quaternion[1].asArray();\r\n}\r\n\r\n/**\r\n * Collapses GLTF parent and node into a single node. This is useful for removing nodes that were added by the GLTF importer.\r\n * @param node Target parent node.\r\n * @param parentNode Original GLTF node (Light or Camera).\r\n */\r\nexport function CollapseParentNode(node: INode, parentNode: INode) {\r\n const parentTranslation = Vector3.FromArrayToRef(parentNode.translation || [0, 0, 0], 0, TmpVectors.Vector3[0]);\r\n const parentRotation = Quaternion.FromArrayToRef(parentNode.rotation || [0, 0, 0, 1], 0, TmpVectors.Quaternion[0]);\r\n const parentScale = Vector3.FromArrayToRef(parentNode.scale || [1, 1, 1], 0, TmpVectors.Vector3[1]);\r\n const parentMatrix = Matrix.ComposeToRef(parentScale, parentRotation, parentTranslation, TmpVectors.Matrix[0]);\r\n\r\n const translation = Vector3.FromArrayToRef(node.translation || [0, 0, 0], 0, TmpVectors.Vector3[2]);\r\n const rotation = Quaternion.FromArrayToRef(node.rotation || [0, 0, 0, 1], 0, TmpVectors.Quaternion[1]);\r\n const scale = Vector3.FromArrayToRef(node.scale || [1, 1, 1], 0, TmpVectors.Vector3[1]);\r\n const matrix = Matrix.ComposeToRef(scale, rotation, translation, TmpVectors.Matrix[1]);\r\n\r\n parentMatrix.multiplyToRef(matrix, matrix);\r\n matrix.decompose(parentScale, parentRotation, parentTranslation);\r\n\r\n if (parentTranslation.equalsWithEpsilon(DefaultTranslation, Epsilon)) {\r\n delete parentNode.translation;\r\n } else {\r\n parentNode.translation = parentTranslation.asArray();\r\n }\r\n\r\n if (Quaternion.IsIdentity(parentRotation)) {\r\n delete parentNode.rotation;\r\n } else {\r\n parentNode.rotation = parentRotation.asArray();\r\n }\r\n\r\n if (parentScale.equalsWithEpsilon(DefaultScale, Epsilon)) {\r\n delete parentNode.scale;\r\n } else {\r\n parentNode.scale = parentScale.asArray();\r\n }\r\n}\r\n\r\n/**\r\n * Sometimes the GLTF Importer can add extra transform nodes (for lights and cameras). This checks if a parent node was added by the GLTF Importer. If so, it should be removed during serialization.\r\n * @param babylonNode Original GLTF node (Light or Camera).\r\n * @param parentBabylonNode Target parent node.\r\n * @returns True if the parent node was added by the GLTF importer.\r\n */\r\nexport function IsParentAddedByImporter(babylonNode: Node, parentBabylonNode: Node): boolean {\r\n return parentBabylonNode instanceof TransformNode && parentBabylonNode.getChildren().length == 1 && babylonNode.getChildren().length == 0;\r\n}\r\n\r\nexport function IsNoopNode(node: Node, useRightHandedSystem: boolean): boolean {\r\n if (!(node instanceof TransformNode)) {\r\n return false;\r\n }\r\n\r\n // Transform\r\n if (useRightHandedSystem) {\r\n const matrix = node.getWorldMatrix();\r\n if (!matrix.isIdentity()) {\r\n return false;\r\n }\r\n } else {\r\n const matrix = node.getWorldMatrix().multiplyToRef(ConvertHandednessMatrix, TmpVectors.Matrix[0]);\r\n if (!matrix.isIdentity()) {\r\n return false;\r\n }\r\n }\r\n\r\n // Geometry\r\n if (node instanceof AbstractMesh && node.geometry) {\r\n return false;\r\n }\r\n\r\n return true;\r\n}\r\n\r\n/**\r\n * Converts an IndicesArray into either Uint32Array or Uint16Array, only copying if the data is number[].\r\n * @param indices input array to be converted\r\n * @param start starting index to copy from\r\n * @param count number of indices to copy\r\n * @returns a Uint32Array or Uint16Array\r\n * @internal\r\n */\r\nexport function IndicesArrayToTypedArray(indices: IndicesArray, start: number, count: number, is32Bits: boolean): Uint32Array | Uint16Array {\r\n if (indices instanceof Uint16Array || indices instanceof Uint32Array) {\r\n return indices;\r\n }\r\n\r\n // If Int32Array, cast the indices (which are all positive) to Uint32Array\r\n if (indices instanceof Int32Array) {\r\n return new Uint32Array(indices.buffer, indices.byteOffset, indices.length);\r\n }\r\n\r\n const subarray = indices.slice(start, start + count);\r\n return is32Bits ? new Uint32Array(subarray) : new Uint16Array(subarray);\r\n}\r\n\r\nexport function DataArrayToUint8Array(data: DataArray): Uint8Array {\r\n if (data instanceof Array) {\r\n const floatData = new Float32Array(data);\r\n return new Uint8Array(floatData.buffer, floatData.byteOffset, floatData.byteLength);\r\n }\r\n\r\n return ArrayBuffer.isView(data) ? new Uint8Array(data.buffer, data.byteOffset, data.byteLength) : new Uint8Array(data);\r\n}\r\n\r\nexport function GetMinMax(data: DataArray, vertexBuffer: VertexBuffer, start: number, count: number): { min: number[]; max: number[] } {\r\n const { byteOffset, byteStride, type, normalized } = vertexBuffer;\r\n const size = vertexBuffer.getSize();\r\n const min = new Array<number>(size).fill(Infinity);\r\n const max = new Array<number>(size).fill(-Infinity);\r\n EnumerateFloatValues(data, byteOffset + start * byteStride, byteStride, size, type, count * size, normalized, (values) => {\r\n for (let i = 0; i < size; i++) {\r\n min[i] = Math.min(min[i], values[i]);\r\n max[i] = Math.max(max[i], values[i]);\r\n }\r\n });\r\n\r\n return { min, max };\r\n}\r\n\r\n/**\r\n * Removes, in-place, object properties which have the same value as the default value.\r\n * Useful for avoiding unnecessary properties in the glTF JSON.\r\n * @param object the object to omit default values from\r\n * @param defaultValues a partial object with default values\r\n * @returns object with default values omitted\r\n */\r\nexport function OmitDefaultValues<T extends object>(object: T, defaultValues: Partial<T>): T {\r\n for (const [key, value] of Object.entries(object)) {\r\n const defaultValue = defaultValues[key as keyof T];\r\n if ((Array.isArray(value) && Array.isArray(defaultValue) && AreArraysEqual(value, defaultValue)) || value === defaultValue) {\r\n delete object[key as keyof T];\r\n }\r\n }\r\n return object;\r\n}\r\n\r\nfunction AreArraysEqual(array1: unknown[], array2: unknown[]): boolean {\r\n return array1.length === array2.length && array1.every((val, i) => val === array2[i]);\r\n}\r\n","/* eslint-disable @typescript-eslint/naming-convention */\r\n/* eslint-disable babylonjs/available */\r\nimport type { TypedArray } from \"core/types\";\r\n\r\nconst TypedArrayToWriteMethod = new Map<Function, (dataView: DataView, byteOffset: number, value: number) => void>([\r\n [Int8Array, (d, b, v) => d.setInt8(b, v)],\r\n [Uint8Array, (dv, bo, v) => dv.setUint8(bo, v)],\r\n [Uint8ClampedArray, (dv, bo, v) => dv.setUint8(bo, v)],\r\n [Int16Array, (dv, bo, v) => dv.setInt16(bo, v, true)],\r\n [Uint16Array, (dv, bo, v) => dv.setUint16(bo, v, true)],\r\n [Int32Array, (dv, bo, v) => dv.setInt32(bo, v, true)],\r\n [Uint32Array, (dv, bo, v) => dv.setUint32(bo, v, true)],\r\n [Float32Array, (dv, bo, v) => dv.setFloat32(bo, v, true)],\r\n [Float64Array, (dv, bo, v) => dv.setFloat64(bo, v, true)],\r\n]);\r\n\r\n/** @internal */\r\nexport class DataWriter {\r\n private _data: Uint8Array;\r\n private _dataView: DataView;\r\n private _byteOffset: number;\r\n\r\n public writeTypedArray(value: Exclude<TypedArray, BigInt64Array | BigUint64Array>): void {\r\n this._checkGrowBuffer(value.byteLength);\r\n const setMethod = TypedArrayToWriteMethod.get(value.constructor)!;\r\n for (let i = 0; i < value.length; i++) {\r\n setMethod(this._dataView, this._byteOffset, value[i]);\r\n this._byteOffset += value.BYTES_PER_ELEMENT;\r\n }\r\n }\r\n\r\n public constructor(byteLength: number) {\r\n this._data = new Uint8Array(byteLength);\r\n this._dataView = new DataView(this._data.buffer);\r\n this._byteOffset = 0;\r\n }\r\n\r\n public get byteOffset(): number {\r\n return this._byteOffset;\r\n }\r\n\r\n public getOutputData(): Uint8Array {\r\n return new Uint8Array(this._data.buffer, 0, this._byteOffset);\r\n }\r\n\r\n public writeUInt8(value: number): void {\r\n this._checkGrowBuffer(1);\r\n this._dataView.setUint8(this._byteOffset, value);\r\n this._byteOffset++;\r\n }\r\n\r\n public writeInt8(value: number): void {\r\n this._checkGrowBuffer(1);\r\n this._dataView.setInt8(this._byteOffset, value);\r\n this._byteOffset++;\r\n }\r\n\r\n public writeInt16(entry: number): void {\r\n this._checkGrowBuffer(2);\r\n this._dataView.setInt16(this._byteOffset, entry, true);\r\n this._byteOffset += 2;\r\n }\r\n\r\n public writeUInt16(value: number): void {\r\n this._checkGrowBuffer(2);\r\n this._dataView.setUint16(this._byteOffset, value, true);\r\n this._byteOffset += 2;\r\n }\r\n\r\n public writeInt32(entry: number): void {\r\n this._checkGrowBuffer(4);\r\n this._dataView.setInt32(this._byteOffset, entry, true);\r\n this._byteOffset += 4;\r\n }\r\n\r\n public writeUInt32(value: number): void {\r\n this._checkGrowBuffer(4);\r\n this._dataView.setUint32(this._byteOffset, value, true);\r\n this._byteOffset += 4;\r\n }\r\n\r\n public writeFloat32(value: number): void {\r\n this._checkGrowBuffer(4);\r\n this._dataView.setFloat32(this._byteOffset, value, true);\r\n this._byteOffset += 4;\r\n }\r\n\r\n public writeFloat64(value: number): void {\r\n this._checkGrowBuffer(8);\r\n this._dataView.setFloat64(this._byteOffset, value, true);\r\n this._byteOffset += 8;\r\n }\r\n\r\n private _checkGrowBuffer(byteLength: number): void {\r\n const newByteLength = this.byteOffset + byteLength;\r\n if (newByteLength > this._data.byteLength) {\r\n const newData = new Uint8Array(newByteLength * 2);\r\n newData.set(this._data);\r\n this._data = newData;\r\n this._dataView = new DataView(this._data.buffer);\r\n }\r\n }\r\n}\r\n","import type { TypedArray } from \"core/types\";\nimport type { AccessorComponentType, AccessorType, IAccessor, IBufferView } from \"babylonjs-gltf2interface\";\nimport { DataWriter } from \"./dataWriter\";\n\ntype TypedArrayForglTF = Exclude<TypedArray, Float64Array | BigInt64Array | BigUint64Array>;\n\ninterface IPropertyWithBufferView {\n bufferView?: number;\n}\n\nfunction GetHighestByteAlignment(byteLength: number): number {\n if (byteLength % 4 === 0) {\n return 4;\n }\n if (byteLength % 2 === 0) {\n return 2;\n }\n return 1;\n}\n\n/**\n * Utility class to centralize the management of binary data, bufferViews, and the objects that reference them.\n * @internal\n */\nexport class BufferManager {\n /**\n * Maps a bufferView to its data\n */\n private _bufferViewToData: Map<IBufferView, TypedArrayForglTF> = new Map<IBufferView, TypedArrayForglTF>();\n\n /**\n * Maps a bufferView to glTF objects that reference it via a \"bufferView\" property (e.g. accessors, images)\n */\n private _bufferViewToProperties: Map<IBufferView, IPropertyWithBufferView[]> = new Map<IBufferView, IPropertyWithBufferView[]>();\n\n /**\n * Maps an accessor to its bufferView\n */\n private _accessorToBufferView: Map<IAccessor, IBufferView> = new Map<IAccessor, IBufferView>();\n\n /**\n * Generates a binary buffer from the stored bufferViews. Also populates the bufferViews list.\n * @param bufferViews The list of bufferViews to be populated while writing the binary\n * @returns The binary buffer\n */\n public generateBinary(bufferViews: IBufferView[]): Uint8Array {\n // Construct a DataWriter with the total byte length to prevent resizing\n let totalByteLength = 0;\n this._bufferViewToData.forEach((data) => {\n totalByteLength += data.byteLength;\n });\n const dataWriter = new DataWriter(totalByteLength);\n\n // Order the bufferViews in descending order of their alignment requirements\n const orderedBufferViews = Array.from(this._bufferViewToData.keys()).sort((a, b) => GetHighestByteAlignment(b.byteLength) - GetHighestByteAlignment(a.byteLength));\n\n // Fill in the bufferViews list and missing bufferView index references while writing the binary\n for (const bufferView of orderedBufferViews) {\n bufferView.byteOffset = dataWriter.byteOffset;\n bufferViews.push(bufferView);\n\n const bufferViewIndex = bufferViews.length - 1;\n const properties = this.getPropertiesWithBufferView(bufferView);\n for (const object of properties) {\n object.bufferView = bufferViewIndex;\n }\n\n dataWriter.writeTypedArray(this._bufferViewToData.get(bufferView)!);\n\n this._bufferViewToData.delete(bufferView); // Try to free up memory ASAP\n }\n\n return dataWriter.getOutputData();\n }\n\n /**\n * Creates a buffer view based on the supplied arguments\n * @param data a TypedArray to create the bufferView for\n * @param byteStride byte distance between consecutive elements\n * @returns bufferView for glTF\n */\n public createBufferView(data: TypedArrayForglTF, byteStride?: number): IBufferView {\n const bufferView: IBufferView = {\n buffer: 0,\n byteOffset: undefined, // byteOffset will be set later, when we write the binary and decide bufferView ordering\n byteLength: data.byteLength,\n byteStride: byteStride,\n };\n this._bufferViewToData.set(bufferView, data);\n return bufferView;\n }\n\n /**\n * Creates an accessor based on the supplied arguments and assigns it to the bufferView\n * @param bufferView The glTF bufferView referenced by this accessor\n * @param type The type of the accessor\n * @param componentType The datatype of components in the attribute\n * @param count The number of attributes referenced by this accessor\n * @param byteOffset The offset relative to the start of the bufferView in bytes\n * @param minMax Minimum and maximum value of each component in this attribute\n * @param normalized Specifies whether integer data values are normalized before usage\n * @returns accessor for glTF\n */\n public createAccessor(\n bufferView: IBufferView,\n type: AccessorType,\n componentType: AccessorComponentType,\n count: number,\n byteOffset?: number,\n minMax?: { min: number[]; max: number[] },\n normalized?: boolean\n ): IAccessor {\n this._verifyBufferView(bufferView);\n const accessor: IAccessor = {\n bufferView: undefined, // bufferView will be set to a real index later, once we write the binary and decide bufferView ordering\n componentType: componentType,\n count: count,\n type: type,\n min: minMax?.min,\n max: minMax?.max,\n normalized: normalized,\n byteOffset: byteOffset,\n };\n this.setBufferView(accessor, bufferView);\n this._accessorToBufferView.set(accessor, bufferView);\n return accessor;\n }\n\n /**\n * Assigns a bufferView to a glTF object that references it\n * @param object The glTF object\n * @param bufferView The bufferView to assign\n */\n public setBufferView(object: IPropertyWithBufferView, bufferView: IBufferView) {\n this._verifyBufferView(bufferView);\n const properties = this.getPropertiesWithBufferView(bufferView);\n properties.push(object);\n }\n\n /**\n * Removes buffer view from the binary data, as well as from all its known references\n * @param bufferView the bufferView to remove\n */\n public removeBufferView(bufferView: IBufferView): void {\n const properties = this.getPropertiesWithBufferView(bufferView);\n for (const object of properties) {\n if (object.bufferView !== undefined) {\n delete object.bufferView;\n }\n }\n\n this._bufferViewToData.delete(bufferView);\n this._bufferViewToProperties.delete(bufferView);\n this._accessorToBufferView.forEach((bv, accessor) => {\n if (bv === bufferView) {\n // Additionally, remove byteOffset from accessor referencing this bufferView\n if (accessor.byteOffset !== undefined) {\n delete accessor.byteOffset;\n }\n this._accessorToBufferView.delete(accessor);\n }\n });\n }\n\n public getBufferView(accessor: IAccessor): IBufferView {\n const bufferView = this._accessorToBufferView.get(accessor);\n this._verifyBufferView(bufferView);\n return bufferView!;\n }\n\n public getPropertiesWithBufferView(bufferView: IBufferView): IPropertyWithBufferView[] {\n this._verifyBufferView(bufferView);\n this._bufferViewToProperties.set(bufferView, this._bufferViewToProperties.get(bufferView) ?? []);\n return this._bufferViewToProperties.get(bufferView)!;\n }\n\n public getData(bufferView: IBufferView): TypedArrayForglTF {\n this._verifyBufferView(bufferView);\n return this._bufferViewToData.get(bufferView)!;\n }\n\n private _verifyBufferView(bufferView?: IBufferView): void {\n if (bufferView === undefined || !this._bufferViewToData.has(bufferView)) {\n throw new Error(`BufferView ${bufferView} not found in BufferManager.`);\n }\n }\n}\n","import type { IAnimation, INode, IBufferView, IAccessor, IAnimationSampler, IAnimationChannel } from \"babylonjs-gltf2interface\";\r\nimport { AnimationSamplerInterpolation, AnimationChannelTargetPath, AccessorType, AccessorComponentType } from \"babylonjs-gltf2interface\";\r\nimport type { Node } from \"core/node\";\r\nimport type { Nullable } from \"core/types\";\r\nimport { Vector3, Quaternion } from \"core/Maths/math.vector\";\r\nimport { Tools } from \"core/Misc/tools\";\r\nimport { Animation } from \"core/Animations/animation\";\r\nimport { TransformNode } from \"core/Meshes/transformNode\";\r\nimport type { Scene } from \"core/scene\";\r\nimport { MorphTarget } from \"core/Morph/morphTarget\";\r\nimport { Mesh } from \"core/Meshes/mesh\";\r\n\r\nimport type { IAnimationKey } from \"core/Animations/animationKey\";\r\nimport { AnimationKeyInterpolation } from \"core/Animations/animationKey\";\r\n\r\nimport { Camera } from \"core/Cameras/camera\";\r\nimport { Light } from \"core/Lights/light\";\r\nimport type { BufferManager } from \"./bufferManager\";\r\nimport { GetAccessorElementCount, ConvertToRightHandedPosition, ConvertCameraRotationToGLTF, ConvertToRightHandedRotation } from \"./glTFUtilities\";\r\n\r\n/**\r\n * @internal\r\n * Interface to store animation data.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface _IAnimationData {\r\n /**\r\n * Keyframe data.\r\n */\r\n inputs: number[];\r\n /**\r\n * Value data.\r\n */\r\n outputs: number[][];\r\n /**\r\n * Animation interpolation data.\r\n */\r\n samplerInterpolation: AnimationSamplerInterpolation;\r\n /**\r\n * Minimum keyframe value.\r\n */\r\n inputsMin: number;\r\n /**\r\n * Maximum keyframe value.\r\n */\r\n inputsMax: number;\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface _IAnimationInfo {\r\n /**\r\n * The target channel for the animation\r\n */\r\n animationChannelTargetPath: AnimationChannelTargetPath;\r\n /**\r\n * The glTF accessor type for the data.\r\n */\r\n dataAccessorType: AccessorType.VEC3 | AccessorType.VEC4 | AccessorType.SCALAR;\r\n /**\r\n * Specifies if quaternions should be used.\r\n */\r\n useQuaternion: boolean;\r\n}\r\n\r\n/**\r\n * @internal\r\n * Enum for handling in tangent and out tangent.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nenum _TangentType {\r\n /**\r\n * Specifies that input tangents are used.\r\n */\r\n INTANGENT,\r\n /**\r\n * Specifies that output tangents are used.\r\n */\r\n OUTTANGENT,\r\n}\r\n\r\n/**\r\n * @internal\r\n * Utility class for generating glTF animation data from BabylonJS.\r\n */\r\nexport class _GLTFAnimation {\r\n /**\r\n * Determine if a node is transformable - ie has properties it should be part of animation of transformation.\r\n * @param babylonNode the node to test\r\n * @returns true if can be animated, false otherwise. False if the parameter is null or undefined.\r\n */\r\n private static _IsTransformable(babylonNode: Node): boolean {\r\n return babylonNode && (babylonNode instanceof TransformNode || babylonNode instanceof Camera || babylonNode instanceof Light);\r\n }\r\n\r\n /**\r\n * @ignore\r\n *\r\n * Creates glTF channel animation from BabylonJS animation.\r\n * @param babylonTransformNode - BabylonJS mesh.\r\n * @param animation - animation.\r\n * @param animationChannelTargetPath - The target animation channel.\r\n * @param useQuaternion - Specifies if quaternions are used.\r\n * @returns nullable IAnimationData\r\n */\r\n public static _CreateNodeAnimation(\r\n babylonTransformNode: Node,\r\n animation: Animation,\r\n animationChannelTargetPath: AnimationChannelTargetPath,\r\n useQuaternion: boolean,\r\n animationSampleRate: number\r\n ): Nullable<_IAnimationData> {\r\n if (this._IsTransformable(babylonTransformNode)) {\r\n const inputs: number[] = [];\r\n const outputs: number[][] = [];\r\n const keyFrames = animation.getKeys();\r\n const minMaxKeyFrames = _GLTFAnimation._CalculateMinMaxKeyFrames(keyFrames);\r\n const interpolationOrBake = _GLTFAnimation._DeduceInterpolation(keyFrames, animationChannelTargetPath, useQuaternion);\r\n\r\n const interpolation = interpolationOrBake.interpolationType;\r\n const shouldBakeAnimation = interpolationOrBake.shouldBakeAnimation;\r\n\r\n if (shouldBakeAnimation) {\r\n _GLTFAnimation._CreateBakedAnimation(\r\n babylonTransformNode,\r\n animation,\r\n animationChannelTargetPath,\r\n minMaxKeyFrames.min,\r\n minMaxKeyFrames.max,\r\n animation.framePerSecond,\r\n animationSampleRate,\r\n inputs,\r\n outputs,\r\n minMaxKeyFrames,\r\n useQuaternion\r\n );\r\n } else {\r\n if (interpolation === AnimationSamplerInterpolation.LINEAR || interpolation === AnimationSamplerInterpolation.STEP) {\r\n _GLTFAnimation._CreateLinearOrStepAnimation(babylonTransformNode, animation, animationChannelTargetPath, inputs, outputs, useQuaternion);\r\n } else if (interpolation === AnimationSamplerInterpolation.CUBICSPLINE) {\r\n _GLTFAnimation._CreateCubicSplineAnimation(babylonTransformNode, animation, animationChannelTargetPath, inputs, outputs, useQuaternion);\r\n } else {\r\n _GLTFAnimation._CreateBakedAnimation(\r\n babylonTransformNode,\r\n animation,\r\n animationChannelTargetPath,\r\n minMaxKeyFrames.min,\r\n minMaxKeyFrames.max,\r\n animation.framePerSecond,\r\n animationSampleRate,\r\n inputs,\r\n outputs,\r\n minMaxKeyFrames,\r\n useQuaternion\r\n );\r\n }\r\n }\r\n\r\n if (inputs.length && outputs.length) {\r\n const result: _IAnimationData = {\r\n inputs: inputs,\r\n outputs: outputs,\r\n samplerInterpolation: interpolation,\r\n inputsMin: shouldBakeAnimation ? minMaxKeyFrames.min : Tools.FloatRound(minMaxKeyFrames.min / animation.framePerSecond),\r\n inputsMax: shouldBakeAnimation ? minMaxKeyFrames.max : Tools.FloatRound(minMaxKeyFrames.max / animation.framePerSecond),\r\n };\r\n\r\n return result;\r\n }\r\n }\r\n\r\n return null;\r\n }\r\n\r\n private static _DeduceAnimationInfo(animation: Animation): Nullable<_IAnimationInfo> {\r\n let animationChannelTargetPath: Nullable<AnimationChannelTargetPath> = null;\r\n let dataAccessorType = AccessorType.VEC3;\r\n let useQuaternion: boolean = false;\r\n const property = animation.targetProperty.split(\".\");\r\n switch (property[0]) {\r\n case \"scaling\": {\r\n animationChannelTargetPath = AnimationChannelTargetPath.SCALE;\r\n break;\r\n }\r\n case \"position\": {\r\n animationChannelTargetPath = AnimationChannelTargetPath.TRANSLATION;\r\n break;\r\n }\r\n case \"rotation\": {\r\n dataAccessorType = AccessorType.VEC4;\r\n animationChannelTargetPath = AnimationChannelTargetPath.ROTATION;\r\n break;\r\n }\r\n case \"rotationQuaternion\": {\r\n dataAccessorType = AccessorType.VEC4;\r\n useQuaternion = true;\r\n animationChannelTargetPath = AnimationChannelTargetPath.ROTATION;\r\n break;\r\n }\r\n case \"influence\": {\r\n dataAccessorType = AccessorType.SCALAR;\r\n animationChannelTargetPath = AnimationChannelTargetPath.WEIGHTS;\r\n break;\r\n }\r\n default: {\r\n Tools.Error(`Unsupported animatable property ${property[0]}`);\r\n }\r\n }\r\n if (animationChannelTargetPath) {\r\n return { animationChannelTargetPath: animationChannelTargetPath, dataAccessorType: dataAccessorType, useQuaternion: useQuaternion };\r\n } else {\r\n Tools.Error(\"animation channel target path and data accessor type could be deduced\");\r\n }\r\n return null;\r\n }\r\n\r\n /**\r\n * @ignore\r\n * Create node animations from the transform node animations\r\n * @param babylonNode\r\n * @param runtimeGLTFAnimation\r\n * @param idleGLTFAnimations\r\n * @param nodeMap\r\n * @param nodes\r\n * @param bufferManager\r\n * @param bufferViews\r\n * @param accessors\r\n * @param animationSampleRate\r\n */\r\n public static _CreateNodeAnimationFromNodeAnimations(\r\n babylonNode: Node,\r\n runtimeGLTFAnimation: IAnimation,\r\n idleGLTFAnimations: IAnimation[],\r\n nodeMap: Map<Node, number>,\r\n nodes: INode[],\r\n bufferManager: BufferManager,\r\n bufferViews: IBufferView[],\r\n accessors: IAccessor[],\r\n animationSampleRate: number,\r\n useRightHanded: boolean,\r\n shouldExportAnimation?: (animation: Animation) => boolean\r\n ) {\r\n let glTFAnimation: IAnimation;\r\n if (_GLTFAnimation._IsTransformable(babylonNode)) {\r\n if (babylonNode.animations) {\r\n for (const animation of babylonNode.animations) {\r\n if (shouldExportAnimation && !shouldExportAnimation(animation)) {\r\n continue;\r\n }\r\n const animationInfo = _GLTFAnimation._DeduceAnimationInfo(animation);\r\n if (animationInfo) {\r\n glTFAnimation = {\r\n name: animation.name,\r\n samplers: [],\r\n channels: [],\r\n };\r\n _GLTFAnimation._AddAnimation(\r\n `${animation.name}`,\r\n animation.hasRunningRuntimeAnimations ? runtimeGLTFAnimation : glTFAnimation,\r\n babylonNode,\r\n animation,\r\n animationInfo.dataAccessorType,\r\n animationInfo.animationChannelTargetPath,\r\n nodeMap,\r\n bufferManager,\r\n bufferViews,\r\n accessors,\r\n animationInfo.useQuaternion,\r\n animationSampleRate,\r\n useRightHanded\r\n );\r\n if (glTFAnimation.samplers.length && glTFAnimation.channels.length) {\r\n idleGLTFAnimations.push(glTFAnimation);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * @ignore\r\n * Create individual morph animations from the mesh's morph target animation tracks\r\n * @param babylonNode\r\n * @param runtimeGLTFAnimation\r\n * @param idleGLTFAnimations\r\n * @param nodeMap\r\n * @param nodes\r\n * @param bufferManager\r\n * @param bufferViews\r\n * @param accessors\r\n * @param animationSampleRate\r\n */\r\n public static _CreateMorphTargetAnimationFromMorphTargetAnimations(\r\n babylonNode: Node,\r\n runtimeGLTFAnimation: IAnimation,\r\n idleGLTFAnimations: IAnimation[],\r\n nodeMap: Map<Node, number>,\r\n nodes: INode[],\r\n bufferManager: BufferManager,\r\n bufferViews: IBufferView[],\r\n accessors: IAccessor[],\r\n animationSampleRate: number,\r\n useRightHanded: boolean,\r\n shouldExportAnimation?: (animation: Animation) => boolean\r\n ) {\r\n let glTFAnimation: IAnimation;\r\n if (babylonNode instanceof Mesh) {\r\n const morphTargetManager = babylonNode.morphTargetManager;\r\n if (morphTargetManager) {\r\n for (let i = 0; i < morphTargetManager.numTargets; ++i) {\r\n const morphTarget = morphTargetManager.getTarget(i);\r\n for (const animation of morphTarget.animations) {\r\n if (shouldExportAnimation && !shouldExportAnimation(animation)) {\r\n continue;\r\n }\r\n const combinedAnimation = new Animation(\r\n `${animation.name}`,\r\n \"influence\",\r\n animation.framePerSecond,\r\n animation.dataType,\r\n animation.loopMode,\r\n animation.enableBlending\r\n );\r\n const combinedAnimationKeys: IAnimationKey[] = [];\r\n const animationKeys = animation.getKeys();\r\n\r\n for (let j = 0; j < animationKeys.length; ++j) {\r\n const animationKey = animationKeys[j];\r\n for (let k = 0; k < morphTargetManager.numTargets; ++k) {\r\n if (k == i) {\r\n combinedAnimationKeys.push(animationKey);\r\n } else {\r\n combinedAnimationKeys.push({ frame: animationKey.frame, value: 0 });\r\n }\r\n }\r\n }\r\n combinedAnimation.setKeys(combinedAnimationKeys);\r\n const animationInfo = _GLTFAnimation._DeduceAnimationInfo(combinedAnimation);\r\n if (animationInfo) {\r\n glTFAnimation = {\r\n name: combinedAnimation.name,\r\n samplers: [],\r\n channels: [],\r\n };\r\n _GLTFAnimation._AddAnimation(\r\n animation.name,\r\n animation.hasRunningRuntimeAnimations ? runtimeGLTFAnimation : glTFAnimation,\r\n babylonNode,\r\n combinedAnimation,\r\n animationInfo.dataAccessorType,\r\n animationInfo.animationChannelTargetPath,\r\n nodeMap,\r\n bufferManager,\r\n bufferViews,\r\n accessors,\r\n animationInfo.useQuaternion,\r\n animationSampleRate,\r\n useRightHanded,\r\n morphTargetManager.numTargets\r\n );\r\n if (glTFAnimation.samplers.length && glTFAnimation.channels.length) {\r\n idleGLTFAnimations.push(glTFAnimation);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * @internal\r\n * Create node and morph animations from the animation groups\r\n * @param babylonScene\r\n * @param glTFAnimations\r\n * @param nodeMap\r\n * @param nodes\r\n * @param bufferManager\r\n * @param bufferViews\r\n * @param accessors\r\n * @param animationSampleRate\r\n */\r\n public static _CreateNodeAndMorphAnimationFromAnimationGroups(\r\n babylonScene: Scene,\r\n glTFAnimations: IAnimation[],\r\n nodeMap: Map<Node, number>,\r\n bufferManager: BufferManager,\r\n bufferViews: IBufferView[],\r\n accessors: IAccessor[],\r\n animationSampleRate: number,\r\n leftHandedNodes: Set<Node>,\r\n shouldExportAnimation?: (animation: Animation) => boolean\r\n ) {\r\n let glTFAnimation: IAnimation;\r\n if (babylonScene.animationGroups) {\r\n const animationGroups = babylonScene.animationGroups;\r\n for (const animationGroup of animationGroups) {\r\n const morphAnimations: Map<Mesh, Map<MorphTarget, Animation>> = new Map();\r\n const sampleAnimations: Map<Mesh, Animation> = new Map();\r\n const morphAnimationMeshes: Set<Mesh> = new Set();\r\n const animationGroupFrameDiff = animationGroup.to - animationGroup.from;\r\n glTFAnimation = {\r\n name: animationGroup.name,\r\n channels: [],\r\n samplers: [],\r\n };\r\n for (let i = 0; i < animationGroup.targetedAnimations.length; ++i) {\r\n const targetAnimation = animationGroup.targetedAnimations[i];\r\n const target = targetAnimation.target;\r\n const animation = targetAnimation.animation;\r\n if (shouldExportAnimation && !shouldExportAnimation(animation)) {\r\n continue;\r\n }\r\n\r\n const convertToRightHanded = leftHandedNodes.has(target);\r\n\r\n if (this._IsTransformable(target) || (target.length === 1 && this._IsTransformable(target[0]))) {\r\n const animationInfo = _GLTFAnimation._DeduceAnimationInfo(targetAnimation.animation);\r\n if (animationInfo) {\r\n const babylonTransformNode = this._IsTransformable(target) ? target : this._IsTransformable(target[0]) ? target[0] : null;\r\n if (babylonTransformNode) {\r\n _GLTFAnimation._AddAnimation(\r\n `${animation.name}`,\r\n glTFAnimation,\r\n babylonTransformNode,\r\n animation,\r\n animationInfo.dataAccessorType,\r\n animationInfo.animationChannelTargetPath,\r\n nodeMap,\r\n bufferManager,\r\n bufferViews,\r\n accessors,\r\n animationInfo.useQuaternion,\r\n animationSampleRate,\r\n convertToRightHanded\r\n );\r\n }\r\n }\r\n } else if (target instanceof MorphTarget || (target.length === 1 && target[0] instanceof MorphTarget)) {\r\n const animationInfo = _GLTFAnimation._DeduceAnimationInfo(targetAnimation.animation);\r\n if (animationInfo) {\r\n const babylonMorphTarget = target instanceof MorphTarget ? target : (target[0] as MorphTarget);\r\n if (babylonMorphTarget) {\r\n const babylonMorphTargetManager = babylonScene.morphTargetManagers.find((morphTargetManager) => {\r\n for (let j = 0; j < morphTargetManager.numTargets; ++j) {\r\n if (morphTargetManager.getTarget(j) === babylonMorphTarget) {\r\n return true;\r\n }\r\n }\r\n return false;\r\n });\r\n if (babylonMorphTargetManager) {\r\n const babylonMesh = babylonScene.meshes.find((mesh) => {\r\n return (mesh as Mesh).morphTargetManager === babylonMorphTargetManager;\r\n }) as Mesh;\r\n if (babylonMesh) {\r\n if (!morphAnimations.has(babylonMesh)) {\r\n morphAnimations.set(babylonMesh, new Map());\r\n }\r\n morphAnimations.get(babylonMesh)?.set(babylonMorphTarget, animation);\r\n morphAnimationMeshes.add(babylonMesh);\r\n sampleAnimations.set(babylonMesh, animation);\r\n }\r\n }\r\n }\r\n }\r\n } else {\r\n // this is the place for the KHR_animation_pointer.\r\n }\r\n }\r\n morphAnimationMeshes.forEach((mesh) => {\r\n const morphTargetManager = mesh.morphTargetManager!;\r\n let combinedAnimationGroup: Nullable<Animation> = null;\r\n const animationKeys: IAnimationKey[] = [];\r\n const sampleAnimation = sampleAnimations.get(mesh)!;\r\n const sampleAnimationKeys = sampleAnimation.getKeys();\r\n const numAnimationKeys = sampleAnimationKeys.length;\r\n /*\r\n Due to how glTF expects morph target animation data to be formatted, we need to rearrange the individual morph target animation tracks,\r\n such that we have a single animation, where a given keyframe input value has successive output values for each morph target belonging to the manager.\r\n See: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#animations\r\n\r\n We do this via constructing a new Animation track, and interleaving the frames of each morph target animation track in the current Animation Group\r\n We reuse the Babylon Animation data structure for ease of handling export of cubic spline animation keys, and to reuse the\r\n existing _GLTFAnimation.AddAnimation codepath with minimal modification, however the constructed Babylon Animation is NOT intended for use in-engine.\r\n */\r\n for (let i = 0; i < numAnimationKeys; ++i) {\r\n for (let j = 0; j < morphTargetManager.numTargets; ++j) {\r\n const morphTarget = morphTargetManager.getTarget(j);\r\n const animationsByMorphTarget = morphAnimations.get(mesh);\r\n if (animationsByMorphTarget) {\r\n const morphTargetAnimation = animationsByMorphTarget.get(morphTarget);\r\n if (morphTargetAnimation) {\r\n if (!combinedAnimationGroup) {\r\n combinedAnimationGroup = new Animation(\r\n `${animationGroup.name}_${mesh.name}_MorphWeightAnimation`,\r\n \"influence\",\r\n morphTargetAnimation.framePerSecond,\r\n Animation.ANIMATIONTYPE_FLOAT,\r\n morphTargetAnimation.loopMode,\r\n morphTargetAnimation.enableBlending\r\n );\r\n }\r\n animationKeys.push(morphTargetAnimation.getKeys()[i]);\r\n } else {\r\n animationKeys.push({\r\n frame: animationGroup.from + (animationGroupFrameDiff / numAnimationKeys) * i,\r\n value: morphTarget.influence,\r\n inTangent: sampleAnimationKeys[0].inTangent ? 0 : undefined,\r\n outTangent: sampleAnimationKeys[0].outTangent ? 0 : undefined,\r\n });\r\n }\r\n }\r\n }\r\n }\r\n combinedAnimationGroup!.setKeys(animationKeys);\r\n const animationInfo = _GLTFAnimation._DeduceAnimationInfo(combinedAnimationGroup!);\r\n if (animationInfo) {\r\n _GLTFAnimation._AddAnimation(\r\n `${animationGroup.name}_${mesh.name}_MorphWeightAnimation`,\r\n glTFAnimation,\r\n mesh,\r\n combinedAnimationGroup!,\r\n animationInfo.dataAccessorType,\r\n animationInfo.animationChannelTargetPath,\r\n nodeMap,\r\n bufferManager,\r\n bufferViews,\r\n accessors,\r\n animationInfo.useQuaternion,\r\n animationSampleRate,\r\n false,\r\n morphTargetManager?.numTargets\r\n );\r\n }\r\n });\r\n if (glTFAnimation.channels.length && glTFAnimation.samplers.length) {\r\n glTFAnimations.push(glTFAnimation);\r\n }\r\n }\r\n }\r\n }\r\n\r\n private static _AddAnimation(\r\n name: string,\r\n glTFAnimation: IAnimation,\r\n babylonTransformNode: Node,\r\n animation: Animation,\r\n dataAccessorType: AccessorType,\r\n animationChannelTargetPath: AnimationChannelTargetPath,\r\n nodeMap: Map<Node, number>,\r\n bufferManager: BufferManager,\r\n bufferViews: IBufferView[],\r\n accessors: IAccessor[],\r\n useQuaternion: boolean,\r\n animationSampleRate: number,\r\n convertToRightHanded: boolean,\r\n morphAnimationChannels?: number\r\n ) {\r\n const animationData = _GLTFAnimation._CreateNodeAnimation(babylonTransformNode, animation, animationChannelTargetPath, useQuaternion, animationSampleRate);\r\n let bufferView: IBufferView;\r\n let accessor: IAccessor;\r\n let keyframeAccessorIndex: number;\r\n let dataAccessorIndex: number;\r\n let animationSampler: IAnimationSampler;\r\n let animationChannel: IAnimationChannel;\r\n\r\n if (animationData) {\r\n /*\r\n * Now that we have the glTF converted morph target animation data,\r\n * we can remove redundant input data so that we have n input frames,\r\n * and morphAnimationChannels * n output frames\r\n */\r\n if (morphAnimationChannels) {\r\n let index = 0;\r\n let currentInput: number = 0;\r\n const newInputs: number[] = [];\r\n while (animationData.inputs.length > 0) {\r\n currentInput = animationData.inputs.shift()!;\r\n if (index % morphAnimationChannels == 0) {\r\n newInputs.push(currentInput);\r\n }\r\n index++;\r\n }\r\n animationData.inputs = newInputs;\r\n }\r\n\r\n const nodeIndex = nodeMap.get(babylonTransformNode);\r\n\r\n // Create buffer view and accessor for key frames.\r\n const inputData = new Float32Array(animationData.inputs);\r\n bufferView = bufferManager.createBufferView(inputData);\r\n accessor = bufferManager.createAccessor(bufferView, AccessorType.SCALAR, AccessorComponentType.FLOAT, animationData.inputs.length, undefined, {\r\n min: [animationData.inputsMin],\r\n max: [animationData.inputsMax],\r\n });\r\n accessors.push(accessor);\r\n keyframeAccessorIndex = accessors.length - 1;\r\n\r\n // Perform conversions on keyed values while also building their buffer.\r\n const rotationQuaternion = new Quaternion();\r\n const eulerVec3 = new Vector3();\r\n const position = new Vector3();\r\n const isCamera = babylonTransformNode instanceof Camera;\r\n\r\n const elementCount = GetAccessorElementCount(dataAccessorType);\r\n const outputData = new Float32Array(animationData.outputs.length * elementCount);\r\n animationData.outputs.forEach(function (output: number[], index: number) {\r\n let outputToWrite: number[] = output;\r\n if (convertToRightHanded) {\r\n switch (animationChannelTargetPath) {\r\n case AnimationChannelTargetPath.TRANSLATION:\r\n Vector3.FromArrayToRef(output, 0, position);\r\n ConvertToRightHandedPosition(position);\r\n position.toArray(outputToWrite);\r\n break;\r\n case AnimationChannelTargetPath.ROTATION:\r\n if (output.length === 4) {\r\n Quaternion.FromArrayToRef(output, 0, rotationQuaternion);\r\n } else {\r\n outputToWrite = new Array(4); // Will need 4, not 3, for a quaternion\r\n Vector3.FromArrayToRef(output, 0, eulerVec3);\r\n Quaternion.FromEulerVectorToRef(eulerVec3, rotationQuaternion);\r\n }\r\n\r\n if (isCamera) {\r\n ConvertCameraRotationToGLTF(rotationQuaternion);\r\n } else {\r\n if (!Quaternion.IsIdentity(rotationQuaternion)) {\r\n ConvertToRightHandedRotation(rotationQuaternion);\r\n }\r\n }\r\n\r\n rotationQuaternion.toArray(outputToWrite);\r\n break;\r\n }\r\n } else {\r\n switch (animationChannelTargetPath) {\r\n case AnimationChannelTargetPath.ROTATION:\r\n if (output.length === 4) {\r\n Quaternion.FromArrayToRef(output, 0, rotationQuaternion);\r\n } else {\r\n outputToWrite = new Array(4); // Will need 4, not 3, for a quaternion\r\n Vector3.FromArrayToRef(output, 0, eulerVec3);\r\n Quaternion.FromEulerVectorToRef(eulerVec3, rotationQuaternion);\r\n }\r\n\r\n if (isCamera) {\r\n ConvertCameraRotationToGLTF(rotationQuaternion);\r\n }\r\n\r\n rotationQuaternion.toArray(outputToWrite);\r\n break;\r\n }\r\n }\r\n outputData.set(outputToWrite, index * elementCount);\r\n });\r\n\r\n // Create buffer view and accessor for keyed values.\r\n bufferView = bufferManager.createBufferView(outputData);\r\n accessor = bufferManager.createAccessor(bufferView, dataAccessorType, AccessorComponentType.FLOAT, animationData.outputs.length);\r\n accessors.push(accessor);\r\n dataAccessorIndex = accessors.length - 1;\r\n\r\n // create sampler\r\n animationSampler = {\r\n interpolation: animationData.samplerInterpolation,\r\n input: keyframeAccessorIndex,\r\n output: dataAccessorIndex,\r\n };\r\n glTFAnimation.samplers.push(animationSampler);\r\n\r\n // create channel\r\n animationChannel = {\r\n sampler: glTFAnimation.samplers.length - 1,\r\n target: {\r\n node: nodeIndex,\r\n path: animationChannelTargetPath,\r\n },\r\n };\r\n glTFAnimation.channels.push(animationChannel);\r\n }\r\n }\r\n\r\n /**\r\n * Create a baked animation\r\n * @param babylonTransformNode BabylonJS mesh\r\n * @param animation BabylonJS animation corresponding to the BabylonJS mesh\r\n * @param animationChannelTargetPath animation target channel\r\n * @param minFrame minimum animation frame\r\n * @param maxFrame maximum animation frame\r\n * @param fps frames per second of the animation\r\n * @param sampleRate\r\n * @param inputs input key frames of the animation\r\n * @param outputs output key frame data of the animation\r\n * @param minMaxFrames\r\n * @param minMaxFrames.min\r\n * @param minMaxFrames.max\r\n * @param useQuaternion specifies if quaternions should be used\r\n */\r\n private static _CreateBakedAnimation(\r\n babylonTransformNode: Node,\r\n animation: Animation,\r\n animationChannelTargetPath: AnimationChannelTargetPath,\r\n minFrame: number,\r\n maxFrame: number,\r\n fps: number,\r\n sampleRate: number,\r\n inputs: number[],\r\n outputs: number[][],\r\n minMaxFrames: { min: number; max: number },\r\n useQuaternion: boolean\r\n ) {\r\n let value: number | Vector3 | Quaternion;\r\n const quaternionCache: Quaternion = Quaternion.Identity();\r\n let previousTime: Nullable<number> = null;\r\n let time: number;\r\n let maxUsedFrame: Nullable<number> = null;\r\n let currKeyFrame: Nullable<IAnimationKey> = null;\r\n let nextKeyFrame: Nullable<IAnimationKey> = null;\r\n let prevKeyFrame: Nullable<IAnimationKey> = null;\r\n let endFrame: Nullable<number> = null;\r\n minMaxFrames.min = Tools.FloatRound(minFrame / fps);\r\n\r\n const keyFrames = animation.getKeys();\r\n\r\n for (let i = 0, length = keyFrames.length; i < length; ++i) {\r\n endFrame = null;\r\n currKeyFrame = keyFrames[i];\r\n\r\n if (i + 1 < length) {\r\n nextKeyFrame = keyFrames[i + 1];\r\n if ((currKeyFrame.value.equals && currKeyFrame.value.equals(nextKeyFrame.value)) || currKeyFrame.value === nextKeyFrame.value) {\r\n if (i === 0) {\r\n // set the first frame to itself\r\n endFrame = currKeyFrame.frame;\r\n } else {\r\n continue;\r\n }\r\n } else {\r\n endFrame = nextKeyFrame.frame;\r\n }\r\n } else {\r\n // at the last key frame\r\n prevKeyFrame = keyFrames[i - 1];\r\n if ((currKeyFrame.value.equals && currKeyFrame.value.equals(prevKeyFrame.value)) || currKeyFrame.value === prevKeyFrame.value) {\r\n continue;\r\n } else {\r\n endFrame = maxFrame;\r\n }\r\n }\r\n if (endFrame) {\r\n for (let f = currKeyFrame.frame; f <= endFrame; f += sampleRate) {\r\n time = Tools.FloatRound(f / fps);\r\n if (time === previousTime) {\r\n continue;\r\n }\r\n previousTime = time;\r\n maxUsedFrame = time;\r\n const state = {\r\n key: 0,\r\n repeatCount: 0,\r\n loopMode: animation.loopMode,\r\n };\r\n value = animation._interpolate(f, state);\r\n\r\n _GLTFAnimation._SetInterpolatedValue(babylonTransformNode, value, time, animation, animationChannelTargetPath, quaternionCache, inputs, outputs, useQuaternion);\r\n }\r\n }\r\n }\r\n if (maxUsedFrame) {\r\n minMaxFrames.max = maxUsedFrame;\r\n }\r\n }\r\n\r\n private static _ConvertFactorToVector3OrQuaternion(\r\n factor: number,\r\n babylonTransformNode: Node,\r\n animation: Animation,\r\n animationChannelTargetPath: AnimationChannelTargetPath,\r\n useQuaternion: boolean\r\n ): Vector3 | Quaternion {\r\n const basePositionRotationOrScale = _GLTFAnimation._GetBasePositionRotationOrScale(babylonTransformNode, animationChannelTargetPath, useQuaternion);\r\n // handles single component x, y, z or w component animation by using a base property and animating over a component.\r\n const property = animation.targetProperty.split(\".\");\r\n const componentName = property ? property[1] : \"\"; // x, y, z, or w component\r\n const value = useQuaternion ? Quaternion.FromArray(basePositionRotationOrScale).normalize() : Vector3.FromArray(basePositionRotationOrScale);\r\n\r\n switch (componentName) {\r\n case \"x\":\r\n case \"y\":\r\n case \"z\": {\r\n value[componentName] = factor;\r\n break;\r\n }\r\n case \"w\": {\r\n (value as Quaternion).w = factor;\r\n break;\r\n }\r\n default: {\r\n Tools.Error(`glTFAnimation: Unsupported component name \"${componentName}\"!`);\r\n }\r\n }\r\n\r\n return value;\r\n }\r\n\r\n private static _SetInterpolatedValue(\r\n babylonTransformNode: Node,\r\n value: number | Vector3 | Quaternion,\r\n time: number,\r\n animation: Animation,\r\n animationChannelTargetPath: AnimationChannelTargetPath,\r\n quaternionCache: Quaternion,\r\n inputs: number[],\r\n outputs: number[][],\r\n useQuaternion: boolean\r\n ) {\r\n let cacheValue: Vector3 | Quaternion | number;\r\n inputs.push(time);\r\n\r\n if (animationChannelTargetPath === AnimationChannelTargetPath.WEIGHTS) {\r\n outputs.push([value as number]);\r\n return;\r\n }\r\n\r\n if (animation.dataType === Animation.ANIMATIONTYPE_FLOAT) {\r\n value = this._ConvertFactorToVector3OrQuaternion(value as number, babylonTransformNode, animation, animationChannelTargetPath, useQuaternion);\r\n }\r\n\r\n if (animationChannelTargetPath === AnimationChannelTargetPath.ROTATION) {\r\n if (useQuaternion) {\r\n quaternionCache = value as Quaternion;\r\n } else {\r\n cacheValue = value as Vector3;\r\n Quaternion.RotationYawPitchRollToRef(cacheValue.y, cacheValue.x, cacheValue.z, quaternionCache);\r\n }\r\n outputs.push(quaternionCache.asArray());\r\n } else {\r\n // scaling and position animation\r\n cacheValue = value as Vector3;\r\n outputs.push(cacheValue.asArray());\r\n }\r\n }\r\n\r\n /**\r\n * Creates linear animation from the animation key frames\r\n * @param babylonTransformNode BabylonJS mesh\r\n * @param animation BabylonJS animation\r\n * @param animationChannelTargetPath The target animation channel\r\n * @param inputs Array to store the key frame times\r\n * @param outputs Array to store the key frame data\r\n * @param useQuaternion Specifies if quaternions are used in the animation\r\n */\r\n private static _CreateLinearOrStepAnimation(\r\n babylonTransformNode: Node,\r\n animation: Animation,\r\n animationChannelTargetPath: AnimationChannelTargetPath,\r\n inputs: number[],\r\n outputs: number[][],\r\n useQuaternion: boolean\r\n ) {\r\n for (const keyFrame of animation.getKeys()) {\r\n inputs.push(keyFrame.frame / animation.framePerSecond); // keyframes in seconds.\r\n _GLTFAnimation._AddKeyframeValue(keyFrame, animation, outputs, animationChannelTargetPath, babylonTransformNode, useQuaternion);\r\n }\r\n }\r\n\r\n /**\r\n * Creates cubic spline animation from the animation key frames\r\n * @param babylonTransformNode BabylonJS mesh\r\n * @param animation BabylonJS animation\r\n * @param animationChannelTargetPath The target animation channel\r\n * @param inputs Array to store the key frame times\r\n * @param outputs Array to store the key frame data\r\n * @param useQuaternion Specifies if quaternions are used in the animation\r\n */\r\n private static _CreateCubicSplineAnimation(\r\n babylonTransformNode: Node,\r\n animation: Animation,\r\n animationChannelTargetPath: AnimationChannelTargetPath,\r\n inputs: number[],\r\n outputs: number[][],\r\n useQuaternion: boolean\r\n ) {\r\n animation.getKeys().forEach(function (keyFrame) {\r\n inputs.push(keyFrame.frame / animation.framePerSecond); // keyframes in seconds.\r\n _GLTFAnimation._AddSplineTangent(_TangentType.INTANGENT, outputs, animationChannelTargetPath, AnimationSamplerInterpolation.CUBICSPLINE, keyFrame, useQuaternion);\r\n _GLTFAnimation._AddKeyframeValue(keyFrame, animation, outputs, animationChannelTargetPath, babylonTransformNode, useQuaternion);\r\n\r\n _GLTFAnimation._AddSplineTangent(_TangentType.OUTTANGENT, outputs, animationChannelTargetPath, AnimationSamplerInterpolation.CUBICSPLINE, keyFrame, useQuaternion);\r\n });\r\n }\r\n\r\n private static _GetBasePositionRotationOrScale(babylonTransformNode: Node, animationChannelTargetPath: AnimationChannelTargetPath, useQuaternion: boolean) {\r\n let basePositionRotationOrScale: number[];\r\n if (animationChannelTargetPath === AnimationChannelTargetPath.ROTATION) {\r\n if (useQuaternion) {\r\n const q = (babylonTransformNode as TransformNode).rotationQuaternion;\r\n basePositionRotationOrScale = (q ?? Quaternion.Identity()).asArray();\r\n } else {\r\n const r: Vector3 = (babylonTransformNode as TransformNode).rotation;\r\n basePositionRotationOrScale = (r ?? Vector3.Zero()).asArray();\r\n }\r\n } else if (animationChannelTargetPath === AnimationChannelTargetPath.TRANSLATION) {\r\n const p: Vector3 = (babylonTransformNode as TransformNode).position;\r\n basePositionRotationOrScale = (p ?? Vector3.Zero()).asArray();\r\n } else {\r\n // scale\r\n const s: Vector3 = (babylonTransformNode as TransformNode).scaling;\r\n basePositionRotationOrScale = (s ?? Vector3.One()).asArray();\r\n }\r\n return basePositionRotationOrScale;\r\n }\r\n\r\n /**\r\n * Adds a key frame value\r\n * @param keyFrame\r\n * @param animation\r\n * @param outputs\r\n * @param animationChannelTargetPath\r\n * @param babylonTransformNode\r\n * @param useQuaternion\r\n */\r\n private static _AddKeyframeValue(\r\n keyFrame: IAnimationKey,\r\n animation: Animation,\r\n outputs: number[][],\r\n animationChannelTargetPath: AnimationChannelTargetPath,\r\n babylonTransformNode: Node,\r\n useQuaternion: boolean\r\n ) {\r\n let newPositionRotationOrScale: Nullable<Vector3 | Quaternion | number>;\r\n const animationType = animation.dataType;\r\n if (animationType === Animation.ANIMATIONTYPE_VECTOR3) {\r\n let value = keyFrame.value.asArray();\r\n if (animationChannelTargetPath === AnimationChannelTargetPath.ROTATION) {\r\n const array = Vector3.FromArray(value);\r\n const rotationQuaternion = Quaternion.RotationYawPitchRoll(array.y, array.x, array.z);\r\n value = rotationQuaternion.asArray();\r\n }\r\n outputs.push(value); // scale vector.\r\n } else if (animationType === Animation.ANIMATIONTYPE_FLOAT) {\r\n if (animationChannelTargetPath === AnimationChannelTargetPath.WEIGHTS) {\r\n outputs.push([keyFrame.value]);\r\n } else {\r\n // handles single component x, y, z or w component animation by using a base property and animating over a component.\r\n newPositionRotationOrScale = this._ConvertFactorToVector3OrQuaternion(\r\n keyFrame.value as number,\r\n babylonTransformNode,\r\n animation,\r\n animationChannelTargetPath,\r\n useQuaternion\r\n );\r\n if (newPositionRotationOrScale) {\r\n if (animationChannelTargetPath === AnimationChannelTargetPath.ROTATION) {\r\n const posRotScale = useQuaternion\r\n ? (newPositionRotationOrScale as Quaternion)\r\n : Quaternion.RotationYawPitchRoll(newPositionRotationOrScale.y, newPositionRotationOrScale.x, newPositionRotationOrScale.z).normalize();\r\n outputs.push(posRotScale.asArray());\r\n }\r\n outputs.push(newPositionRotationOrScale.asArray());\r\n }\r\n }\r\n } else if (animationType === Animation.ANIMATIONTYPE_QUATERNION) {\r\n outputs.push((keyFrame.value as Quaternion).normalize().asArray());\r\n } else {\r\n Tools.Error(\"glTFAnimation: Unsupported key frame values for animation!\");\r\n }\r\n }\r\n\r\n /**\r\n * @internal\r\n * Determine the interpolation based on the key frames\r\n * @param keyFrames\r\n * @param animationChannelTargetPath\r\n * @param useQuaternion\r\n */\r\n private static _DeduceInterpolation(\r\n keyFrames: IAnimationKey[],\r\n animationChannelTargetPath: AnimationChannelTargetPath,\r\n useQuaternion: boolean\r\n ): { interpolationType: AnimationSamplerInterpolation; shouldBakeAnimation: boolean } {\r\n let interpolationType: AnimationSamplerInterpolation | undefined;\r\n let shouldBakeAnimation = false;\r\n let key: IAnimationKey;\r\n\r\n if (animationChannelTargetPath === AnimationChannelTargetPath.ROTATION && !useQuaternion) {\r\n return { interpolationType: AnimationSamplerInterpolation.LINEAR, shouldBakeAnimation: true };\r\n }\r\n\r\n for (let i = 0, length = keyFrames.length; i < length; ++i) {\r\n key = keyFrames[i];\r\n if (key.inTangent || key.outTangent) {\r\n if (interpolationType) {\r\n if (interpolationType !== AnimationSamplerInterpolation.CUBICSPLINE) {\r\n interpolationType = AnimationSamplerInterpolation.LINEAR;\r\n shouldBakeAnimation = true;\r\n break;\r\n }\r\n } else {\r\n interpolationType = AnimationSamplerInterpolation.CUBICSPLINE;\r\n }\r\n } else {\r\n if (interpolationType) {\r\n if (\r\n interpolationType === AnimationSamplerInterpolation.CUBICSPLINE ||\r\n (key.interpolation && key.interpolation === AnimationKeyInterpolation.STEP && interpolationType !== AnimationSamplerInterpolation.STEP)\r\n ) {\r\n interpolationType = AnimationSamplerInterpolation.LINEAR;\r\n shouldBakeAnimation = true;\r\n break;\r\n }\r\n } else {\r\n if (key.interpolation && key.interpolation === AnimationKeyInterpolation.STEP) {\r\n interpolationType = AnimationSamplerInterpolation.STEP;\r\n } else {\r\n interpolationType = AnimationSamplerInterpolation.LINEAR;\r\n }\r\n }\r\n }\r\n }\r\n if (!interpolationType) {\r\n interpolationType = AnimationSamplerInterpolation.LINEAR;\r\n }\r\n\r\n return { interpolationType: interpolationType, shouldBakeAnimation: shouldBakeAnimation };\r\n }\r\n\r\n /**\r\n * Adds an input tangent or output tangent to the output data\r\n * If an input tangent or output tangent is missing, it uses the zero vector or zero quaternion\r\n * @param tangentType Specifies which type of tangent to handle (inTangent or outTangent)\r\n * @param outputs The animation data by keyframe\r\n * @param animationChannelTargetPath The target animation channel\r\n * @param interpolation The interpolation type\r\n * @param keyFrame The key frame with the animation data\r\n * @param useQuaternion Specifies if quaternions are used\r\n */\r\n private static _AddSplineTangent(\r\n tangentType: _TangentType,\r\n outputs: number[][],\r\n animationChannelTargetPath: AnimationChannelTargetPath,\r\n interpolation: AnimationSamplerInterpolation,\r\n keyFrame: IAnimationKey,\r\n useQuaternion: boolean\r\n ) {\r\n let tangent: number[];\r\n const tangentValue: Vector3 | Quaternion | number = tangentType === _TangentType.INTANGENT ? keyFrame.inTangent : keyFrame.outTangent;\r\n if (interpolation === AnimationSamplerInterpolation.CUBICSPLINE) {\r\n if (animationChannelTargetPath === AnimationChannelTargetPath.ROTATION) {\r\n if (tangentValue) {\r\n if (useQuaternion) {\r\n tangent = (tangentValue as Quaternion).asArray();\r\n } else {\r\n const array = tangentValue as Vector3;\r\n tangent = Quaternion.RotationYawPitchRoll(array.y, array.x, array.z).asArray();\r\n }\r\n } else {\r\n tangent = [0, 0, 0, 0];\r\n }\r\n } else if (animationChannelTargetPath === AnimationChannelTargetPath.WEIGHTS) {\r\n if (tangentValue) {\r\n tangent = [tangentValue as number];\r\n } else {\r\n tangent = [0];\r\n }\r\n } else {\r\n if (tangentValue) {\r\n tangent = (tangentValue as Vector3).asArray();\r\n } else {\r\n tangent = [0, 0, 0];\r\n }\r\n }\r\n\r\n outputs.push(tangent);\r\n }\r\n }\r\n\r\n /**\r\n * Get the minimum and maximum key frames' frame values\r\n * @param keyFrames animation key frames\r\n * @returns the minimum and maximum key frame value\r\n */\r\n private static _CalculateMinMaxKeyFrames(keyFrames: IAnimationKey[]): { min: number; max: number } {\r\n let min: number = Infinity;\r\n let max: number = -Infinity;\r\n keyFrames.forEach(function (keyFrame) {\r\n min = Math.min(min, keyFrame.frame);\r\n max = Math.max(max, keyFrame.frame);\r\n });\r\n\r\n return { min: min, max: max };\r\n }\r\n}\r\n","import type { IBufferView, IAccessor } from \"babylonjs-gltf2interface\";\r\nimport { AccessorComponentType, AccessorType } from \"babylonjs-gltf2interface\";\r\nimport type { MorphTarget } from \"core/Morph/morphTarget\";\r\nimport type { BufferManager } from \"./bufferManager\";\r\n\r\nimport { NormalizeTangent } from \"./glTFUtilities\";\r\nimport type { AbstractMesh } from \"core/Meshes/abstractMesh\";\r\nimport { VertexBuffer } from \"core/Buffers/buffer\";\r\nimport { Vector3, Vector4 } from \"core/Maths/math.vector\";\r\nimport { Tools } from \"core/Misc/tools\";\r\n\r\n/**\r\n * Interface to store morph target information.\r\n * @internal\r\n */\r\nexport interface IMorphTargetData {\r\n attributes: Record<string, number>;\r\n influence: number;\r\n name: string;\r\n}\r\n\r\nexport function BuildMorphTargetBuffers(\r\n morphTarget: MorphTarget,\r\n mesh: AbstractMesh,\r\n bufferManager: BufferManager,\r\n bufferViews: IBufferView[],\r\n accessors: IAccessor[],\r\n convertToRightHanded: boolean\r\n): IMorphTargetData {\r\n const result: IMorphTargetData = {\r\n attributes: {},\r\n influence: morphTarget.influence,\r\n name: morphTarget.name,\r\n };\r\n\r\n const geometry = mesh.geometry;\r\n if (!geometry) {\r\n Tools.Warn(\"Attempted to export morph target data from a mesh without geometry. This should not happen.\");\r\n return result;\r\n }\r\n\r\n const flipX = convertToRightHanded ? -1 : 1;\r\n const floatSize = 4;\r\n const difference = Vector3.Zero();\r\n let vertexStart = 0;\r\n let vertexCount = 0;\r\n\r\n if (morphTarget.hasPositions) {\r\n const morphPositions = morphTarget.getPositions()!;\r\n const originalPositions = geometry.getVerticesData(VertexBuffer.PositionKind); // Bypasses any instance data of mesh\r\n\r\n if (originalPositions) {\r\n const positionData = new Float32Array(originalPositions.length);\r\n const min = [Infinity, Infinity, Infinity];\r\n const max = [-Infinity, -Infinity, -Infinity];\r\n vertexCount = originalPositions.length / 3;\r\n vertexStart = 0;\r\n for (let i = vertexStart; i < vertexCount; ++i) {\r\n const originalPosition = Vector3.FromArray(originalPositions, i * 3);\r\n const morphPosition = Vector3.FromArray(morphPositions, i * 3);\r\n morphPosition.subtractToRef(originalPosition, difference);\r\n difference.x *= flipX;\r\n\r\n min[0] = Math.min(min[0], difference.x);\r\n max[0] = Math.max(max[0], difference.x);\r\n\r\n min[1] = Math.min(min[1], difference.y);\r\n max[1] = Math.max(max[1], difference.y);\r\n\r\n min[2] = Math.min(min[2], difference.z);\r\n max[2] = Math.max(max[2], difference.z);\r\n\r\n positionData[i * 3] = difference.x;\r\n positionData[i * 3 + 1] = difference.y;\r\n positionData[i * 3 + 2] = difference.z;\r\n }\r\n\r\n const bufferView = bufferManager.createBufferView(positionData, floatSize * 3);\r\n const accessor = bufferManager.createAccessor(bufferView, AccessorType.VEC3, AccessorComponentType.FLOAT, morphPositions.length / 3, 0, { min, max });\r\n accessors.push(accessor);\r\n result.attributes[\"POSITION\"] = accessors.length - 1;\r\n } else {\r\n Tools.Warn(`Morph target positions for mesh ${mesh.name} were not exported. Mesh does not have position vertex data`);\r\n }\r\n }\r\n\r\n if (morphTarget.hasNormals) {\r\n const morphNormals = morphTarget.getNormals()!;\r\n const originalNormals = geometry.getVerticesData(VertexBuffer.NormalKind);\r\n\r\n if (originalNormals) {\r\n const normalData = new Float32Array(originalNormals.length);\r\n vertexCount = originalNormals.length / 3;\r\n vertexStart = 0;\r\n for (let i = vertexStart; i < vertexCount; ++i) {\r\n const originalNormal = Vector3.FromArray(originalNormals, i * 3).normalize();\r\n const morphNormal = Vector3.FromArray(morphNormals, i * 3).normalize();\r\n morphNormal.subtractToRef(originalNormal, difference);\r\n\r\n normalData[i * 3] = difference.x * flipX;\r\n normalData[i * 3 + 1] = difference.y;\r\n normalData[i * 3 + 2] = difference.z;\r\n }\r\n\r\n const bufferView = bufferManager.createBufferView(normalData, floatSize * 3);\r\n const accessor = bufferManager.createAccessor(bufferView, AccessorType.VEC3, AccessorComponentType.FLOAT, morphNormals.length / 3, 0);\r\n accessors.push(accessor);\r\n result.attributes[\"NORMAL\"] = accessors.length - 1;\r\n } else {\r\n Tools.Warn(`Morph target normals for mesh ${mesh.name} were not exported. Mesh does not have normals vertex data`);\r\n }\r\n }\r\n\r\n if (morphTarget.hasTangents) {\r\n const morphTangents = morphTarget.getTangents()!;\r\n const originalTangents = geometry.getVerticesData(VertexBuffer.TangentKind);\r\n\r\n if (originalTangents) {\r\n vertexCount = originalTangents.length / 4;\r\n const tangentData = new Float32Array(vertexCount * 3);\r\n vertexStart = 0;\r\n for (let i = vertexStart; i < vertexCount; ++i) {\r\n // Only read the x, y, z components and ignore w\r\n const originalTangent = Vector3.FromArray(originalTangents, i * 4);\r\n NormalizeTangent(originalTangent);\r\n\r\n // Morph target tangents omit the w component so it won't be present in the data\r\n const morphTangent = Vector3.FromArray(morphTangents, i * 3);\r\n NormalizeTangent(morphTangent);\r\n\r\n morphTangent.subtractToRef(originalTangent, difference);\r\n tangentData[i * 3] = difference.x * flipX;\r\n tangentData[i * 3 + 1] = difference.y;\r\n tangentData[i * 3 + 2] = difference.z;\r\n }\r\n const bufferView = bufferManager.createBufferView(tangentData, floatSize * 3);\r\n const accessor = bufferManager.createAccessor(bufferView, AccessorType.VEC3, AccessorComponentType.FLOAT, vertexCount, 0);\r\n accessors.push(accessor);\r\n result.attributes[\"TANGENT\"] = accessors.length - 1;\r\n } else {\r\n Tools.Warn(`Morph target tangents for mesh ${mesh.name} were not exported. Mesh does not have tangents vertex data`);\r\n }\r\n }\r\n\r\n if (morphTarget.hasColors) {\r\n const morphColors = morphTarget.getColors()!;\r\n const originalColors = geometry.getVerticesData(VertexBuffer.ColorKind);\r\n const buffer = geometry.getVertexBuffer(VertexBuffer.ColorKind);\r\n\r\n if (originalColors && buffer) {\r\n const componentSize = buffer.getSize();\r\n\r\n vertexCount = originalColors.length / componentSize;\r\n const colorData = new Float32Array(vertexCount * componentSize);\r\n vertexStart = 0;\r\n for (let i = vertexStart; i < vertexCount; ++i) {\r\n if (componentSize === 3) {\r\n const originalColor = Vector3.FromArray(originalColors, i * componentSize);\r\n const morphColor = Vector3.FromArray(morphColors, i * componentSize);\r\n\r\n morphColor.subtractToRef(originalColor, difference);\r\n colorData[i * 3] = difference.x;\r\n colorData[i * 3 + 1] = difference.y;\r\n colorData[i * 3 + 2] = difference.z;\r\n } else if (componentSize === 4) {\r\n const difference4 = new Vector4();\r\n const originalColor = Vector4.FromArray(originalColors, i * componentSize);\r\n const morphColor = Vector4.FromArray(morphColors, i * componentSize);\r\n\r\n morphColor.subtractToRef(originalColor, difference4);\r\n colorData[i * 4] = difference4.x;\r\n colorData[i * 4 + 1] = difference4.y;\r\n colorData[i * 4 + 2] = difference4.z;\r\n colorData[i * 4 + 3] = difference4.w;\r\n } else {\r\n Tools.Warn(`Unsupported number of components for color attribute: ${componentSize}`);\r\n }\r\n }\r\n const bufferView = bufferManager.createBufferView(colorData, floatSize * componentSize);\r\n const accessor = bufferManager.createAccessor(bufferView, componentSize === 3 ? AccessorType.VEC3 : AccessorType.VEC4, AccessorComponentType.FLOAT, vertexCount, 0);\r\n accessors.push(accessor);\r\n result.attributes[\"COLOR_0\"] = accessors.length - 1;\r\n } else {\r\n Tools.Warn(`Morph target colors for mesh ${mesh.name} were not exported. Mesh does not have colors vertex data`);\r\n }\r\n }\r\n\r\n return result;\r\n}\r\n","import type {\r\n IBufferView,\r\n IAccessor,\r\n INode,\r\n IScene,\r\n IMesh,\r\n IMaterial,\r\n ITexture,\r\n IImage,\r\n ISampler,\r\n IAnimation,\r\n IMeshPrimitive,\r\n IBuffer,\r\n IGLTF,\r\n ITextureInfo,\r\n ISkin,\r\n ICamera,\r\n} from \"babylonjs-gltf2interface\";\r\nimport { AccessorComponentType, AccessorType, CameraType, ImageMimeType } from \"babylonjs-gltf2interface\";\r\n\r\nimport type { FloatArray, IndicesArray, Nullable } from \"core/types\";\r\nimport { TmpVectors, Quaternion, Matrix } from \"core/Maths/math.vector\";\r\nimport { Tools } from \"core/Misc/tools\";\r\nimport type { Buffer } from \"core/Buffers/buffer\";\r\nimport { VertexBuffer } from \"core/Buffers/buffer\";\r\nimport type { Node } from \"core/node\";\r\nimport { TransformNode } from \"core/Meshes/transformNode\";\r\nimport type { SubMesh } from \"core/Meshes/subMesh\";\r\nimport type { Mesh } from \"core/Meshes/mesh\";\r\nimport { AbstractMesh } from \"core/Meshes/abstractMesh\";\r\nimport { InstancedMesh } from \"core/Meshes/instancedMesh\";\r\nimport type { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\nimport type { Texture } from \"core/Materials/Textures/texture\";\r\nimport { Material } from \"core/Materials/material\";\r\nimport { Engine } from \"core/Engines/engine\";\r\nimport type { Scene } from \"core/scene\";\r\nimport { EngineStore } from \"core/Engines/engineStore\";\r\n\r\nimport type { IGLTFExporterExtensionV2 } from \"./glTFExporterExtension\";\r\nimport { GLTFMaterialExporter } from \"./glTFMaterialExporter\";\r\nimport type { IExportOptions } from \"./glTFSerializer\";\r\nimport { GLTFData } from \"./glTFData\";\r\nimport {\r\n ConvertToRightHandedPosition,\r\n ConvertToRightHandedRotation,\r\n DataArrayToUint8Array,\r\n GetAccessorType,\r\n GetAttributeType,\r\n GetMinMax,\r\n GetPrimitiveMode,\r\n IsNoopNode,\r\n IsTriangleFillMode,\r\n IsParentAddedByImporter,\r\n ConvertToRightHandedNode,\r\n RotateNode180Y,\r\n FloatsNeed16BitInteger,\r\n IsStandardVertexAttribute,\r\n IndicesArrayToTypedArray,\r\n GetVertexBufferInfo,\r\n} from \"./glTFUtilities\";\r\nimport { BufferManager } from \"./bufferManager\";\r\nimport { Camera } from \"core/Cameras/camera\";\r\nimport { MultiMaterial } from \"core/Materials/multiMaterial\";\r\nimport { PBRMaterial } from \"core/Materials/PBR/pbrMaterial\";\r\nimport { StandardMaterial } from \"core/Materials/standardMaterial\";\r\nimport { Logger } from \"core/Misc/logger\";\r\nimport { EnumerateFloatValues, AreIndices32Bits } from \"core/Buffers/bufferUtils\";\r\nimport type { Bone, Skeleton } from \"core/Bones\";\r\nimport { _GLTFAnimation } from \"./glTFAnimation\";\r\nimport type { MorphTarget } from \"core/Morph\";\r\nimport { BuildMorphTargetBuffers } from \"./glTFMorphTargetsUtilities\";\r\nimport type { IMorphTargetData } from \"./glTFMorphTargetsUtilities\";\r\nimport { LinesMesh } from \"core/Meshes/linesMesh\";\r\nimport { GreasedLineBaseMesh } from \"core/Meshes/GreasedLine/greasedLineBaseMesh\";\r\nimport { Color3, Color4 } from \"core/Maths/math.color\";\r\n\r\nclass ExporterState {\r\n // Babylon indices array, start, count, offset, flip -> glTF accessor index\r\n private _indicesAccessorMap = new Map<Nullable<IndicesArray>, Map<number, Map<number, Map<number, Map<boolean, number>>>>>();\r\n\r\n // Babylon buffer -> glTF buffer view\r\n private _vertexBufferViewMap = new Map<Buffer, IBufferView>();\r\n\r\n // Babylon vertex buffer, start, count -> glTF accessor index\r\n private _vertexAccessorMap = new Map<VertexBuffer, Map<number, Map<number, number>>>();\r\n\r\n private _remappedBufferView = new Map<Buffer, Map<VertexBuffer, IBufferView>>();\r\n\r\n private _meshMorphTargetMap = new Map<AbstractMesh, IMorphTargetData[]>();\r\n\r\n private _vertexMapColorAlpha = new Map<VertexBuffer, boolean>();\r\n\r\n private _exportedNodes = new Set<Node>();\r\n\r\n // Babylon mesh -> glTF mesh index\r\n private _meshMap = new Map<AbstractMesh, number>();\r\n\r\n public constructor(convertToRightHanded: boolean, wasAddedByNoopNode: boolean) {\r\n this.convertToRightHanded = convertToRightHanded;\r\n this.wasAddedByNoopNode = wasAddedByNoopNode;\r\n }\r\n\r\n public readonly convertToRightHanded: boolean;\r\n\r\n public readonly wasAddedByNoopNode: boolean;\r\n\r\n // Only used when convertToRightHanded is true.\r\n public readonly convertedToRightHandedBuffers = new Map<Buffer, Uint8Array>();\r\n\r\n public getIndicesAccessor(indices: Nullable<IndicesArray>, start: number, count: number, offset: number, flip: boolean): number | undefined {\r\n return this._indicesAccessorMap.get(indices)?.get(start)?.get(count)?.get(offset)?.get(flip);\r\n }\r\n\r\n public setIndicesAccessor(indices: Nullable<IndicesArray>, start: number, count: number, offset: number, flip: boolean, accessorIndex: number): void {\r\n let map1 = this._indicesAccessorMap.get(indices);\r\n if (!map1) {\r\n map1 = new Map<number, Map<number, Map<number, Map<boolean, number>>>>();\r\n this._indicesAccessorMap.set(indices, map1);\r\n }\r\n\r\n let map2 = map1.get(start);\r\n if (!map2) {\r\n map2 = new Map<number, Map<number, Map<boolean, number>>>();\r\n map1.set(start, map2);\r\n }\r\n\r\n let map3 = map2.get(count);\r\n if (!map3) {\r\n map3 = new Map<number, Map<boolean, number>>();\r\n map2.set(count, map3);\r\n }\r\n\r\n let map4 = map3.get(offset);\r\n if (!map4) {\r\n map4 = new Map<boolean, number>();\r\n map3.set(offset, map4);\r\n }\r\n\r\n map4.set(flip, accessorIndex);\r\n }\r\n\r\n public pushExportedNode(node: Node) {\r\n if (!this._exportedNodes.has(node)) {\r\n this._exportedNodes.add(node);\r\n }\r\n }\r\n\r\n public getNodesSet(): Set<Node> {\r\n return this._exportedNodes;\r\n }\r\n\r\n public getVertexBufferView(buffer: Buffer): IBufferView | undefined {\r\n return this._vertexBufferViewMap.get(buffer);\r\n }\r\n\r\n public setVertexBufferView(buffer: Buffer, bufferView: IBufferView): void {\r\n this._vertexBufferViewMap.set(buffer, bufferView);\r\n }\r\n\r\n public setRemappedBufferView(buffer: Buffer, vertexBuffer: VertexBuffer, bufferView: IBufferView) {\r\n this._remappedBufferView.set(buffer, new Map<VertexBuffer, IBufferView>());\r\n this._remappedBufferView.get(buffer)!.set(vertexBuffer, bufferView);\r\n }\r\n\r\n public getRemappedBufferView(buffer: Buffer, vertexBuffer: VertexBuffer): IBufferView | undefined {\r\n return this._remappedBufferView.get(buffer)?.get(vertexBuffer);\r\n }\r\n\r\n public getVertexAccessor(vertexBuffer: VertexBuffer, start: number, count: number): number | undefined {\r\n return this._vertexAccessorMap.get(vertexBuffer)?.get(start)?.get(count);\r\n }\r\n\r\n public setVertexAccessor(vertexBuffer: VertexBuffer, start: number, count: number, accessorIndex: number): void {\r\n let map1 = this._vertexAccessorMap.get(vertexBuffer);\r\n if (!map1) {\r\n map1 = new Map<number, Map<number, number>>();\r\n this._vertexAccessorMap.set(vertexBuffer, map1);\r\n }\r\n\r\n let map2 = map1.get(start);\r\n if (!map2) {\r\n map2 = new Map<number, number>();\r\n map1.set(start, map2);\r\n }\r\n\r\n map2.set(count, accessorIndex);\r\n }\r\n\r\n public hasVertexColorAlpha(vertexBuffer: VertexBuffer): boolean {\r\n return this._vertexMapColorAlpha.get(vertexBuffer) || false;\r\n }\r\n\r\n public setHasVertexColorAlpha(vertexBuffer: VertexBuffer, hasAlpha: boolean) {\r\n return this._vertexMapColorAlpha.set(vertexBuffer, hasAlpha);\r\n }\r\n\r\n public getMesh(mesh: AbstractMesh): number | undefined {\r\n return this._meshMap.get(mesh);\r\n }\r\n\r\n public setMesh(mesh: AbstractMesh, meshIndex: number): void {\r\n this._meshMap.set(mesh, meshIndex);\r\n }\r\n\r\n public bindMorphDataToMesh(mesh: AbstractMesh, morphData: IMorphTargetData) {\r\n const morphTargets = this._meshMorphTargetMap.get(mesh) || [];\r\n this._meshMorphTargetMap.set(mesh, morphTargets);\r\n if (morphTargets.indexOf(morphData) === -1) {\r\n morphTargets.push(morphData);\r\n }\r\n }\r\n\r\n public getMorphTargetsFromMesh(mesh: AbstractMesh): IMorphTargetData[] | undefined {\r\n return this._meshMorphTargetMap.get(mesh);\r\n }\r\n}\r\n\r\n/** @internal */\r\nexport class GLTFExporter {\r\n public readonly _glTF: IGLTF = {\r\n asset: { generator: `Babylon.js v${Engine.Version}`, version: \"2.0\" },\r\n };\r\n\r\n public readonly _animations: IAnimation[] = [];\r\n public readonly _accessors: IAccessor[] = [];\r\n public readonly _bufferViews: IBufferView[] = [];\r\n public readonly _cameras: ICamera[] = [];\r\n public readonly _images: IImage[] = [];\r\n public readonly _materials: IMaterial[] = [];\r\n public readonly _meshes: IMesh[] = [];\r\n public readonly _nodes: INode[] = [];\r\n public readonly _samplers: ISampler[] = [];\r\n public readonly _scenes: IScene[] = [];\r\n public readonly _skins: ISkin[] = [];\r\n public readonly _textures: ITexture[] = [];\r\n\r\n public readonly _babylonScene: Scene;\r\n public readonly _imageData: { [fileName: string]: { data: ArrayBuffer; mimeType: ImageMimeType } } = {};\r\n\r\n /**\r\n * Baked animation sample rate\r\n */\r\n private _animationSampleRate: number;\r\n\r\n private readonly _options: Required<IExportOptions>;\r\n\r\n public _shouldUseGlb: boolean = false;\r\n\r\n public readonly _materialExporter = new GLTFMaterialExporter(this);\r\n\r\n private readonly _extensions: { [name: string]: IGLTFExporterExtensionV2 } = {};\r\n\r\n public readonly _bufferManager = new BufferManager();\r\n\r\n private readonly _shouldExportNodeMap = new Map<Node, boolean>();\r\n\r\n // Babylon node -> glTF node index\r\n private readonly _nodeMap = new Map<Node, number>();\r\n\r\n // Babylon material -> glTF material index\r\n public readonly _materialMap = new Map<Material, number>();\r\n private readonly _camerasMap = new Map<Camera, ICamera>();\r\n private readonly _nodesCameraMap = new Map<ICamera, INode[]>();\r\n private readonly _skinMap = new Map<Skeleton, ISkin>();\r\n private readonly _nodesSkinMap = new Map<ISkin, INode[]>();\r\n\r\n // A material in this set requires UVs\r\n public readonly _materialNeedsUVsSet = new Set<Material>();\r\n\r\n private static readonly _ExtensionNames = new Array<string>();\r\n private static readonly _ExtensionFactories: { [name: string]: (exporter: GLTFExporter) => IGLTFExporterExtensionV2 } = {};\r\n\r\n // eslint-disable-next-line @typescript-eslint/naming-convention, @typescript-eslint/promise-function-async\r\n private _ApplyExtension<T>(\r\n node: T,\r\n extensions: IGLTFExporterExtensionV2[],\r\n index: number,\r\n actionAsync: (extension: IGLTFExporterExtensionV2, node: T) => Promise<Nullable<T>> | undefined\r\n ): Promise<Nullable<T>> {\r\n if (index >= extensions.length) {\r\n return Promise.resolve(node);\r\n }\r\n\r\n const currentPromise = actionAsync(extensions[index], node);\r\n\r\n if (!currentPromise) {\r\n return this._ApplyExtension(node, extensions, index + 1, actionAsync);\r\n }\r\n\r\n // eslint-disable-next-line github/no-then\r\n return currentPromise.then(async (newNode) => (newNode ? await this._ApplyExtension(newNode, extensions, index + 1, actionAsync) : null));\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/naming-convention, @typescript-eslint/promise-function-async\r\n private _ApplyExtensions<T>(node: T, actionAsync: (extension: IGLTFExporterExtensionV2, node: T) => Promise<Nullable<T>> | undefined): Promise<Nullable<T>> {\r\n const extensions: IGLTFExporterExtensionV2[] = [];\r\n for (const name of GLTFExporter._ExtensionNames) {\r\n extensions.push(this._extensions[name]);\r\n }\r\n\r\n return this._ApplyExtension(node, extensions, 0, actionAsync);\r\n }\r\n\r\n // eslint-disable-next-line no-restricted-syntax, @typescript-eslint/promise-function-async\r\n public _extensionsPreExportTextureAsync(context: string, babylonTexture: Texture, mimeType: ImageMimeType): Promise<Nullable<BaseTexture>> {\r\n // eslint-disable-next-line @typescript-eslint/promise-function-async\r\n return this._ApplyExtensions(babylonTexture, (extension, node) => extension.preExportTextureAsync && extension.preExportTextureAsync(context, node, mimeType));\r\n }\r\n\r\n // eslint-disable-next-line no-restricted-syntax, @typescript-eslint/promise-function-async\r\n public _extensionsPostExportNodeAsync(context: string, node: INode, babylonNode: Node, nodeMap: Map<Node, number>, convertToRightHanded: boolean): Promise<Nullable<INode>> {\r\n return this._ApplyExtensions(\r\n node,\r\n // eslint-disable-next-line @typescript-eslint/promise-function-async\r\n (extension, node) => extension.postExportNodeAsync && extension.postExportNodeAsync(context, node, babylonNode, nodeMap, convertToRightHanded, this._bufferManager)\r\n );\r\n }\r\n\r\n // eslint-disable-next-line no-restricted-syntax, @typescript-eslint/promise-function-async\r\n public _extensionsPostExportMaterialAsync(context: string, material: IMaterial, babylonMaterial: Material): Promise<Nullable<IMaterial>> {\r\n // eslint-disable-next-line @typescript-eslint/promise-function-async\r\n return this._ApplyExtensions(material, (extension, node) => extension.postExportMaterialAsync && extension.postExportMaterialAsync(context, node, babylonMaterial));\r\n }\r\n\r\n public _extensionsPostExportMaterialAdditionalTextures(context: string, material: IMaterial, babylonMaterial: Material): BaseTexture[] {\r\n const output: BaseTexture[] = [];\r\n\r\n for (const name of GLTFExporter._ExtensionNames) {\r\n const extension = this._extensions[name];\r\n\r\n if (extension.postExportMaterialAdditionalTextures) {\r\n output.push(...extension.postExportMaterialAdditionalTextures(context, material, babylonMaterial));\r\n }\r\n }\r\n\r\n return output;\r\n }\r\n\r\n public _extensionsPostExportTextures(context: string, textureInfo: ITextureInfo, babylonTexture: BaseTexture): void {\r\n for (const name of GLTFExporter._ExtensionNames) {\r\n const extension = this._extensions[name];\r\n\r\n if (extension.postExportTexture) {\r\n extension.postExportTexture(context, textureInfo, babylonTexture);\r\n }\r\n }\r\n }\r\n\r\n public _extensionsPostExportMeshPrimitive(primitive: IMeshPrimitive): void {\r\n for (const name of GLTFExporter._ExtensionNames) {\r\n const extension = this._extensions[name];\r\n\r\n if (extension.postExportMeshPrimitive) {\r\n extension.postExportMeshPrimitive(primitive, this._bufferManager, this._accessors);\r\n }\r\n }\r\n }\r\n\r\n public async _extensionsPreGenerateBinaryAsync(): Promise<void> {\r\n for (const name of GLTFExporter._ExtensionNames) {\r\n const extension = this._extensions[name];\r\n\r\n if (extension.preGenerateBinaryAsync) {\r\n // eslint-disable-next-line no-await-in-loop\r\n await extension.preGenerateBinaryAsync(this._bufferManager);\r\n }\r\n }\r\n }\r\n\r\n private _forEachExtensions(action: (extension: IGLTFExporterExtensionV2) => void): void {\r\n for (const name of GLTFExporter._ExtensionNames) {\r\n const extension = this._extensions[name];\r\n if (extension.enabled) {\r\n action(extension);\r\n }\r\n }\r\n }\r\n\r\n private _extensionsOnExporting(): void {\r\n this._forEachExtensions((extension) => {\r\n if (extension.wasUsed) {\r\n this._glTF.extensionsUsed ||= [];\r\n if (this._glTF.extensionsUsed.indexOf(extension.name) === -1) {\r\n this._glTF.extensionsUsed.push(extension.name);\r\n }\r\n\r\n if (extension.required) {\r\n this._glTF.extensionsRequired ||= [];\r\n if (this._glTF.extensionsRequired.indexOf(extension.name) === -1) {\r\n this._glTF.extensionsRequired.push(extension.name);\r\n }\r\n }\r\n\r\n this._glTF.extensions ||= {};\r\n if (extension.onExporting) {\r\n extension.onExporting();\r\n }\r\n }\r\n });\r\n }\r\n\r\n private _loadExtensions(): void {\r\n for (const name of GLTFExporter._ExtensionNames) {\r\n const extension = GLTFExporter._ExtensionFactories[name](this);\r\n this._extensions[name] = extension;\r\n }\r\n }\r\n\r\n public constructor(babylonScene: Nullable<Scene> = EngineStore.LastCreatedScene, options?: IExportOptions) {\r\n if (!babylonScene) {\r\n throw new Error(\"No scene available to export\");\r\n }\r\n\r\n this._babylonScene = babylonScene;\r\n\r\n this._options = {\r\n shouldExportNode: () => true,\r\n shouldExportAnimation: () => true,\r\n metadataSelector: (metadata) => metadata?.gltf?.extras,\r\n animationSampleRate: 1 / 60,\r\n exportWithoutWaitingForScene: false,\r\n exportUnusedUVs: false,\r\n removeNoopRootNodes: true,\r\n includeCoordinateSystemConversionNodes: false,\r\n meshCompressionMethod: \"None\",\r\n ...options,\r\n };\r\n\r\n this._loadExtensions();\r\n }\r\n\r\n public dispose() {\r\n for (const key in this._extensions) {\r\n const extension = this._extensions[key];\r\n extension.dispose();\r\n }\r\n }\r\n\r\n public get options() {\r\n return this._options;\r\n }\r\n\r\n public static RegisterExtension(name: string, factory: (exporter: GLTFExporter) => IGLTFExporterExtensionV2): void {\r\n if (GLTFExporter.UnregisterExtension(name)) {\r\n Tools.Warn(`Extension with the name ${name} already exists`);\r\n }\r\n\r\n GLTFExporter._ExtensionFactories[name] = factory;\r\n GLTFExporter._ExtensionNames.push(name);\r\n }\r\n\r\n public static UnregisterExtension(name: string): boolean {\r\n if (!GLTFExporter._ExtensionFactories[name]) {\r\n return false;\r\n }\r\n delete GLTFExporter._ExtensionFactories[name];\r\n\r\n const index = GLTFExporter._ExtensionNames.indexOf(name);\r\n if (index !== -1) {\r\n GLTFExporter._ExtensionNames.splice(index, 1);\r\n }\r\n\r\n return true;\r\n }\r\n\r\n private _generateJSON(bufferByteLength: number, fileName?: string, prettyPrint?: boolean): string {\r\n const buffer: IBuffer = { byteLength: bufferByteLength };\r\n\r\n if (buffer.byteLength) {\r\n this._glTF.buffers = [buffer];\r\n }\r\n if (this._nodes && this._nodes.length) {\r\n this._glTF.nodes = this._nodes;\r\n }\r\n if (this._meshes && this._meshes.length) {\r\n this._glTF.meshes = this._meshes;\r\n }\r\n if (this._scenes && this._scenes.length) {\r\n this._glTF.scenes = this._scenes;\r\n this._glTF.scene = 0;\r\n }\r\n if (this._cameras && this._cameras.length) {\r\n this._glTF.cameras = this._cameras;\r\n }\r\n if (this._bufferViews && this._bufferViews.length) {\r\n this._glTF.bufferViews = this._bufferViews;\r\n }\r\n if (this._accessors && this._accessors.length) {\r\n this._glTF.accessors = this._accessors;\r\n }\r\n if (this._animations && this._animations.length) {\r\n this._glTF.animations = this._animations;\r\n }\r\n if (this._materials && this._materials.length) {\r\n this._glTF.materials = this._materials;\r\n }\r\n if (this._textures && this._textures.length) {\r\n this._glTF.textures = this._textures;\r\n }\r\n if (this._samplers && this._samplers.length) {\r\n this._glTF.samplers = this._samplers;\r\n }\r\n if (this._skins && this._skins.length) {\r\n this._glTF.skins = this._skins;\r\n }\r\n if (this._images && this._images.length) {\r\n this._glTF.images = this._images;\r\n }\r\n\r\n if (!this._shouldUseGlb) {\r\n buffer.uri = fileName + \".bin\";\r\n }\r\n\r\n return prettyPrint ? JSON.stringify(this._glTF, null, 2) : JSON.stringify(this._glTF);\r\n }\r\n\r\n public async generateGLTFAsync(glTFPrefix: string): Promise<GLTFData> {\r\n const binaryBuffer = await this._generateBinaryAsync();\r\n\r\n this._extensionsOnExporting();\r\n const jsonText = this._generateJSON(binaryBuffer.byteLength, glTFPrefix, true);\r\n const bin = new Blob([binaryBuffer], { type: \"application/octet-stream\" });\r\n\r\n const glTFFileName = glTFPrefix + \".gltf\";\r\n const glTFBinFile = glTFPrefix + \".bin\";\r\n\r\n const container = new GLTFData();\r\n\r\n container.files[glTFFileName] = jsonText;\r\n container.files[glTFBinFile] = bin;\r\n\r\n if (this._imageData) {\r\n for (const image in this._imageData) {\r\n container.files[image] = new Blob([this._imageData[image].data], { type: this._imageData[image].mimeType });\r\n }\r\n }\r\n\r\n return container;\r\n }\r\n\r\n private async _generateBinaryAsync(): Promise<Uint8Array> {\r\n await this._exportSceneAsync();\r\n await this._extensionsPreGenerateBinaryAsync();\r\n return this._bufferManager.generateBinary(this._bufferViews);\r\n }\r\n\r\n /**\r\n * Pads the number to a multiple of 4\r\n * @param num number to pad\r\n * @returns padded number\r\n */\r\n private _getPadding(num: number): number {\r\n const remainder = num % 4;\r\n const padding = remainder === 0 ? remainder : 4 - remainder;\r\n\r\n return padding;\r\n }\r\n\r\n public async generateGLBAsync(glTFPrefix: string): Promise<GLTFData> {\r\n this._shouldUseGlb = true;\r\n const binaryBuffer = await this._generateBinaryAsync();\r\n\r\n this._extensionsOnExporting();\r\n const jsonText = this._generateJSON(binaryBuffer.byteLength);\r\n const glbFileName = glTFPrefix + \".glb\";\r\n const headerLength = 12;\r\n const chunkLengthPrefix = 8;\r\n let jsonLength = jsonText.length;\r\n let encodedJsonText;\r\n // make use of TextEncoder when available\r\n if (typeof TextEncoder !== \"undefined\") {\r\n const encoder = new TextEncoder();\r\n encodedJsonText = encoder.encode(jsonText);\r\n jsonLength = encodedJsonText.length;\r\n }\r\n const jsonPadding = this._getPadding(jsonLength);\r\n const binPadding = this._getPadding(binaryBuffer.byteLength);\r\n\r\n const byteLength = headerLength + 2 * chunkLengthPrefix + jsonLength + jsonPadding + binaryBuffer.byteLength + binPadding;\r\n\r\n // header\r\n const headerBuffer = new ArrayBuffer(headerLength);\r\n const headerBufferView = new DataView(headerBuffer);\r\n headerBufferView.setUint32(0, 0x46546c67, true); //glTF\r\n headerBufferView.setUint32(4, 2, true); // version\r\n headerBufferView.setUint32(8, byteLength, true); // total bytes in file\r\n\r\n // json chunk\r\n const jsonChunkBuffer = new ArrayBuffer(chunkLengthPrefix + jsonLength + jsonPadding);\r\n const jsonChunkBufferView = new DataView(jsonChunkBuffer);\r\n jsonChunkBufferView.setUint32(0, jsonLength + jsonPadding, true);\r\n jsonChunkBufferView.setUint32(4, 0x4e4f534a, true);\r\n\r\n // json chunk bytes\r\n const jsonData = new Uint8Array(jsonChunkBuffer, chunkLengthPrefix);\r\n // if TextEncoder was available, we can simply copy the encoded array\r\n if (encodedJsonText) {\r\n jsonData.set(encodedJsonText);\r\n } else {\r\n const blankCharCode = \"_\".charCodeAt(0);\r\n for (let i = 0; i < jsonLength; ++i) {\r\n const charCode = jsonText.charCodeAt(i);\r\n // if the character doesn't fit into a single UTF-16 code unit, just put a blank character\r\n if (charCode != jsonText.codePointAt(i)) {\r\n jsonData[i] = blankCharCode;\r\n } else {\r\n jsonData[i] = charCode;\r\n }\r\n }\r\n }\r\n\r\n // json padding\r\n const jsonPaddingView = new Uint8Array(jsonChunkBuffer, chunkLengthPrefix + jsonLength);\r\n for (let i = 0; i < jsonPadding; ++i) {\r\n jsonPaddingView[i] = 0x20;\r\n }\r\n\r\n // binary chunk\r\n const binaryChunkBuffer = new ArrayBuffer(chunkLengthPrefix);\r\n const binaryChunkBufferView = new DataView(binaryChunkBuffer);\r\n binaryChunkBufferView.setUint32(0, binaryBuffer.byteLength + binPadding, true);\r\n binaryChunkBufferView.setUint32(4, 0x004e4942, true);\r\n\r\n // binary padding\r\n const binPaddingBuffer = new ArrayBuffer(binPadding);\r\n const binPaddingView = new Uint8Array(binPaddingBuffer);\r\n for (let i = 0; i < binPadding; ++i) {\r\n binPaddingView[i] = 0;\r\n }\r\n\r\n const glbData = [headerBuffer, jsonChunkBuffer, binaryChunkBuffer, binaryBuffer, binPaddingBuffer];\r\n const glbFile = new Blob(glbData, { type: \"application/octet-stream\" });\r\n\r\n const container = new GLTFData();\r\n container.files[glbFileName] = glbFile;\r\n\r\n return container;\r\n }\r\n\r\n private _setNodeTransformation(node: INode, babylonTransformNode: TransformNode, convertToRightHanded: boolean): void {\r\n if (!babylonTransformNode.getPivotPoint().equalsToFloats(0, 0, 0)) {\r\n Tools.Warn(\"Pivot points are not supported in the glTF serializer\");\r\n }\r\n\r\n if (!babylonTransformNode.position.equalsToFloats(0, 0, 0)) {\r\n const translation = TmpVectors.Vector3[0].copyFrom(babylonTransformNode.position);\r\n if (convertToRightHanded) {\r\n ConvertToRightHandedPosition(translation);\r\n }\r\n\r\n node.translation = translation.asArray();\r\n }\r\n\r\n if (!babylonTransformNode.scaling.equalsToFloats(1, 1, 1)) {\r\n node.scale = babylonTransformNode.scaling.asArray();\r\n }\r\n\r\n const rotationQuaternion = Quaternion.FromEulerAngles(babylonTransformNode.rotation.x, babylonTransformNode.rotation.y, babylonTransformNode.rotation.z);\r\n if (babylonTransformNode.rotationQuaternion) {\r\n rotationQuaternion.multiplyInPlace(babylonTransformNode.rotationQuaternion);\r\n }\r\n if (!Quaternion.IsIdentity(rotationQuaternion)) {\r\n if (convertToRightHanded) {\r\n ConvertToRightHandedRotation(rotationQuaternion);\r\n }\r\n\r\n node.rotation = rotationQuaternion.normalize().asArray();\r\n }\r\n }\r\n\r\n private _setCameraTransformation(node: INode, babylonCamera: Camera, convertToRightHanded: boolean, parent: Nullable<Node>): void {\r\n const translation = TmpVectors.Vector3[0];\r\n const rotation = TmpVectors.Quaternion[0];\r\n\r\n if (parent !== null) {\r\n // Camera.getWorldMatrix returns global coordinates. GLTF node must use local coordinates. If camera has parent we need to use local translation/rotation.\r\n const parentWorldMatrix = Matrix.Invert(parent.getWorldMatrix());\r\n const cameraWorldMatrix = babylonCamera.getWorldMatrix();\r\n const cameraLocal = cameraWorldMatrix.multiply(parentWorldMatrix);\r\n cameraLocal.decompose(undefined, rotation, translation);\r\n } else {\r\n babylonCamera.getWorldMatrix().decompose(undefined, rotation, translation);\r\n }\r\n\r\n if (!translation.equalsToFloats(0, 0, 0)) {\r\n node.translation = translation.asArray();\r\n }\r\n\r\n if (!Quaternion.IsIdentity(rotation)) {\r\n node.rotation = rotation.asArray();\r\n }\r\n }\r\n\r\n // Export babylon cameras to glTF cameras\r\n private _listAvailableCameras(): void {\r\n for (const camera of this._babylonScene.cameras) {\r\n const glTFCamera: ICamera = {\r\n type: camera.mode === Camera.PERSPECTIVE_CAMERA ? CameraType.PERSPECTIVE : CameraType.ORTHOGRAPHIC,\r\n };\r\n\r\n if (camera.name) {\r\n glTFCamera.name = camera.name;\r\n }\r\n\r\n if (glTFCamera.type === CameraType.PERSPECTIVE) {\r\n glTFCamera.perspective = {\r\n aspectRatio: camera.getEngine().getAspectRatio(camera),\r\n yfov: camera.fovMode === Camera.FOVMODE_VERTICAL_FIXED ? camera.fov : camera.fov * camera.getEngine().getAspectRatio(camera),\r\n znear: camera.minZ,\r\n zfar: camera.maxZ,\r\n };\r\n } else if (glTFCamera.type === CameraType.ORTHOGRAPHIC) {\r\n const halfWidth = camera.orthoLeft && camera.orthoRight ? 0.5 * (camera.orthoRight - camera.orthoLeft) : camera.getEngine().getRenderWidth() * 0.5;\r\n const halfHeight = camera.orthoBottom && camera.orthoTop ? 0.5 * (camera.orthoTop - camera.orthoBottom) : camera.getEngine().getRenderHeight() * 0.5;\r\n glTFCamera.orthographic = {\r\n xmag: halfWidth,\r\n ymag: halfHeight,\r\n znear: camera.minZ,\r\n zfar: camera.maxZ,\r\n };\r\n }\r\n this._camerasMap.set(camera, glTFCamera);\r\n }\r\n }\r\n\r\n // Cleanup unused cameras and assign index to nodes.\r\n private _exportAndAssignCameras(): void {\r\n const gltfCameras = Array.from(this._camerasMap.values());\r\n for (const gltfCamera of gltfCameras) {\r\n const usedNodes = this._nodesCameraMap.get(gltfCamera);\r\n if (usedNodes !== undefined) {\r\n this._cameras.push(gltfCamera);\r\n for (const node of usedNodes) {\r\n node.camera = this._cameras.length - 1;\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Builds all skins in the skins array so nodes can reference it during node parsing.\r\n private _listAvailableSkeletons(): void {\r\n for (const skeleton of this._babylonScene.skeletons) {\r\n if (skeleton.bones.length <= 0) {\r\n continue;\r\n }\r\n\r\n const skin: ISkin = { joints: [] };\r\n this._skinMap.set(skeleton, skin);\r\n }\r\n }\r\n\r\n private _exportAndAssignSkeletons() {\r\n for (const skeleton of this._babylonScene.skeletons) {\r\n if (skeleton.bones.length <= 0) {\r\n continue;\r\n }\r\n\r\n const skin = this._skinMap.get(skeleton);\r\n\r\n if (skin == undefined) {\r\n continue;\r\n }\r\n\r\n const boneIndexMap: { [index: number]: Bone } = {};\r\n const inverseBindMatrices: Matrix[] = [];\r\n\r\n let maxBoneIndex = -1;\r\n for (let i = 0; i < skeleton.bones.length; ++i) {\r\n const bone = skeleton.bones[i];\r\n const boneIndex = bone.getIndex() ?? i;\r\n if (boneIndex !== -1) {\r\n boneIndexMap[boneIndex] = bone;\r\n if (boneIndex > maxBoneIndex) {\r\n maxBoneIndex = boneIndex;\r\n }\r\n }\r\n }\r\n\r\n // Set joints index to scene node.\r\n for (let boneIndex = 0; boneIndex <= maxBoneIndex; ++boneIndex) {\r\n const bone = boneIndexMap[boneIndex];\r\n inverseBindMatrices.push(bone.getAbsoluteInverseBindMatrix());\r\n const transformNode = bone.getTransformNode();\r\n\r\n if (transformNode !== null) {\r\n const nodeID = this._nodeMap.get(transformNode);\r\n if (transformNode && nodeID !== null && nodeID !== undefined) {\r\n skin.joints.push(nodeID);\r\n } else {\r\n Tools.Warn(\"Exporting a bone without a linked transform node is currently unsupported\");\r\n }\r\n } else {\r\n Tools.Warn(\"Exporting a bone without a linked transform node is currently unsupported\");\r\n }\r\n }\r\n\r\n // Nodes that use this skin.\r\n const skinedNodes = this._nodesSkinMap.get(skin);\r\n\r\n // Only create skeleton if it has at least one joint and is used by a mesh.\r\n if (skin.joints.length > 0 && skinedNodes !== undefined) {\r\n // Put IBM data into TypedArraybuffer view\r\n const byteLength = inverseBindMatrices.length * 64; // Always a 4 x 4 matrix of 32 bit float\r\n const inverseBindMatricesData = new Float32Array(byteLength / 4);\r\n inverseBindMatrices.forEach((mat: Matrix, index: number) => {\r\n inverseBindMatricesData.set(mat.m, index * 16);\r\n });\r\n // Create buffer view and accessor\r\n const bufferView = this._bufferManager.createBufferView(inverseBindMatricesData);\r\n this._accessors.push(this._bufferManager.createAccessor(bufferView, AccessorType.MAT4, AccessorComponentType.FLOAT, inverseBindMatrices.length));\r\n skin.inverseBindMatrices = this._accessors.length - 1;\r\n\r\n this._skins.push(skin);\r\n for (const skinedNode of skinedNodes) {\r\n skinedNode.skin = this._skins.length - 1;\r\n }\r\n }\r\n }\r\n }\r\n\r\n private async _exportSceneAsync(): Promise<void> {\r\n const scene: IScene = { nodes: [] };\r\n\r\n // Scene metadata\r\n if (this._babylonScene.metadata) {\r\n const extras = this._options.metadataSelector(this._babylonScene.metadata);\r\n if (extras) {\r\n scene.extras = extras;\r\n }\r\n }\r\n\r\n // TODO:\r\n // deal with this from the loader:\r\n // babylonMaterial.invertNormalMapX = !this._babylonScene.useRightHandedSystem;\r\n // babylonMaterial.invertNormalMapY = this._babylonScene.useRightHandedSystem;\r\n\r\n const rootNodesRH = new Array<Node>();\r\n const rootNodesLH = new Array<Node>();\r\n const rootNoopNodesRH = new Array<Node>();\r\n\r\n for (const rootNode of this._babylonScene.rootNodes) {\r\n if (this._options.removeNoopRootNodes && !this._options.includeCoordinateSystemConversionNodes && IsNoopNode(rootNode, this._babylonScene.useRightHandedSystem)) {\r\n rootNoopNodesRH.push(...rootNode.getChildren());\r\n } else if (this._babylonScene.useRightHandedSystem) {\r\n rootNodesRH.push(rootNode);\r\n } else {\r\n rootNodesLH.push(rootNode);\r\n }\r\n }\r\n\r\n this._listAvailableCameras();\r\n this._listAvailableSkeletons();\r\n\r\n const stateLH = new ExporterState(true, false);\r\n scene.nodes.push(...(await this._exportNodesAsync(rootNodesLH, stateLH)));\r\n const stateRH = new ExporterState(false, false);\r\n scene.nodes.push(...(await this._exportNodesAsync(rootNodesRH, stateRH)));\r\n const noopRH = new ExporterState(false, true);\r\n scene.nodes.push(...(await this._exportNodesAsync(rootNoopNodesRH, noopRH)));\r\n\r\n if (scene.nodes.length) {\r\n this._scenes.push(scene);\r\n }\r\n\r\n this._exportAndAssignCameras();\r\n this._exportAndAssignSkeletons();\r\n\r\n if (this._babylonScene.animationGroups.length) {\r\n _GLTFAnimation._CreateNodeAndMorphAnimationFromAnimationGroups(\r\n this._babylonScene,\r\n this._animations,\r\n this._nodeMap,\r\n this._bufferManager,\r\n this._bufferViews,\r\n this._accessors,\r\n this._animationSampleRate,\r\n stateLH.getNodesSet(),\r\n this._options.shouldExportAnimation\r\n );\r\n }\r\n }\r\n\r\n private _shouldExportNode(babylonNode: Node): boolean {\r\n let result = this._shouldExportNodeMap.get(babylonNode);\r\n\r\n if (result === undefined) {\r\n result = this._options.shouldExportNode(babylonNode);\r\n this._shouldExportNodeMap.set(babylonNode, result);\r\n }\r\n\r\n return result;\r\n }\r\n\r\n private async _exportNodesAsync(babylonRootNodes: Node[], state: ExporterState): Promise<number[]> {\r\n const nodes = new Array<number>();\r\n\r\n this._exportBuffers(babylonRootNodes, state);\r\n\r\n for (const babylonNode of babylonRootNodes) {\r\n // eslint-disable-next-line no-await-in-loop\r\n await this._exportNodeAsync(babylonNode, nodes, state);\r\n }\r\n\r\n return nodes;\r\n }\r\n\r\n private _collectBuffers(\r\n babylonNode: Node,\r\n bufferToVertexBuffersMap: Map<Buffer, VertexBuffer[]>,\r\n vertexBufferToMeshesMap: Map<VertexBuffer, AbstractMesh[]>,\r\n morphTargetsToMeshesMap: Map<MorphTarget, AbstractMesh[]>,\r\n state: ExporterState\r\n ): void {\r\n if (this._shouldExportNode(babylonNode) && babylonNode instanceof AbstractMesh && babylonNode.geometry) {\r\n const vertexBuffers = babylonNode.geometry.getVertexBuffers();\r\n if (vertexBuffers) {\r\n for (const kind in vertexBuffers) {\r\n if (!IsStandardVertexAttribute(kind)) {\r\n continue;\r\n }\r\n const vertexBuffer = vertexBuffers[kind];\r\n state.setHasVertexColorAlpha(vertexBuffer, babylonNode.hasVertexAlpha);\r\n const buffer = vertexBuffer._buffer;\r\n const vertexBufferArray = bufferToVertexBuffersMap.get(buffer) || [];\r\n bufferToVertexBuffersMap.set(buffer, vertexBufferArray);\r\n if (vertexBufferArray.indexOf(vertexBuffer) === -1) {\r\n vertexBufferArray.push(vertexBuffer);\r\n }\r\n\r\n const meshes = vertexBufferToMeshesMap.get(vertexBuffer) || [];\r\n vertexBufferToMeshesMap.set(vertexBuffer, meshes);\r\n if (meshes.indexOf(babylonNode) === -1) {\r\n meshes.push(babylonNode);\r\n }\r\n }\r\n }\r\n\r\n const morphTargetManager = babylonNode.morphTargetManager;\r\n\r\n if (morphTargetManager) {\r\n for (let morphIndex = 0; morphIndex < morphTargetManager.numTargets; morphIndex++) {\r\n const morphTarget = morphTargetManager.getTarget(morphIndex);\r\n\r\n const meshes = morphTargetsToMeshesMap.get(morphTarget) || [];\r\n morphTargetsToMeshesMap.set(morphTarget, meshes);\r\n if (meshes.indexOf(babylonNode) === -1) {\r\n meshes.push(babylonNode);\r\n }\r\n }\r\n }\r\n }\r\n\r\n for (const babylonChildNode of babylonNode.getChildren()) {\r\n this._collectBuffers(babylonChildNode, bufferToVertexBuffersMap, vertexBufferToMeshesMap, morphTargetsToMeshesMap, state);\r\n }\r\n }\r\n\r\n private _exportBuffers(babylonRootNodes: Node[], state: ExporterState): void {\r\n const bufferToVertexBuffersMap = new Map<Buffer, VertexBuffer[]>();\r\n const vertexBufferToMeshesMap = new Map<VertexBuffer, AbstractMesh[]>();\r\n const morphTargetsMeshesMap = new Map<MorphTarget, AbstractMesh[]>();\r\n\r\n for (const babylonNode of babylonRootNodes) {\r\n this._collectBuffers(babylonNode, bufferToVertexBuffersMap, vertexBufferToMeshesMap, morphTargetsMeshesMap, state);\r\n }\r\n\r\n const buffers = Array.from(bufferToVertexBuffersMap.keys());\r\n\r\n for (const buffer of buffers) {\r\n const data = buffer.getData();\r\n if (!data) {\r\n throw new Error(\"Buffer data is not available\");\r\n }\r\n\r\n const vertexBuffers = bufferToVertexBuffersMap.get(buffer);\r\n\r\n if (!vertexBuffers) {\r\n continue;\r\n }\r\n\r\n const byteStride = vertexBuffers[0].byteStride;\r\n if (vertexBuffers.some((vertexBuffer) => vertexBuffer.byteStride !== byteStride)) {\r\n throw new Error(\"Vertex buffers pointing to the same buffer must have the same byte stride\");\r\n }\r\n\r\n const bytes = DataArrayToUint8Array(data).slice();\r\n\r\n // Apply normalizations and color corrections to buffer data in-place.\r\n for (const vertexBuffer of vertexBuffers) {\r\n const meshes = vertexBufferToMeshesMap.get(vertexBuffer)!;\r\n const { byteOffset, byteStride, componentCount, type, count, normalized, kind } = GetVertexBufferInfo(vertexBuffer, meshes);\r\n\r\n switch (kind) {\r\n // Normalize normals and tangents.\r\n case VertexBuffer.NormalKind:\r\n case VertexBuffer.TangentKind: {\r\n EnumerateFloatValues(bytes, byteOffset, byteStride, componentCount, type, count, normalized, (values) => {\r\n const length = Math.sqrt(values[0] * values[0] + values[1] * values[1] + values[2] * values[2]);\r\n if (length > 0) {\r\n const invLength = 1 / length;\r\n values[0] *= invLength;\r\n values[1] *= invLength;\r\n values[2] *= invLength;\r\n }\r\n });\r\n break;\r\n }\r\n // Convert StandardMaterial vertex colors from gamma to linear space.\r\n case VertexBuffer.ColorKind: {\r\n const stdMaterialCount = meshes.filter((mesh) => mesh.material instanceof StandardMaterial || mesh.material == null).length;\r\n if (stdMaterialCount == 0) {\r\n break; // Buffer not used by StandardMaterials, so no conversion needed.\r\n }\r\n // TODO: Implement this case.\r\n if (stdMaterialCount != meshes.length) {\r\n Logger.Warn(\"Not converting vertex color space, as buffer is shared by StandardMaterials and other material types. Results may look incorrect.\");\r\n break;\r\n }\r\n if (type == VertexBuffer.UNSIGNED_BYTE) {\r\n Logger.Warn(\"Converting uint8 vertex colors to linear space. Results may look incorrect.\");\r\n }\r\n\r\n const vertexData3 = new Color3();\r\n const vertexData4 = new Color4();\r\n const useExactSrgbConversions = this._babylonScene.getEngine().useExactSrgbConversions;\r\n\r\n EnumerateFloatValues(bytes, byteOffset, byteStride, componentCount, type, count, normalized, (values) => {\r\n // Using separate Color3 and Color4 objects to ensure the right functions are called.\r\n if (values.length === 3) {\r\n vertexData3.fromArray(values, 0);\r\n vertexData3.toLinearSpaceToRef(vertexData3, useExactSrgbConversions);\r\n vertexData3.toArray(values, 0);\r\n } else {\r\n vertexData4.fromArray(values, 0);\r\n vertexData4.toLinearSpaceToRef(vertexData4, useExactSrgbConversions);\r\n vertexData4.toArray(values, 0);\r\n }\r\n });\r\n }\r\n }\r\n }\r\n\r\n // Perform coordinate conversions, if needed, to buffer data in-place (only for positions, normals and tangents).\r\n if (state.convertToRightHanded) {\r\n for (const vertexBuffer of vertexBuffers) {\r\n const meshes = vertexBufferToMeshesMap.get(vertexBuffer)!;\r\n const { byteOffset, byteStride, componentCount, type, count, normalized, kind } = GetVertexBufferInfo(vertexBuffer, meshes);\r\n\r\n switch (kind) {\r\n case VertexBuffer.PositionKind:\r\n case VertexBuffer.NormalKind:\r\n case VertexBuffer.TangentKind: {\r\n EnumerateFloatValues(bytes, byteOffset, byteStride, componentCount, type, count, normalized, (values) => {\r\n values[0] = -values[0];\r\n });\r\n }\r\n }\r\n }\r\n\r\n // Save converted bytes for min/max computation.\r\n state.convertedToRightHandedBuffers.set(buffer, bytes);\r\n }\r\n\r\n // Create buffer view, but defer accessor creation for later. Instead, track it via ExporterState.\r\n const bufferView = this._bufferManager.createBufferView(bytes, byteStride);\r\n state.setVertexBufferView(buffer, bufferView);\r\n\r\n const floatMatricesIndices = new Map<VertexBuffer, FloatArray>();\r\n\r\n // If buffers are of type MatricesIndicesKind and have float values, we need to create a new buffer instead.\r\n for (const vertexBuffer of vertexBuffers) {\r\n const meshes = vertexBufferToMeshesMap.get(vertexBuffer)!;\r\n const { kind, totalVertices } = GetVertexBufferInfo(vertexBuffer, meshes);\r\n switch (kind) {\r\n case VertexBuffer.MatricesIndicesKind:\r\n case VertexBuffer.MatricesIndicesExtraKind: {\r\n if (vertexBuffer.type == VertexBuffer.FLOAT) {\r\n const floatData = vertexBuffer.getFloatData(totalVertices);\r\n if (floatData !== null) {\r\n floatMatricesIndices.set(vertexBuffer, floatData);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n if (floatMatricesIndices.size !== 0) {\r\n Logger.Warn(\r\n `Joints conversion needed: some joints are stored as floats in Babylon but GLTF requires UNSIGNED BYTES. We will perform the conversion but this might lead to unused data in the buffer.`\r\n );\r\n }\r\n\r\n const floatArrayVertexBuffers = Array.from(floatMatricesIndices.keys());\r\n\r\n for (const vertexBuffer of floatArrayVertexBuffers) {\r\n const array = floatMatricesIndices.get(vertexBuffer);\r\n\r\n if (!array) {\r\n continue;\r\n }\r\n\r\n const is16Bit = FloatsNeed16BitInteger(array);\r\n const newArray = new (is16Bit ? Uint16Array : Uint8Array)(array.length);\r\n for (let index = 0; index < array.length; index++) {\r\n newArray[index] = array[index];\r\n }\r\n const bufferView = this._bufferManager.createBufferView(newArray, 4 * (is16Bit ? 2 : 1));\r\n state.setRemappedBufferView(buffer, vertexBuffer, bufferView);\r\n }\r\n }\r\n\r\n // Build morph targets buffers\r\n const morphTargets = Array.from(morphTargetsMeshesMap.keys());\r\n\r\n for (const morphTarget of morphTargets) {\r\n const meshes = morphTargetsMeshesMap.get(morphTarget);\r\n\r\n if (!meshes) {\r\n continue;\r\n }\r\n\r\n const glTFMorphTarget = BuildMorphTargetBuffers(morphTarget, meshes[0], this._bufferManager, this._bufferViews, this._accessors, state.convertToRightHanded);\r\n\r\n for (const mesh of meshes) {\r\n state.bindMorphDataToMesh(mesh, glTFMorphTarget);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Processes a node to be exported to the glTF file\r\n * @returns A promise that resolves once the node has been exported\r\n * @internal\r\n */\r\n private async _exportNodeAsync(babylonNode: Node, parentNodeChildren: Array<number>, state: ExporterState): Promise<void> {\r\n let nodeIndex = this._nodeMap.get(babylonNode);\r\n if (nodeIndex !== undefined) {\r\n if (!parentNodeChildren.includes(nodeIndex)) {\r\n parentNodeChildren.push(nodeIndex);\r\n }\r\n return;\r\n }\r\n\r\n const node = await this._createNodeAsync(babylonNode, state);\r\n\r\n if (node) {\r\n nodeIndex = this._nodes.length;\r\n this._nodes.push(node);\r\n this._nodeMap.set(babylonNode, nodeIndex);\r\n state.pushExportedNode(babylonNode);\r\n parentNodeChildren.push(nodeIndex);\r\n\r\n // Process node's animations once the node has been added to nodeMap (TODO: This should be refactored)\r\n const runtimeGLTFAnimation: IAnimation = {\r\n name: \"runtime animations\",\r\n channels: [],\r\n samplers: [],\r\n };\r\n const idleGLTFAnimations: IAnimation[] = [];\r\n\r\n if (!this._babylonScene.animationGroups.length) {\r\n _GLTFAnimation._CreateMorphTargetAnimationFromMorphTargetAnimations(\r\n babylonNode,\r\n runtimeGLTFAnimation,\r\n idleGLTFAnimations,\r\n this._nodeMap,\r\n this._nodes,\r\n this._bufferManager,\r\n this._bufferViews,\r\n this._accessors,\r\n this._animationSampleRate,\r\n state.convertToRightHanded,\r\n this._options.shouldExportAnimation\r\n );\r\n if (babylonNode.animations.length) {\r\n _GLTFAnimation._CreateNodeAnimationFromNodeAnimations(\r\n babylonNode,\r\n runtimeGLTFAnimation,\r\n idleGLTFAnimations,\r\n this._nodeMap,\r\n this._nodes,\r\n this._bufferManager,\r\n this._bufferViews,\r\n this._accessors,\r\n this._animationSampleRate,\r\n state.convertToRightHanded,\r\n this._options.shouldExportAnimation\r\n );\r\n }\r\n }\r\n\r\n if (runtimeGLTFAnimation.channels.length && runtimeGLTFAnimation.samplers.length) {\r\n this._animations.push(runtimeGLTFAnimation);\r\n }\r\n idleGLTFAnimations.forEach((idleGLTFAnimation) => {\r\n if (idleGLTFAnimation.channels.length && idleGLTFAnimation.samplers.length) {\r\n this._animations.push(idleGLTFAnimation);\r\n }\r\n });\r\n }\r\n\r\n // Begin processing child nodes once parent has been added to the node list\r\n const children = node ? [] : parentNodeChildren;\r\n for (const babylonChildNode of babylonNode.getChildren()) {\r\n // eslint-disable-next-line no-await-in-loop\r\n await this._exportNodeAsync(babylonChildNode, children, state);\r\n }\r\n\r\n if (node && children.length) {\r\n node.children = children;\r\n }\r\n }\r\n\r\n /**\r\n * Creates a glTF node from a Babylon.js node. If skipped, returns null.\r\n * @internal\r\n */\r\n private async _createNodeAsync(babylonNode: Node, state: ExporterState): Promise<Nullable<INode>> {\r\n if (!this._shouldExportNode(babylonNode)) {\r\n return null;\r\n }\r\n\r\n const node: INode = {};\r\n\r\n if (babylonNode.name) {\r\n node.name = babylonNode.name;\r\n }\r\n\r\n // Node metadata\r\n if (babylonNode.metadata) {\r\n const extras = this._options.metadataSelector(babylonNode.metadata);\r\n if (extras) {\r\n node.extras = extras;\r\n }\r\n }\r\n\r\n if (babylonNode instanceof TransformNode) {\r\n this._setNodeTransformation(node, babylonNode, state.convertToRightHanded);\r\n\r\n if (babylonNode instanceof AbstractMesh) {\r\n const babylonMesh = babylonNode instanceof InstancedMesh ? babylonNode.sourceMesh : (babylonNode as Mesh);\r\n if (babylonMesh.subMeshes && babylonMesh.subMeshes.length > 0) {\r\n node.mesh = await this._exportMeshAsync(babylonMesh, state);\r\n }\r\n\r\n if (babylonNode.skeleton) {\r\n const skin = this._skinMap.get(babylonNode.skeleton);\r\n\r\n if (skin !== undefined) {\r\n if (this._nodesSkinMap.get(skin) === undefined) {\r\n this._nodesSkinMap.set(skin, []);\r\n }\r\n\r\n this._nodesSkinMap.get(skin)?.push(node);\r\n }\r\n }\r\n }\r\n }\r\n\r\n if (babylonNode instanceof Camera) {\r\n const gltfCamera = this._camerasMap.get(babylonNode);\r\n\r\n if (gltfCamera) {\r\n if (this._nodesCameraMap.get(gltfCamera) === undefined) {\r\n this._nodesCameraMap.set(gltfCamera, []);\r\n }\r\n\r\n const parentBabylonNode = babylonNode.parent;\r\n this._setCameraTransformation(node, babylonNode, state.convertToRightHanded, parentBabylonNode);\r\n\r\n // If a camera has a node that was added by the GLTF importer, we can just use the parent node transform as the \"camera\" transform.\r\n if (parentBabylonNode && IsParentAddedByImporter(babylonNode, parentBabylonNode)) {\r\n const parentNodeIndex = this._nodeMap.get(parentBabylonNode);\r\n if (parentNodeIndex) {\r\n const parentNode = this._nodes[parentNodeIndex];\r\n this._nodesCameraMap.get(gltfCamera)?.push(parentNode);\r\n return null; // Skip exporting this node\r\n }\r\n }\r\n if (state.convertToRightHanded) {\r\n ConvertToRightHandedNode(node);\r\n RotateNode180Y(node);\r\n }\r\n this._nodesCameraMap.get(gltfCamera)?.push(node);\r\n }\r\n }\r\n\r\n // Apply extensions to the node. If this resolves to null, it means we should skip exporting this node\r\n const processedNode = await this._extensionsPostExportNodeAsync(\"exportNodeAsync\", node, babylonNode, this._nodeMap, state.convertToRightHanded);\r\n if (!processedNode) {\r\n Logger.Warn(`Not exporting node ${babylonNode.name}`);\r\n return null;\r\n }\r\n\r\n return node;\r\n }\r\n\r\n private _exportIndices(\r\n indices: Nullable<IndicesArray>,\r\n is32Bits: boolean,\r\n start: number,\r\n count: number,\r\n offset: number,\r\n fillMode: number,\r\n sideOrientation: number,\r\n state: ExporterState,\r\n primitive: IMeshPrimitive\r\n ): void {\r\n let indicesToExport = indices;\r\n\r\n primitive.mode = GetPrimitiveMode(fillMode);\r\n\r\n // Flip if triangle winding order is not CCW as glTF is always CCW.\r\n const invertedMaterial = sideOrientation !== Material.CounterClockWiseSideOrientation;\r\n\r\n const flipWhenInvertedMaterial = !state.wasAddedByNoopNode && invertedMaterial;\r\n\r\n const flip = IsTriangleFillMode(fillMode) && flipWhenInvertedMaterial;\r\n\r\n if (flip) {\r\n if (fillMode === Material.TriangleStripDrawMode || fillMode === Material.TriangleFanDrawMode) {\r\n throw new Error(\"Triangle strip/fan fill mode is not implemented\");\r\n }\r\n\r\n primitive.mode = GetPrimitiveMode(fillMode);\r\n\r\n const newIndices = is32Bits ? new Uint32Array(count) : new Uint16Array(count);\r\n\r\n if (indices) {\r\n for (let i = 0; i + 2 < count; i += 3) {\r\n newIndices[i] = indices[start + i] + offset;\r\n newIndices[i + 1] = indices[start + i + 2] + offset;\r\n newIndices[i + 2] = indices[start + i + 1] + offset;\r\n }\r\n } else {\r\n for (let i = 0; i + 2 < count; i += 3) {\r\n newIndices[i] = i;\r\n newIndices[i + 1] = i + 2;\r\n newIndices[i + 2] = i + 1;\r\n }\r\n }\r\n\r\n indicesToExport = newIndices;\r\n } else if (indices && offset !== 0) {\r\n const newIndices = is32Bits ? new Uint32Array(count) : new Uint16Array(count);\r\n for (let i = 0; i < count; i++) {\r\n newIndices[i] = indices[start + i] + offset;\r\n }\r\n\r\n indicesToExport = newIndices;\r\n }\r\n\r\n if (indicesToExport) {\r\n let accessorIndex = state.getIndicesAccessor(indices, start, count, offset, flip);\r\n if (accessorIndex === undefined) {\r\n const bytes = IndicesArrayToTypedArray(indicesToExport, 0, count, is32Bits);\r\n const bufferView = this._bufferManager.createBufferView(bytes);\r\n\r\n const componentType = is32Bits ? AccessorComponentType.UNSIGNED_INT : AccessorComponentType.UNSIGNED_SHORT;\r\n this._accessors.push(this._bufferManager.createAccessor(bufferView, AccessorType.SCALAR, componentType, count, 0));\r\n accessorIndex = this._accessors.length - 1;\r\n state.setIndicesAccessor(indices, start, count, offset, flip, accessorIndex);\r\n }\r\n\r\n primitive.indices = accessorIndex;\r\n }\r\n }\r\n\r\n private _exportVertexBuffer(vertexBuffer: VertexBuffer, babylonMaterial: Material, start: number, count: number, state: ExporterState, primitive: IMeshPrimitive): void {\r\n const kind = vertexBuffer.getKind();\r\n\r\n if (!IsStandardVertexAttribute(kind)) {\r\n return;\r\n }\r\n\r\n if (kind.startsWith(\"uv\") && !this._options.exportUnusedUVs) {\r\n if (!babylonMaterial || !this._materialNeedsUVsSet.has(babylonMaterial)) {\r\n return;\r\n }\r\n }\r\n\r\n let accessorIndex = state.getVertexAccessor(vertexBuffer, start, count);\r\n\r\n if (accessorIndex === undefined) {\r\n // Get min/max from converted or original data.\r\n const data = state.convertedToRightHandedBuffers.get(vertexBuffer._buffer) || vertexBuffer._buffer.getData()!;\r\n const minMax = kind === VertexBuffer.PositionKind ? GetMinMax(data, vertexBuffer, start, count) : undefined;\r\n\r\n // For the remapped buffer views we created for float matrices indices, make sure to use their updated information.\r\n const isFloatMatricesIndices =\r\n (kind === VertexBuffer.MatricesIndicesKind || kind === VertexBuffer.MatricesIndicesExtraKind) && vertexBuffer.type === VertexBuffer.FLOAT;\r\n\r\n const vertexBufferType = isFloatMatricesIndices ? VertexBuffer.UNSIGNED_BYTE : vertexBuffer.type;\r\n const vertexBufferNormalized = isFloatMatricesIndices ? undefined : vertexBuffer.normalized;\r\n const bufferView = isFloatMatricesIndices ? state.getRemappedBufferView(vertexBuffer._buffer, vertexBuffer)! : state.getVertexBufferView(vertexBuffer._buffer)!;\r\n\r\n const byteOffset = vertexBuffer.byteOffset + start * vertexBuffer.byteStride;\r\n this._accessors.push(\r\n this._bufferManager.createAccessor(\r\n bufferView,\r\n GetAccessorType(kind, state.hasVertexColorAlpha(vertexBuffer)),\r\n vertexBufferType,\r\n count,\r\n byteOffset,\r\n minMax,\r\n vertexBufferNormalized // TODO: Find other places where this is needed.\r\n )\r\n );\r\n accessorIndex = this._accessors.length - 1;\r\n state.setVertexAccessor(vertexBuffer, start, count, accessorIndex);\r\n }\r\n\r\n primitive.attributes[GetAttributeType(kind)] = accessorIndex;\r\n }\r\n\r\n private async _exportMaterialAsync(babylonMaterial: Material, vertexBuffers: { [kind: string]: VertexBuffer }, subMesh: SubMesh, primitive: IMeshPrimitive): Promise<void> {\r\n let materialIndex = this._materialMap.get(babylonMaterial);\r\n if (materialIndex === undefined) {\r\n const hasUVs = vertexBuffers && Object.keys(vertexBuffers).some((kind) => kind.startsWith(\"uv\"));\r\n babylonMaterial = babylonMaterial instanceof MultiMaterial ? babylonMaterial.subMaterials[subMesh.materialIndex]! : babylonMaterial;\r\n if (babylonMaterial instanceof PBRMaterial) {\r\n materialIndex = await this._materialExporter.exportPBRMaterialAsync(babylonMaterial, ImageMimeType.PNG, hasUVs);\r\n } else if (babylonMaterial instanceof StandardMaterial) {\r\n materialIndex = await this._materialExporter.exportStandardMaterialAsync(babylonMaterial, ImageMimeType.PNG, hasUVs);\r\n } else {\r\n Logger.Warn(`Unsupported material '${babylonMaterial.name}' with type ${babylonMaterial.getClassName()}`);\r\n return;\r\n }\r\n\r\n this._materialMap.set(babylonMaterial, materialIndex);\r\n }\r\n\r\n primitive.material = materialIndex;\r\n }\r\n\r\n private async _exportMeshAsync(babylonMesh: Mesh, state: ExporterState): Promise<number> {\r\n let meshIndex = state.getMesh(babylonMesh);\r\n if (meshIndex !== undefined) {\r\n return meshIndex;\r\n }\r\n\r\n const mesh: IMesh = { primitives: [] };\r\n meshIndex = this._meshes.length;\r\n this._meshes.push(mesh);\r\n state.setMesh(babylonMesh, meshIndex);\r\n\r\n const indices = babylonMesh.isUnIndexed ? null : babylonMesh.getIndices();\r\n const vertexBuffers = babylonMesh.geometry?.getVertexBuffers();\r\n const morphTargets = state.getMorphTargetsFromMesh(babylonMesh);\r\n\r\n const isLinesMesh = babylonMesh instanceof LinesMesh;\r\n const isGreasedLineMesh = babylonMesh instanceof GreasedLineBaseMesh;\r\n\r\n const subMeshes = babylonMesh.subMeshes;\r\n if (vertexBuffers && subMeshes && subMeshes.length > 0) {\r\n for (const subMesh of subMeshes) {\r\n const primitive: IMeshPrimitive = { attributes: {} };\r\n\r\n const babylonMaterial = subMesh.getMaterial() || this._babylonScene.defaultMaterial;\r\n\r\n if (isGreasedLineMesh) {\r\n const material: IMaterial = {\r\n name: babylonMaterial.name,\r\n };\r\n\r\n const babylonLinesMesh = babylonMesh;\r\n\r\n const colorWhite = Color3.White();\r\n const alpha = babylonLinesMesh.material?.alpha ?? 1;\r\n const color = babylonLinesMesh.greasedLineMaterial?.color ?? colorWhite;\r\n if (!color.equals(colorWhite) || alpha < 1) {\r\n material.pbrMetallicRoughness = {\r\n baseColorFactor: [...color.asArray(), alpha],\r\n };\r\n }\r\n\r\n this._materials.push(material);\r\n primitive.material = this._materials.length - 1;\r\n } else if (isLinesMesh) {\r\n // Special case for LinesMesh\r\n const material: IMaterial = {\r\n name: babylonMaterial.name,\r\n };\r\n\r\n const babylonLinesMesh = babylonMesh;\r\n\r\n if (!babylonLinesMesh.color.equals(Color3.White()) || babylonLinesMesh.alpha < 1) {\r\n material.pbrMetallicRoughness = {\r\n baseColorFactor: [...babylonLinesMesh.color.asArray(), babylonLinesMesh.alpha],\r\n };\r\n }\r\n\r\n this._materials.push(material);\r\n primitive.material = this._materials.length - 1;\r\n } else {\r\n // Material\r\n // eslint-disable-next-line no-await-in-loop\r\n await this._exportMaterialAsync(babylonMaterial, vertexBuffers, subMesh, primitive);\r\n }\r\n\r\n // Index buffer\r\n const fillMode = isLinesMesh || isGreasedLineMesh ? Material.LineListDrawMode : (babylonMesh.overrideRenderingFillMode ?? babylonMaterial.fillMode);\r\n\r\n const sideOrientation = babylonMaterial._getEffectiveOrientation(babylonMesh);\r\n\r\n this._exportIndices(\r\n indices,\r\n indices ? AreIndices32Bits(indices, subMesh.indexCount, subMesh.indexStart, subMesh.verticesStart) : subMesh.verticesCount > 65535,\r\n indices ? subMesh.indexStart : subMesh.verticesStart,\r\n indices ? subMesh.indexCount : subMesh.verticesCount,\r\n -subMesh.verticesStart,\r\n fillMode,\r\n sideOrientation,\r\n state,\r\n primitive\r\n );\r\n\r\n // Vertex buffers\r\n for (const vertexBuffer of Object.values(vertexBuffers)) {\r\n this._exportVertexBuffer(vertexBuffer, babylonMaterial, subMesh.verticesStart, subMesh.verticesCount, state, primitive);\r\n }\r\n\r\n if (morphTargets) {\r\n primitive.targets = [];\r\n for (const gltfMorphTarget of morphTargets) {\r\n primitive.targets.push(gltfMorphTarget.attributes);\r\n }\r\n }\r\n\r\n mesh.primitives.push(primitive);\r\n this._extensionsPostExportMeshPrimitive(primitive);\r\n }\r\n }\r\n\r\n if (morphTargets) {\r\n mesh.weights = [];\r\n\r\n if (!mesh.extras) {\r\n mesh.extras = {};\r\n }\r\n mesh.extras.targetNames = [];\r\n\r\n for (const gltfMorphTarget of morphTargets) {\r\n mesh.weights.push(gltfMorphTarget.influence);\r\n mesh.extras.targetNames.push(gltfMorphTarget.name);\r\n }\r\n }\r\n\r\n return meshIndex;\r\n }\r\n}\r\n","import type { Node } from \"core/node\";\r\nimport type { Scene } from \"core/scene\";\r\nimport type { Animation } from \"core/Animations/animation\";\r\nimport type { GLTFData } from \"./glTFData\";\r\nimport { GLTFExporter } from \"./glTFExporter\";\r\n\r\n/**\r\n * Mesh compression methods.\r\n */\r\nexport type MeshCompressionMethod = \"None\" | \"Draco\";\r\n\r\n/**\r\n * Holds a collection of exporter options and parameters\r\n */\r\nexport interface IExportOptions {\r\n /**\r\n * Function which indicates whether a babylon node should be exported or not\r\n * @param node source Babylon node. It is used to check whether it should be exported to glTF or not\r\n * @returns boolean, which indicates whether the node should be exported (true) or not (false)\r\n */\r\n shouldExportNode?(node: Node): boolean;\r\n\r\n /**\r\n * Function which indicates whether an animation on the scene should be exported or not\r\n * @param animation source animation\r\n * @returns boolean, which indicates whether the animation should be exported (true) or not (false)\r\n */\r\n shouldExportAnimation?(animation: Animation): boolean;\r\n\r\n /**\r\n * Function to extract the part of the scene or node's `metadata` that will populate the corresponding\r\n * glTF object's `extras` field. If not defined, `node.metadata.gltf.extras` will be used.\r\n * @param metadata source metadata to read from\r\n * @returns the data to store into the glTF extras field\r\n */\r\n metadataSelector?(metadata: any): any;\r\n\r\n /**\r\n * The sample rate to bake animation curves. Defaults to 1 / 60.\r\n */\r\n animationSampleRate?: number;\r\n\r\n /**\r\n * Begin serialization without waiting for the scene to be ready. Defaults to false.\r\n */\r\n exportWithoutWaitingForScene?: boolean;\r\n\r\n /**\r\n * Indicates if unused vertex uv attributes should be included in export. Defaults to false.\r\n */\r\n exportUnusedUVs?: boolean;\r\n\r\n /**\r\n * Remove no-op root nodes when possible. Defaults to true.\r\n */\r\n removeNoopRootNodes?: boolean;\r\n\r\n /**\r\n * Indicates if coordinate system swapping root nodes should be included in export. Defaults to false.\r\n * @deprecated Please use removeNoopRootNodes instead\r\n */\r\n includeCoordinateSystemConversionNodes?: boolean;\r\n\r\n /**\r\n * Indicates what compression method to apply to mesh data.\r\n */\r\n meshCompressionMethod?: MeshCompressionMethod;\r\n}\r\n\r\n/**\r\n * Class for generating glTF data from a Babylon scene.\r\n */\r\nexport class GLTF2Export {\r\n /**\r\n * Exports the scene to .gltf file format\r\n * @param scene Babylon scene\r\n * @param fileName Name to use for the .gltf file\r\n * @param options Exporter options\r\n * @returns Returns the exported data\r\n */\r\n public static async GLTFAsync(scene: Scene, fileName: string, options?: IExportOptions): Promise<GLTFData> {\r\n if (!options || !options.exportWithoutWaitingForScene) {\r\n await scene.whenReadyAsync();\r\n }\r\n\r\n const exporter = new GLTFExporter(scene, options);\r\n const data = await exporter.generateGLTFAsync(fileName.replace(/\\.[^/.]+$/, \"\"));\r\n exporter.dispose();\r\n\r\n return data;\r\n }\r\n\r\n /**\r\n * Exports the scene to .glb file format\r\n * @param scene Babylon scene\r\n * @param fileName Name to use for the .glb file\r\n * @param options Exporter options\r\n * @returns Returns the exported data\r\n */\r\n public static async GLBAsync(scene: Scene, fileName: string, options?: IExportOptions): Promise<GLTFData> {\r\n if (!options || !options.exportWithoutWaitingForScene) {\r\n await scene.whenReadyAsync();\r\n }\r\n\r\n const exporter = new GLTFExporter(scene, options);\r\n const data = await exporter.generateGLBAsync(fileName.replace(/\\.[^/.]+$/, \"\"));\r\n exporter.dispose();\r\n\r\n return data;\r\n }\r\n}\r\n","import type { INode, IEXTMeshGpuInstancing } from \"babylonjs-gltf2interface\";\r\nimport { AccessorType, AccessorComponentType } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport type { BufferManager } from \"../bufferManager\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport type { Nullable } from \"core/types\";\r\nimport type { Node } from \"core/node\";\r\nimport { Mesh } from \"core/Meshes/mesh\";\r\nimport \"core/Meshes/thinInstanceMesh\";\r\nimport { TmpVectors, Quaternion, Vector3 } from \"core/Maths/math.vector\";\r\nimport { ConvertToRightHandedPosition, ConvertToRightHandedRotation } from \"../glTFUtilities\";\r\n\r\nconst NAME = \"EXT_mesh_gpu_instancing\";\r\n\r\n/**\r\n * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Vendor/EXT_mesh_gpu_instancing/README.md)\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class EXT_mesh_gpu_instancing implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n private _exporter: GLTFExporter;\r\n\r\n private _wasUsed = false;\r\n\r\n constructor(exporter: GLTFExporter) {\r\n this._exporter = exporter;\r\n }\r\n\r\n public dispose() {}\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n /**\r\n * After node is exported\r\n * @param context the GLTF context when loading the asset\r\n * @param node the node exported\r\n * @param babylonNode the corresponding babylon node\r\n * @param nodeMap map from babylon node id to node index\r\n * @param convertToRightHanded true if we need to convert data from left hand to right hand system.\r\n * @param bufferManager buffer manager\r\n * @returns nullable promise, resolves with the node\r\n */\r\n public async postExportNodeAsync(\r\n context: string,\r\n node: Nullable<INode>,\r\n babylonNode: Node,\r\n nodeMap: Map<Node, number>,\r\n convertToRightHanded: boolean,\r\n bufferManager: BufferManager\r\n ): Promise<Nullable<INode>> {\r\n return await new Promise((resolve) => {\r\n if (node && babylonNode instanceof Mesh) {\r\n if (babylonNode.hasThinInstances && this._exporter) {\r\n this._wasUsed = true;\r\n\r\n const noTranslation = Vector3.Zero();\r\n const noRotation = Quaternion.Identity();\r\n const noScale = Vector3.One();\r\n\r\n // retrieve all the instance world matrix\r\n const matrix = babylonNode.thinInstanceGetWorldMatrices();\r\n\r\n const iwt = TmpVectors.Vector3[2];\r\n const iwr = TmpVectors.Quaternion[1];\r\n const iws = TmpVectors.Vector3[3];\r\n\r\n let hasAnyInstanceWorldTranslation = false;\r\n let hasAnyInstanceWorldRotation = false;\r\n let hasAnyInstanceWorldScale = false;\r\n\r\n // prepare temp buffers\r\n const translationBuffer = new Float32Array(babylonNode.thinInstanceCount * 3);\r\n const rotationBuffer = new Float32Array(babylonNode.thinInstanceCount * 4);\r\n const scaleBuffer = new Float32Array(babylonNode.thinInstanceCount * 3);\r\n\r\n let i = 0;\r\n for (const m of matrix) {\r\n m.decompose(iws, iwr, iwt);\r\n\r\n if (convertToRightHanded) {\r\n ConvertToRightHandedPosition(iwt);\r\n ConvertToRightHandedRotation(iwr);\r\n }\r\n\r\n // fill the temp buffer\r\n translationBuffer.set(iwt.asArray(), i * 3);\r\n rotationBuffer.set(iwr.normalize().asArray(), i * 4); // ensure the quaternion is normalized\r\n scaleBuffer.set(iws.asArray(), i * 3);\r\n\r\n // this is where we decide if there is any transformation\r\n hasAnyInstanceWorldTranslation = hasAnyInstanceWorldTranslation || !iwt.equalsWithEpsilon(noTranslation);\r\n hasAnyInstanceWorldRotation = hasAnyInstanceWorldRotation || !iwr.equalsWithEpsilon(noRotation);\r\n hasAnyInstanceWorldScale = hasAnyInstanceWorldScale || !iws.equalsWithEpsilon(noScale);\r\n\r\n i++;\r\n }\r\n\r\n const extension: IEXTMeshGpuInstancing = {\r\n attributes: {},\r\n };\r\n\r\n // do we need to write TRANSLATION ?\r\n if (hasAnyInstanceWorldTranslation) {\r\n extension.attributes[\"TRANSLATION\"] = this._buildAccessor(translationBuffer, AccessorType.VEC3, babylonNode.thinInstanceCount, bufferManager);\r\n }\r\n // do we need to write ROTATION ?\r\n if (hasAnyInstanceWorldRotation) {\r\n // we decided to stay on FLOAT for now see https://github.com/BabylonJS/Babylon.js/pull/12495\r\n extension.attributes[\"ROTATION\"] = this._buildAccessor(rotationBuffer, AccessorType.VEC4, babylonNode.thinInstanceCount, bufferManager);\r\n }\r\n // do we need to write SCALE ?\r\n if (hasAnyInstanceWorldScale) {\r\n extension.attributes[\"SCALE\"] = this._buildAccessor(scaleBuffer, AccessorType.VEC3, babylonNode.thinInstanceCount, bufferManager);\r\n }\r\n\r\n /* eslint-enable @typescript-eslint/naming-convention*/\r\n node.extensions = node.extensions || {};\r\n node.extensions[NAME] = extension;\r\n }\r\n }\r\n resolve(node);\r\n });\r\n }\r\n\r\n private _buildAccessor(buffer: Float32Array, type: AccessorType, count: number, bufferManager: BufferManager): number {\r\n // build the buffer view\r\n const bv = bufferManager.createBufferView(buffer);\r\n\r\n // finally build the accessor\r\n const accessor = bufferManager.createAccessor(bv, type, AccessorComponentType.FLOAT, count);\r\n this._exporter._accessors.push(accessor);\r\n return this._exporter._accessors.length - 1;\r\n }\r\n}\r\n\r\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\r\nGLTFExporter.RegisterExtension(NAME, (exporter) => new EXT_mesh_gpu_instancing(exporter));\r\n","import type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\nimport { GLTFExporter } from \"../glTFExporter\";\nimport { MeshPrimitiveMode } from \"babylonjs-gltf2interface\";\nimport type { IAccessor, IBufferView, IKHRDracoMeshCompression, IMeshPrimitive } from \"babylonjs-gltf2interface\";\nimport type { BufferManager } from \"../bufferManager\";\nimport { DracoEncoder } from \"core/Meshes/Compression/dracoEncoder\";\nimport { GetTypedArrayData, GetTypeByteLength } from \"core/Buffers/bufferUtils\";\nimport { GetAccessorElementCount } from \"../glTFUtilities\";\nimport type { DracoAttributeName, IDracoAttributeData, IDracoEncoderOptions } from \"core/Meshes/Compression/dracoEncoder.types\";\nimport { Logger } from \"core/Misc/logger\";\nimport type { Nullable } from \"core/types\";\n\nconst NAME = \"KHR_draco_mesh_compression\";\n\nfunction GetDracoAttributeName(glTFName: string): DracoAttributeName {\n if (glTFName === \"POSITION\") {\n return \"POSITION\";\n } else if (glTFName === \"NORMAL\") {\n return \"NORMAL\";\n } else if (glTFName.startsWith(\"COLOR\")) {\n return \"COLOR\";\n } else if (glTFName.startsWith(\"TEXCOORD\")) {\n return \"TEX_COORD\";\n }\n return \"GENERIC\";\n}\n\n/**\n * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_draco_mesh_compression/README.md)\n */\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport class KHR_draco_mesh_compression implements IGLTFExporterExtensionV2 {\n /** Name of this extension */\n public readonly name = NAME;\n\n /** Defines whether this extension is enabled */\n public enabled;\n\n /** KHR_draco_mesh_compression is required, as uncompressed fallback data is not yet implemented. */\n public required = true;\n\n /** BufferViews used for Draco data, which may be eligible for removal after Draco encoding */\n private _bufferViewsUsed: Set<IBufferView> = new Set();\n\n /** Accessors that were replaced with Draco data, which may be eligible for removal after Draco encoding */\n private _accessorsUsed: Set<IAccessor> = new Set();\n\n /** Promise pool for Draco encoding work */\n private _encodePromises: Promise<void>[] = [];\n\n private _wasUsed = false;\n\n /** @internal */\n public get wasUsed() {\n return this._wasUsed;\n }\n\n /** @internal */\n constructor(exporter: GLTFExporter) {\n this.enabled = exporter.options.meshCompressionMethod === \"Draco\" && DracoEncoder.DefaultAvailable;\n }\n\n /** @internal */\n public dispose() {}\n\n /** @internal */\n public postExportMeshPrimitive(primitive: IMeshPrimitive, bufferManager: BufferManager, accessors: IAccessor[]): void {\n if (!this.enabled) {\n return;\n }\n\n if (primitive.mode !== MeshPrimitiveMode.TRIANGLES && primitive.mode !== MeshPrimitiveMode.TRIANGLE_STRIP) {\n Logger.Warn(\"Cannot compress primitive with mode \" + primitive.mode + \".\");\n return;\n }\n\n // Collect bufferViews and accessors used by this primitive\n const primitiveBufferViews: IBufferView[] = [];\n const primitiveAccessors: IAccessor[] = [];\n\n // Prepare indices for Draco encoding\n let indices: Nullable<Uint32Array | Uint16Array> = null;\n if (primitive.indices !== undefined) {\n const accessor = accessors[primitive.indices];\n const bufferView = bufferManager.getBufferView(accessor);\n // Per exportIndices, indices must be either Uint16Array or Uint32Array\n indices = bufferManager.getData(bufferView).slice() as Uint32Array | Uint16Array;\n\n primitiveBufferViews.push(bufferView);\n primitiveAccessors.push(accessor);\n }\n\n // Prepare attributes for Draco encoding\n const attributes: IDracoAttributeData[] = [];\n for (const [name, accessorIndex] of Object.entries(primitive.attributes)) {\n const accessor = accessors[accessorIndex];\n const bufferView = bufferManager.getBufferView(accessor);\n\n const size = GetAccessorElementCount(accessor.type);\n const data = GetTypedArrayData(\n bufferManager.getData(bufferView),\n size,\n accessor.componentType,\n accessor.byteOffset || 0,\n bufferView.byteStride || GetTypeByteLength(accessor.componentType) * size,\n accessor.normalized || false,\n accessor.count,\n true\n );\n\n attributes.push({ kind: name, dracoName: GetDracoAttributeName(name), size: GetAccessorElementCount(accessor.type), data: data });\n\n primitiveBufferViews.push(bufferView);\n primitiveAccessors.push(accessor);\n }\n\n // Use sequential encoding to preserve vertex order for cases like morph targets\n const options: IDracoEncoderOptions = {\n method: primitive.targets ? \"MESH_SEQUENTIAL_ENCODING\" : \"MESH_EDGEBREAKER_ENCODING\",\n };\n\n const promise = DracoEncoder.Default._encodeAsync(attributes, indices, options)\n // eslint-disable-next-line github/no-then\n .then((encodedData) => {\n if (!encodedData) {\n Logger.Error(\"Draco encoding failed for primitive.\");\n return;\n }\n\n const dracoInfo: IKHRDracoMeshCompression = {\n bufferView: -1, // bufferView will be set to a real index later, when we write the binary and decide bufferView ordering\n attributes: encodedData.attributeIds,\n };\n const bufferView = bufferManager.createBufferView(encodedData.data);\n bufferManager.setBufferView(dracoInfo, bufferView);\n\n for (const bufferView of primitiveBufferViews) {\n this._bufferViewsUsed.add(bufferView);\n }\n for (const accessor of primitiveAccessors) {\n this._accessorsUsed.add(accessor);\n }\n\n primitive.extensions ||= {};\n primitive.extensions[NAME] = dracoInfo;\n })\n // eslint-disable-next-line github/no-then\n .catch((error) => {\n Logger.Error(\"Draco encoding failed for primitive: \" + error);\n });\n\n this._encodePromises.push(promise);\n\n this._wasUsed = true;\n }\n\n /** @internal */\n public async preGenerateBinaryAsync(bufferManager: BufferManager): Promise<void> {\n if (!this.enabled) {\n return;\n }\n\n await Promise.all(this._encodePromises);\n\n // Cull obsolete bufferViews that were replaced with Draco data\n this._bufferViewsUsed.forEach((bufferView) => {\n const references = bufferManager.getPropertiesWithBufferView(bufferView);\n const onlyUsedByEncodedPrimitives = references.every((object) => {\n return this._accessorsUsed.has(object as IAccessor); // has() can handle any object, but TS doesn't know that\n });\n if (onlyUsedByEncodedPrimitives) {\n bufferManager.removeBufferView(bufferView);\n }\n });\n\n this._bufferViewsUsed.clear();\n this._accessorsUsed.clear();\n }\n}\n\nGLTFExporter.RegisterExtension(NAME, (exporter) => new KHR_draco_mesh_compression(exporter));\n","import type { SpotLight } from \"core/Lights/spotLight\";\r\nimport type { Nullable } from \"core/types\";\r\nimport { Vector3, Quaternion, TmpVectors } from \"core/Maths/math.vector\";\r\nimport { Light } from \"core/Lights/light\";\r\nimport type { Node } from \"core/node\";\r\nimport { ShadowLight } from \"core/Lights/shadowLight\";\r\nimport type { INode, IKHRLightsPunctual_LightReference, IKHRLightsPunctual_Light, IKHRLightsPunctual } from \"babylonjs-gltf2interface\";\r\nimport { KHRLightsPunctual_LightType } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport { Logger } from \"core/Misc/logger\";\r\nimport { ConvertToRightHandedPosition, OmitDefaultValues, CollapseParentNode, IsParentAddedByImporter } from \"../glTFUtilities\";\r\n\r\nconst NAME = \"KHR_lights_punctual\";\r\nconst DEFAULTS: Omit<IKHRLightsPunctual_Light, \"type\"> = {\r\n name: \"\",\r\n color: [1, 1, 1],\r\n intensity: 1,\r\n range: Number.MAX_VALUE,\r\n};\r\nconst SPOTDEFAULTS: NonNullable<IKHRLightsPunctual_Light[\"spot\"]> = {\r\n innerConeAngle: 0,\r\n outerConeAngle: Math.PI / 4.0,\r\n};\r\nconst LIGHTDIRECTION = Vector3.Backward();\r\n\r\n/**\r\n * [Specification](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_lights_punctual/README.md)\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_lights_punctual implements IGLTFExporterExtensionV2 {\r\n /** The name of this extension. */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled. */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n /** Reference to the glTF exporter */\r\n private _exporter: GLTFExporter;\r\n\r\n private _lights: IKHRLightsPunctual;\r\n\r\n /**\r\n * @internal\r\n */\r\n constructor(exporter: GLTFExporter) {\r\n this._exporter = exporter;\r\n }\r\n\r\n /** @internal */\r\n public dispose() {\r\n (this._lights as any) = null;\r\n }\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return !!this._lights;\r\n }\r\n\r\n /** @internal */\r\n public onExporting(): void {\r\n this._exporter._glTF.extensions![NAME] = this._lights;\r\n }\r\n /**\r\n * Define this method to modify the default behavior when exporting a node\r\n * @param context The context when exporting the node\r\n * @param node glTF node\r\n * @param babylonNode BabylonJS node\r\n * @param nodeMap Node mapping of babylon node to glTF node index\r\n * @param convertToRightHanded Flag to convert the values to right-handed\r\n * @returns nullable INode promise\r\n */\r\n public async postExportNodeAsync(context: string, node: INode, babylonNode: Node, nodeMap: Map<Node, number>, convertToRightHanded: boolean): Promise<Nullable<INode>> {\r\n return await new Promise((resolve) => {\r\n if (!(babylonNode instanceof ShadowLight)) {\r\n resolve(node);\r\n return;\r\n }\r\n\r\n const lightType =\r\n babylonNode.getTypeID() == Light.LIGHTTYPEID_POINTLIGHT\r\n ? KHRLightsPunctual_LightType.POINT\r\n : babylonNode.getTypeID() == Light.LIGHTTYPEID_DIRECTIONALLIGHT\r\n ? KHRLightsPunctual_LightType.DIRECTIONAL\r\n : babylonNode.getTypeID() == Light.LIGHTTYPEID_SPOTLIGHT\r\n ? KHRLightsPunctual_LightType.SPOT\r\n : null;\r\n if (!lightType) {\r\n Logger.Warn(`${context}: Light ${babylonNode.name} is not supported in ${NAME}`);\r\n resolve(node);\r\n return;\r\n }\r\n\r\n if (babylonNode.falloffType !== Light.FALLOFF_GLTF) {\r\n Logger.Warn(`${context}: Light falloff for ${babylonNode.name} does not match the ${NAME} specification!`);\r\n }\r\n\r\n // Set the node's translation and rotation here, since lights are not handled in exportNodeAsync\r\n if (!babylonNode.position.equalsToFloats(0, 0, 0)) {\r\n const translation = TmpVectors.Vector3[0].copyFrom(babylonNode.position);\r\n if (convertToRightHanded) {\r\n ConvertToRightHandedPosition(translation);\r\n }\r\n node.translation = translation.asArray();\r\n }\r\n\r\n // Babylon lights have \"constant\" rotation and variable direction, while\r\n // glTF lights have variable rotation and constant direction. Therefore,\r\n // compute a quaternion that aligns the Babylon light's direction with glTF's constant one.\r\n if (lightType !== KHRLightsPunctual_LightType.POINT) {\r\n const direction = babylonNode.direction.normalizeToRef(TmpVectors.Vector3[0]);\r\n if (convertToRightHanded) {\r\n ConvertToRightHandedPosition(direction);\r\n }\r\n const angle = Math.acos(Vector3.Dot(LIGHTDIRECTION, direction));\r\n const axis = Vector3.Cross(LIGHTDIRECTION, direction);\r\n const lightRotationQuaternion = Quaternion.RotationAxisToRef(axis, angle, TmpVectors.Quaternion[0]);\r\n if (!Quaternion.IsIdentity(lightRotationQuaternion)) {\r\n node.rotation = lightRotationQuaternion.asArray();\r\n }\r\n }\r\n\r\n const light: IKHRLightsPunctual_Light = {\r\n type: lightType,\r\n name: babylonNode.name,\r\n color: babylonNode.diffuse.asArray(),\r\n intensity: babylonNode.intensity,\r\n range: babylonNode.range,\r\n };\r\n OmitDefaultValues(light, DEFAULTS);\r\n\r\n // Separately handle the required 'spot' field for spot lights\r\n if (lightType === KHRLightsPunctual_LightType.SPOT) {\r\n const babylonSpotLight = babylonNode as SpotLight;\r\n light.spot = {\r\n innerConeAngle: babylonSpotLight.innerAngle / 2.0,\r\n outerConeAngle: babylonSpotLight.angle / 2.0,\r\n };\r\n OmitDefaultValues(light.spot, SPOTDEFAULTS);\r\n }\r\n\r\n this._lights ||= {\r\n lights: [],\r\n };\r\n this._lights.lights.push(light);\r\n\r\n const lightReference: IKHRLightsPunctual_LightReference = {\r\n light: this._lights.lights.length - 1,\r\n };\r\n\r\n // Assign the light to its parent node, if possible, to condense the glTF\r\n // Why and when: the glTF loader generates a new parent TransformNode for each light node, which we should undo on export\r\n const parentBabylonNode = babylonNode.parent;\r\n\r\n if (parentBabylonNode && IsParentAddedByImporter(babylonNode, parentBabylonNode)) {\r\n const parentNodeIndex = nodeMap.get(parentBabylonNode);\r\n if (parentNodeIndex) {\r\n // Combine the light's transformation with the parent's\r\n const parentNode = this._exporter._nodes[parentNodeIndex];\r\n CollapseParentNode(node, parentNode);\r\n parentNode.extensions ||= {};\r\n parentNode.extensions[NAME] = lightReference;\r\n\r\n // Do not export the original node\r\n resolve(null);\r\n return;\r\n }\r\n }\r\n\r\n node.extensions ||= {};\r\n node.extensions[NAME] = lightReference;\r\n resolve(node);\r\n });\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, (exporter) => new KHR_lights_punctual(exporter));\r\n","import type { IMaterial, IKHRMaterialsAnisotropy } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport { PBRBaseMaterial } from \"core/Materials/PBR/pbrBaseMaterial\";\r\nimport type { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\n\r\nconst NAME = \"KHR_materials_anisotropy\";\r\n\r\n/**\r\n * @internal\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_materials_anisotropy implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n private _exporter: GLTFExporter;\r\n\r\n private _wasUsed = false;\r\n\r\n constructor(exporter: GLTFExporter) {\r\n this._exporter = exporter;\r\n }\r\n\r\n public dispose() {}\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n public postExportMaterialAdditionalTextures?(context: string, node: IMaterial, babylonMaterial: Material): BaseTexture[] {\r\n const additionalTextures: BaseTexture[] = [];\r\n if (babylonMaterial instanceof PBRBaseMaterial) {\r\n if (babylonMaterial.anisotropy.isEnabled && !babylonMaterial.anisotropy.legacy) {\r\n if (babylonMaterial.anisotropy.texture) {\r\n additionalTextures.push(babylonMaterial.anisotropy.texture);\r\n }\r\n return additionalTextures;\r\n }\r\n }\r\n\r\n return [];\r\n }\r\n\r\n // eslint-disable-next-line no-restricted-syntax\r\n public postExportMaterialAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<IMaterial> {\r\n return new Promise((resolve) => {\r\n if (babylonMaterial instanceof PBRBaseMaterial) {\r\n if (!babylonMaterial.anisotropy.isEnabled || babylonMaterial.anisotropy.legacy) {\r\n resolve(node);\r\n return;\r\n }\r\n\r\n this._wasUsed = true;\r\n\r\n node.extensions = node.extensions || {};\r\n\r\n const anisotropyTextureInfo = this._exporter._materialExporter.getTextureInfo(babylonMaterial.anisotropy.texture);\r\n\r\n const anisotropyInfo: IKHRMaterialsAnisotropy = {\r\n anisotropyStrength: babylonMaterial.anisotropy.intensity,\r\n anisotropyRotation: babylonMaterial.anisotropy.angle,\r\n anisotropyTexture: anisotropyTextureInfo ?? undefined,\r\n };\r\n\r\n if (anisotropyInfo.anisotropyTexture !== null) {\r\n this._exporter._materialNeedsUVsSet.add(babylonMaterial);\r\n }\r\n\r\n node.extensions[NAME] = anisotropyInfo;\r\n }\r\n resolve(node);\r\n });\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, (exporter) => new KHR_materials_anisotropy(exporter));\r\n","import type { IMaterial, IKHRMaterialsClearcoat } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport { PBRBaseMaterial } from \"core/Materials/PBR/pbrBaseMaterial\";\r\nimport type { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\n\r\nimport { Tools } from \"core/Misc/tools\";\r\n\r\nconst NAME = \"KHR_materials_clearcoat\";\r\n\r\n/**\r\n * @internal\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_materials_clearcoat implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n private _exporter: GLTFExporter;\r\n\r\n private _wasUsed = false;\r\n\r\n constructor(exporter: GLTFExporter) {\r\n this._exporter = exporter;\r\n }\r\n\r\n public dispose() {}\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n public postExportMaterialAdditionalTextures?(context: string, node: IMaterial, babylonMaterial: Material): BaseTexture[] {\r\n const additionalTextures: BaseTexture[] = [];\r\n if (babylonMaterial instanceof PBRBaseMaterial) {\r\n if (babylonMaterial.clearCoat.isEnabled) {\r\n if (babylonMaterial.clearCoat.texture) {\r\n additionalTextures.push(babylonMaterial.clearCoat.texture);\r\n }\r\n if (!babylonMaterial.clearCoat.useRoughnessFromMainTexture && babylonMaterial.clearCoat.textureRoughness) {\r\n additionalTextures.push(babylonMaterial.clearCoat.textureRoughness);\r\n }\r\n if (babylonMaterial.clearCoat.bumpTexture) {\r\n additionalTextures.push(babylonMaterial.clearCoat.bumpTexture);\r\n }\r\n return additionalTextures;\r\n }\r\n }\r\n\r\n return [];\r\n }\r\n\r\n // eslint-disable-next-line no-restricted-syntax\r\n public postExportMaterialAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<IMaterial> {\r\n return new Promise((resolve) => {\r\n if (babylonMaterial instanceof PBRBaseMaterial) {\r\n if (!babylonMaterial.clearCoat.isEnabled) {\r\n resolve(node);\r\n return;\r\n }\r\n\r\n this._wasUsed = true;\r\n\r\n node.extensions = node.extensions || {};\r\n\r\n const clearCoatTextureInfo = this._exporter._materialExporter.getTextureInfo(babylonMaterial.clearCoat.texture);\r\n let clearCoatTextureRoughnessInfo;\r\n if (babylonMaterial.clearCoat.useRoughnessFromMainTexture) {\r\n clearCoatTextureRoughnessInfo = this._exporter._materialExporter.getTextureInfo(babylonMaterial.clearCoat.texture);\r\n } else {\r\n clearCoatTextureRoughnessInfo = this._exporter._materialExporter.getTextureInfo(babylonMaterial.clearCoat.textureRoughness);\r\n }\r\n\r\n if (babylonMaterial.clearCoat.isTintEnabled) {\r\n Tools.Warn(`Clear Color tint is not supported for glTF export. Ignoring for: ${babylonMaterial.name}`);\r\n }\r\n\r\n if (babylonMaterial.clearCoat.remapF0OnInterfaceChange) {\r\n Tools.Warn(`Clear Color F0 remapping is not supported for glTF export. Ignoring for: ${babylonMaterial.name}`);\r\n }\r\n\r\n const clearCoatNormalTextureInfo = this._exporter._materialExporter.getTextureInfo(babylonMaterial.clearCoat.bumpTexture);\r\n\r\n const clearCoatInfo: IKHRMaterialsClearcoat = {\r\n clearcoatFactor: babylonMaterial.clearCoat.intensity,\r\n clearcoatTexture: clearCoatTextureInfo ?? undefined,\r\n clearcoatRoughnessFactor: babylonMaterial.clearCoat.roughness,\r\n clearcoatRoughnessTexture: clearCoatTextureRoughnessInfo ?? undefined,\r\n clearcoatNormalTexture: clearCoatNormalTextureInfo ?? undefined,\r\n };\r\n\r\n if (clearCoatInfo.clearcoatTexture !== null || clearCoatInfo.clearcoatRoughnessTexture !== null || clearCoatInfo.clearcoatRoughnessTexture !== null) {\r\n this._exporter._materialNeedsUVsSet.add(babylonMaterial);\r\n }\r\n\r\n node.extensions[NAME] = clearCoatInfo;\r\n }\r\n resolve(node);\r\n });\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, (exporter) => new KHR_materials_clearcoat(exporter));\r\n","import type { IMaterial, IKHRMaterialsDiffuseTransmission } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport { PBRMaterial } from \"core/Materials/PBR/pbrMaterial\";\r\nimport type { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\nimport { Logger } from \"core/Misc/logger\";\r\nimport type { Nullable } from \"core/types\";\r\n\r\nconst NAME = \"KHR_materials_diffuse_transmission\";\r\n\r\n/**\r\n * Get the appropriate translucency intensity texture for the material.\r\n * @internal\r\n */\r\nfunction GetTranslucencyIntensityTexture(context: string, babylonMaterial: PBRMaterial): Nullable<BaseTexture> {\r\n const subs = babylonMaterial.subSurface;\r\n let texture = null;\r\n\r\n // Check if translucency intensity texture is available or can be derived from thickness texture\r\n if (subs.translucencyIntensityTexture) {\r\n texture = subs.translucencyIntensityTexture;\r\n } else if (subs.thicknessTexture && subs.useMaskFromThicknessTexture) {\r\n texture = subs.thicknessTexture;\r\n }\r\n\r\n if (texture && !subs.useGltfStyleTextures) {\r\n Logger.Warn(`${context}: Translucency intensity texture is not supported when useGltfStyleTextures = false. Ignoring for: ${babylonMaterial.name}`, 1);\r\n return null;\r\n }\r\n\r\n return texture;\r\n}\r\n\r\n/**\r\n * [Proposed Specification](https://github.com/KhronosGroup/glTF/pull/1825)\r\n * !!! Experimental Extension Subject to Changes !!!\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_materials_diffuse_transmission implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n private _exporter: GLTFExporter;\r\n\r\n private _wasUsed = false;\r\n\r\n constructor(exporter: GLTFExporter) {\r\n this._exporter = exporter;\r\n }\r\n\r\n public dispose() {}\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n /**\r\n * After exporting a material, deal with additional textures\r\n * @param context GLTF context of the material\r\n * @param node exported GLTF node\r\n * @param babylonMaterial corresponding babylon material\r\n * @returns array of additional textures to export\r\n */\r\n public postExportMaterialAdditionalTextures?(context: string, node: IMaterial, babylonMaterial: Material): BaseTexture[] {\r\n const additionalTextures: BaseTexture[] = [];\r\n\r\n if (babylonMaterial instanceof PBRMaterial && this._isExtensionEnabled(babylonMaterial)) {\r\n const translucencyIntensityTexture = GetTranslucencyIntensityTexture(context, babylonMaterial);\r\n if (translucencyIntensityTexture) {\r\n additionalTextures.push(translucencyIntensityTexture);\r\n }\r\n if (babylonMaterial.subSurface.translucencyColorTexture) {\r\n additionalTextures.push(babylonMaterial.subSurface.translucencyColorTexture);\r\n }\r\n return additionalTextures;\r\n }\r\n\r\n return additionalTextures;\r\n }\r\n\r\n private _isExtensionEnabled(mat: PBRMaterial): boolean {\r\n // This extension must not be used on a material that also uses KHR_materials_unlit\r\n if (mat.unlit) {\r\n return false;\r\n }\r\n const subs = mat.subSurface;\r\n if (!subs.isTranslucencyEnabled) {\r\n return false;\r\n }\r\n\r\n return (\r\n !mat.unlit &&\r\n !subs.useAlbedoToTintTranslucency &&\r\n subs.useGltfStyleTextures &&\r\n subs.volumeIndexOfRefraction === 1 &&\r\n subs.minimumThickness === 0 &&\r\n subs.maximumThickness === 0\r\n );\r\n }\r\n\r\n /**\r\n * After exporting a material\r\n * @param context GLTF context of the material\r\n * @param node exported GLTF node\r\n * @param babylonMaterial corresponding babylon material\r\n * @returns promise that resolves with the updated node\r\n */\r\n // eslint-disable-next-line no-restricted-syntax\r\n public postExportMaterialAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<IMaterial> {\r\n return new Promise((resolve) => {\r\n if (babylonMaterial instanceof PBRMaterial && this._isExtensionEnabled(babylonMaterial)) {\r\n this._wasUsed = true;\r\n\r\n const subs = babylonMaterial.subSurface;\r\n const translucencyIntensityTexture = GetTranslucencyIntensityTexture(context, babylonMaterial);\r\n\r\n const diffuseTransmissionFactor = subs.translucencyIntensity == 0 ? undefined : subs.translucencyIntensity;\r\n const diffuseTransmissionTexture = this._exporter._materialExporter.getTextureInfo(translucencyIntensityTexture) ?? undefined;\r\n const diffuseTransmissionColorFactor = !subs.translucencyColor || subs.translucencyColor.equalsFloats(1.0, 1.0, 1.0) ? undefined : subs.translucencyColor.asArray();\r\n const diffuseTransmissionColorTexture = this._exporter._materialExporter.getTextureInfo(subs.translucencyColorTexture) ?? undefined;\r\n\r\n const diffuseTransmissionInfo: IKHRMaterialsDiffuseTransmission = {\r\n diffuseTransmissionFactor,\r\n diffuseTransmissionTexture,\r\n diffuseTransmissionColorFactor,\r\n diffuseTransmissionColorTexture,\r\n };\r\n\r\n if (diffuseTransmissionTexture || diffuseTransmissionColorTexture) {\r\n this._exporter._materialNeedsUVsSet.add(babylonMaterial);\r\n }\r\n\r\n node.extensions = node.extensions || {};\r\n node.extensions[NAME] = diffuseTransmissionInfo;\r\n }\r\n resolve(node);\r\n });\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, (exporter) => new KHR_materials_diffuse_transmission(exporter));\r\n","import type { IMaterial, IKHRMaterialsDispersion } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport { PBRMaterial } from \"core/Materials/PBR/pbrMaterial\";\r\n\r\nconst NAME = \"KHR_materials_dispersion\";\r\n\r\n/**\r\n * [Specification](https://github.com/KhronosGroup/glTF/blob/87bd64a7f5e23c84b6aef2e6082069583ed0ddb4/extensions/2.0/Khronos/KHR_materials_dispersion/README.md)\r\n * @experimental\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_materials_dispersion implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n private _wasUsed = false;\r\n\r\n /** Constructor */\r\n constructor() {}\r\n\r\n /** Dispose */\r\n public dispose() {}\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n private _isExtensionEnabled(mat: PBRMaterial): boolean {\r\n // This extension must not be used on a material that also uses KHR_materials_unlit\r\n if (mat.unlit) {\r\n return false;\r\n }\r\n const subs = mat.subSurface;\r\n // this extension requires refraction to be enabled.\r\n if (!subs.isRefractionEnabled && !subs.isDispersionEnabled) {\r\n return false;\r\n }\r\n return true;\r\n }\r\n\r\n /**\r\n * After exporting a material\r\n * @param context GLTF context of the material\r\n * @param node exported GLTF node\r\n * @param babylonMaterial corresponding babylon material\r\n * @returns promise, resolves with the material\r\n */\r\n // eslint-disable-next-line no-restricted-syntax\r\n public postExportMaterialAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<IMaterial> {\r\n return new Promise((resolve) => {\r\n if (babylonMaterial instanceof PBRMaterial && this._isExtensionEnabled(babylonMaterial)) {\r\n this._wasUsed = true;\r\n\r\n const subs = babylonMaterial.subSurface;\r\n const dispersion = subs.dispersion;\r\n\r\n const dispersionInfo: IKHRMaterialsDispersion = {\r\n dispersion: dispersion,\r\n };\r\n node.extensions = node.extensions || {};\r\n node.extensions[NAME] = dispersionInfo;\r\n }\r\n resolve(node);\r\n });\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, () => new KHR_materials_dispersion());\r\n","import type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport { PBRMaterial } from \"core/Materials/PBR/pbrMaterial\";\r\nimport type { IMaterial, IKHRMaterialsEmissiveStrength } from \"babylonjs-gltf2interface\";\r\n\r\nconst NAME = \"KHR_materials_emissive_strength\";\r\n\r\n/**\r\n * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_emissive_strength/README.md)\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_materials_emissive_strength implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n private _wasUsed = false;\r\n\r\n /** Dispose */\r\n public dispose() {}\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n /**\r\n * After exporting a material\r\n * @param context GLTF context of the material\r\n * @param node exported GLTF node\r\n * @param babylonMaterial corresponding babylon material\r\n * @returns promise, resolves with the material\r\n */\r\n public async postExportMaterialAsync(context: string, node: IMaterial, babylonMaterial: Material): Promise<IMaterial> {\r\n return await new Promise((resolve) => {\r\n if (!(babylonMaterial instanceof PBRMaterial)) {\r\n return resolve(node);\r\n }\r\n\r\n const emissiveColor = babylonMaterial.emissiveColor.asArray();\r\n const tempEmissiveStrength = Math.max(...emissiveColor);\r\n\r\n if (tempEmissiveStrength > 1) {\r\n this._wasUsed = true;\r\n\r\n node.extensions ||= {};\r\n\r\n const emissiveStrengthInfo: IKHRMaterialsEmissiveStrength = {\r\n emissiveStrength: tempEmissiveStrength,\r\n };\r\n\r\n // Normalize each value of the emissive factor to have a max value of 1\r\n const newEmissiveFactor = babylonMaterial.emissiveColor.scale(1 / emissiveStrengthInfo.emissiveStrength);\r\n\r\n node.emissiveFactor = newEmissiveFactor.asArray();\r\n node.extensions[NAME] = emissiveStrengthInfo;\r\n }\r\n\r\n return resolve(node);\r\n });\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, (exporter) => new KHR_materials_emissive_strength());\r\n","import type { IMaterial, IKHRMaterialsIor } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport { PBRMaterial } from \"core/Materials/PBR/pbrMaterial\";\r\n\r\nconst NAME = \"KHR_materials_ior\";\r\n\r\n/**\r\n * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_ior/README.md)\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_materials_ior implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n private _wasUsed = false;\r\n\r\n constructor() {}\r\n\r\n /** Dispose */\r\n public dispose() {}\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n private _isExtensionEnabled(mat: PBRMaterial): boolean {\r\n // This extension must not be used on a material that also uses KHR_materials_unlit\r\n if (mat.unlit) {\r\n return false;\r\n }\r\n return mat.indexOfRefraction != undefined && mat.indexOfRefraction != 1.5; // 1.5 is normative default value.\r\n }\r\n\r\n /**\r\n * After exporting a material\r\n * @param context GLTF context of the material\r\n * @param node exported GLTF node\r\n * @param babylonMaterial corresponding babylon material\r\n * @returns promise, resolves with the material\r\n */\r\n // eslint-disable-next-line no-restricted-syntax\r\n public postExportMaterialAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<IMaterial> {\r\n return new Promise((resolve) => {\r\n if (babylonMaterial instanceof PBRMaterial && this._isExtensionEnabled(babylonMaterial)) {\r\n this._wasUsed = true;\r\n\r\n const iorInfo: IKHRMaterialsIor = {\r\n ior: babylonMaterial.indexOfRefraction,\r\n };\r\n node.extensions = node.extensions || {};\r\n node.extensions[NAME] = iorInfo;\r\n }\r\n resolve(node);\r\n });\r\n }\r\n}\r\n\r\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\r\nGLTFExporter.RegisterExtension(NAME, (exporter) => new KHR_materials_ior());\r\n","import type { IMaterial, IKHRMaterialsIridescence } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport { PBRBaseMaterial } from \"core/Materials/PBR/pbrBaseMaterial\";\r\nimport type { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\n\r\nconst NAME = \"KHR_materials_iridescence\";\r\n\r\n/**\r\n * @internal\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_materials_iridescence implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n private _exporter: GLTFExporter;\r\n\r\n private _wasUsed = false;\r\n\r\n constructor(exporter: GLTFExporter) {\r\n this._exporter = exporter;\r\n }\r\n\r\n public dispose() {}\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n public postExportMaterialAdditionalTextures?(context: string, node: IMaterial, babylonMaterial: Material): BaseTexture[] {\r\n const additionalTextures: BaseTexture[] = [];\r\n if (babylonMaterial instanceof PBRBaseMaterial) {\r\n if (babylonMaterial.iridescence.isEnabled) {\r\n if (babylonMaterial.iridescence.texture) {\r\n additionalTextures.push(babylonMaterial.iridescence.texture);\r\n }\r\n if (babylonMaterial.iridescence.thicknessTexture && babylonMaterial.iridescence.thicknessTexture !== babylonMaterial.iridescence.texture) {\r\n additionalTextures.push(babylonMaterial.iridescence.thicknessTexture);\r\n }\r\n return additionalTextures;\r\n }\r\n }\r\n\r\n return [];\r\n }\r\n\r\n // eslint-disable-next-line no-restricted-syntax\r\n public postExportMaterialAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<IMaterial> {\r\n return new Promise((resolve) => {\r\n if (babylonMaterial instanceof PBRBaseMaterial) {\r\n if (!babylonMaterial.iridescence.isEnabled) {\r\n resolve(node);\r\n return;\r\n }\r\n\r\n this._wasUsed = true;\r\n\r\n node.extensions = node.extensions || {};\r\n\r\n const iridescenceTextureInfo = this._exporter._materialExporter.getTextureInfo(babylonMaterial.iridescence.texture);\r\n const iridescenceThicknessTextureInfo = this._exporter._materialExporter.getTextureInfo(babylonMaterial.iridescence.thicknessTexture);\r\n\r\n const iridescenceInfo: IKHRMaterialsIridescence = {\r\n iridescenceFactor: babylonMaterial.iridescence.intensity,\r\n iridescenceIor: babylonMaterial.iridescence.indexOfRefraction,\r\n iridescenceThicknessMinimum: babylonMaterial.iridescence.minimumThickness,\r\n iridescenceThicknessMaximum: babylonMaterial.iridescence.maximumThickness,\r\n\r\n iridescenceTexture: iridescenceTextureInfo ?? undefined,\r\n iridescenceThicknessTexture: iridescenceThicknessTextureInfo ?? undefined,\r\n };\r\n\r\n if (iridescenceInfo.iridescenceTexture !== null || iridescenceInfo.iridescenceThicknessTexture !== null) {\r\n this._exporter._materialNeedsUVsSet.add(babylonMaterial);\r\n }\r\n\r\n node.extensions[NAME] = iridescenceInfo;\r\n }\r\n resolve(node);\r\n });\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, (exporter) => new KHR_materials_iridescence(exporter));\r\n","import type { IMaterial, IKHRMaterialsSheen } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport { PBRMaterial } from \"core/Materials/PBR/pbrMaterial\";\r\nimport type { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\n\r\nconst NAME = \"KHR_materials_sheen\";\r\n\r\n/**\r\n * @internal\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_materials_sheen implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n private _wasUsed = false;\r\n\r\n private _exporter: GLTFExporter;\r\n\r\n constructor(exporter: GLTFExporter) {\r\n this._exporter = exporter;\r\n }\r\n\r\n public dispose() {}\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n public postExportMaterialAdditionalTextures(context: string, node: IMaterial, babylonMaterial: Material): BaseTexture[] {\r\n if (babylonMaterial instanceof PBRMaterial) {\r\n if (babylonMaterial.sheen.isEnabled && babylonMaterial.sheen.texture) {\r\n return [babylonMaterial.sheen.texture];\r\n }\r\n }\r\n\r\n return [];\r\n }\r\n\r\n public async postExportMaterialAsync(context: string, node: IMaterial, babylonMaterial: Material): Promise<IMaterial> {\r\n return await new Promise((resolve) => {\r\n if (babylonMaterial instanceof PBRMaterial) {\r\n if (!babylonMaterial.sheen.isEnabled) {\r\n resolve(node);\r\n return;\r\n }\r\n\r\n this._wasUsed = true;\r\n\r\n if (node.extensions == null) {\r\n node.extensions = {};\r\n }\r\n const sheenInfo: IKHRMaterialsSheen = {\r\n sheenColorFactor: babylonMaterial.sheen.color.asArray(),\r\n sheenRoughnessFactor: babylonMaterial.sheen.roughness ?? 0,\r\n };\r\n\r\n if (sheenInfo.sheenColorTexture !== null || sheenInfo.sheenRoughnessTexture !== null) {\r\n this._exporter._materialNeedsUVsSet.add(babylonMaterial);\r\n }\r\n\r\n if (babylonMaterial.sheen.texture) {\r\n sheenInfo.sheenColorTexture = this._exporter._materialExporter.getTextureInfo(babylonMaterial.sheen.texture) ?? undefined;\r\n }\r\n\r\n if (babylonMaterial.sheen.textureRoughness && !babylonMaterial.sheen.useRoughnessFromMainTexture) {\r\n sheenInfo.sheenRoughnessTexture = this._exporter._materialExporter.getTextureInfo(babylonMaterial.sheen.textureRoughness) ?? undefined;\r\n } else if (babylonMaterial.sheen.texture && babylonMaterial.sheen.useRoughnessFromMainTexture) {\r\n sheenInfo.sheenRoughnessTexture = this._exporter._materialExporter.getTextureInfo(babylonMaterial.sheen.texture) ?? undefined;\r\n }\r\n\r\n node.extensions[NAME] = sheenInfo;\r\n }\r\n resolve(node);\r\n });\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, (exporter) => new KHR_materials_sheen(exporter));\r\n","import type { IMaterial, IKHRMaterialsSpecular } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport { PBRMaterial } from \"core/Materials/PBR/pbrMaterial\";\r\nimport type { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\n\r\nconst NAME = \"KHR_materials_specular\";\r\n\r\n/**\r\n * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_specular/README.md)\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_materials_specular implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n private _exporter: GLTFExporter;\r\n\r\n private _wasUsed = false;\r\n\r\n constructor(exporter: GLTFExporter) {\r\n this._exporter = exporter;\r\n }\r\n\r\n /** Dispose */\r\n public dispose() {}\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n /**\r\n * After exporting a material, deal with the additional textures\r\n * @param context GLTF context of the material\r\n * @param node exported GLTF node\r\n * @param babylonMaterial corresponding babylon material\r\n * @returns array of additional textures to export\r\n */\r\n public postExportMaterialAdditionalTextures?(context: string, node: IMaterial, babylonMaterial: Material): BaseTexture[] {\r\n const additionalTextures: BaseTexture[] = [];\r\n\r\n if (babylonMaterial instanceof PBRMaterial) {\r\n if (this._isExtensionEnabled(babylonMaterial)) {\r\n if (babylonMaterial.metallicReflectanceTexture) {\r\n additionalTextures.push(babylonMaterial.metallicReflectanceTexture);\r\n }\r\n if (babylonMaterial.reflectanceTexture) {\r\n additionalTextures.push(babylonMaterial.reflectanceTexture);\r\n }\r\n return additionalTextures;\r\n }\r\n }\r\n\r\n return additionalTextures;\r\n }\r\n\r\n private _isExtensionEnabled(mat: PBRMaterial): boolean {\r\n // This extension must not be used on a material that also uses KHR_materials_unlit\r\n if (mat.unlit) {\r\n return false;\r\n }\r\n return (\r\n (mat.metallicF0Factor != undefined && mat.metallicF0Factor != 1.0) ||\r\n (mat.metallicReflectanceColor != undefined && !mat.metallicReflectanceColor.equalsFloats(1.0, 1.0, 1.0)) ||\r\n this._hasTexturesExtension(mat)\r\n );\r\n }\r\n\r\n private _hasTexturesExtension(mat: PBRMaterial): boolean {\r\n return mat.metallicReflectanceTexture != null || mat.reflectanceTexture != null;\r\n }\r\n\r\n /**\r\n * After exporting a material\r\n * @param context GLTF context of the material\r\n * @param node exported GLTF node\r\n * @param babylonMaterial corresponding babylon material\r\n * @returns promise, resolves with the material\r\n */\r\n // eslint-disable-next-line no-restricted-syntax\r\n public postExportMaterialAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<IMaterial> {\r\n return new Promise((resolve) => {\r\n if (babylonMaterial instanceof PBRMaterial && this._isExtensionEnabled(babylonMaterial)) {\r\n this._wasUsed = true;\r\n\r\n node.extensions = node.extensions || {};\r\n\r\n const metallicReflectanceTexture = this._exporter._materialExporter.getTextureInfo(babylonMaterial.metallicReflectanceTexture) ?? undefined;\r\n const reflectanceTexture = this._exporter._materialExporter.getTextureInfo(babylonMaterial.reflectanceTexture) ?? undefined;\r\n const metallicF0Factor = babylonMaterial.metallicF0Factor == 1.0 ? undefined : babylonMaterial.metallicF0Factor;\r\n const metallicReflectanceColor = babylonMaterial.metallicReflectanceColor.equalsFloats(1.0, 1.0, 1.0)\r\n ? undefined\r\n : babylonMaterial.metallicReflectanceColor.asArray();\r\n\r\n const specularInfo: IKHRMaterialsSpecular = {\r\n specularFactor: metallicF0Factor,\r\n specularTexture: metallicReflectanceTexture,\r\n specularColorFactor: metallicReflectanceColor,\r\n specularColorTexture: reflectanceTexture,\r\n };\r\n\r\n if (this._hasTexturesExtension(babylonMaterial)) {\r\n this._exporter._materialNeedsUVsSet.add(babylonMaterial);\r\n }\r\n\r\n node.extensions[NAME] = specularInfo;\r\n }\r\n resolve(node);\r\n });\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, (exporter) => new KHR_materials_specular(exporter));\r\n","import type { IMaterial, IKHRMaterialsTransmission } from \"babylonjs-gltf2interface\";\r\nimport { ImageMimeType } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport { PBRMaterial } from \"core/Materials/PBR/pbrMaterial\";\r\nimport type { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\nimport { Logger } from \"core/Misc/logger\";\r\n\r\nconst NAME = \"KHR_materials_transmission\";\r\n\r\n/**\r\n * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_transmission/README.md)\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_materials_transmission implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n private _exporter: GLTFExporter;\r\n\r\n private _wasUsed = false;\r\n\r\n constructor(exporter: GLTFExporter) {\r\n this._exporter = exporter;\r\n }\r\n\r\n /** Dispose */\r\n public dispose() {}\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n /**\r\n * After exporting a material, deal with additional textures\r\n * @param context GLTF context of the material\r\n * @param node exported GLTF node\r\n * @param babylonMaterial corresponding babylon material\r\n * @returns array of additional textures to export\r\n */\r\n public postExportMaterialAdditionalTextures?(context: string, node: IMaterial, babylonMaterial: Material): BaseTexture[] {\r\n const additionalTextures: BaseTexture[] = [];\r\n\r\n if (babylonMaterial instanceof PBRMaterial) {\r\n if (this._isExtensionEnabled(babylonMaterial)) {\r\n if (babylonMaterial.subSurface.thicknessTexture) {\r\n additionalTextures.push(babylonMaterial.subSurface.thicknessTexture);\r\n }\r\n return additionalTextures;\r\n }\r\n }\r\n\r\n return additionalTextures;\r\n }\r\n\r\n private _isExtensionEnabled(mat: PBRMaterial): boolean {\r\n // This extension must not be used on a material that also uses KHR_materials_unlit\r\n if (mat.unlit) {\r\n return false;\r\n }\r\n const subs = mat.subSurface;\r\n return (subs.isRefractionEnabled && subs.refractionIntensity != undefined && subs.refractionIntensity != 0) || this._hasTexturesExtension(mat);\r\n }\r\n\r\n private _hasTexturesExtension(mat: PBRMaterial): boolean {\r\n return mat.subSurface.refractionIntensityTexture != null;\r\n }\r\n\r\n /**\r\n * After exporting a material\r\n * @param context GLTF context of the material\r\n * @param node exported GLTF node\r\n * @param babylonMaterial corresponding babylon material\r\n * @returns true if successful\r\n */\r\n public async postExportMaterialAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<IMaterial> {\r\n if (babylonMaterial instanceof PBRMaterial && this._isExtensionEnabled(babylonMaterial)) {\r\n this._wasUsed = true;\r\n\r\n const subSurface = babylonMaterial.subSurface;\r\n const transmissionFactor = subSurface.refractionIntensity === 0 ? undefined : subSurface.refractionIntensity;\r\n\r\n const volumeInfo: IKHRMaterialsTransmission = {\r\n transmissionFactor: transmissionFactor,\r\n };\r\n\r\n if (this._hasTexturesExtension(babylonMaterial)) {\r\n this._exporter._materialNeedsUVsSet.add(babylonMaterial);\r\n }\r\n\r\n if (subSurface.refractionIntensityTexture) {\r\n if (subSurface.useGltfStyleTextures) {\r\n const transmissionTexture = await this._exporter._materialExporter.exportTextureAsync(subSurface.refractionIntensityTexture, ImageMimeType.PNG);\r\n if (transmissionTexture) {\r\n volumeInfo.transmissionTexture = transmissionTexture;\r\n }\r\n } else {\r\n Logger.Warn(`${context}: Exporting a subsurface refraction intensity texture without \\`useGltfStyleTextures\\` is not supported`);\r\n }\r\n }\r\n\r\n node.extensions ||= {};\r\n node.extensions[NAME] = volumeInfo;\r\n }\r\n\r\n return node;\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, (exporter) => new KHR_materials_transmission(exporter));\r\n","import type { IMaterial } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport { PBRMaterial } from \"core/Materials/PBR/pbrMaterial\";\r\nimport { StandardMaterial } from \"core/Materials/standardMaterial\";\r\n\r\nconst NAME = \"KHR_materials_unlit\";\r\n\r\n/**\r\n * @internal\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_materials_unlit implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n private _wasUsed = false;\r\n\r\n constructor() {}\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n public dispose() {}\r\n\r\n // eslint-disable-next-line no-restricted-syntax\r\n public postExportMaterialAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<IMaterial> {\r\n return new Promise((resolve) => {\r\n let unlitMaterial = false;\r\n\r\n if (babylonMaterial instanceof PBRMaterial) {\r\n unlitMaterial = babylonMaterial.unlit;\r\n } else if (babylonMaterial instanceof StandardMaterial) {\r\n unlitMaterial = babylonMaterial.disableLighting;\r\n }\r\n\r\n if (unlitMaterial) {\r\n this._wasUsed = true;\r\n\r\n if (node.extensions == null) {\r\n node.extensions = {};\r\n }\r\n\r\n node.extensions[NAME] = {};\r\n }\r\n\r\n resolve(node);\r\n });\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, () => new KHR_materials_unlit());\r\n","import type { IMaterial, IKHRMaterialsVolume } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport { PBRMaterial } from \"core/Materials/PBR/pbrMaterial\";\r\nimport type { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\nimport { Color3 } from \"core/Maths/math.color\";\r\n\r\nconst NAME = \"KHR_materials_volume\";\r\n\r\n/**\r\n * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_volume/README.md)\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_materials_volume implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n private _exporter: GLTFExporter;\r\n\r\n private _wasUsed = false;\r\n\r\n constructor(exporter: GLTFExporter) {\r\n this._exporter = exporter;\r\n }\r\n\r\n public dispose() {}\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n /**\r\n * After exporting a material, deal with additional textures\r\n * @param context GLTF context of the material\r\n * @param node exported GLTF node\r\n * @param babylonMaterial corresponding babylon material\r\n * @returns array of additional textures to export\r\n */\r\n public postExportMaterialAdditionalTextures?(context: string, node: IMaterial, babylonMaterial: Material): BaseTexture[] {\r\n const additionalTextures: BaseTexture[] = [];\r\n\r\n if (babylonMaterial instanceof PBRMaterial) {\r\n if (this._isExtensionEnabled(babylonMaterial)) {\r\n if (babylonMaterial.subSurface.thicknessTexture) {\r\n additionalTextures.push(babylonMaterial.subSurface.thicknessTexture);\r\n }\r\n return additionalTextures;\r\n }\r\n }\r\n\r\n return additionalTextures;\r\n }\r\n\r\n private _isExtensionEnabled(mat: PBRMaterial): boolean {\r\n // This extension must not be used on a material that also uses KHR_materials_unlit\r\n if (mat.unlit) {\r\n return false;\r\n }\r\n const subs = mat.subSurface;\r\n // this extension requires either the KHR_materials_transmission or KHR_materials_diffuse_transmission extensions.\r\n if (!subs.isRefractionEnabled && !subs.isTranslucencyEnabled) {\r\n return false;\r\n }\r\n return (\r\n (subs.maximumThickness != undefined && subs.maximumThickness != 0) ||\r\n (subs.tintColorAtDistance != undefined && subs.tintColorAtDistance != Number.POSITIVE_INFINITY) ||\r\n (subs.tintColor != undefined && subs.tintColor != Color3.White()) ||\r\n this._hasTexturesExtension(mat)\r\n );\r\n }\r\n\r\n private _hasTexturesExtension(mat: PBRMaterial): boolean {\r\n return mat.subSurface.thicknessTexture != null;\r\n }\r\n\r\n /**\r\n * After exporting a material\r\n * @param context GLTF context of the material\r\n * @param node exported GLTF node\r\n * @param babylonMaterial corresponding babylon material\r\n * @returns promise that resolves with the updated node\r\n */\r\n // eslint-disable-next-line no-restricted-syntax\r\n public postExportMaterialAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<IMaterial> {\r\n return new Promise((resolve) => {\r\n if (babylonMaterial instanceof PBRMaterial && this._isExtensionEnabled(babylonMaterial)) {\r\n this._wasUsed = true;\r\n\r\n const subs = babylonMaterial.subSurface;\r\n const thicknessFactor = subs.maximumThickness == 0 ? undefined : subs.maximumThickness;\r\n const thicknessTexture = this._exporter._materialExporter.getTextureInfo(subs.thicknessTexture) ?? undefined;\r\n const attenuationDistance = subs.tintColorAtDistance == Number.POSITIVE_INFINITY ? undefined : subs.tintColorAtDistance;\r\n const attenuationColor = subs.tintColor.equalsFloats(1.0, 1.0, 1.0) ? undefined : subs.tintColor.asArray();\r\n\r\n const volumeInfo: IKHRMaterialsVolume = {\r\n thicknessFactor: thicknessFactor,\r\n thicknessTexture: thicknessTexture,\r\n attenuationDistance: attenuationDistance,\r\n attenuationColor: attenuationColor,\r\n };\r\n\r\n if (this._hasTexturesExtension(babylonMaterial)) {\r\n this._exporter._materialNeedsUVsSet.add(babylonMaterial);\r\n }\r\n\r\n node.extensions = node.extensions || {};\r\n node.extensions[NAME] = volumeInfo;\r\n }\r\n resolve(node);\r\n });\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, (exporter) => new KHR_materials_volume(exporter));\r\n","import type { IMaterial, IEXTMaterialsDiffuseRoughness } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport { PBRBaseMaterial } from \"core/Materials/PBR/pbrBaseMaterial\";\r\nimport type { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\n\r\nconst NAME = \"EXT_materials_diffuse_roughness\";\r\n\r\n/**\r\n * @internal\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class EXT_materials_diffuse_roughness implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n private _exporter: GLTFExporter;\r\n\r\n private _wasUsed = false;\r\n\r\n constructor(exporter: GLTFExporter) {\r\n this._exporter = exporter;\r\n }\r\n\r\n public dispose() {}\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n public postExportMaterialAdditionalTextures?(context: string, node: IMaterial, babylonMaterial: Material): BaseTexture[] {\r\n const additionalTextures: BaseTexture[] = [];\r\n if (babylonMaterial instanceof PBRBaseMaterial) {\r\n if (babylonMaterial._baseDiffuseRoughness) {\r\n if (babylonMaterial._baseDiffuseRoughnessTexture) {\r\n additionalTextures.push(babylonMaterial._baseDiffuseRoughnessTexture);\r\n }\r\n return additionalTextures;\r\n }\r\n }\r\n\r\n return [];\r\n }\r\n\r\n // eslint-disable-next-line no-restricted-syntax\r\n public postExportMaterialAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<IMaterial> {\r\n return new Promise((resolve) => {\r\n if (babylonMaterial instanceof PBRBaseMaterial) {\r\n if (!babylonMaterial._baseDiffuseRoughness) {\r\n resolve(node);\r\n return;\r\n }\r\n\r\n this._wasUsed = true;\r\n\r\n node.extensions = node.extensions || {};\r\n\r\n const diffuseRoughnessTextureInfo = this._exporter._materialExporter.getTextureInfo(babylonMaterial._baseDiffuseRoughnessTexture);\r\n\r\n const diffuseRoughnessInfo: IEXTMaterialsDiffuseRoughness = {\r\n diffuseRoughnessFactor: babylonMaterial._baseDiffuseRoughness,\r\n diffuseRoughnessTexture: diffuseRoughnessTextureInfo ?? undefined,\r\n };\r\n\r\n if (diffuseRoughnessInfo.diffuseRoughnessTexture !== null) {\r\n this._exporter._materialNeedsUVsSet.add(babylonMaterial);\r\n }\r\n\r\n node.extensions[NAME] = diffuseRoughnessInfo;\r\n }\r\n resolve(node);\r\n });\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, (exporter) => new EXT_materials_diffuse_roughness(exporter));\r\n","import type { ITextureInfo, IKHRTextureTransform } from \"babylonjs-gltf2interface\";\r\nimport { Tools } from \"core/Misc/tools\";\r\nimport type { Texture } from \"core/Materials/Textures/texture\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\n\r\nconst NAME = \"KHR_texture_transform\";\r\n\r\n/**\r\n * Computes the adjusted offset for a rotation centered about the origin.\r\n * @internal\r\n */\r\nfunction AdjustOffsetForRotationCenter(babylonTexture: Texture): [number, number] {\r\n const { uOffset, vOffset, uRotationCenter, vRotationCenter, uScale, vScale, wAng } = babylonTexture;\r\n const cosAngle = Math.cos(wAng);\r\n const sinAngle = Math.sin(wAng);\r\n const scaledURotationCenter = uRotationCenter * uScale;\r\n const scaledVRotationCenter = vRotationCenter * vScale;\r\n const deltaU = scaledURotationCenter * (1 - cosAngle) + scaledVRotationCenter * sinAngle;\r\n const deltaV = scaledVRotationCenter * (1 - cosAngle) - scaledURotationCenter * sinAngle;\r\n return [uOffset + deltaU, vOffset + deltaV];\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_texture_transform implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n /** Reference to the glTF exporter */\r\n private _wasUsed = false;\r\n\r\n constructor() {}\r\n\r\n public dispose() {}\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n public postExportTexture?(context: string, textureInfo: ITextureInfo, babylonTexture: Texture): void {\r\n const scene = babylonTexture.getScene();\r\n if (!scene) {\r\n Tools.Warn(`${context}: \"scene\" is not defined for Babylon texture ${babylonTexture.name}!`);\r\n }\r\n\r\n /*\r\n * The KHR_texture_transform schema only supports w rotation around the origin.\r\n * See https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_texture_transform#gltf-schema-updates.\r\n */\r\n if (babylonTexture.uAng !== 0 || babylonTexture.vAng !== 0) {\r\n Tools.Warn(`${context}: Texture ${babylonTexture.name} with rotation in the u or v axis is not supported in glTF.`);\r\n // Usually, we'd always early return here if the texture uses an unsupported combination of transform properties,\r\n // but we're making an exception here to maintain backwards compatibility.\r\n if (babylonTexture.uRotationCenter !== 0 || babylonTexture.vRotationCenter !== 0) {\r\n return;\r\n }\r\n }\r\n\r\n const textureTransform: IKHRTextureTransform = {};\r\n let transformIsRequired = false;\r\n\r\n if (babylonTexture.uOffset !== 0 || babylonTexture.vOffset !== 0) {\r\n textureTransform.offset = [babylonTexture.uOffset, babylonTexture.vOffset];\r\n transformIsRequired = true;\r\n }\r\n\r\n if (babylonTexture.uScale !== 1 || babylonTexture.vScale !== 1) {\r\n textureTransform.scale = [babylonTexture.uScale, babylonTexture.vScale];\r\n transformIsRequired = true;\r\n }\r\n\r\n if (babylonTexture.wAng !== 0) {\r\n if (babylonTexture.uRotationCenter !== 0 || babylonTexture.vRotationCenter !== 0) {\r\n // See https://github.com/mrdoob/three.js/issues/15831 for more details.\r\n if (babylonTexture.homogeneousRotationInUVTransform && babylonTexture.uScale !== babylonTexture.vScale) {\r\n Tools.Warn(\r\n `${context}: Texture ${babylonTexture.name} with homogenousRotationInUVTransform, non-uniform scaling, and non-zero rotation cannot be exported with ${NAME}.`\r\n );\r\n return;\r\n }\r\n Tools.Warn(`${context}: Texture ${babylonTexture.name} with non-origin rotation center will be exported using an adjusted offset with ${NAME}.`);\r\n textureTransform.offset = AdjustOffsetForRotationCenter(babylonTexture);\r\n }\r\n textureTransform.rotation = -babylonTexture.wAng;\r\n transformIsRequired = true;\r\n }\r\n\r\n if (babylonTexture.coordinatesIndex !== 0) {\r\n textureTransform.texCoord = babylonTexture.coordinatesIndex;\r\n transformIsRequired = true;\r\n }\r\n\r\n if (!transformIsRequired) {\r\n return;\r\n }\r\n\r\n this._wasUsed = true;\r\n if (!textureInfo.extensions) {\r\n textureInfo.extensions = {};\r\n }\r\n textureInfo.extensions[NAME] = textureTransform;\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, () => new KHR_texture_transform());\r\n","/* eslint-disable import/no-internal-modules */\r\nimport * as Exporters from \"serializers/glTF/glTFFileExporter\";\r\nimport * as Datas from \"serializers/glTF/2.0/glTFData\";\r\nimport * as Serializers from \"serializers/glTF/2.0/glTFSerializer\";\r\nimport * as Extensions from \"serializers/glTF/2.0/Extensions/index\";\r\nimport * as GLTF2 from \"serializers/glTF/2.0/index\";\r\n\r\n/**\r\n * This is the entry point for the UMD module.\r\n * The entry point for a future ESM package should be index.ts\r\n */\r\nconst globalObject = typeof global !== \"undefined\" ? global : typeof window !== \"undefined\" ? window : undefined;\r\nif (typeof globalObject !== \"undefined\") {\r\n (<any>globalObject).BABYLON = (<any>globalObject).BABYLON || {};\r\n const BABYLON = (<any>globalObject).BABYLON;\r\n BABYLON.GLTF2 = BABYLON.GLTF2 || {};\r\n BABYLON.GLTF2.Exporter = BABYLON.GLTF2.Exporter || {};\r\n BABYLON.GLTF2.Exporter.Extensions = BABYLON.GLTF2.Exporter.Extensions || {};\r\n\r\n const keys = [];\r\n for (const key in Exporters) {\r\n BABYLON[key] = (<any>Exporters)[key];\r\n keys.push(key);\r\n }\r\n for (const key in Datas) {\r\n BABYLON[key] = (<any>Datas)[key];\r\n keys.push(key);\r\n }\r\n for (const key in Serializers) {\r\n BABYLON[key] = (<any>Serializers)[key];\r\n keys.push(key);\r\n }\r\n\r\n for (const key in Extensions) {\r\n BABYLON.GLTF2.Exporter.Extensions[key] = (<any>Extensions)[key];\r\n keys.push(key);\r\n }\r\n\r\n for (const key in GLTF2) {\r\n // Prevent Reassignment.\r\n if (keys.indexOf(key) > -1) {\r\n continue;\r\n }\r\n\r\n BABYLON.GLTF2.Exporter[key] = (<any>GLTF2)[key];\r\n }\r\n}\r\n\r\nexport * from \"serializers/glTF/glTFFileExporter\";\r\nexport * from \"serializers/glTF/2.0/index\";\r\n","import * as serializers from \"@lts/serializers/legacy/legacy-glTF2Serializer\";\r\nexport { serializers };\r\nexport default serializers;\r\n"],"names":["root","factory","exports","module","require","define","amd","self","global","this","__WEBPACK_EXTERNAL_MODULE__597__","leafPrototypes","getProto","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","undefined","__webpack_modules__","Object","getPrototypeOf","obj","t","value","mode","__esModule","then","ns","create","r","def","current","indexOf","getOwnPropertyNames","forEach","key","d","definition","o","defineProperty","enumerable","get","g","globalThis","Function","e","window","prop","prototype","hasOwnProperty","call","Symbol","toStringTag","__IGLTFExporterExtension","files","downloadFiles","blob","Blob","type","GetMimeType","Tools","Download","__assign","assign","s","i","n","arguments","length","p","apply","__awaiter","thisArg","_arguments","P","generator","Promise","resolve","reject","fulfilled","step","next","rejected","result","done","__generator","body","f","y","_","label","sent","trys","ops","Iterator","verb","iterator","v","op","TypeError","pop","push","__spreadArray","to","from","pack","ar","l","Array","slice","concat","SuppressedError","Epsilon","DielectricSpecular","Color3","MaxSpecularPower","White","Black","_SolveMetallic","diffuse","specular","oneMinusSpecularStrength","a","b","Scalar","Clamp","Math","sqrt","_ConvertToGLTFPBRMetallicRoughness","babylonStandardMaterial","diffuseColor","toLinearSpace","getScene","getEngine","useExactSrgbConversions","scale","opacity","alpha","specularPower","roughness","SpecularPowerToRoughness","baseColorFactor","metallicFactor","roughnessFactor","SetAlphaMode","glTFMaterial","babylonMaterial","needAlphaBlending","alphaMode","needAlphaTesting","alphaCutoff","alphaCutOff","CreateWhiteTexture","width","height","scene","data","Uint8Array","RawTexture","CreateRGBATexture","ConvertPixelArrayToFloat32","pixels","buffer","Float32Array","Error","_exporter","_textureMap","Map","_internalTextureToImage","getTextureInfo","babylonTexture","exportStandardMaterialAsync","mimeType","hasUVs","pbrMetallicRoughness","material","name","backFaceCulling","twoSidedLighting","Warn","doubleSided","promises","diffuseTexture","exportTextureAsync","textureInfo","baseColorTexture","bumpTexture","normalTexture","level","emissiveTexture","emissiveFactor","ambientTexture","occlusionTexture","index","_materialNeedsUVsSet","add","all","opacityTexture","Constants","ALPHA_COMBINE","toString","emissiveColor","equalsWithEpsilon","asArray","_finishMaterialAsync","materials","_materials","textures","_extensionsPostExportMaterialAdditionalTextures","texture","_extensionsPostExportMaterialAsync","_getImageDataAsync","textureType","TEXTURETYPE_UNSIGNED_BYTE","hostingScene","_babylonScene","engine","tempTexture","createRawTexture","TEXTUREFORMAT_RGBA","Texture","NEAREST_SAMPLINGMODE","isWebGPU","TextureTools","ApplyPostProcess","TEXTURE_NEAREST_SAMPLINGMODE","_readTexturePixels","DumpTools","DumpDataAsync","_resizeTexturesToSameDimensions","texture1","texture2","resizedTexture1","resizedTexture2","texture1Size","getSize","texture2Size","CreateResizedCopy","_convertSpecularGlossinessTexturesToMetallicRoughnessAsync","specularGlossinessTexture","factors","resizedTextures","diffuseSize","diffuseBuffer","specularGlossinessBuffer","readPixels","diffusePixels","specularPixels","byteLength","metallicRoughnessBuffer","baseColorBuffer","maxBaseColor","maxMetallic","maxRoughness","h","w","offset","multiply","specularColor","glossiness","specularGlossiness","metallicRoughness","_convertSpecularGlossinessToMetallicRoughness","max","baseColor","metallic","hasAlpha","writeOutMetallicRoughnessTexture","writeOutBaseColorTexture","destinationOffset","linearBaseColorPixel","FromInts","sRGBBaseColorPixel","toGammaSpace","metallicRoughnessTextureData","baseColorTextureData","diffusePerceivedBrightness","_getPerceivedBrightness","specularPerceivedBrightness","_getMaxComponent","baseColorFromDiffuse","baseColorFromSpecular","subtract","Lerp","clampToRef","color","_convertMetalRoughFactorsToMetallicRoughnessAsync","babylonPBRMaterial","glTFPbrMetallicRoughness","_albedoColor","_metallic","_roughness","_albedoTexture","glTFTexture","metallicTexture","_metallicTexture","metallicRoughnessTexture","_getTextureSampler","sampler","wrapS","_getGLTFTextureWrapMode","wrapU","wrapT","wrapV","samplingMode","LINEAR_LINEAR","magFilter","minFilter","LINEAR_NEAREST","NEAREST_LINEAR","NEAREST_LINEAR_MIPLINEAR","NEAREST_NEAREST","NEAREST_LINEAR_MIPNEAREST","LINEAR_NEAREST_MIPNEAREST","LINEAR_NEAREST_MIPLINEAR","NEAREST_NEAREST_MIPLINEAR","LINEAR_LINEAR_MIPLINEAR","LINEAR_LINEAR_MIPNEAREST","NEAREST_NEAREST_MIPNEAREST","wrapMode","WRAP_ADDRESSMODE","CLAMP_ADDRESSMODE","MIRROR_ADDRESSMODE","_convertSpecGlossFactorsToMetallicRoughnessAsync","specGloss","_reflectivityColor","_microSurface","albedoTexture","reflectivityTexture","_reflectivityTexture","useMicrosurfaceFromReflectivityMapAlpha","_useMicroSurfaceFromReflectivityMapAlpha","samplerIndex","_exportTextureSampler","metallicRoughnessFactors","_textures","imageIndex","_exportImage","_exportTextureInfo","coordinatesIndex","exportPBRMaterialAsync","useMetallicRoughness","isMetallicWorkflow","albedoColor","_setMetallicRoughnessPbrMaterialAsync","WithinEpsilon","_twoSidedLighting","_bumpTexture","_ambientTexture","texCoord","extensions","ambientTextureStrength","_ambientTextureStrength","strength","_emissiveTexture","_emissiveColor","_getPixelsFromTextureAsync","format","TEXTUREFORMAT_COMPRESSED_RGBA_BPTC_UNORM","TEXTUREFORMAT_COMPRESSED_SRGB_ALPHA_BPTC_UNORM","TEXTUREFORMAT_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT","TEXTUREFORMAT_COMPRESSED_RGB_BPTC_SIGNED_FLOAT","TEXTUREFORMAT_COMPRESSED_RGBA_S3TC_DXT5","TEXTUREFORMAT_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT","TEXTUREFORMAT_COMPRESSED_RGBA_S3TC_DXT3","TEXTUREFORMAT_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT","TEXTUREFORMAT_COMPRESSED_RGBA_S3TC_DXT1","TEXTUREFORMAT_COMPRESSED_RGB_S3TC_DXT1","TEXTUREFORMAT_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT","TEXTUREFORMAT_COMPRESSED_SRGB_S3TC_DXT1_EXT","TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_4x4","TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR","TEXTUREFORMAT_COMPRESSED_RGB_ETC1_WEBGL","TEXTUREFORMAT_COMPRESSED_RGB8_ETC2","TEXTUREFORMAT_COMPRESSED_SRGB8_ETC2","TEXTUREFORMAT_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2","TEXTUREFORMAT_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2","TEXTUREFORMAT_COMPRESSED_RGBA8_ETC2_EAC","TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC","IsCompressedTextureFormat","textureFormat","GetTextureDataAsync","_texture","extensionPromise","_extensionsPreExportTextureAsync","_exportTextureInfoAsync","textureMimeType","internalTextureToImage","internalTextureUniqueId","getInternalTexture","uniqueId","imageIndexPromise","set","_extensionsPostExportTextures","image","images","_images","_shouldUseGlb","bufferView","_bufferManager","createBufferView","setBufferView","baseName","replace","extension","GetFileExtensionFromMimeType","some","uri","RandomId","_imageData","textureIndex","findIndex","source","samplers","_samplers","ConvertHandednessMatrix","Matrix","Compose","Vector3","Quaternion","Identity","Zero","DefaultTranslation","DefaultScale","One","GetVertexBufferInfo","vertexBuffer","meshes","byteOffset","byteStride","normalized","componentCount","totalVertices","reduce","getTotalVertices","Number","MAX_VALUE","count","kind","getKind","GetAccessorElementCount","accessorType","IsStandardVertexAttribute","VertexBuffer","PositionKind","NormalKind","TangentKind","ColorKind","MatricesIndicesKind","MatricesIndicesExtraKind","MatricesWeightsKind","MatricesWeightsExtraKind","UVKind","UV2Kind","UV3Kind","UV4Kind","UV5Kind","UV6Kind","GetPrimitiveMode","fillMode","Material","TriangleFillMode","TriangleStripDrawMode","TriangleFanDrawMode","PointListDrawMode","PointFillMode","LineLoopDrawMode","LineListDrawMode","LineStripDrawMode","NormalizeTangent","tangent","x","z","ConvertToRightHandedPosition","ConvertToRightHandedRotation","absX","abs","absY","sign","absZ","absW","ConvertCameraRotationToGLTF","rotation","copyFromFloats","IsParentAddedByImporter","babylonNode","parentBabylonNode","TransformNode","getChildren","IsNoopNode","node","useRightHandedSystem","getWorldMatrix","isIdentity","multiplyToRef","TmpVectors","AbstractMesh","geometry","OmitDefaultValues","object","defaultValues","entries","defaultValue","isArray","AreArraysEqual","array1","array2","every","val","TypedArrayToWriteMethod","Int8Array","setInt8","dv","bo","setUint8","Uint8ClampedArray","Int16Array","setInt16","Uint16Array","setUint16","Int32Array","setInt32","Uint32Array","setUint32","setFloat32","Float64Array","setFloat64","_data","_dataView","DataView","_byteOffset","writeTypedArray","_checkGrowBuffer","setMethod","constructor","BYTES_PER_ELEMENT","getOutputData","writeUInt8","writeInt8","writeInt16","entry","writeUInt16","writeInt32","writeUInt32","writeFloat32","writeFloat64","newByteLength","newData","GetHighestByteAlignment","_TangentType","_bufferViewToData","_bufferViewToProperties","_accessorToBufferView","generateBinary","bufferViews","totalByteLength","dataWriter","DataWriter","keys","sort","bufferViewIndex","getPropertiesWithBufferView","delete","createAccessor","componentType","minMax","_verifyBufferView","accessor","min","removeBufferView","bv","getBufferView","getData","has","_IsTransformable","Camera","Light","_CreateNodeAnimation","babylonTransformNode","animation","animationChannelTargetPath","useQuaternion","animationSampleRate","inputs","outputs","keyFrames","getKeys","minMaxKeyFrames","_GLTFAnimation","_CalculateMinMaxKeyFrames","interpolationOrBake","_DeduceInterpolation","interpolation","interpolationType","shouldBakeAnimation","_CreateBakedAnimation","framePerSecond","_CreateLinearOrStepAnimation","_CreateCubicSplineAnimation","samplerInterpolation","inputsMin","FloatRound","inputsMax","_DeduceAnimationInfo","dataAccessorType","property","targetProperty","split","_CreateNodeAnimationFromNodeAnimations","runtimeGLTFAnimation","idleGLTFAnimations","nodeMap","nodes","bufferManager","accessors","useRightHanded","shouldExportAnimation","glTFAnimation","animations","animationInfo","channels","_AddAnimation","hasRunningRuntimeAnimations","_CreateMorphTargetAnimationFromMorphTargetAnimations","Mesh","morphTargetManager","numTargets","getTarget","combinedAnimation","Animation","dataType","loopMode","enableBlending","combinedAnimationKeys","animationKeys","j","animationKey","k","frame","setKeys","_CreateNodeAndMorphAnimationFromAnimationGroups","babylonScene","glTFAnimations","leftHandedNodes","animationGroups","animationGroup","morphAnimations","sampleAnimations","morphAnimationMeshes","Set","animationGroupFrameDiff","targetAnimation","targetedAnimations","target","convertToRightHanded","MorphTarget","morphTargetManagers","find","babylonMesh","mesh","combinedAnimationGroup","sampleAnimationKeys","numAnimationKeys","morphTarget","animationsByMorphTarget","morphTargetAnimation","ANIMATIONTYPE_FLOAT","influence","inTangent","outTangent","morphAnimationChannels","keyframeAccessorIndex","dataAccessorIndex","animationSampler","animationChannel","animationData","currentInput","newInputs","shift","nodeIndex","inputData","output","outputToWrite","FromArrayToRef","toArray","FromEulerVectorToRef","IsIdentity","input","path","minFrame","maxFrame","fps","sampleRate","minMaxFrames","time","quaternionCache","previousTime","maxUsedFrame","currKeyFrame","nextKeyFrame","prevKeyFrame","endFrame","equals","state","repeatCount","_interpolate","_SetInterpolatedValue","_ConvertFactorToVector3OrQuaternion","factor","basePositionRotationOrScale","_GetBasePositionRotationOrScale","componentName","FromArray","normalize","cacheValue","RotationYawPitchRollToRef","keyFrame","_AddKeyframeValue","_AddSplineTangent","INTANGENT","OUTTANGENT","q","rotationQuaternion","position","scaling","newPositionRotationOrScale","animationType","ANIMATIONTYPE_VECTOR3","array","RotationYawPitchRoll","posRotScale","ANIMATIONTYPE_QUATERNION","tangentType","tangentValue","Infinity","BuildMorphTargetBuffers","attributes","flipX","difference","vertexCount","hasPositions","morphPositions","getPositions","originalPositions","getVerticesData","positionData","originalPosition","subtractToRef","floatSize","hasNormals","morphNormals","getNormals","originalNormals","normalData","originalNormal","hasTangents","morphTangents","getTangents","originalTangents","tangentData","originalTangent","morphTangent","hasColors","morphColors","getColors","originalColors","getVertexBuffer","componentSize","colorData","originalColor","difference4","Vector4","wasAddedByNoopNode","_indicesAccessorMap","_vertexBufferViewMap","_vertexAccessorMap","_remappedBufferView","_meshMorphTargetMap","_vertexMapColorAlpha","_exportedNodes","_meshMap","convertedToRightHandedBuffers","getIndicesAccessor","indices","start","flip","setIndicesAccessor","accessorIndex","map1","map2","map3","map4","pushExportedNode","getNodesSet","getVertexBufferView","setVertexBufferView","setRemappedBufferView","getRemappedBufferView","getVertexAccessor","setVertexAccessor","hasVertexColorAlpha","setHasVertexColorAlpha","getMesh","setMesh","meshIndex","bindMorphDataToMesh","morphData","morphTargets","getMorphTargetsFromMesh","options","EngineStore","LastCreatedScene","_glTF","asset","Engine","Version","version","_animations","_accessors","_bufferViews","_cameras","_meshes","_nodes","_scenes","_skins","_materialExporter","GLTFMaterialExporter","_extensions","BufferManager","_shouldExportNodeMap","_nodeMap","_materialMap","_camerasMap","_nodesCameraMap","_skinMap","_nodesSkinMap","_options","shouldExportNode","metadataSelector","metadata","gltf","extras","exportWithoutWaitingForScene","exportUnusedUVs","removeNoopRootNodes","includeCoordinateSystemConversionNodes","meshCompressionMethod","_loadExtensions","_ApplyExtension","actionAsync","currentPromise","newNode","_ApplyExtensions","GLTFExporter","_ExtensionNames","context","preExportTextureAsync","_extensionsPostExportNodeAsync","postExportNodeAsync","postExportMaterialAsync","postExportMaterialAdditionalTextures","postExportTexture","_extensionsPostExportMeshPrimitive","primitive","postExportMeshPrimitive","_extensionsPreGenerateBinaryAsync","preGenerateBinaryAsync","_forEachExtensions","action","enabled","_extensionsOnExporting","wasUsed","extensionsUsed","required","extensionsRequired","onExporting","_ExtensionFactories","dispose","RegisterExtension","UnregisterExtension","splice","_generateJSON","bufferByteLength","fileName","prettyPrint","buffers","scenes","cameras","skins","JSON","stringify","generateGLTFAsync","glTFPrefix","_generateBinaryAsync","binaryBuffer","jsonText","bin","glTFFileName","glTFBinFile","container","GLTFData","_exportSceneAsync","_getPadding","num","remainder","generateGLBAsync","glbFileName","jsonLength","TextEncoder","encoder","encodedJsonText","encode","jsonPadding","binPadding","headerLength","headerBuffer","ArrayBuffer","headerBufferView","jsonChunkBuffer","jsonChunkBufferView","jsonData","blankCharCode","charCodeAt","charCode","codePointAt","jsonPaddingView","binaryChunkBuffer","binaryChunkBufferView","binPaddingBuffer","binPaddingView","glbFile","_setNodeTransformation","getPivotPoint","equalsToFloats","translation","copyFrom","FromEulerAngles","multiplyInPlace","_setCameraTransformation","babylonCamera","parent","parentWorldMatrix","Invert","decompose","_listAvailableCameras","camera","glTFCamera","PERSPECTIVE_CAMERA","perspective","aspectRatio","getAspectRatio","yfov","fovMode","FOVMODE_VERTICAL_FIXED","fov","znear","minZ","zfar","maxZ","halfWidth","orthoLeft","orthoRight","getRenderWidth","halfHeight","orthoBottom","orthoTop","getRenderHeight","orthographic","xmag","ymag","_exportAndAssignCameras","values","gltfCamera","usedNodes","_listAvailableSkeletons","skeletons","skeleton","bones","joints","_exportAndAssignSkeletons","skin","boneIndexMap","inverseBindMatrices","maxBoneIndex","bone","boneIndex","getIndex","getAbsoluteInverseBindMatrix","transformNode","getTransformNode","nodeID","skinedNodes","mat","m","rootNodesRH","rootNodesLH","rootNoopNodesRH","rootNodes","rootNode","stateLH","ExporterState","_exportNodesAsync","stateRH","noopRH","_animationSampleRate","_shouldExportNode","babylonRootNodes","_exportBuffers","_exportNodeAsync","_collectBuffers","bufferToVertexBuffersMap","vertexBufferToMeshesMap","morphTargetsToMeshesMap","vertexBuffers","getVertexBuffers","hasVertexAlpha","_buffer","vertexBufferArray","morphIndex","babylonChildNode","morphTargetsMeshesMap","bytes","floatData","isView","DataArrayToUint8Array","EnumerateFloatValues","invLength","stdMaterialCount","filter","StandardMaterial","Logger","UNSIGNED_BYTE","Color4","fromArray","toLinearSpaceToRef","floatMatricesIndices","FLOAT","getFloatData","size","is16Bit","newArray","glTFMorphTarget","parentNodeChildren","includes","_createNodeAsync","idleGLTFAnimation","children","InstancedMesh","sourceMesh","subMeshes","_exportMeshAsync","parentNodeIndex","parentNode","RotateNode180Y","_exportIndices","is32Bits","sideOrientation","indicesToExport","invertedMaterial","CounterClockWiseSideOrientation","flipWhenInvertedMaterial","IsTriangleFillMode","newIndices","subarray","IndicesArrayToTypedArray","_exportVertexBuffer","startsWith","fill","GetMinMax","isFloatMatricesIndices","vertexBufferType","vertexBufferNormalized","GetAccessorType","GetAttributeType","_exportMaterialAsync","subMesh","materialIndex","MultiMaterial","subMaterials","PBRMaterial","getClassName","primitives","isUnIndexed","getIndices","isLinesMesh","LinesMesh","isGreasedLineMesh","GreasedLineBaseMesh","getMaterial","defaultMaterial","babylonLinesMesh","colorWhite","greasedLineMaterial","overrideRenderingFillMode","_getEffectiveOrientation","AreIndices32Bits","indexCount","indexStart","verticesStart","verticesCount","targets","gltfMorphTarget","weights","targetNames","GLTFAsync","whenReadyAsync","exporter","GLBAsync","NAME","_wasUsed","hasThinInstances","noTranslation","noRotation","noScale","matrix","thinInstanceGetWorldMatrices","iwt","iwr","iws","hasAnyInstanceWorldTranslation","hasAnyInstanceWorldRotation","hasAnyInstanceWorldScale","translationBuffer","thinInstanceCount","rotationBuffer","scaleBuffer","_buildAccessor","EXT_mesh_gpu_instancing","_bufferViewsUsed","_accessorsUsed","_encodePromises","DracoEncoder","DefaultAvailable","primitiveBufferViews","primitiveAccessors","glTFName","GetTypedArrayData","GetTypeByteLength","dracoName","method","promise","Default","_encodeAsync","encodedData","dracoInfo","attributeIds","catch","error","clear","KHR_draco_mesh_compression","DEFAULTS","intensity","range","SPOTDEFAULTS","innerConeAngle","outerConeAngle","PI","LIGHTDIRECTION","Backward","_lights","ShadowLight","lightType","getTypeID","LIGHTTYPEID_POINTLIGHT","LIGHTTYPEID_DIRECTIONALLIGHT","LIGHTTYPEID_SPOTLIGHT","falloffType","FALLOFF_GLTF","direction","normalizeToRef","angle","acos","Dot","axis","Cross","lightRotationQuaternion","RotationAxisToRef","light","babylonSpotLight","spot","innerAngle","lights","lightReference","parentTranslation","parentRotation","parentScale","parentMatrix","ComposeToRef","CollapseParentNode","KHR_lights_punctual","additionalTextures","PBRBaseMaterial","anisotropy","isEnabled","legacy","anisotropyTextureInfo","anisotropyInfo","anisotropyStrength","anisotropyRotation","anisotropyTexture","KHR_materials_anisotropy","clearCoat","useRoughnessFromMainTexture","textureRoughness","clearCoatTextureRoughnessInfo","clearCoatTextureInfo","isTintEnabled","remapF0OnInterfaceChange","clearCoatNormalTextureInfo","clearCoatInfo","clearcoatFactor","clearcoatTexture","clearcoatRoughnessFactor","clearcoatRoughnessTexture","clearcoatNormalTexture","KHR_materials_clearcoat","GetTranslucencyIntensityTexture","subs","subSurface","translucencyIntensityTexture","thicknessTexture","useMaskFromThicknessTexture","useGltfStyleTextures","_isExtensionEnabled","translucencyColorTexture","unlit","isTranslucencyEnabled","useAlbedoToTintTranslucency","volumeIndexOfRefraction","minimumThickness","maximumThickness","diffuseTransmissionFactor","translucencyIntensity","diffuseTransmissionTexture","diffuseTransmissionColorFactor","translucencyColor","equalsFloats","diffuseTransmissionColorTexture","diffuseTransmissionInfo","KHR_materials_diffuse_transmission","isRefractionEnabled","isDispersionEnabled","dispersionInfo","dispersion","KHR_materials_dispersion","tempEmissiveStrength","emissiveStrengthInfo","emissiveStrength","newEmissiveFactor","KHR_materials_emissive_strength","indexOfRefraction","iorInfo","ior","KHR_materials_ior","iridescence","iridescenceTextureInfo","iridescenceThicknessTextureInfo","iridescenceInfo","iridescenceFactor","iridescenceIor","iridescenceThicknessMinimum","iridescenceThicknessMaximum","iridescenceTexture","iridescenceThicknessTexture","KHR_materials_iridescence","sheen","sheenInfo","sheenColorFactor","sheenRoughnessFactor","sheenColorTexture","sheenRoughnessTexture","KHR_materials_sheen","metallicReflectanceTexture","reflectanceTexture","metallicF0Factor","metallicReflectanceColor","_hasTexturesExtension","specularInfo","specularFactor","specularTexture","specularColorFactor","specularColorTexture","KHR_materials_specular","refractionIntensity","refractionIntensityTexture","transmissionFactor","volumeInfo","transmissionTexture","KHR_materials_transmission","unlitMaterial","disableLighting","KHR_materials_unlit","tintColorAtDistance","POSITIVE_INFINITY","tintColor","thicknessFactor","attenuationDistance","attenuationColor","KHR_materials_volume","_baseDiffuseRoughness","_baseDiffuseRoughnessTexture","diffuseRoughnessTextureInfo","diffuseRoughnessInfo","diffuseRoughnessFactor","diffuseRoughnessTexture","EXT_materials_diffuse_roughness","uAng","vAng","uRotationCenter","vRotationCenter","textureTransform","transformIsRequired","uOffset","vOffset","uScale","vScale","wAng","homogeneousRotationInUVTransform","cosAngle","cos","sinAngle","sin","scaledURotationCenter","scaledVRotationCenter","AdjustOffsetForRotationCenter","KHR_texture_transform","globalObject","BABYLON","GLTF2","Exporter","Extensions"],"sourceRoot":""}
|
|
1
|
+
{"version":3,"file":"babylon.glTF2Serializer.min.js","mappings":"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","sources":["webpack://SERIALIZERS/webpack/universalModuleDefinition","webpack://SERIALIZERS/webpack/runtime/create fake namespace object","webpack://SERIALIZERS/external umd {\"root\":\"BABYLON\",\"commonjs\":\"babylonjs\",\"commonjs2\":\"babylonjs\",\"amd\":\"babylonjs\"}","webpack://SERIALIZERS/webpack/bootstrap","webpack://SERIALIZERS/webpack/runtime/define property getters","webpack://SERIALIZERS/webpack/runtime/global","webpack://SERIALIZERS/webpack/runtime/hasOwnProperty shorthand","webpack://SERIALIZERS/webpack/runtime/make namespace object","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/glTFFileExporter.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/glTFData.ts","webpack://SERIALIZERS/../../../../node_modules/tslib/tslib.es6.mjs","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/glTFMaterialExporter.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/glTFUtilities.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/dataWriter.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/bufferManager.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/glTFAnimation.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/glTFMorphTargetsUtilities.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/glTFExporter.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/glTFSerializer.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_draco_mesh_compression.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_lights_punctual.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_anisotropy.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_clearcoat.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_dispersion.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_emissive_strength.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_ior.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_iridescence.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_sheen.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_specular.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_transmission.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_unlit.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_materials_volume.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/EXT_materials_diffuse_roughness.ts","webpack://SERIALIZERS/../../../dev/serializers/src/glTF/2.0/Extensions/KHR_texture_transform.ts","webpack://SERIALIZERS/../../../lts/serializers/src/legacy/legacy-glTF2Serializer.ts","webpack://SERIALIZERS/./src/glTF2.ts"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory(require(\"babylonjs\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine(\"babylonjs-serializers\", [\"babylonjs\"], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"babylonjs-serializers\"] = factory(require(\"babylonjs\"));\n\telse\n\t\troot[\"SERIALIZERS\"] = factory(root[\"BABYLON\"]);\n})((typeof self !== \"undefined\" ? self : typeof global !== \"undefined\" ? global : this), (__WEBPACK_EXTERNAL_MODULE__597__) => {\nreturn ","var getProto = Object.getPrototypeOf ? (obj) => (Object.getPrototypeOf(obj)) : (obj) => (obj.__proto__);\nvar leafPrototypes;\n// create a fake namespace object\n// mode & 1: value is a module id, require it\n// mode & 2: merge all properties of value into the ns\n// mode & 4: return value when already ns object\n// mode & 16: return value when it's Promise-like\n// mode & 8|1: behave like require\n__webpack_require__.t = function(value, mode) {\n\tif(mode & 1) value = this(value);\n\tif(mode & 8) return value;\n\tif(typeof value === 'object' && value) {\n\t\tif((mode & 4) && value.__esModule) return value;\n\t\tif((mode & 16) && typeof value.then === 'function') return value;\n\t}\n\tvar ns = Object.create(null);\n\t__webpack_require__.r(ns);\n\tvar def = {};\n\tleafPrototypes = leafPrototypes || [null, getProto({}), getProto([]), getProto(getProto)];\n\tfor(var current = mode & 2 && value; typeof current == 'object' && !~leafPrototypes.indexOf(current); current = getProto(current)) {\n\t\tObject.getOwnPropertyNames(current).forEach((key) => (def[key] = () => (value[key])));\n\t}\n\tdef['default'] = () => (value);\n\t__webpack_require__.d(ns, def);\n\treturn ns;\n};","module.exports = __WEBPACK_EXTERNAL_MODULE__597__;","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.g = (function() {\n\tif (typeof globalThis === 'object') return globalThis;\n\ttry {\n\t\treturn this || new Function('return this')();\n\t} catch (e) {\n\t\tif (typeof window === 'object') return window;\n\t}\n})();","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","/** @internal */\r\n// eslint-disable-next-line no-var, @typescript-eslint/naming-convention\r\nexport var __IGLTFExporterExtension = 0; // I am here to allow dts to be created\r\n\r\n/**\r\n * Interface for extending the exporter\r\n * @internal\r\n */\r\nexport interface IGLTFExporterExtension {\r\n /**\r\n * The name of this extension\r\n */\r\n readonly name: string;\r\n /**\r\n * Defines whether this extension is enabled\r\n */\r\n enabled: boolean;\r\n\r\n /**\r\n * Defines whether this extension is required\r\n */\r\n required: boolean;\r\n}\r\n","import { GetMimeType } from \"core/Misc/fileTools\";\r\nimport { Tools } from \"core/Misc/tools\";\r\n\r\n/**\r\n * Class for holding and downloading glTF file data\r\n */\r\nexport class GLTFData {\r\n /**\r\n * Object which contains the file name as the key and its data as the value\r\n */\r\n public readonly files: { [fileName: string]: string | Blob } = {};\r\n\r\n /**\r\n * @deprecated Use files instead\r\n */\r\n public get glTFFiles() {\r\n return this.files;\r\n }\r\n\r\n /**\r\n * Downloads the glTF data as files based on their names and data\r\n */\r\n public downloadFiles(): void {\r\n for (const key in this.files) {\r\n const value = this.files[key];\r\n const blob = new Blob([value], { type: GetMimeType(key) });\r\n Tools.Download(blob, key);\r\n }\r\n }\r\n}\r\n","/******************************************************************************\nCopyright (c) Microsoft Corporation.\n\nPermission to use, copy, modify, and/or distribute this software for any\npurpose with or without fee is hereby granted.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\nPERFORMANCE OF THIS SOFTWARE.\n***************************************************************************** */\n/* global Reflect, Promise, SuppressedError, Symbol, Iterator */\n\nvar extendStatics = function(d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n};\n\nexport function __extends(d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n}\n\nexport var __assign = function() {\n __assign = Object.assign || function __assign(t) {\n for (var s, i = 1, n = arguments.length; i < n; i++) {\n s = arguments[i];\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\n }\n return t;\n }\n return __assign.apply(this, arguments);\n}\n\nexport function __rest(s, e) {\n var t = {};\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\n t[p] = s[p];\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\n t[p[i]] = s[p[i]];\n }\n return t;\n}\n\nexport function __decorate(decorators, target, key, desc) {\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\n return c > 3 && r && Object.defineProperty(target, key, r), r;\n}\n\nexport function __param(paramIndex, decorator) {\n return function (target, key) { decorator(target, key, paramIndex); }\n}\n\nexport function __esDecorate(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {\n function accept(f) { if (f !== void 0 && typeof f !== \"function\") throw new TypeError(\"Function expected\"); return f; }\n var kind = contextIn.kind, key = kind === \"getter\" ? \"get\" : kind === \"setter\" ? \"set\" : \"value\";\n var target = !descriptorIn && ctor ? contextIn[\"static\"] ? ctor : ctor.prototype : null;\n var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});\n var _, done = false;\n for (var i = decorators.length - 1; i >= 0; i--) {\n var context = {};\n for (var p in contextIn) context[p] = p === \"access\" ? {} : contextIn[p];\n for (var p in contextIn.access) context.access[p] = contextIn.access[p];\n context.addInitializer = function (f) { if (done) throw new TypeError(\"Cannot add initializers after decoration has completed\"); extraInitializers.push(accept(f || null)); };\n var result = (0, decorators[i])(kind === \"accessor\" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);\n if (kind === \"accessor\") {\n if (result === void 0) continue;\n if (result === null || typeof result !== \"object\") throw new TypeError(\"Object expected\");\n if (_ = accept(result.get)) descriptor.get = _;\n if (_ = accept(result.set)) descriptor.set = _;\n if (_ = accept(result.init)) initializers.unshift(_);\n }\n else if (_ = accept(result)) {\n if (kind === \"field\") initializers.unshift(_);\n else descriptor[key] = _;\n }\n }\n if (target) Object.defineProperty(target, contextIn.name, descriptor);\n done = true;\n};\n\nexport function __runInitializers(thisArg, initializers, value) {\n var useValue = arguments.length > 2;\n for (var i = 0; i < initializers.length; i++) {\n value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);\n }\n return useValue ? value : void 0;\n};\n\nexport function __propKey(x) {\n return typeof x === \"symbol\" ? x : \"\".concat(x);\n};\n\nexport function __setFunctionName(f, name, prefix) {\n if (typeof name === \"symbol\") name = name.description ? \"[\".concat(name.description, \"]\") : \"\";\n return Object.defineProperty(f, \"name\", { configurable: true, value: prefix ? \"\".concat(prefix, \" \", name) : name });\n};\n\nexport function __metadata(metadataKey, metadataValue) {\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\n}\n\nexport function __awaiter(thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n}\n\nexport function __generator(thisArg, body) {\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === \"function\" ? Iterator : Object).prototype);\n return g.next = verb(0), g[\"throw\"] = verb(1), g[\"return\"] = verb(2), typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\n function verb(n) { return function (v) { return step([n, v]); }; }\n function step(op) {\n if (f) throw new TypeError(\"Generator is already executing.\");\n while (g && (g = 0, op[0] && (_ = 0)), _) try {\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\n if (y = 0, t) op = [op[0] & 2, t.value];\n switch (op[0]) {\n case 0: case 1: t = op; break;\n case 4: _.label++; return { value: op[1], done: false };\n case 5: _.label++; y = op[1]; op = [0]; continue;\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\n default:\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\n if (t[2]) _.ops.pop();\n _.trys.pop(); continue;\n }\n op = body.call(thisArg, _);\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\n }\n}\n\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() { return m[k]; } };\n }\n Object.defineProperty(o, k2, desc);\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n});\n\nexport function __exportStar(m, o) {\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\n}\n\nexport function __values(o) {\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\n if (m) return m.call(o);\n if (o && typeof o.length === \"number\") return {\n next: function () {\n if (o && i >= o.length) o = void 0;\n return { value: o && o[i++], done: !o };\n }\n };\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\n}\n\nexport function __read(o, n) {\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\n if (!m) return o;\n var i = m.call(o), r, ar = [], e;\n try {\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\n }\n catch (error) { e = { error: error }; }\n finally {\n try {\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\n }\n finally { if (e) throw e.error; }\n }\n return ar;\n}\n\n/** @deprecated */\nexport function __spread() {\n for (var ar = [], i = 0; i < arguments.length; i++)\n ar = ar.concat(__read(arguments[i]));\n return ar;\n}\n\n/** @deprecated */\nexport function __spreadArrays() {\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\n r[k] = a[j];\n return r;\n}\n\nexport function __spreadArray(to, from, pack) {\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\n if (ar || !(i in from)) {\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\n ar[i] = from[i];\n }\n }\n return to.concat(ar || Array.prototype.slice.call(from));\n}\n\nexport function __await(v) {\n return this instanceof __await ? (this.v = v, this) : new __await(v);\n}\n\nexport function __asyncGenerator(thisArg, _arguments, generator) {\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\n return i = Object.create((typeof AsyncIterator === \"function\" ? AsyncIterator : Object).prototype), verb(\"next\"), verb(\"throw\"), verb(\"return\", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i;\n function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; }\n function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } }\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\n function fulfill(value) { resume(\"next\", value); }\n function reject(value) { resume(\"throw\", value); }\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\n}\n\nexport function __asyncDelegator(o) {\n var i, p;\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: false } : f ? f(v) : v; } : f; }\n}\n\nexport function __asyncValues(o) {\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n var m = o[Symbol.asyncIterator], i;\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\n}\n\nexport function __makeTemplateObject(cooked, raw) {\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\n return cooked;\n};\n\nvar __setModuleDefault = Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n};\n\nvar ownKeys = function(o) {\n ownKeys = Object.getOwnPropertyNames || function (o) {\n var ar = [];\n for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;\n return ar;\n };\n return ownKeys(o);\n};\n\nexport function __importStar(mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== \"default\") __createBinding(result, mod, k[i]);\n __setModuleDefault(result, mod);\n return result;\n}\n\nexport function __importDefault(mod) {\n return (mod && mod.__esModule) ? mod : { default: mod };\n}\n\nexport function __classPrivateFieldGet(receiver, state, kind, f) {\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\n}\n\nexport function __classPrivateFieldSet(receiver, state, value, kind, f) {\n if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\n return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\n}\n\nexport function __classPrivateFieldIn(state, receiver) {\n if (receiver === null || (typeof receiver !== \"object\" && typeof receiver !== \"function\")) throw new TypeError(\"Cannot use 'in' operator on non-object\");\n return typeof state === \"function\" ? receiver === state : state.has(receiver);\n}\n\nexport function __addDisposableResource(env, value, async) {\n if (value !== null && value !== void 0) {\n if (typeof value !== \"object\" && typeof value !== \"function\") throw new TypeError(\"Object expected.\");\n var dispose, inner;\n if (async) {\n if (!Symbol.asyncDispose) throw new TypeError(\"Symbol.asyncDispose is not defined.\");\n dispose = value[Symbol.asyncDispose];\n }\n if (dispose === void 0) {\n if (!Symbol.dispose) throw new TypeError(\"Symbol.dispose is not defined.\");\n dispose = value[Symbol.dispose];\n if (async) inner = dispose;\n }\n if (typeof dispose !== \"function\") throw new TypeError(\"Object not disposable.\");\n if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };\n env.stack.push({ value: value, dispose: dispose, async: async });\n }\n else if (async) {\n env.stack.push({ async: true });\n }\n return value;\n}\n\nvar _SuppressedError = typeof SuppressedError === \"function\" ? SuppressedError : function (error, suppressed, message) {\n var e = new Error(message);\n return e.name = \"SuppressedError\", e.error = error, e.suppressed = suppressed, e;\n};\n\nexport function __disposeResources(env) {\n function fail(e) {\n env.error = env.hasError ? new _SuppressedError(e, env.error, \"An error was suppressed during disposal.\") : e;\n env.hasError = true;\n }\n var r, s = 0;\n function next() {\n while (r = env.stack.pop()) {\n try {\n if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);\n if (r.dispose) {\n var result = r.dispose.call(r.value);\n if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });\n }\n else s |= 1;\n }\n catch (e) {\n fail(e);\n }\n }\n if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();\n if (env.hasError) throw env.error;\n }\n return next();\n}\n\nexport function __rewriteRelativeImportExtension(path, preserveJsx) {\n if (typeof path === \"string\" && /^\\.\\.?\\//.test(path)) {\n return path.replace(/\\.(tsx)$|((?:\\.d)?)((?:\\.[^./]+?)?)\\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {\n return tsx ? preserveJsx ? \".jsx\" : \".js\" : d && (!ext || !cm) ? m : (d + ext + \".\" + cm.toLowerCase() + \"js\");\n });\n }\n return path;\n}\n\nexport default {\n __extends,\n __assign,\n __rest,\n __decorate,\n __param,\n __esDecorate,\n __runInitializers,\n __propKey,\n __setFunctionName,\n __metadata,\n __awaiter,\n __generator,\n __createBinding,\n __exportStar,\n __values,\n __read,\n __spread,\n __spreadArrays,\n __spreadArray,\n __await,\n __asyncGenerator,\n __asyncDelegator,\n __asyncValues,\n __makeTemplateObject,\n __importStar,\n __importDefault,\n __classPrivateFieldGet,\n __classPrivateFieldSet,\n __classPrivateFieldIn,\n __addDisposableResource,\n __disposeResources,\n __rewriteRelativeImportExtension,\n};\n","/* eslint-disable @typescript-eslint/prefer-promise-reject-errors */\r\n/* eslint-disable github/no-then */\r\n/* eslint-disable babylonjs/available */\r\n\r\nimport type { ITextureInfo, IMaterial, IMaterialPbrMetallicRoughness, IMaterialOcclusionTextureInfo, ISampler, IImage } from \"babylonjs-gltf2interface\";\r\nimport { ImageMimeType, MaterialAlphaMode, TextureMagFilter, TextureMinFilter, TextureWrapMode } from \"babylonjs-gltf2interface\";\r\n\r\nimport type { Nullable } from \"core/types\";\r\nimport { Color3 } from \"core/Maths/math.color\";\r\nimport { Scalar } from \"core/Maths/math.scalar\";\r\nimport { Tools } from \"core/Misc/tools\";\r\nimport { GetTextureDataAsync, TextureTools } from \"core/Misc/textureTools\";\r\nimport type { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\nimport { Texture } from \"core/Materials/Textures/texture\";\r\nimport { RawTexture } from \"core/Materials/Textures/rawTexture\";\r\n\r\nimport type { Scene } from \"core/scene\";\r\n\r\nimport type { GLTFExporter } from \"./glTFExporter\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { DumpTools } from \"core/Misc/dumpTools\";\r\n\r\nimport type { Material } from \"core/Materials/material\";\r\nimport type { StandardMaterial } from \"core/Materials/standardMaterial\";\r\nimport type { PBRBaseMaterial } from \"core/Materials/PBR/pbrBaseMaterial\";\r\nimport { SpecularPowerToRoughness } from \"core/Helpers/materialConversionHelper\";\r\n\r\nconst Epsilon = 1e-6;\r\nconst DielectricSpecular = new Color3(0.04, 0.04, 0.04);\r\nconst MaxSpecularPower = 1024;\r\nconst White = Color3.White();\r\nconst Black = Color3.Black();\r\n\r\n/**\r\n * Interface for storing specular glossiness factors\r\n * @internal\r\n */\r\ninterface IPBRSpecularGlossiness {\r\n /**\r\n * Represents the linear diffuse factors of the material\r\n */\r\n diffuseColor: Color3;\r\n specularColor: Color3;\r\n glossiness: number;\r\n}\r\n\r\ninterface IPBRMetallicRoughness {\r\n baseColor: Color3;\r\n metallic: Nullable<number>;\r\n roughness: Nullable<number>;\r\n metallicRoughnessTextureData?: Nullable<ArrayBuffer>;\r\n baseColorTextureData?: Nullable<ArrayBuffer>;\r\n}\r\n\r\nfunction GetFileExtensionFromMimeType(mimeType: ImageMimeType): string {\r\n switch (mimeType) {\r\n case ImageMimeType.JPEG:\r\n return \".jpg\";\r\n case ImageMimeType.PNG:\r\n return \".png\";\r\n case ImageMimeType.WEBP:\r\n return \".webp\";\r\n case ImageMimeType.AVIF:\r\n return \".avif\";\r\n }\r\n}\r\n\r\nfunction IsCompressedTextureFormat(format: number): boolean {\r\n switch (format) {\r\n case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_BPTC_UNORM:\r\n case Constants.TEXTUREFORMAT_COMPRESSED_SRGB_ALPHA_BPTC_UNORM:\r\n case Constants.TEXTUREFORMAT_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT:\r\n case Constants.TEXTUREFORMAT_COMPRESSED_RGB_BPTC_SIGNED_FLOAT:\r\n case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_S3TC_DXT5:\r\n case Constants.TEXTUREFORMAT_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:\r\n case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_S3TC_DXT3:\r\n case Constants.TEXTUREFORMAT_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:\r\n case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_S3TC_DXT1:\r\n case Constants.TEXTUREFORMAT_COMPRESSED_RGB_S3TC_DXT1:\r\n case Constants.TEXTUREFORMAT_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:\r\n case Constants.TEXTUREFORMAT_COMPRESSED_SRGB_S3TC_DXT1_EXT:\r\n case Constants.TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_4x4:\r\n case Constants.TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:\r\n case Constants.TEXTUREFORMAT_COMPRESSED_RGB_ETC1_WEBGL:\r\n case Constants.TEXTUREFORMAT_COMPRESSED_RGB8_ETC2:\r\n case Constants.TEXTUREFORMAT_COMPRESSED_SRGB8_ETC2:\r\n case Constants.TEXTUREFORMAT_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:\r\n case Constants.TEXTUREFORMAT_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:\r\n case Constants.TEXTUREFORMAT_COMPRESSED_RGBA8_ETC2_EAC:\r\n case Constants.TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:\r\n return true;\r\n default:\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Computes the metallic factor from specular glossiness values.\r\n * @param diffuse diffused value\r\n * @param specular specular value\r\n * @param oneMinusSpecularStrength one minus the specular strength\r\n * @returns metallic value\r\n * @internal\r\n */\r\nexport function _SolveMetallic(diffuse: number, specular: number, oneMinusSpecularStrength: number): number {\r\n if (specular < DielectricSpecular.r) {\r\n DielectricSpecular;\r\n return 0;\r\n }\r\n\r\n const a = DielectricSpecular.r;\r\n const b = (diffuse * oneMinusSpecularStrength) / (1.0 - DielectricSpecular.r) + specular - 2.0 * DielectricSpecular.r;\r\n const c = DielectricSpecular.r - specular;\r\n const d = b * b - 4.0 * a * c;\r\n return Scalar.Clamp((-b + Math.sqrt(d)) / (2.0 * a), 0, 1);\r\n}\r\n\r\n/**\r\n * Computes the metallic/roughness factors from a Standard Material.\r\n * @internal\r\n */\r\nexport function _ConvertToGLTFPBRMetallicRoughness(babylonStandardMaterial: StandardMaterial): IMaterialPbrMetallicRoughness {\r\n const diffuse = babylonStandardMaterial.diffuseColor.toLinearSpace(babylonStandardMaterial.getScene().getEngine().useExactSrgbConversions).scale(0.5);\r\n const opacity = babylonStandardMaterial.alpha;\r\n const specularPower = Scalar.Clamp(babylonStandardMaterial.specularPower, 0, MaxSpecularPower);\r\n\r\n const roughness = SpecularPowerToRoughness(specularPower);\r\n\r\n const glTFPbrMetallicRoughness: IMaterialPbrMetallicRoughness = {\r\n baseColorFactor: [diffuse.r, diffuse.g, diffuse.b, opacity],\r\n metallicFactor: 0,\r\n roughnessFactor: roughness,\r\n };\r\n\r\n return glTFPbrMetallicRoughness;\r\n}\r\n\r\n/**\r\n * Sets the glTF alpha mode to a glTF material from the Babylon Material\r\n * @param glTFMaterial glTF material\r\n * @param babylonMaterial Babylon material\r\n */\r\nfunction SetAlphaMode(glTFMaterial: IMaterial, babylonMaterial: Material & { alphaCutOff?: number }): void {\r\n if (babylonMaterial.needAlphaBlending()) {\r\n glTFMaterial.alphaMode = MaterialAlphaMode.BLEND;\r\n } else if (babylonMaterial.needAlphaTesting()) {\r\n glTFMaterial.alphaMode = MaterialAlphaMode.MASK;\r\n glTFMaterial.alphaCutoff = babylonMaterial.alphaCutOff;\r\n }\r\n}\r\n\r\nfunction CreateWhiteTexture(width: number, height: number, scene: Scene): Texture {\r\n const data = new Uint8Array(width * height * 4);\r\n\r\n for (let i = 0; i < data.length; i = i + 4) {\r\n data[i] = data[i + 1] = data[i + 2] = data[i + 3] = 0xff;\r\n }\r\n\r\n const rawTexture = RawTexture.CreateRGBATexture(data, width, height, scene);\r\n\r\n return rawTexture;\r\n}\r\n\r\nfunction ConvertPixelArrayToFloat32(pixels: ArrayBufferView): Float32Array {\r\n if (pixels instanceof Uint8Array) {\r\n const length = pixels.length;\r\n const buffer = new Float32Array(pixels.length);\r\n for (let i = 0; i < length; ++i) {\r\n buffer[i] = pixels[i] / 255;\r\n }\r\n return buffer;\r\n } else if (pixels instanceof Float32Array) {\r\n return pixels;\r\n } else {\r\n throw new Error(\"Unsupported pixel format!\");\r\n }\r\n}\r\n\r\n/**\r\n * Utility methods for working with glTF material conversion properties.\r\n * @internal\r\n */\r\nexport class GLTFMaterialExporter {\r\n // Mapping to store textures\r\n private _textureMap = new Map<BaseTexture, ITextureInfo>();\r\n\r\n // Mapping of internal textures to images to avoid exporting duplicate images\r\n private _internalTextureToImage: { [uniqueId: number]: { [mimeType: string]: Promise<number> } } = {};\r\n\r\n constructor(private readonly _exporter: GLTFExporter) {}\r\n\r\n public getTextureInfo(babylonTexture: Nullable<BaseTexture>): Nullable<ITextureInfo> {\r\n return babylonTexture ? (this._textureMap.get(babylonTexture) ?? null) : null;\r\n }\r\n\r\n public async exportStandardMaterialAsync(babylonStandardMaterial: StandardMaterial, mimeType: ImageMimeType, hasUVs: boolean): Promise<number> {\r\n const pbrMetallicRoughness = _ConvertToGLTFPBRMetallicRoughness(babylonStandardMaterial);\r\n\r\n const material: IMaterial = { name: babylonStandardMaterial.name };\r\n if (babylonStandardMaterial.backFaceCulling != null && !babylonStandardMaterial.backFaceCulling) {\r\n if (!babylonStandardMaterial.twoSidedLighting) {\r\n Tools.Warn(babylonStandardMaterial.name + \": Back-face culling disabled and two-sided lighting disabled is not supported in glTF.\");\r\n }\r\n material.doubleSided = true;\r\n }\r\n\r\n if (hasUVs) {\r\n const promises: Promise<void>[] = [];\r\n\r\n const diffuseTexture = babylonStandardMaterial.diffuseTexture;\r\n if (diffuseTexture) {\r\n promises.push(\r\n this.exportTextureAsync(diffuseTexture, mimeType).then((textureInfo) => {\r\n if (textureInfo) {\r\n pbrMetallicRoughness.baseColorTexture = textureInfo;\r\n }\r\n })\r\n );\r\n }\r\n\r\n const bumpTexture = babylonStandardMaterial.bumpTexture;\r\n if (bumpTexture) {\r\n promises.push(\r\n this.exportTextureAsync(bumpTexture, mimeType).then((textureInfo) => {\r\n if (textureInfo) {\r\n material.normalTexture = textureInfo;\r\n if (bumpTexture.level !== 1) {\r\n material.normalTexture.scale = bumpTexture.level;\r\n }\r\n }\r\n })\r\n );\r\n }\r\n\r\n const emissiveTexture = babylonStandardMaterial.emissiveTexture;\r\n if (emissiveTexture) {\r\n material.emissiveFactor = [1.0, 1.0, 1.0];\r\n\r\n promises.push(\r\n this.exportTextureAsync(emissiveTexture, mimeType).then((textureInfo) => {\r\n if (textureInfo) {\r\n material.emissiveTexture = textureInfo;\r\n }\r\n })\r\n );\r\n }\r\n\r\n const ambientTexture = babylonStandardMaterial.ambientTexture;\r\n if (ambientTexture) {\r\n promises.push(\r\n this.exportTextureAsync(ambientTexture, mimeType).then((textureInfo) => {\r\n if (textureInfo) {\r\n const occlusionTexture: IMaterialOcclusionTextureInfo = {\r\n index: textureInfo.index,\r\n };\r\n material.occlusionTexture = occlusionTexture;\r\n }\r\n })\r\n );\r\n }\r\n\r\n if (promises.length > 0) {\r\n this._exporter._materialNeedsUVsSet.add(babylonStandardMaterial);\r\n await Promise.all(promises);\r\n }\r\n }\r\n\r\n if (babylonStandardMaterial.alpha < 1.0 || babylonStandardMaterial.opacityTexture) {\r\n if (babylonStandardMaterial.alphaMode === Constants.ALPHA_COMBINE) {\r\n material.alphaMode = MaterialAlphaMode.BLEND;\r\n } else {\r\n Tools.Warn(babylonStandardMaterial.name + \": glTF 2.0 does not support alpha mode: \" + babylonStandardMaterial.alphaMode.toString());\r\n }\r\n }\r\n\r\n if (babylonStandardMaterial.emissiveColor && !babylonStandardMaterial.emissiveColor.equalsWithEpsilon(Black, Epsilon)) {\r\n material.emissiveFactor = babylonStandardMaterial.emissiveColor.asArray();\r\n }\r\n\r\n material.pbrMetallicRoughness = pbrMetallicRoughness;\r\n SetAlphaMode(material, babylonStandardMaterial);\r\n\r\n await this._finishMaterialAsync(material, babylonStandardMaterial, mimeType);\r\n\r\n const materials = this._exporter._materials;\r\n materials.push(material);\r\n return materials.length - 1;\r\n }\r\n\r\n private async _finishMaterialAsync(glTFMaterial: IMaterial, babylonMaterial: Material, mimeType: ImageMimeType): Promise<void> {\r\n const textures = this._exporter._extensionsPostExportMaterialAdditionalTextures(\"exportMaterial\", glTFMaterial, babylonMaterial);\r\n\r\n const promises: Array<Promise<Nullable<ITextureInfo>>> = [];\r\n\r\n for (const texture of textures) {\r\n promises.push(this.exportTextureAsync(texture, mimeType));\r\n }\r\n\r\n await Promise.all(promises);\r\n\r\n await this._exporter._extensionsPostExportMaterialAsync(\"exportMaterial\", glTFMaterial, babylonMaterial);\r\n }\r\n\r\n private async _getImageDataAsync(buffer: Uint8Array | Float32Array, width: number, height: number, mimeType: ImageMimeType): Promise<ArrayBuffer> {\r\n const textureType = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n\r\n const hostingScene = this._exporter._babylonScene;\r\n const engine = hostingScene.getEngine();\r\n\r\n // Create a temporary texture with the texture buffer data\r\n const tempTexture = engine.createRawTexture(buffer, width, height, Constants.TEXTUREFORMAT_RGBA, false, true, Texture.NEAREST_SAMPLINGMODE, null, textureType);\r\n\r\n engine.isWebGPU ? await import(\"core/ShadersWGSL/pass.fragment\") : await import(\"core/Shaders/pass.fragment\");\r\n await TextureTools.ApplyPostProcess(\"pass\", tempTexture, hostingScene, textureType, Constants.TEXTURE_NEAREST_SAMPLINGMODE, Constants.TEXTUREFORMAT_RGBA);\r\n\r\n const data = await engine._readTexturePixels(tempTexture, width, height);\r\n\r\n return (await DumpTools.DumpDataAsync(width, height, data, mimeType, undefined, true, true)) as ArrayBuffer;\r\n }\r\n\r\n /**\r\n * Resizes the two source textures to the same dimensions. If a texture is null, a default white texture is generated. If both textures are null, returns null\r\n * @param texture1 first texture to resize\r\n * @param texture2 second texture to resize\r\n * @param scene babylonjs scene\r\n * @returns resized textures or null\r\n */\r\n private _resizeTexturesToSameDimensions(texture1: Nullable<BaseTexture>, texture2: Nullable<BaseTexture>, scene: Scene): { texture1: BaseTexture; texture2: BaseTexture } {\r\n const texture1Size = texture1 ? texture1.getSize() : { width: 0, height: 0 };\r\n const texture2Size = texture2 ? texture2.getSize() : { width: 0, height: 0 };\r\n let resizedTexture1: BaseTexture;\r\n let resizedTexture2: BaseTexture;\r\n\r\n if (texture1Size.width < texture2Size.width) {\r\n if (texture1 && texture1 instanceof Texture) {\r\n resizedTexture1 = TextureTools.CreateResizedCopy(texture1, texture2Size.width, texture2Size.height, true);\r\n } else {\r\n resizedTexture1 = CreateWhiteTexture(texture2Size.width, texture2Size.height, scene);\r\n }\r\n resizedTexture2 = texture2!;\r\n } else if (texture1Size.width > texture2Size.width) {\r\n if (texture2 && texture2 instanceof Texture) {\r\n resizedTexture2 = TextureTools.CreateResizedCopy(texture2, texture1Size.width, texture1Size.height, true);\r\n } else {\r\n resizedTexture2 = CreateWhiteTexture(texture1Size.width, texture1Size.height, scene);\r\n }\r\n resizedTexture1 = texture1!;\r\n } else {\r\n resizedTexture1 = texture1!;\r\n resizedTexture2 = texture2!;\r\n }\r\n\r\n return {\r\n texture1: resizedTexture1!,\r\n texture2: resizedTexture2!,\r\n };\r\n }\r\n\r\n /**\r\n * Convert Specular Glossiness Textures to Metallic Roughness\r\n * See link below for info on the material conversions from PBR Metallic/Roughness and Specular/Glossiness\r\n * @see https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Archived/KHR_materials_pbrSpecularGlossiness/examples/convert-between-workflows-bjs/js/babylon.pbrUtilities.js\r\n * @param diffuseTexture texture used to store diffuse information\r\n * @param specularGlossinessTexture texture used to store specular and glossiness information\r\n * @param factors specular glossiness material factors\r\n * @param mimeType the mime type to use for the texture\r\n * @returns pbr metallic roughness interface or null\r\n */\r\n private async _convertSpecularGlossinessTexturesToMetallicRoughnessAsync(\r\n diffuseTexture: Nullable<BaseTexture>,\r\n specularGlossinessTexture: Nullable<BaseTexture>,\r\n factors: IPBRSpecularGlossiness,\r\n mimeType: ImageMimeType\r\n ): Promise<IPBRMetallicRoughness> {\r\n const promises = new Array<Promise<void>>();\r\n if (!(diffuseTexture || specularGlossinessTexture)) {\r\n return await Promise.reject(\"diffuse and specular glossiness textures are not defined!\");\r\n }\r\n\r\n const scene: Nullable<Scene> = diffuseTexture ? diffuseTexture.getScene() : specularGlossinessTexture ? specularGlossinessTexture.getScene() : null;\r\n if (scene) {\r\n const resizedTextures = this._resizeTexturesToSameDimensions(diffuseTexture, specularGlossinessTexture, scene);\r\n\r\n const diffuseSize = resizedTextures.texture1?.getSize();\r\n\r\n let diffuseBuffer: Float32Array;\r\n let specularGlossinessBuffer: Float32Array;\r\n\r\n const width = diffuseSize.width;\r\n const height = diffuseSize.height;\r\n\r\n const diffusePixels = await resizedTextures.texture1.readPixels();\r\n const specularPixels = await resizedTextures.texture2.readPixels();\r\n\r\n if (diffusePixels) {\r\n diffuseBuffer = ConvertPixelArrayToFloat32(diffusePixels);\r\n } else {\r\n return await Promise.reject(\"Failed to retrieve pixels from diffuse texture!\");\r\n }\r\n if (specularPixels) {\r\n specularGlossinessBuffer = ConvertPixelArrayToFloat32(specularPixels);\r\n } else {\r\n return await Promise.reject(\"Failed to retrieve pixels from specular glossiness texture!\");\r\n }\r\n\r\n const byteLength = specularGlossinessBuffer.byteLength;\r\n\r\n const metallicRoughnessBuffer = new Uint8Array(byteLength);\r\n const baseColorBuffer = new Uint8Array(byteLength);\r\n\r\n const strideSize = 4;\r\n const maxBaseColor = Black;\r\n let maxMetallic = 0;\r\n let maxRoughness = 0;\r\n\r\n for (let h = 0; h < height; ++h) {\r\n for (let w = 0; w < width; ++w) {\r\n const offset = (width * h + w) * strideSize;\r\n\r\n const diffuseColor = new Color3(diffuseBuffer[offset], diffuseBuffer[offset + 1], diffuseBuffer[offset + 2])\r\n .toLinearSpace(scene.getEngine().useExactSrgbConversions)\r\n .multiply(factors.diffuseColor);\r\n const specularColor = new Color3(specularGlossinessBuffer[offset], specularGlossinessBuffer[offset + 1], specularGlossinessBuffer[offset + 2])\r\n .toLinearSpace(scene.getEngine().useExactSrgbConversions)\r\n .multiply(factors.specularColor);\r\n const glossiness = specularGlossinessBuffer[offset + 3] * factors.glossiness;\r\n\r\n const specularGlossiness: IPBRSpecularGlossiness = {\r\n diffuseColor: diffuseColor,\r\n specularColor: specularColor,\r\n glossiness: glossiness,\r\n };\r\n\r\n const metallicRoughness = this._convertSpecularGlossinessToMetallicRoughness(specularGlossiness);\r\n maxBaseColor.r = Math.max(maxBaseColor.r, metallicRoughness.baseColor.r);\r\n maxBaseColor.g = Math.max(maxBaseColor.g, metallicRoughness.baseColor.g);\r\n maxBaseColor.b = Math.max(maxBaseColor.b, metallicRoughness.baseColor.b);\r\n maxMetallic = Math.max(maxMetallic, metallicRoughness.metallic!);\r\n maxRoughness = Math.max(maxRoughness, metallicRoughness.roughness!);\r\n\r\n baseColorBuffer[offset] = metallicRoughness.baseColor.r * 255;\r\n baseColorBuffer[offset + 1] = metallicRoughness.baseColor.g * 255;\r\n baseColorBuffer[offset + 2] = metallicRoughness.baseColor.b * 255;\r\n baseColorBuffer[offset + 3] = resizedTextures.texture1.hasAlpha ? diffuseBuffer[offset + 3] * 255 : 255;\r\n\r\n metallicRoughnessBuffer[offset] = 0;\r\n metallicRoughnessBuffer[offset + 1] = metallicRoughness.roughness! * 255;\r\n metallicRoughnessBuffer[offset + 2] = metallicRoughness.metallic! * 255;\r\n metallicRoughnessBuffer[offset + 3] = 255;\r\n }\r\n }\r\n\r\n // Retrieves the metallic roughness factors from the maximum texture values.\r\n const metallicRoughnessFactors: IPBRMetallicRoughness = {\r\n baseColor: maxBaseColor,\r\n metallic: maxMetallic,\r\n roughness: maxRoughness,\r\n };\r\n\r\n let writeOutMetallicRoughnessTexture = false;\r\n let writeOutBaseColorTexture = false;\r\n\r\n for (let h = 0; h < height; ++h) {\r\n for (let w = 0; w < width; ++w) {\r\n const destinationOffset = (width * h + w) * strideSize;\r\n\r\n baseColorBuffer[destinationOffset] /= metallicRoughnessFactors.baseColor.r > Epsilon ? metallicRoughnessFactors.baseColor.r : 1;\r\n baseColorBuffer[destinationOffset + 1] /= metallicRoughnessFactors.baseColor.g > Epsilon ? metallicRoughnessFactors.baseColor.g : 1;\r\n baseColorBuffer[destinationOffset + 2] /= metallicRoughnessFactors.baseColor.b > Epsilon ? metallicRoughnessFactors.baseColor.b : 1;\r\n\r\n const linearBaseColorPixel = Color3.FromInts(\r\n baseColorBuffer[destinationOffset],\r\n baseColorBuffer[destinationOffset + 1],\r\n baseColorBuffer[destinationOffset + 2]\r\n );\r\n const sRGBBaseColorPixel = linearBaseColorPixel.toGammaSpace(scene.getEngine().useExactSrgbConversions);\r\n baseColorBuffer[destinationOffset] = sRGBBaseColorPixel.r * 255;\r\n baseColorBuffer[destinationOffset + 1] = sRGBBaseColorPixel.g * 255;\r\n baseColorBuffer[destinationOffset + 2] = sRGBBaseColorPixel.b * 255;\r\n\r\n if (!sRGBBaseColorPixel.equalsWithEpsilon(White, Epsilon)) {\r\n writeOutBaseColorTexture = true;\r\n }\r\n\r\n metallicRoughnessBuffer[destinationOffset + 1] /= metallicRoughnessFactors.roughness! > Epsilon ? metallicRoughnessFactors.roughness! : 1;\r\n metallicRoughnessBuffer[destinationOffset + 2] /= metallicRoughnessFactors.metallic! > Epsilon ? metallicRoughnessFactors.metallic! : 1;\r\n\r\n const metallicRoughnessPixel = Color3.FromInts(255, metallicRoughnessBuffer[destinationOffset + 1], metallicRoughnessBuffer[destinationOffset + 2]);\r\n\r\n if (!metallicRoughnessPixel.equalsWithEpsilon(White, Epsilon)) {\r\n writeOutMetallicRoughnessTexture = true;\r\n }\r\n }\r\n }\r\n\r\n if (writeOutMetallicRoughnessTexture) {\r\n promises.push(\r\n this._getImageDataAsync(metallicRoughnessBuffer, width, height, mimeType).then((data) => {\r\n metallicRoughnessFactors.metallicRoughnessTextureData = data;\r\n })\r\n );\r\n }\r\n if (writeOutBaseColorTexture) {\r\n promises.push(\r\n this._getImageDataAsync(baseColorBuffer, width, height, mimeType).then((data) => {\r\n metallicRoughnessFactors.baseColorTextureData = data;\r\n })\r\n );\r\n }\r\n\r\n return await Promise.all(promises).then(() => {\r\n return metallicRoughnessFactors;\r\n });\r\n } else {\r\n return await Promise.reject(\"_ConvertSpecularGlossinessTexturesToMetallicRoughness: Scene from textures is missing!\");\r\n }\r\n }\r\n\r\n /**\r\n * Converts specular glossiness material properties to metallic roughness\r\n * @param specularGlossiness interface with specular glossiness material properties\r\n * @returns interface with metallic roughness material properties\r\n */\r\n private _convertSpecularGlossinessToMetallicRoughness(specularGlossiness: IPBRSpecularGlossiness): IPBRMetallicRoughness {\r\n const diffusePerceivedBrightness = this._getPerceivedBrightness(specularGlossiness.diffuseColor);\r\n const specularPerceivedBrightness = this._getPerceivedBrightness(specularGlossiness.specularColor);\r\n const oneMinusSpecularStrength = 1 - this._getMaxComponent(specularGlossiness.specularColor);\r\n const metallic = _SolveMetallic(diffusePerceivedBrightness, specularPerceivedBrightness, oneMinusSpecularStrength);\r\n const baseColorFromDiffuse = specularGlossiness.diffuseColor.scale(oneMinusSpecularStrength / (1.0 - DielectricSpecular.r) / Math.max(1 - metallic));\r\n const baseColorFromSpecular = specularGlossiness.specularColor.subtract(DielectricSpecular.scale(1 - metallic)).scale(1 / Math.max(metallic));\r\n let baseColor = Color3.Lerp(baseColorFromDiffuse, baseColorFromSpecular, metallic * metallic);\r\n baseColor = baseColor.clampToRef(0, 1, baseColor);\r\n\r\n const metallicRoughness: IPBRMetallicRoughness = {\r\n baseColor: baseColor,\r\n metallic: metallic,\r\n roughness: 1 - specularGlossiness.glossiness,\r\n };\r\n\r\n return metallicRoughness;\r\n }\r\n\r\n /**\r\n * Calculates the surface reflectance, independent of lighting conditions\r\n * @param color Color source to calculate brightness from\r\n * @returns number representing the perceived brightness, or zero if color is undefined\r\n */\r\n private _getPerceivedBrightness(color: Color3): number {\r\n if (color) {\r\n return Math.sqrt(0.299 * color.r * color.r + 0.587 * color.g * color.g + 0.114 * color.b * color.b);\r\n }\r\n return 0;\r\n }\r\n\r\n /**\r\n * Returns the maximum color component value\r\n * @param color\r\n * @returns maximum color component value, or zero if color is null or undefined\r\n */\r\n private _getMaxComponent(color: Color3): number {\r\n if (color) {\r\n return Math.max(color.r, Math.max(color.g, color.b));\r\n }\r\n return 0;\r\n }\r\n\r\n /**\r\n * Convert a PBRMaterial (Metallic/Roughness) to Metallic Roughness factors\r\n * @param babylonPBRMaterial BJS PBR Metallic Roughness Material\r\n * @param mimeType mime type to use for the textures\r\n * @param glTFPbrMetallicRoughness glTF PBR Metallic Roughness interface\r\n * @param hasUVs specifies if texture coordinates are present on the submesh to determine if textures should be applied\r\n * @returns glTF PBR Metallic Roughness factors\r\n */\r\n private async _convertMetalRoughFactorsToMetallicRoughnessAsync(\r\n babylonPBRMaterial: PBRBaseMaterial,\r\n mimeType: ImageMimeType,\r\n glTFPbrMetallicRoughness: IMaterialPbrMetallicRoughness,\r\n hasUVs: boolean\r\n ): Promise<IPBRMetallicRoughness> {\r\n const promises: Promise<void>[] = [];\r\n\r\n const metallicRoughness: IPBRMetallicRoughness = {\r\n baseColor: babylonPBRMaterial._albedoColor,\r\n metallic: babylonPBRMaterial._metallic,\r\n roughness: babylonPBRMaterial._roughness,\r\n };\r\n\r\n if (hasUVs) {\r\n const albedoTexture = babylonPBRMaterial._albedoTexture;\r\n if (albedoTexture) {\r\n promises.push(\r\n this.exportTextureAsync(babylonPBRMaterial._albedoTexture!, mimeType).then((glTFTexture) => {\r\n if (glTFTexture) {\r\n glTFPbrMetallicRoughness.baseColorTexture = glTFTexture;\r\n }\r\n })\r\n );\r\n }\r\n const metallicTexture = babylonPBRMaterial._metallicTexture;\r\n if (metallicTexture) {\r\n promises.push(\r\n this.exportTextureAsync(metallicTexture, mimeType).then((glTFTexture) => {\r\n if (glTFTexture) {\r\n glTFPbrMetallicRoughness.metallicRoughnessTexture = glTFTexture;\r\n }\r\n })\r\n );\r\n }\r\n }\r\n\r\n if (promises.length > 0) {\r\n this._exporter._materialNeedsUVsSet.add(babylonPBRMaterial);\r\n await Promise.all(promises);\r\n }\r\n\r\n return metallicRoughness;\r\n }\r\n\r\n private _getTextureSampler(texture: Nullable<BaseTexture>): ISampler {\r\n const sampler: ISampler = {};\r\n if (!texture || !(texture instanceof Texture)) {\r\n return sampler;\r\n }\r\n\r\n const wrapS = this._getGLTFTextureWrapMode(texture.wrapU);\r\n if (wrapS !== TextureWrapMode.REPEAT) {\r\n sampler.wrapS = wrapS;\r\n }\r\n\r\n const wrapT = this._getGLTFTextureWrapMode(texture.wrapV);\r\n if (wrapT !== TextureWrapMode.REPEAT) {\r\n sampler.wrapT = wrapT;\r\n }\r\n\r\n switch (texture.samplingMode) {\r\n case Texture.LINEAR_LINEAR: {\r\n sampler.magFilter = TextureMagFilter.LINEAR;\r\n sampler.minFilter = TextureMinFilter.LINEAR;\r\n break;\r\n }\r\n case Texture.LINEAR_NEAREST: {\r\n sampler.magFilter = TextureMagFilter.LINEAR;\r\n sampler.minFilter = TextureMinFilter.NEAREST;\r\n break;\r\n }\r\n case Texture.NEAREST_LINEAR: {\r\n sampler.magFilter = TextureMagFilter.NEAREST;\r\n sampler.minFilter = TextureMinFilter.LINEAR;\r\n break;\r\n }\r\n case Texture.NEAREST_LINEAR_MIPLINEAR: {\r\n sampler.magFilter = TextureMagFilter.NEAREST;\r\n sampler.minFilter = TextureMinFilter.LINEAR_MIPMAP_LINEAR;\r\n break;\r\n }\r\n case Texture.NEAREST_NEAREST: {\r\n sampler.magFilter = TextureMagFilter.NEAREST;\r\n sampler.minFilter = TextureMinFilter.NEAREST;\r\n break;\r\n }\r\n case Texture.NEAREST_LINEAR_MIPNEAREST: {\r\n sampler.magFilter = TextureMagFilter.NEAREST;\r\n sampler.minFilter = TextureMinFilter.LINEAR_MIPMAP_NEAREST;\r\n break;\r\n }\r\n case Texture.LINEAR_NEAREST_MIPNEAREST: {\r\n sampler.magFilter = TextureMagFilter.LINEAR;\r\n sampler.minFilter = TextureMinFilter.NEAREST_MIPMAP_NEAREST;\r\n break;\r\n }\r\n case Texture.LINEAR_NEAREST_MIPLINEAR: {\r\n sampler.magFilter = TextureMagFilter.LINEAR;\r\n sampler.minFilter = TextureMinFilter.NEAREST_MIPMAP_LINEAR;\r\n break;\r\n }\r\n case Texture.NEAREST_NEAREST_MIPLINEAR: {\r\n sampler.magFilter = TextureMagFilter.NEAREST;\r\n sampler.minFilter = TextureMinFilter.NEAREST_MIPMAP_LINEAR;\r\n break;\r\n }\r\n case Texture.LINEAR_LINEAR_MIPLINEAR: {\r\n sampler.magFilter = TextureMagFilter.LINEAR;\r\n sampler.minFilter = TextureMinFilter.LINEAR_MIPMAP_LINEAR;\r\n break;\r\n }\r\n case Texture.LINEAR_LINEAR_MIPNEAREST: {\r\n sampler.magFilter = TextureMagFilter.LINEAR;\r\n sampler.minFilter = TextureMinFilter.LINEAR_MIPMAP_NEAREST;\r\n break;\r\n }\r\n case Texture.NEAREST_NEAREST_MIPNEAREST: {\r\n sampler.magFilter = TextureMagFilter.NEAREST;\r\n sampler.minFilter = TextureMinFilter.NEAREST_MIPMAP_NEAREST;\r\n break;\r\n }\r\n }\r\n\r\n return sampler;\r\n }\r\n\r\n private _getGLTFTextureWrapMode(wrapMode: number): TextureWrapMode {\r\n switch (wrapMode) {\r\n case Texture.WRAP_ADDRESSMODE: {\r\n return TextureWrapMode.REPEAT;\r\n }\r\n case Texture.CLAMP_ADDRESSMODE: {\r\n return TextureWrapMode.CLAMP_TO_EDGE;\r\n }\r\n case Texture.MIRROR_ADDRESSMODE: {\r\n return TextureWrapMode.MIRRORED_REPEAT;\r\n }\r\n default: {\r\n Tools.Error(`Unsupported Texture Wrap Mode ${wrapMode}!`);\r\n return TextureWrapMode.REPEAT;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Convert a PBRMaterial (Specular/Glossiness) to Metallic Roughness factors\r\n * @param babylonPBRMaterial BJS PBR Metallic Roughness Material\r\n * @param mimeType mime type to use for the textures\r\n * @param pbrMetallicRoughness glTF PBR Metallic Roughness interface\r\n * @param hasUVs specifies if texture coordinates are present on the submesh to determine if textures should be applied\r\n * @returns glTF PBR Metallic Roughness factors\r\n */\r\n private async _convertSpecGlossFactorsToMetallicRoughnessAsync(\r\n babylonPBRMaterial: PBRBaseMaterial,\r\n mimeType: ImageMimeType,\r\n pbrMetallicRoughness: IMaterialPbrMetallicRoughness,\r\n hasUVs: boolean\r\n ): Promise<IPBRMetallicRoughness> {\r\n const specGloss: IPBRSpecularGlossiness = {\r\n diffuseColor: babylonPBRMaterial._albedoColor,\r\n specularColor: babylonPBRMaterial._reflectivityColor,\r\n glossiness: babylonPBRMaterial._microSurface,\r\n };\r\n\r\n const albedoTexture = babylonPBRMaterial._albedoTexture;\r\n const reflectivityTexture = babylonPBRMaterial._reflectivityTexture;\r\n const useMicrosurfaceFromReflectivityMapAlpha = babylonPBRMaterial._useMicroSurfaceFromReflectivityMapAlpha;\r\n if (reflectivityTexture && !useMicrosurfaceFromReflectivityMapAlpha) {\r\n return await Promise.reject(\"_ConvertPBRMaterial: Glossiness values not included in the reflectivity texture are currently not supported\");\r\n }\r\n\r\n if ((albedoTexture || reflectivityTexture) && hasUVs) {\r\n this._exporter._materialNeedsUVsSet.add(babylonPBRMaterial);\r\n\r\n const samplerIndex = this._exportTextureSampler(albedoTexture || reflectivityTexture);\r\n const metallicRoughnessFactors = await this._convertSpecularGlossinessTexturesToMetallicRoughnessAsync(albedoTexture, reflectivityTexture, specGloss, mimeType);\r\n\r\n const textures = this._exporter._textures;\r\n\r\n if (metallicRoughnessFactors.baseColorTextureData) {\r\n const imageIndex = this._exportImage(`baseColor${textures.length}`, mimeType, metallicRoughnessFactors.baseColorTextureData);\r\n pbrMetallicRoughness.baseColorTexture = this._exportTextureInfo(imageIndex, samplerIndex, albedoTexture?.coordinatesIndex);\r\n }\r\n\r\n if (metallicRoughnessFactors.metallicRoughnessTextureData) {\r\n const imageIndex = this._exportImage(`metallicRoughness${textures.length}`, mimeType, metallicRoughnessFactors.metallicRoughnessTextureData);\r\n pbrMetallicRoughness.metallicRoughnessTexture = this._exportTextureInfo(imageIndex, samplerIndex, reflectivityTexture?.coordinatesIndex);\r\n }\r\n\r\n return metallicRoughnessFactors;\r\n } else {\r\n return this._convertSpecularGlossinessToMetallicRoughness(specGloss);\r\n }\r\n }\r\n\r\n public async exportPBRMaterialAsync(babylonPBRMaterial: PBRBaseMaterial, mimeType: ImageMimeType, hasUVs: boolean): Promise<number> {\r\n const glTFPbrMetallicRoughness: IMaterialPbrMetallicRoughness = {};\r\n\r\n const glTFMaterial: IMaterial = {\r\n name: babylonPBRMaterial.name,\r\n };\r\n\r\n const useMetallicRoughness = babylonPBRMaterial.isMetallicWorkflow();\r\n\r\n if (useMetallicRoughness) {\r\n const albedoColor = babylonPBRMaterial._albedoColor;\r\n const alpha = babylonPBRMaterial.alpha;\r\n if (albedoColor) {\r\n glTFPbrMetallicRoughness.baseColorFactor = [albedoColor.r, albedoColor.g, albedoColor.b, alpha];\r\n }\r\n }\r\n\r\n const metallicRoughness = useMetallicRoughness\r\n ? await this._convertMetalRoughFactorsToMetallicRoughnessAsync(babylonPBRMaterial, mimeType, glTFPbrMetallicRoughness, hasUVs)\r\n : await this._convertSpecGlossFactorsToMetallicRoughnessAsync(babylonPBRMaterial, mimeType, glTFPbrMetallicRoughness, hasUVs);\r\n\r\n await this._setMetallicRoughnessPbrMaterialAsync(metallicRoughness, babylonPBRMaterial, glTFMaterial, glTFPbrMetallicRoughness, mimeType, hasUVs);\r\n await this._finishMaterialAsync(glTFMaterial, babylonPBRMaterial, mimeType);\r\n\r\n const materials = this._exporter._materials;\r\n materials.push(glTFMaterial);\r\n return materials.length - 1;\r\n }\r\n\r\n private async _setMetallicRoughnessPbrMaterialAsync(\r\n metallicRoughness: IPBRMetallicRoughness,\r\n babylonPBRMaterial: PBRBaseMaterial,\r\n glTFMaterial: IMaterial,\r\n glTFPbrMetallicRoughness: IMaterialPbrMetallicRoughness,\r\n mimeType: ImageMimeType,\r\n hasUVs: boolean\r\n ): Promise<void> {\r\n SetAlphaMode(glTFMaterial, babylonPBRMaterial);\r\n\r\n if (!metallicRoughness.baseColor.equalsWithEpsilon(White, Epsilon) || !Scalar.WithinEpsilon(babylonPBRMaterial.alpha, 1, Epsilon)) {\r\n glTFPbrMetallicRoughness.baseColorFactor = [metallicRoughness.baseColor.r, metallicRoughness.baseColor.g, metallicRoughness.baseColor.b, babylonPBRMaterial.alpha];\r\n }\r\n\r\n if (metallicRoughness.metallic != null && metallicRoughness.metallic !== 1) {\r\n glTFPbrMetallicRoughness.metallicFactor = metallicRoughness.metallic;\r\n }\r\n if (metallicRoughness.roughness != null && metallicRoughness.roughness !== 1) {\r\n glTFPbrMetallicRoughness.roughnessFactor = metallicRoughness.roughness;\r\n }\r\n\r\n if (babylonPBRMaterial.backFaceCulling != null && !babylonPBRMaterial.backFaceCulling) {\r\n if (!babylonPBRMaterial._twoSidedLighting) {\r\n Tools.Warn(babylonPBRMaterial.name + \": Back-face culling disabled and two-sided lighting disabled is not supported in glTF.\");\r\n }\r\n glTFMaterial.doubleSided = true;\r\n }\r\n\r\n if (hasUVs) {\r\n const promises: Promise<void>[] = [];\r\n\r\n const bumpTexture = babylonPBRMaterial._bumpTexture;\r\n if (bumpTexture) {\r\n promises.push(\r\n this.exportTextureAsync(bumpTexture, mimeType).then((glTFTexture) => {\r\n if (glTFTexture) {\r\n glTFMaterial.normalTexture = glTFTexture;\r\n if (bumpTexture.level !== 1) {\r\n glTFMaterial.normalTexture.scale = bumpTexture.level;\r\n }\r\n }\r\n })\r\n );\r\n }\r\n\r\n const ambientTexture = babylonPBRMaterial._ambientTexture;\r\n if (ambientTexture) {\r\n promises.push(\r\n this.exportTextureAsync(ambientTexture, mimeType).then((glTFTexture) => {\r\n if (glTFTexture) {\r\n const occlusionTexture: IMaterialOcclusionTextureInfo = {\r\n index: glTFTexture.index,\r\n texCoord: glTFTexture.texCoord,\r\n extensions: glTFTexture.extensions,\r\n };\r\n\r\n glTFMaterial.occlusionTexture = occlusionTexture;\r\n const ambientTextureStrength = babylonPBRMaterial._ambientTextureStrength;\r\n if (ambientTextureStrength) {\r\n occlusionTexture.strength = ambientTextureStrength;\r\n }\r\n }\r\n })\r\n );\r\n }\r\n\r\n const emissiveTexture = babylonPBRMaterial._emissiveTexture;\r\n if (emissiveTexture) {\r\n promises.push(\r\n this.exportTextureAsync(emissiveTexture, mimeType).then((glTFTexture) => {\r\n if (glTFTexture) {\r\n glTFMaterial.emissiveTexture = glTFTexture;\r\n }\r\n })\r\n );\r\n }\r\n\r\n if (promises.length > 0) {\r\n this._exporter._materialNeedsUVsSet.add(babylonPBRMaterial);\r\n await Promise.all(promises);\r\n }\r\n }\r\n\r\n const emissiveColor = babylonPBRMaterial._emissiveColor;\r\n if (!emissiveColor.equalsWithEpsilon(Black, Epsilon)) {\r\n glTFMaterial.emissiveFactor = emissiveColor.asArray();\r\n }\r\n\r\n glTFMaterial.pbrMetallicRoughness = glTFPbrMetallicRoughness;\r\n }\r\n\r\n /**\r\n * Get the RGBA pixel data from a texture\r\n * @param babylonTexture\r\n * @returns an array buffer promise containing the pixel data\r\n */\r\n // eslint-disable-next-line no-restricted-syntax, @typescript-eslint/promise-function-async\r\n private _getPixelsFromTextureAsync(babylonTexture: BaseTexture): Promise<Nullable<Uint8Array | Float32Array>> {\r\n // If the internal texture format is compressed, we cannot read the pixels directly.\r\n if (IsCompressedTextureFormat(babylonTexture.textureFormat)) {\r\n return GetTextureDataAsync(babylonTexture, babylonTexture._texture!.width, babylonTexture._texture!.height);\r\n }\r\n\r\n return babylonTexture.textureType === Constants.TEXTURETYPE_UNSIGNED_BYTE\r\n ? (babylonTexture.readPixels() as Promise<Uint8Array>)\r\n : (babylonTexture.readPixels() as Promise<Float32Array>);\r\n }\r\n\r\n public async exportTextureAsync(babylonTexture: BaseTexture, mimeType: ImageMimeType): Promise<Nullable<ITextureInfo>> {\r\n const extensionPromise = this._exporter._extensionsPreExportTextureAsync(\"exporter\", babylonTexture as Texture, mimeType);\r\n if (!extensionPromise) {\r\n return await this._exportTextureInfoAsync(babylonTexture, mimeType);\r\n }\r\n\r\n return await extensionPromise.then(async (texture) => {\r\n if (!texture) {\r\n return await this._exportTextureInfoAsync(babylonTexture, mimeType);\r\n }\r\n return await this._exportTextureInfoAsync(texture, mimeType);\r\n });\r\n }\r\n\r\n private async _exportTextureInfoAsync(babylonTexture: BaseTexture, mimeType: ImageMimeType): Promise<Nullable<ITextureInfo>> {\r\n let textureInfo = this._textureMap.get(babylonTexture);\r\n if (!textureInfo) {\r\n const pixels = await this._getPixelsFromTextureAsync(babylonTexture);\r\n if (!pixels) {\r\n return null;\r\n }\r\n\r\n const samplerIndex = this._exportTextureSampler(babylonTexture);\r\n\r\n // Preserve texture mime type if defined\r\n const textureMimeType = (babylonTexture as Texture).mimeType;\r\n if (textureMimeType) {\r\n switch (textureMimeType) {\r\n case \"image/jpeg\":\r\n case \"image/png\":\r\n case \"image/webp\":\r\n mimeType = textureMimeType as ImageMimeType;\r\n break;\r\n default:\r\n Tools.Warn(`Unsupported media type: ${textureMimeType}. Exporting texture as PNG.`);\r\n // Will later fallback to default mime type, image/png, from Canvas API\r\n break;\r\n }\r\n }\r\n\r\n const internalTextureToImage = this._internalTextureToImage;\r\n const internalTextureUniqueId = babylonTexture.getInternalTexture()!.uniqueId;\r\n internalTextureToImage[internalTextureUniqueId] ||= {};\r\n let imageIndexPromise = internalTextureToImage[internalTextureUniqueId][mimeType];\r\n if (imageIndexPromise === undefined) {\r\n const size = babylonTexture.getSize();\r\n imageIndexPromise = (async () => {\r\n const data = await this._getImageDataAsync(pixels, size.width, size.height, mimeType);\r\n return this._exportImage(babylonTexture.name, mimeType, data);\r\n })();\r\n internalTextureToImage[internalTextureUniqueId][mimeType] = imageIndexPromise;\r\n }\r\n\r\n textureInfo = this._exportTextureInfo(await imageIndexPromise, samplerIndex, babylonTexture.coordinatesIndex);\r\n this._textureMap.set(babylonTexture, textureInfo);\r\n this._exporter._extensionsPostExportTextures(\"exporter\", textureInfo, babylonTexture);\r\n }\r\n\r\n return textureInfo;\r\n }\r\n\r\n private _exportImage(name: string, mimeType: ImageMimeType, data: ArrayBuffer): number {\r\n const images = this._exporter._images;\r\n\r\n let image: IImage;\r\n if (this._exporter._shouldUseGlb) {\r\n image = {\r\n name: name,\r\n mimeType: mimeType,\r\n bufferView: undefined, // Will be updated later by BufferManager\r\n };\r\n const bufferView = this._exporter._bufferManager.createBufferView(new Uint8Array(data));\r\n this._exporter._bufferManager.setBufferView(image, bufferView);\r\n } else {\r\n // Build a unique URI\r\n const baseName = name.replace(/\\.\\/|\\/|\\.\\\\|\\\\/g, \"_\");\r\n const extension = GetFileExtensionFromMimeType(mimeType);\r\n let fileName = baseName + extension;\r\n if (images.some((image) => image.uri === fileName)) {\r\n fileName = `${baseName}_${Tools.RandomId()}${extension}`;\r\n }\r\n\r\n image = {\r\n name: name,\r\n uri: fileName,\r\n };\r\n this._exporter._imageData[fileName] = { data: data, mimeType: mimeType }; // Save image data to be written to file later\r\n }\r\n\r\n images.push(image);\r\n\r\n return images.length - 1;\r\n }\r\n\r\n private _exportTextureInfo(imageIndex: number, samplerIndex: number, coordinatesIndex?: number): ITextureInfo {\r\n const textures = this._exporter._textures;\r\n let textureIndex = textures.findIndex((t) => t.sampler == samplerIndex && t.source === imageIndex);\r\n if (textureIndex === -1) {\r\n textureIndex = textures.length;\r\n textures.push({\r\n source: imageIndex,\r\n sampler: samplerIndex,\r\n });\r\n }\r\n\r\n const textureInfo: ITextureInfo = { index: textureIndex };\r\n if (coordinatesIndex) {\r\n textureInfo.texCoord = coordinatesIndex;\r\n }\r\n return textureInfo;\r\n }\r\n\r\n private _exportTextureSampler(texture: Nullable<BaseTexture>): number {\r\n const sampler = this._getTextureSampler(texture);\r\n\r\n // if a pre-existing sampler with identical parameters exists, then reuse the previous sampler\r\n const samplers = this._exporter._samplers;\r\n const samplerIndex = samplers.findIndex(\r\n (s) => s.minFilter === sampler.minFilter && s.magFilter === sampler.magFilter && s.wrapS === sampler.wrapS && s.wrapT === sampler.wrapT\r\n );\r\n if (samplerIndex !== -1) {\r\n return samplerIndex;\r\n }\r\n\r\n samplers.push(sampler);\r\n return samplers.length - 1;\r\n }\r\n}\r\n","/* eslint-disable jsdoc/require-jsdoc */\r\n\r\nimport type { INode } from \"babylonjs-gltf2interface\";\r\nimport { AccessorType, MeshPrimitiveMode } from \"babylonjs-gltf2interface\";\r\nimport type { FloatArray, DataArray, IndicesArray } from \"core/types\";\r\nimport type { Vector4 } from \"core/Maths/math.vector\";\r\nimport { Quaternion, TmpVectors, Matrix, Vector3 } from \"core/Maths/math.vector\";\r\nimport { VertexBuffer } from \"core/Buffers/buffer\";\r\nimport { Material } from \"core/Materials/material\";\r\nimport { TransformNode } from \"core/Meshes/transformNode\";\r\nimport { AbstractMesh } from \"core/Meshes/abstractMesh\";\r\nimport { EnumerateFloatValues } from \"core/Buffers/bufferUtils\";\r\nimport type { Node } from \"core/node\";\r\n\r\n// Matrix that converts handedness on the X-axis. Can convert from LH to RH and vice versa.\r\nconst ConvertHandednessMatrix = Matrix.Compose(new Vector3(-1, 1, 1), Quaternion.Identity(), Vector3.Zero());\r\n\r\n// Default values for comparison.\r\nconst Epsilon = 1e-6;\r\nconst DefaultTranslation = Vector3.Zero();\r\nconst DefaultScale = Vector3.One();\r\n\r\n/**\r\n * Get the information necessary for enumerating a vertex buffer.\r\n * @param vertexBuffer the vertex buffer to enumerate\r\n * @param meshes the meshes that use the vertex buffer\r\n * @returns the information necessary to enumerate the vertex buffer\r\n */\r\nexport function GetVertexBufferInfo(vertexBuffer: VertexBuffer, meshes: AbstractMesh[]) {\r\n const { byteOffset, byteStride, type, normalized } = vertexBuffer;\r\n const componentCount = vertexBuffer.getSize();\r\n const totalVertices = meshes.reduce((max, current) => {\r\n return current.getTotalVertices() > max ? current.getTotalVertices() : max;\r\n }, -Number.MAX_VALUE); // Get the max total vertices count, to ensure we capture the full range of vertex data used by the meshes.\r\n const count = totalVertices * componentCount;\r\n const kind = vertexBuffer.getKind();\r\n\r\n return { byteOffset, byteStride, componentCount, type, count, normalized, totalVertices, kind };\r\n}\r\n\r\nexport function GetAccessorElementCount(accessorType: AccessorType): number {\r\n switch (accessorType) {\r\n case AccessorType.MAT2:\r\n return 4;\r\n case AccessorType.MAT3:\r\n return 9;\r\n case AccessorType.MAT4:\r\n return 16;\r\n case AccessorType.SCALAR:\r\n return 1;\r\n case AccessorType.VEC2:\r\n return 2;\r\n case AccessorType.VEC3:\r\n return 3;\r\n case AccessorType.VEC4:\r\n return 4;\r\n }\r\n}\r\n\r\nexport function FloatsNeed16BitInteger(floatArray: FloatArray): boolean {\r\n return floatArray.some((value) => value >= 256);\r\n}\r\n\r\nexport function IsStandardVertexAttribute(type: string): boolean {\r\n switch (type) {\r\n case VertexBuffer.PositionKind:\r\n case VertexBuffer.NormalKind:\r\n case VertexBuffer.TangentKind:\r\n case VertexBuffer.ColorKind:\r\n case VertexBuffer.MatricesIndicesKind:\r\n case VertexBuffer.MatricesIndicesExtraKind:\r\n case VertexBuffer.MatricesWeightsKind:\r\n case VertexBuffer.MatricesWeightsExtraKind:\r\n case VertexBuffer.UVKind:\r\n case VertexBuffer.UV2Kind:\r\n case VertexBuffer.UV3Kind:\r\n case VertexBuffer.UV4Kind:\r\n case VertexBuffer.UV5Kind:\r\n case VertexBuffer.UV6Kind:\r\n return true;\r\n }\r\n return false;\r\n}\r\n\r\nexport function GetAccessorType(kind: string, hasVertexColorAlpha: boolean): AccessorType {\r\n if (kind == VertexBuffer.ColorKind) {\r\n return hasVertexColorAlpha ? AccessorType.VEC4 : AccessorType.VEC3;\r\n }\r\n\r\n switch (kind) {\r\n case VertexBuffer.PositionKind:\r\n case VertexBuffer.NormalKind:\r\n return AccessorType.VEC3;\r\n case VertexBuffer.TangentKind:\r\n case VertexBuffer.MatricesIndicesKind:\r\n case VertexBuffer.MatricesIndicesExtraKind:\r\n case VertexBuffer.MatricesWeightsKind:\r\n case VertexBuffer.MatricesWeightsExtraKind:\r\n return AccessorType.VEC4;\r\n case VertexBuffer.UVKind:\r\n case VertexBuffer.UV2Kind:\r\n case VertexBuffer.UV3Kind:\r\n case VertexBuffer.UV4Kind:\r\n case VertexBuffer.UV5Kind:\r\n case VertexBuffer.UV6Kind:\r\n return AccessorType.VEC2;\r\n }\r\n\r\n throw new Error(`Unknown kind ${kind}`);\r\n}\r\n\r\nexport function GetAttributeType(kind: string): string {\r\n switch (kind) {\r\n case VertexBuffer.PositionKind:\r\n return \"POSITION\";\r\n case VertexBuffer.NormalKind:\r\n return \"NORMAL\";\r\n case VertexBuffer.TangentKind:\r\n return \"TANGENT\";\r\n case VertexBuffer.ColorKind:\r\n return \"COLOR_0\";\r\n case VertexBuffer.UVKind:\r\n return \"TEXCOORD_0\";\r\n case VertexBuffer.UV2Kind:\r\n return \"TEXCOORD_1\";\r\n case VertexBuffer.UV3Kind:\r\n return \"TEXCOORD_2\";\r\n case VertexBuffer.UV4Kind:\r\n return \"TEXCOORD_3\";\r\n case VertexBuffer.UV5Kind:\r\n return \"TEXCOORD_4\";\r\n case VertexBuffer.UV6Kind:\r\n return \"TEXCOORD_5\";\r\n case VertexBuffer.MatricesIndicesKind:\r\n return \"JOINTS_0\";\r\n case VertexBuffer.MatricesIndicesExtraKind:\r\n return \"JOINTS_1\";\r\n case VertexBuffer.MatricesWeightsKind:\r\n return \"WEIGHTS_0\";\r\n case VertexBuffer.MatricesWeightsExtraKind:\r\n return \"WEIGHTS_1\";\r\n }\r\n\r\n throw new Error(`Unknown kind: ${kind}`);\r\n}\r\n\r\nexport function GetPrimitiveMode(fillMode: number): MeshPrimitiveMode {\r\n switch (fillMode) {\r\n case Material.TriangleFillMode:\r\n return MeshPrimitiveMode.TRIANGLES;\r\n case Material.TriangleStripDrawMode:\r\n return MeshPrimitiveMode.TRIANGLE_STRIP;\r\n case Material.TriangleFanDrawMode:\r\n return MeshPrimitiveMode.TRIANGLE_FAN;\r\n case Material.PointListDrawMode:\r\n case Material.PointFillMode:\r\n return MeshPrimitiveMode.POINTS;\r\n case Material.LineLoopDrawMode:\r\n return MeshPrimitiveMode.LINE_LOOP;\r\n case Material.LineListDrawMode:\r\n return MeshPrimitiveMode.LINES;\r\n case Material.LineStripDrawMode:\r\n return MeshPrimitiveMode.LINE_STRIP;\r\n }\r\n\r\n throw new Error(`Unknown fill mode: ${fillMode}`);\r\n}\r\n\r\nexport function IsTriangleFillMode(fillMode: number): boolean {\r\n switch (fillMode) {\r\n case Material.TriangleFillMode:\r\n case Material.TriangleStripDrawMode:\r\n case Material.TriangleFanDrawMode:\r\n return true;\r\n }\r\n\r\n return false;\r\n}\r\n\r\nexport function NormalizeTangent(tangent: Vector4 | Vector3) {\r\n const length = Math.sqrt(tangent.x * tangent.x + tangent.y * tangent.y + tangent.z * tangent.z);\r\n if (length > 0) {\r\n tangent.x /= length;\r\n tangent.y /= length;\r\n tangent.z /= length;\r\n }\r\n}\r\n\r\nexport function ConvertToRightHandedPosition(value: Vector3): Vector3 {\r\n value.x *= -1;\r\n return value;\r\n}\r\n\r\n/**\r\n * Converts, in-place, a left-handed quaternion to a right-handed quaternion via a change of basis.\r\n * @param value the unit quaternion to convert\r\n * @returns the converted quaternion\r\n */\r\nexport function ConvertToRightHandedRotation(value: Quaternion): Quaternion {\r\n /**\r\n * This is the simplified version of the following equation:\r\n * q' = to_quaternion(M * to_matrix(q) * M^-1)\r\n * where M is the conversion matrix `convertHandednessMatrix`,\r\n * q is the input quaternion, and q' is the converted quaternion.\r\n * Reference: https://d3cw3dd2w32x2b.cloudfront.net/wp-content/uploads/2015/01/matrix-to-quat.pdf\r\n */\r\n if (value.x * value.x + value.y * value.y > 0.5) {\r\n const absX = Math.abs(value.x);\r\n const absY = Math.abs(value.y);\r\n if (absX > absY) {\r\n const sign = Math.sign(value.x);\r\n value.x = absX;\r\n value.y *= -sign;\r\n value.z *= -sign;\r\n value.w *= sign;\r\n } else {\r\n const sign = Math.sign(value.y);\r\n value.x *= -sign;\r\n value.y = absY;\r\n value.z *= sign;\r\n value.w *= -sign;\r\n }\r\n } else {\r\n const absZ = Math.abs(value.z);\r\n const absW = Math.abs(value.w);\r\n if (absZ > absW) {\r\n const sign = Math.sign(value.z);\r\n value.x *= -sign;\r\n value.y *= sign;\r\n value.z = absZ;\r\n value.w *= -sign;\r\n } else {\r\n const sign = Math.sign(value.w);\r\n value.x *= sign;\r\n value.y *= -sign;\r\n value.z *= -sign;\r\n value.w = absW;\r\n }\r\n }\r\n\r\n return value;\r\n}\r\n\r\nexport function ConvertToRightHandedNode(value: INode) {\r\n let translation = Vector3.FromArrayToRef(value.translation || [0, 0, 0], 0, TmpVectors.Vector3[0]);\r\n let rotation = Quaternion.FromArrayToRef(value.rotation || [0, 0, 0, 1], 0, TmpVectors.Quaternion[0]);\r\n\r\n translation = ConvertToRightHandedPosition(translation);\r\n rotation = ConvertToRightHandedRotation(rotation);\r\n\r\n if (translation.equalsWithEpsilon(DefaultTranslation, Epsilon)) {\r\n delete value.translation;\r\n } else {\r\n value.translation = translation.asArray();\r\n }\r\n\r\n if (Quaternion.IsIdentity(rotation)) {\r\n delete value.rotation;\r\n } else {\r\n value.rotation = rotation.asArray();\r\n }\r\n}\r\n\r\n/**\r\n * Pre-multiplies a 180-degree Y rotation to the quaternion, in order to match glTF's flipped forward direction for cameras.\r\n * @param rotation Target camera rotation.\r\n */\r\nexport function ConvertCameraRotationToGLTF(rotation: Quaternion): void {\r\n // Simplified from: rotation * (0, 1, 0, 0).\r\n rotation.copyFromFloats(-rotation.z, rotation.w, rotation.x, -rotation.y);\r\n}\r\n\r\nexport function RotateNode180Y(node: INode): void {\r\n Quaternion.FromArrayToRef(node.rotation || [0, 0, 0, 1], 0, TmpVectors.Quaternion[1]);\r\n ConvertCameraRotationToGLTF(TmpVectors.Quaternion[1]);\r\n node.rotation = TmpVectors.Quaternion[1].asArray();\r\n}\r\n\r\n/**\r\n * Collapses GLTF parent and node into a single node. This is useful for removing nodes that were added by the GLTF importer.\r\n * @param node Target parent node.\r\n * @param parentNode Original GLTF node (Light or Camera).\r\n */\r\nexport function CollapseParentNode(node: INode, parentNode: INode) {\r\n const parentTranslation = Vector3.FromArrayToRef(parentNode.translation || [0, 0, 0], 0, TmpVectors.Vector3[0]);\r\n const parentRotation = Quaternion.FromArrayToRef(parentNode.rotation || [0, 0, 0, 1], 0, TmpVectors.Quaternion[0]);\r\n const parentScale = Vector3.FromArrayToRef(parentNode.scale || [1, 1, 1], 0, TmpVectors.Vector3[1]);\r\n const parentMatrix = Matrix.ComposeToRef(parentScale, parentRotation, parentTranslation, TmpVectors.Matrix[0]);\r\n\r\n const translation = Vector3.FromArrayToRef(node.translation || [0, 0, 0], 0, TmpVectors.Vector3[2]);\r\n const rotation = Quaternion.FromArrayToRef(node.rotation || [0, 0, 0, 1], 0, TmpVectors.Quaternion[1]);\r\n const scale = Vector3.FromArrayToRef(node.scale || [1, 1, 1], 0, TmpVectors.Vector3[1]);\r\n const matrix = Matrix.ComposeToRef(scale, rotation, translation, TmpVectors.Matrix[1]);\r\n\r\n parentMatrix.multiplyToRef(matrix, matrix);\r\n matrix.decompose(parentScale, parentRotation, parentTranslation);\r\n\r\n if (parentTranslation.equalsWithEpsilon(DefaultTranslation, Epsilon)) {\r\n delete parentNode.translation;\r\n } else {\r\n parentNode.translation = parentTranslation.asArray();\r\n }\r\n\r\n if (Quaternion.IsIdentity(parentRotation)) {\r\n delete parentNode.rotation;\r\n } else {\r\n parentNode.rotation = parentRotation.asArray();\r\n }\r\n\r\n if (parentScale.equalsWithEpsilon(DefaultScale, Epsilon)) {\r\n delete parentNode.scale;\r\n } else {\r\n parentNode.scale = parentScale.asArray();\r\n }\r\n}\r\n\r\n/**\r\n * Sometimes the GLTF Importer can add extra transform nodes (for lights and cameras). This checks if a parent node was added by the GLTF Importer. If so, it should be removed during serialization.\r\n * @param babylonNode Original GLTF node (Light or Camera).\r\n * @param parentBabylonNode Target parent node.\r\n * @returns True if the parent node was added by the GLTF importer.\r\n */\r\nexport function IsParentAddedByImporter(babylonNode: Node, parentBabylonNode: Node): boolean {\r\n return parentBabylonNode instanceof TransformNode && parentBabylonNode.getChildren().length == 1 && babylonNode.getChildren().length == 0;\r\n}\r\n\r\nexport function IsNoopNode(node: Node, useRightHandedSystem: boolean): boolean {\r\n if (!(node instanceof TransformNode)) {\r\n return false;\r\n }\r\n\r\n // Transform\r\n if (useRightHandedSystem) {\r\n const matrix = node.getWorldMatrix();\r\n if (!matrix.isIdentity()) {\r\n return false;\r\n }\r\n } else {\r\n const matrix = node.getWorldMatrix().multiplyToRef(ConvertHandednessMatrix, TmpVectors.Matrix[0]);\r\n if (!matrix.isIdentity()) {\r\n return false;\r\n }\r\n }\r\n\r\n // Geometry\r\n if (node instanceof AbstractMesh && node.geometry) {\r\n return false;\r\n }\r\n\r\n return true;\r\n}\r\n\r\n/**\r\n * Converts an IndicesArray into either Uint32Array or Uint16Array, only copying if the data is number[].\r\n * @param indices input array to be converted\r\n * @param start starting index to copy from\r\n * @param count number of indices to copy\r\n * @returns a Uint32Array or Uint16Array\r\n * @internal\r\n */\r\nexport function IndicesArrayToTypedArray(indices: IndicesArray, start: number, count: number, is32Bits: boolean): Uint32Array | Uint16Array {\r\n if (indices instanceof Uint16Array || indices instanceof Uint32Array) {\r\n return indices;\r\n }\r\n\r\n // If Int32Array, cast the indices (which are all positive) to Uint32Array\r\n if (indices instanceof Int32Array) {\r\n return new Uint32Array(indices.buffer, indices.byteOffset, indices.length);\r\n }\r\n\r\n const subarray = indices.slice(start, start + count);\r\n return is32Bits ? new Uint32Array(subarray) : new Uint16Array(subarray);\r\n}\r\n\r\nexport function DataArrayToUint8Array(data: DataArray): Uint8Array {\r\n if (data instanceof Array) {\r\n const floatData = new Float32Array(data);\r\n return new Uint8Array(floatData.buffer, floatData.byteOffset, floatData.byteLength);\r\n }\r\n\r\n return ArrayBuffer.isView(data) ? new Uint8Array(data.buffer, data.byteOffset, data.byteLength) : new Uint8Array(data);\r\n}\r\n\r\nexport function GetMinMax(data: DataArray, vertexBuffer: VertexBuffer, start: number, count: number): { min: number[]; max: number[] } {\r\n const { byteOffset, byteStride, type, normalized } = vertexBuffer;\r\n const size = vertexBuffer.getSize();\r\n const min = new Array<number>(size).fill(Infinity);\r\n const max = new Array<number>(size).fill(-Infinity);\r\n EnumerateFloatValues(data, byteOffset + start * byteStride, byteStride, size, type, count * size, normalized, (values) => {\r\n for (let i = 0; i < size; i++) {\r\n min[i] = Math.min(min[i], values[i]);\r\n max[i] = Math.max(max[i], values[i]);\r\n }\r\n });\r\n\r\n return { min, max };\r\n}\r\n\r\n/**\r\n * Removes, in-place, object properties which have the same value as the default value.\r\n * Useful for avoiding unnecessary properties in the glTF JSON.\r\n * @param object the object to omit default values from\r\n * @param defaultValues a partial object with default values\r\n * @returns object with default values omitted\r\n */\r\nexport function OmitDefaultValues<T extends object>(object: T, defaultValues: Partial<T>): T {\r\n for (const [key, value] of Object.entries(object)) {\r\n const defaultValue = defaultValues[key as keyof T];\r\n if ((Array.isArray(value) && Array.isArray(defaultValue) && AreArraysEqual(value, defaultValue)) || value === defaultValue) {\r\n delete object[key as keyof T];\r\n }\r\n }\r\n return object;\r\n}\r\n\r\nfunction AreArraysEqual(array1: unknown[], array2: unknown[]): boolean {\r\n return array1.length === array2.length && array1.every((val, i) => val === array2[i]);\r\n}\r\n","/* eslint-disable @typescript-eslint/naming-convention */\r\n/* eslint-disable babylonjs/available */\r\nimport type { TypedArray } from \"core/types\";\r\n\r\nconst TypedArrayToWriteMethod = new Map<Function, (dataView: DataView, byteOffset: number, value: number) => void>([\r\n [Int8Array, (d, b, v) => d.setInt8(b, v)],\r\n [Uint8Array, (dv, bo, v) => dv.setUint8(bo, v)],\r\n [Uint8ClampedArray, (dv, bo, v) => dv.setUint8(bo, v)],\r\n [Int16Array, (dv, bo, v) => dv.setInt16(bo, v, true)],\r\n [Uint16Array, (dv, bo, v) => dv.setUint16(bo, v, true)],\r\n [Int32Array, (dv, bo, v) => dv.setInt32(bo, v, true)],\r\n [Uint32Array, (dv, bo, v) => dv.setUint32(bo, v, true)],\r\n [Float32Array, (dv, bo, v) => dv.setFloat32(bo, v, true)],\r\n [Float64Array, (dv, bo, v) => dv.setFloat64(bo, v, true)],\r\n]);\r\n\r\n/** @internal */\r\nexport class DataWriter {\r\n private _data: Uint8Array;\r\n private _dataView: DataView;\r\n private _byteOffset: number;\r\n\r\n public writeTypedArray(value: Exclude<TypedArray, BigInt64Array | BigUint64Array>): void {\r\n this._checkGrowBuffer(value.byteLength);\r\n const setMethod = TypedArrayToWriteMethod.get(value.constructor)!;\r\n for (let i = 0; i < value.length; i++) {\r\n setMethod(this._dataView, this._byteOffset, value[i]);\r\n this._byteOffset += value.BYTES_PER_ELEMENT;\r\n }\r\n }\r\n\r\n public constructor(byteLength: number) {\r\n this._data = new Uint8Array(byteLength);\r\n this._dataView = new DataView(this._data.buffer);\r\n this._byteOffset = 0;\r\n }\r\n\r\n public get byteOffset(): number {\r\n return this._byteOffset;\r\n }\r\n\r\n public getOutputData(): Uint8Array {\r\n return new Uint8Array(this._data.buffer, 0, this._byteOffset);\r\n }\r\n\r\n public writeUInt8(value: number): void {\r\n this._checkGrowBuffer(1);\r\n this._dataView.setUint8(this._byteOffset, value);\r\n this._byteOffset++;\r\n }\r\n\r\n public writeInt8(value: number): void {\r\n this._checkGrowBuffer(1);\r\n this._dataView.setInt8(this._byteOffset, value);\r\n this._byteOffset++;\r\n }\r\n\r\n public writeInt16(entry: number): void {\r\n this._checkGrowBuffer(2);\r\n this._dataView.setInt16(this._byteOffset, entry, true);\r\n this._byteOffset += 2;\r\n }\r\n\r\n public writeUInt16(value: number): void {\r\n this._checkGrowBuffer(2);\r\n this._dataView.setUint16(this._byteOffset, value, true);\r\n this._byteOffset += 2;\r\n }\r\n\r\n public writeInt32(entry: number): void {\r\n this._checkGrowBuffer(4);\r\n this._dataView.setInt32(this._byteOffset, entry, true);\r\n this._byteOffset += 4;\r\n }\r\n\r\n public writeUInt32(value: number): void {\r\n this._checkGrowBuffer(4);\r\n this._dataView.setUint32(this._byteOffset, value, true);\r\n this._byteOffset += 4;\r\n }\r\n\r\n public writeFloat32(value: number): void {\r\n this._checkGrowBuffer(4);\r\n this._dataView.setFloat32(this._byteOffset, value, true);\r\n this._byteOffset += 4;\r\n }\r\n\r\n public writeFloat64(value: number): void {\r\n this._checkGrowBuffer(8);\r\n this._dataView.setFloat64(this._byteOffset, value, true);\r\n this._byteOffset += 8;\r\n }\r\n\r\n private _checkGrowBuffer(byteLength: number): void {\r\n const newByteLength = this.byteOffset + byteLength;\r\n if (newByteLength > this._data.byteLength) {\r\n const newData = new Uint8Array(newByteLength * 2);\r\n newData.set(this._data);\r\n this._data = newData;\r\n this._dataView = new DataView(this._data.buffer);\r\n }\r\n }\r\n}\r\n","import type { TypedArray } from \"core/types\";\nimport type { AccessorComponentType, AccessorType, IAccessor, IBufferView } from \"babylonjs-gltf2interface\";\nimport { DataWriter } from \"./dataWriter\";\n\ntype TypedArrayForglTF = Exclude<TypedArray, Float64Array | BigInt64Array | BigUint64Array>;\n\ninterface IPropertyWithBufferView {\n bufferView?: number;\n}\n\nfunction GetHighestByteAlignment(byteLength: number): number {\n if (byteLength % 4 === 0) {\n return 4;\n }\n if (byteLength % 2 === 0) {\n return 2;\n }\n return 1;\n}\n\n/**\n * Utility class to centralize the management of binary data, bufferViews, and the objects that reference them.\n * @internal\n */\nexport class BufferManager {\n /**\n * Maps a bufferView to its data\n */\n private _bufferViewToData: Map<IBufferView, TypedArrayForglTF> = new Map<IBufferView, TypedArrayForglTF>();\n\n /**\n * Maps a bufferView to glTF objects that reference it via a \"bufferView\" property (e.g. accessors, images)\n */\n private _bufferViewToProperties: Map<IBufferView, IPropertyWithBufferView[]> = new Map<IBufferView, IPropertyWithBufferView[]>();\n\n /**\n * Maps an accessor to its bufferView\n */\n private _accessorToBufferView: Map<IAccessor, IBufferView> = new Map<IAccessor, IBufferView>();\n\n /**\n * Generates a binary buffer from the stored bufferViews. Also populates the bufferViews list.\n * @param bufferViews The list of bufferViews to be populated while writing the binary\n * @returns The binary buffer\n */\n public generateBinary(bufferViews: IBufferView[]): Uint8Array {\n // Construct a DataWriter with the total byte length to prevent resizing\n let totalByteLength = 0;\n this._bufferViewToData.forEach((data) => {\n totalByteLength += data.byteLength;\n });\n const dataWriter = new DataWriter(totalByteLength);\n\n // Order the bufferViews in descending order of their alignment requirements\n const orderedBufferViews = Array.from(this._bufferViewToData.keys()).sort((a, b) => GetHighestByteAlignment(b.byteLength) - GetHighestByteAlignment(a.byteLength));\n\n // Fill in the bufferViews list and missing bufferView index references while writing the binary\n for (const bufferView of orderedBufferViews) {\n bufferView.byteOffset = dataWriter.byteOffset;\n bufferViews.push(bufferView);\n\n const bufferViewIndex = bufferViews.length - 1;\n const properties = this.getPropertiesWithBufferView(bufferView);\n for (const object of properties) {\n object.bufferView = bufferViewIndex;\n }\n\n dataWriter.writeTypedArray(this._bufferViewToData.get(bufferView)!);\n\n this._bufferViewToData.delete(bufferView); // Try to free up memory ASAP\n }\n\n return dataWriter.getOutputData();\n }\n\n /**\n * Creates a buffer view based on the supplied arguments\n * @param data a TypedArray to create the bufferView for\n * @param byteStride byte distance between consecutive elements\n * @returns bufferView for glTF\n */\n public createBufferView(data: TypedArrayForglTF, byteStride?: number): IBufferView {\n const bufferView: IBufferView = {\n buffer: 0,\n byteOffset: undefined, // byteOffset will be set later, when we write the binary and decide bufferView ordering\n byteLength: data.byteLength,\n byteStride: byteStride,\n };\n this._bufferViewToData.set(bufferView, data);\n return bufferView;\n }\n\n /**\n * Creates an accessor based on the supplied arguments and assigns it to the bufferView\n * @param bufferView The glTF bufferView referenced by this accessor\n * @param type The type of the accessor\n * @param componentType The datatype of components in the attribute\n * @param count The number of attributes referenced by this accessor\n * @param byteOffset The offset relative to the start of the bufferView in bytes\n * @param minMax Minimum and maximum value of each component in this attribute\n * @param normalized Specifies whether integer data values are normalized before usage\n * @returns accessor for glTF\n */\n public createAccessor(\n bufferView: IBufferView,\n type: AccessorType,\n componentType: AccessorComponentType,\n count: number,\n byteOffset?: number,\n minMax?: { min: number[]; max: number[] },\n normalized?: boolean\n ): IAccessor {\n this._verifyBufferView(bufferView);\n const accessor: IAccessor = {\n bufferView: undefined, // bufferView will be set to a real index later, once we write the binary and decide bufferView ordering\n componentType: componentType,\n count: count,\n type: type,\n min: minMax?.min,\n max: minMax?.max,\n normalized: normalized,\n byteOffset: byteOffset,\n };\n this.setBufferView(accessor, bufferView);\n this._accessorToBufferView.set(accessor, bufferView);\n return accessor;\n }\n\n /**\n * Assigns a bufferView to a glTF object that references it\n * @param object The glTF object\n * @param bufferView The bufferView to assign\n */\n public setBufferView(object: IPropertyWithBufferView, bufferView: IBufferView) {\n this._verifyBufferView(bufferView);\n const properties = this.getPropertiesWithBufferView(bufferView);\n properties.push(object);\n }\n\n /**\n * Removes buffer view from the binary data, as well as from all its known references\n * @param bufferView the bufferView to remove\n */\n public removeBufferView(bufferView: IBufferView): void {\n const properties = this.getPropertiesWithBufferView(bufferView);\n for (const object of properties) {\n if (object.bufferView !== undefined) {\n delete object.bufferView;\n }\n }\n\n this._bufferViewToData.delete(bufferView);\n this._bufferViewToProperties.delete(bufferView);\n this._accessorToBufferView.forEach((bv, accessor) => {\n if (bv === bufferView) {\n // Additionally, remove byteOffset from accessor referencing this bufferView\n if (accessor.byteOffset !== undefined) {\n delete accessor.byteOffset;\n }\n this._accessorToBufferView.delete(accessor);\n }\n });\n }\n\n public getBufferView(accessor: IAccessor): IBufferView {\n const bufferView = this._accessorToBufferView.get(accessor);\n this._verifyBufferView(bufferView);\n return bufferView!;\n }\n\n public getPropertiesWithBufferView(bufferView: IBufferView): IPropertyWithBufferView[] {\n this._verifyBufferView(bufferView);\n this._bufferViewToProperties.set(bufferView, this._bufferViewToProperties.get(bufferView) ?? []);\n return this._bufferViewToProperties.get(bufferView)!;\n }\n\n public getData(bufferView: IBufferView): TypedArrayForglTF {\n this._verifyBufferView(bufferView);\n return this._bufferViewToData.get(bufferView)!;\n }\n\n private _verifyBufferView(bufferView?: IBufferView): void {\n if (bufferView === undefined || !this._bufferViewToData.has(bufferView)) {\n throw new Error(`BufferView ${bufferView} not found in BufferManager.`);\n }\n }\n}\n","import type { IAnimation, INode, IBufferView, IAccessor, IAnimationSampler, IAnimationChannel } from \"babylonjs-gltf2interface\";\r\nimport { AnimationSamplerInterpolation, AnimationChannelTargetPath, AccessorType, AccessorComponentType } from \"babylonjs-gltf2interface\";\r\nimport type { Node } from \"core/node\";\r\nimport type { Nullable } from \"core/types\";\r\nimport { Vector3, Quaternion } from \"core/Maths/math.vector\";\r\nimport { Tools } from \"core/Misc/tools\";\r\nimport { Animation } from \"core/Animations/animation\";\r\nimport { TransformNode } from \"core/Meshes/transformNode\";\r\nimport type { Scene } from \"core/scene\";\r\nimport { MorphTarget } from \"core/Morph/morphTarget\";\r\nimport { Mesh } from \"core/Meshes/mesh\";\r\n\r\nimport type { IAnimationKey } from \"core/Animations/animationKey\";\r\nimport { AnimationKeyInterpolation } from \"core/Animations/animationKey\";\r\n\r\nimport { Camera } from \"core/Cameras/camera\";\r\nimport { Light } from \"core/Lights/light\";\r\nimport type { BufferManager } from \"./bufferManager\";\r\nimport { GetAccessorElementCount, ConvertToRightHandedPosition, ConvertCameraRotationToGLTF, ConvertToRightHandedRotation } from \"./glTFUtilities\";\r\n\r\n/**\r\n * @internal\r\n * Interface to store animation data.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface _IAnimationData {\r\n /**\r\n * Keyframe data.\r\n */\r\n inputs: number[];\r\n /**\r\n * Value data.\r\n */\r\n outputs: number[][];\r\n /**\r\n * Animation interpolation data.\r\n */\r\n samplerInterpolation: AnimationSamplerInterpolation;\r\n /**\r\n * Minimum keyframe value.\r\n */\r\n inputsMin: number;\r\n /**\r\n * Maximum keyframe value.\r\n */\r\n inputsMax: number;\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport interface _IAnimationInfo {\r\n /**\r\n * The target channel for the animation\r\n */\r\n animationChannelTargetPath: AnimationChannelTargetPath;\r\n /**\r\n * The glTF accessor type for the data.\r\n */\r\n dataAccessorType: AccessorType.VEC3 | AccessorType.VEC4 | AccessorType.SCALAR;\r\n /**\r\n * Specifies if quaternions should be used.\r\n */\r\n useQuaternion: boolean;\r\n}\r\n\r\n/**\r\n * @internal\r\n * Enum for handling in tangent and out tangent.\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nenum _TangentType {\r\n /**\r\n * Specifies that input tangents are used.\r\n */\r\n INTANGENT,\r\n /**\r\n * Specifies that output tangents are used.\r\n */\r\n OUTTANGENT,\r\n}\r\n\r\n/**\r\n * @internal\r\n * Utility class for generating glTF animation data from BabylonJS.\r\n */\r\nexport class _GLTFAnimation {\r\n /**\r\n * Determine if a node is transformable - ie has properties it should be part of animation of transformation.\r\n * @param babylonNode the node to test\r\n * @returns true if can be animated, false otherwise. False if the parameter is null or undefined.\r\n */\r\n private static _IsTransformable(babylonNode: Node): boolean {\r\n return babylonNode && (babylonNode instanceof TransformNode || babylonNode instanceof Camera || babylonNode instanceof Light);\r\n }\r\n\r\n /**\r\n * @ignore\r\n *\r\n * Creates glTF channel animation from BabylonJS animation.\r\n * @param babylonTransformNode - BabylonJS mesh.\r\n * @param animation - animation.\r\n * @param animationChannelTargetPath - The target animation channel.\r\n * @param useQuaternion - Specifies if quaternions are used.\r\n * @returns nullable IAnimationData\r\n */\r\n public static _CreateNodeAnimation(\r\n babylonTransformNode: Node,\r\n animation: Animation,\r\n animationChannelTargetPath: AnimationChannelTargetPath,\r\n useQuaternion: boolean,\r\n animationSampleRate: number\r\n ): Nullable<_IAnimationData> {\r\n if (this._IsTransformable(babylonTransformNode)) {\r\n const inputs: number[] = [];\r\n const outputs: number[][] = [];\r\n const keyFrames = animation.getKeys();\r\n const minMaxKeyFrames = _GLTFAnimation._CalculateMinMaxKeyFrames(keyFrames);\r\n const interpolationOrBake = _GLTFAnimation._DeduceInterpolation(keyFrames, animationChannelTargetPath, useQuaternion);\r\n\r\n const interpolation = interpolationOrBake.interpolationType;\r\n const shouldBakeAnimation = interpolationOrBake.shouldBakeAnimation;\r\n\r\n if (shouldBakeAnimation) {\r\n _GLTFAnimation._CreateBakedAnimation(\r\n babylonTransformNode,\r\n animation,\r\n animationChannelTargetPath,\r\n minMaxKeyFrames.min,\r\n minMaxKeyFrames.max,\r\n animation.framePerSecond,\r\n animationSampleRate,\r\n inputs,\r\n outputs,\r\n minMaxKeyFrames,\r\n useQuaternion\r\n );\r\n } else {\r\n if (interpolation === AnimationSamplerInterpolation.LINEAR || interpolation === AnimationSamplerInterpolation.STEP) {\r\n _GLTFAnimation._CreateLinearOrStepAnimation(babylonTransformNode, animation, animationChannelTargetPath, inputs, outputs, useQuaternion);\r\n } else if (interpolation === AnimationSamplerInterpolation.CUBICSPLINE) {\r\n _GLTFAnimation._CreateCubicSplineAnimation(babylonTransformNode, animation, animationChannelTargetPath, inputs, outputs, useQuaternion);\r\n } else {\r\n _GLTFAnimation._CreateBakedAnimation(\r\n babylonTransformNode,\r\n animation,\r\n animationChannelTargetPath,\r\n minMaxKeyFrames.min,\r\n minMaxKeyFrames.max,\r\n animation.framePerSecond,\r\n animationSampleRate,\r\n inputs,\r\n outputs,\r\n minMaxKeyFrames,\r\n useQuaternion\r\n );\r\n }\r\n }\r\n\r\n if (inputs.length && outputs.length) {\r\n const result: _IAnimationData = {\r\n inputs: inputs,\r\n outputs: outputs,\r\n samplerInterpolation: interpolation,\r\n inputsMin: shouldBakeAnimation ? minMaxKeyFrames.min : Tools.FloatRound(minMaxKeyFrames.min / animation.framePerSecond),\r\n inputsMax: shouldBakeAnimation ? minMaxKeyFrames.max : Tools.FloatRound(minMaxKeyFrames.max / animation.framePerSecond),\r\n };\r\n\r\n return result;\r\n }\r\n }\r\n\r\n return null;\r\n }\r\n\r\n private static _DeduceAnimationInfo(animation: Animation): Nullable<_IAnimationInfo> {\r\n let animationChannelTargetPath: Nullable<AnimationChannelTargetPath> = null;\r\n let dataAccessorType = AccessorType.VEC3;\r\n let useQuaternion: boolean = false;\r\n const property = animation.targetProperty.split(\".\");\r\n switch (property[0]) {\r\n case \"scaling\": {\r\n animationChannelTargetPath = AnimationChannelTargetPath.SCALE;\r\n break;\r\n }\r\n case \"position\": {\r\n animationChannelTargetPath = AnimationChannelTargetPath.TRANSLATION;\r\n break;\r\n }\r\n case \"rotation\": {\r\n dataAccessorType = AccessorType.VEC4;\r\n animationChannelTargetPath = AnimationChannelTargetPath.ROTATION;\r\n break;\r\n }\r\n case \"rotationQuaternion\": {\r\n dataAccessorType = AccessorType.VEC4;\r\n useQuaternion = true;\r\n animationChannelTargetPath = AnimationChannelTargetPath.ROTATION;\r\n break;\r\n }\r\n case \"influence\": {\r\n dataAccessorType = AccessorType.SCALAR;\r\n animationChannelTargetPath = AnimationChannelTargetPath.WEIGHTS;\r\n break;\r\n }\r\n default: {\r\n Tools.Error(`Unsupported animatable property ${property[0]}`);\r\n }\r\n }\r\n if (animationChannelTargetPath) {\r\n return { animationChannelTargetPath: animationChannelTargetPath, dataAccessorType: dataAccessorType, useQuaternion: useQuaternion };\r\n } else {\r\n Tools.Error(\"animation channel target path and data accessor type could be deduced\");\r\n }\r\n return null;\r\n }\r\n\r\n /**\r\n * @ignore\r\n * Create node animations from the transform node animations\r\n * @param babylonNode\r\n * @param runtimeGLTFAnimation\r\n * @param idleGLTFAnimations\r\n * @param nodeMap\r\n * @param nodes\r\n * @param bufferManager\r\n * @param bufferViews\r\n * @param accessors\r\n * @param animationSampleRate\r\n */\r\n public static _CreateNodeAnimationFromNodeAnimations(\r\n babylonNode: Node,\r\n runtimeGLTFAnimation: IAnimation,\r\n idleGLTFAnimations: IAnimation[],\r\n nodeMap: Map<Node, number>,\r\n nodes: INode[],\r\n bufferManager: BufferManager,\r\n bufferViews: IBufferView[],\r\n accessors: IAccessor[],\r\n animationSampleRate: number,\r\n useRightHanded: boolean,\r\n shouldExportAnimation?: (animation: Animation) => boolean\r\n ) {\r\n let glTFAnimation: IAnimation;\r\n if (_GLTFAnimation._IsTransformable(babylonNode)) {\r\n if (babylonNode.animations) {\r\n for (const animation of babylonNode.animations) {\r\n if (shouldExportAnimation && !shouldExportAnimation(animation)) {\r\n continue;\r\n }\r\n const animationInfo = _GLTFAnimation._DeduceAnimationInfo(animation);\r\n if (animationInfo) {\r\n glTFAnimation = {\r\n name: animation.name,\r\n samplers: [],\r\n channels: [],\r\n };\r\n _GLTFAnimation._AddAnimation(\r\n `${animation.name}`,\r\n animation.hasRunningRuntimeAnimations ? runtimeGLTFAnimation : glTFAnimation,\r\n babylonNode,\r\n animation,\r\n animationInfo.dataAccessorType,\r\n animationInfo.animationChannelTargetPath,\r\n nodeMap,\r\n bufferManager,\r\n bufferViews,\r\n accessors,\r\n animationInfo.useQuaternion,\r\n animationSampleRate,\r\n useRightHanded\r\n );\r\n if (glTFAnimation.samplers.length && glTFAnimation.channels.length) {\r\n idleGLTFAnimations.push(glTFAnimation);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * @ignore\r\n * Create individual morph animations from the mesh's morph target animation tracks\r\n * @param babylonNode\r\n * @param runtimeGLTFAnimation\r\n * @param idleGLTFAnimations\r\n * @param nodeMap\r\n * @param nodes\r\n * @param bufferManager\r\n * @param bufferViews\r\n * @param accessors\r\n * @param animationSampleRate\r\n */\r\n public static _CreateMorphTargetAnimationFromMorphTargetAnimations(\r\n babylonNode: Node,\r\n runtimeGLTFAnimation: IAnimation,\r\n idleGLTFAnimations: IAnimation[],\r\n nodeMap: Map<Node, number>,\r\n nodes: INode[],\r\n bufferManager: BufferManager,\r\n bufferViews: IBufferView[],\r\n accessors: IAccessor[],\r\n animationSampleRate: number,\r\n useRightHanded: boolean,\r\n shouldExportAnimation?: (animation: Animation) => boolean\r\n ) {\r\n let glTFAnimation: IAnimation;\r\n if (babylonNode instanceof Mesh) {\r\n const morphTargetManager = babylonNode.morphTargetManager;\r\n if (morphTargetManager) {\r\n for (let i = 0; i < morphTargetManager.numTargets; ++i) {\r\n const morphTarget = morphTargetManager.getTarget(i);\r\n for (const animation of morphTarget.animations) {\r\n if (shouldExportAnimation && !shouldExportAnimation(animation)) {\r\n continue;\r\n }\r\n const combinedAnimation = new Animation(\r\n `${animation.name}`,\r\n \"influence\",\r\n animation.framePerSecond,\r\n animation.dataType,\r\n animation.loopMode,\r\n animation.enableBlending\r\n );\r\n const combinedAnimationKeys: IAnimationKey[] = [];\r\n const animationKeys = animation.getKeys();\r\n\r\n for (let j = 0; j < animationKeys.length; ++j) {\r\n const animationKey = animationKeys[j];\r\n for (let k = 0; k < morphTargetManager.numTargets; ++k) {\r\n if (k == i) {\r\n combinedAnimationKeys.push(animationKey);\r\n } else {\r\n combinedAnimationKeys.push({ frame: animationKey.frame, value: 0 });\r\n }\r\n }\r\n }\r\n combinedAnimation.setKeys(combinedAnimationKeys);\r\n const animationInfo = _GLTFAnimation._DeduceAnimationInfo(combinedAnimation);\r\n if (animationInfo) {\r\n glTFAnimation = {\r\n name: combinedAnimation.name,\r\n samplers: [],\r\n channels: [],\r\n };\r\n _GLTFAnimation._AddAnimation(\r\n animation.name,\r\n animation.hasRunningRuntimeAnimations ? runtimeGLTFAnimation : glTFAnimation,\r\n babylonNode,\r\n combinedAnimation,\r\n animationInfo.dataAccessorType,\r\n animationInfo.animationChannelTargetPath,\r\n nodeMap,\r\n bufferManager,\r\n bufferViews,\r\n accessors,\r\n animationInfo.useQuaternion,\r\n animationSampleRate,\r\n useRightHanded,\r\n morphTargetManager.numTargets\r\n );\r\n if (glTFAnimation.samplers.length && glTFAnimation.channels.length) {\r\n idleGLTFAnimations.push(glTFAnimation);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * @internal\r\n * Create node and morph animations from the animation groups\r\n * @param babylonScene\r\n * @param glTFAnimations\r\n * @param nodeMap\r\n * @param nodes\r\n * @param bufferManager\r\n * @param bufferViews\r\n * @param accessors\r\n * @param animationSampleRate\r\n */\r\n public static _CreateNodeAndMorphAnimationFromAnimationGroups(\r\n babylonScene: Scene,\r\n glTFAnimations: IAnimation[],\r\n nodeMap: Map<Node, number>,\r\n bufferManager: BufferManager,\r\n bufferViews: IBufferView[],\r\n accessors: IAccessor[],\r\n animationSampleRate: number,\r\n leftHandedNodes: Set<Node>,\r\n shouldExportAnimation?: (animation: Animation) => boolean\r\n ) {\r\n let glTFAnimation: IAnimation;\r\n if (babylonScene.animationGroups) {\r\n const animationGroups = babylonScene.animationGroups;\r\n for (const animationGroup of animationGroups) {\r\n const morphAnimations: Map<Mesh, Map<MorphTarget, Animation>> = new Map();\r\n const sampleAnimations: Map<Mesh, Animation> = new Map();\r\n const morphAnimationMeshes: Set<Mesh> = new Set();\r\n const animationGroupFrameDiff = animationGroup.to - animationGroup.from;\r\n glTFAnimation = {\r\n name: animationGroup.name,\r\n channels: [],\r\n samplers: [],\r\n };\r\n for (let i = 0; i < animationGroup.targetedAnimations.length; ++i) {\r\n const targetAnimation = animationGroup.targetedAnimations[i];\r\n const target = targetAnimation.target;\r\n const animation = targetAnimation.animation;\r\n if (shouldExportAnimation && !shouldExportAnimation(animation)) {\r\n continue;\r\n }\r\n\r\n const convertToRightHanded = leftHandedNodes.has(target);\r\n\r\n if (this._IsTransformable(target) || (target.length === 1 && this._IsTransformable(target[0]))) {\r\n const animationInfo = _GLTFAnimation._DeduceAnimationInfo(targetAnimation.animation);\r\n if (animationInfo) {\r\n const babylonTransformNode = this._IsTransformable(target) ? target : this._IsTransformable(target[0]) ? target[0] : null;\r\n if (babylonTransformNode) {\r\n _GLTFAnimation._AddAnimation(\r\n `${animation.name}`,\r\n glTFAnimation,\r\n babylonTransformNode,\r\n animation,\r\n animationInfo.dataAccessorType,\r\n animationInfo.animationChannelTargetPath,\r\n nodeMap,\r\n bufferManager,\r\n bufferViews,\r\n accessors,\r\n animationInfo.useQuaternion,\r\n animationSampleRate,\r\n convertToRightHanded\r\n );\r\n }\r\n }\r\n } else if (target instanceof MorphTarget || (target.length === 1 && target[0] instanceof MorphTarget)) {\r\n const animationInfo = _GLTFAnimation._DeduceAnimationInfo(targetAnimation.animation);\r\n if (animationInfo) {\r\n const babylonMorphTarget = target instanceof MorphTarget ? target : (target[0] as MorphTarget);\r\n if (babylonMorphTarget) {\r\n const babylonMorphTargetManager = babylonScene.morphTargetManagers.find((morphTargetManager) => {\r\n for (let j = 0; j < morphTargetManager.numTargets; ++j) {\r\n if (morphTargetManager.getTarget(j) === babylonMorphTarget) {\r\n return true;\r\n }\r\n }\r\n return false;\r\n });\r\n if (babylonMorphTargetManager) {\r\n const babylonMesh = babylonScene.meshes.find((mesh) => {\r\n return (mesh as Mesh).morphTargetManager === babylonMorphTargetManager;\r\n }) as Mesh;\r\n if (babylonMesh) {\r\n if (!morphAnimations.has(babylonMesh)) {\r\n morphAnimations.set(babylonMesh, new Map());\r\n }\r\n morphAnimations.get(babylonMesh)?.set(babylonMorphTarget, animation);\r\n morphAnimationMeshes.add(babylonMesh);\r\n sampleAnimations.set(babylonMesh, animation);\r\n }\r\n }\r\n }\r\n }\r\n } else {\r\n // this is the place for the KHR_animation_pointer.\r\n }\r\n }\r\n morphAnimationMeshes.forEach((mesh) => {\r\n const morphTargetManager = mesh.morphTargetManager!;\r\n let combinedAnimationGroup: Nullable<Animation> = null;\r\n const animationKeys: IAnimationKey[] = [];\r\n const sampleAnimation = sampleAnimations.get(mesh)!;\r\n const sampleAnimationKeys = sampleAnimation.getKeys();\r\n const numAnimationKeys = sampleAnimationKeys.length;\r\n /*\r\n Due to how glTF expects morph target animation data to be formatted, we need to rearrange the individual morph target animation tracks,\r\n such that we have a single animation, where a given keyframe input value has successive output values for each morph target belonging to the manager.\r\n See: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#animations\r\n\r\n We do this via constructing a new Animation track, and interleaving the frames of each morph target animation track in the current Animation Group\r\n We reuse the Babylon Animation data structure for ease of handling export of cubic spline animation keys, and to reuse the\r\n existing _GLTFAnimation.AddAnimation codepath with minimal modification, however the constructed Babylon Animation is NOT intended for use in-engine.\r\n */\r\n for (let i = 0; i < numAnimationKeys; ++i) {\r\n for (let j = 0; j < morphTargetManager.numTargets; ++j) {\r\n const morphTarget = morphTargetManager.getTarget(j);\r\n const animationsByMorphTarget = morphAnimations.get(mesh);\r\n if (animationsByMorphTarget) {\r\n const morphTargetAnimation = animationsByMorphTarget.get(morphTarget);\r\n if (morphTargetAnimation) {\r\n if (!combinedAnimationGroup) {\r\n combinedAnimationGroup = new Animation(\r\n `${animationGroup.name}_${mesh.name}_MorphWeightAnimation`,\r\n \"influence\",\r\n morphTargetAnimation.framePerSecond,\r\n Animation.ANIMATIONTYPE_FLOAT,\r\n morphTargetAnimation.loopMode,\r\n morphTargetAnimation.enableBlending\r\n );\r\n }\r\n animationKeys.push(morphTargetAnimation.getKeys()[i]);\r\n } else {\r\n animationKeys.push({\r\n frame: animationGroup.from + (animationGroupFrameDiff / numAnimationKeys) * i,\r\n value: morphTarget.influence,\r\n inTangent: sampleAnimationKeys[0].inTangent ? 0 : undefined,\r\n outTangent: sampleAnimationKeys[0].outTangent ? 0 : undefined,\r\n });\r\n }\r\n }\r\n }\r\n }\r\n combinedAnimationGroup!.setKeys(animationKeys);\r\n const animationInfo = _GLTFAnimation._DeduceAnimationInfo(combinedAnimationGroup!);\r\n if (animationInfo) {\r\n _GLTFAnimation._AddAnimation(\r\n `${animationGroup.name}_${mesh.name}_MorphWeightAnimation`,\r\n glTFAnimation,\r\n mesh,\r\n combinedAnimationGroup!,\r\n animationInfo.dataAccessorType,\r\n animationInfo.animationChannelTargetPath,\r\n nodeMap,\r\n bufferManager,\r\n bufferViews,\r\n accessors,\r\n animationInfo.useQuaternion,\r\n animationSampleRate,\r\n false,\r\n morphTargetManager?.numTargets\r\n );\r\n }\r\n });\r\n if (glTFAnimation.channels.length && glTFAnimation.samplers.length) {\r\n glTFAnimations.push(glTFAnimation);\r\n }\r\n }\r\n }\r\n }\r\n\r\n private static _AddAnimation(\r\n name: string,\r\n glTFAnimation: IAnimation,\r\n babylonTransformNode: Node,\r\n animation: Animation,\r\n dataAccessorType: AccessorType,\r\n animationChannelTargetPath: AnimationChannelTargetPath,\r\n nodeMap: Map<Node, number>,\r\n bufferManager: BufferManager,\r\n bufferViews: IBufferView[],\r\n accessors: IAccessor[],\r\n useQuaternion: boolean,\r\n animationSampleRate: number,\r\n convertToRightHanded: boolean,\r\n morphAnimationChannels?: number\r\n ) {\r\n const animationData = _GLTFAnimation._CreateNodeAnimation(babylonTransformNode, animation, animationChannelTargetPath, useQuaternion, animationSampleRate);\r\n let bufferView: IBufferView;\r\n let accessor: IAccessor;\r\n let keyframeAccessorIndex: number;\r\n let dataAccessorIndex: number;\r\n let animationSampler: IAnimationSampler;\r\n let animationChannel: IAnimationChannel;\r\n\r\n if (animationData) {\r\n /*\r\n * Now that we have the glTF converted morph target animation data,\r\n * we can remove redundant input data so that we have n input frames,\r\n * and morphAnimationChannels * n output frames\r\n */\r\n if (morphAnimationChannels) {\r\n let index = 0;\r\n let currentInput: number = 0;\r\n const newInputs: number[] = [];\r\n while (animationData.inputs.length > 0) {\r\n currentInput = animationData.inputs.shift()!;\r\n if (index % morphAnimationChannels == 0) {\r\n newInputs.push(currentInput);\r\n }\r\n index++;\r\n }\r\n animationData.inputs = newInputs;\r\n }\r\n\r\n const nodeIndex = nodeMap.get(babylonTransformNode);\r\n\r\n // Create buffer view and accessor for key frames.\r\n const inputData = new Float32Array(animationData.inputs);\r\n bufferView = bufferManager.createBufferView(inputData);\r\n accessor = bufferManager.createAccessor(bufferView, AccessorType.SCALAR, AccessorComponentType.FLOAT, animationData.inputs.length, undefined, {\r\n min: [animationData.inputsMin],\r\n max: [animationData.inputsMax],\r\n });\r\n accessors.push(accessor);\r\n keyframeAccessorIndex = accessors.length - 1;\r\n\r\n // Perform conversions on keyed values while also building their buffer.\r\n const rotationQuaternion = new Quaternion();\r\n const eulerVec3 = new Vector3();\r\n const position = new Vector3();\r\n const isCamera = babylonTransformNode instanceof Camera;\r\n\r\n const elementCount = GetAccessorElementCount(dataAccessorType);\r\n const outputData = new Float32Array(animationData.outputs.length * elementCount);\r\n animationData.outputs.forEach(function (output: number[], index: number) {\r\n let outputToWrite: number[] = output;\r\n if (convertToRightHanded) {\r\n switch (animationChannelTargetPath) {\r\n case AnimationChannelTargetPath.TRANSLATION:\r\n Vector3.FromArrayToRef(output, 0, position);\r\n ConvertToRightHandedPosition(position);\r\n position.toArray(outputToWrite);\r\n break;\r\n case AnimationChannelTargetPath.ROTATION:\r\n if (output.length === 4) {\r\n Quaternion.FromArrayToRef(output, 0, rotationQuaternion);\r\n } else {\r\n outputToWrite = new Array(4); // Will need 4, not 3, for a quaternion\r\n Vector3.FromArrayToRef(output, 0, eulerVec3);\r\n Quaternion.FromEulerVectorToRef(eulerVec3, rotationQuaternion);\r\n }\r\n\r\n if (isCamera) {\r\n ConvertCameraRotationToGLTF(rotationQuaternion);\r\n } else {\r\n if (!Quaternion.IsIdentity(rotationQuaternion)) {\r\n ConvertToRightHandedRotation(rotationQuaternion);\r\n }\r\n }\r\n\r\n rotationQuaternion.toArray(outputToWrite);\r\n break;\r\n }\r\n } else {\r\n switch (animationChannelTargetPath) {\r\n case AnimationChannelTargetPath.ROTATION:\r\n if (output.length === 4) {\r\n Quaternion.FromArrayToRef(output, 0, rotationQuaternion);\r\n } else {\r\n outputToWrite = new Array(4); // Will need 4, not 3, for a quaternion\r\n Vector3.FromArrayToRef(output, 0, eulerVec3);\r\n Quaternion.FromEulerVectorToRef(eulerVec3, rotationQuaternion);\r\n }\r\n\r\n if (isCamera) {\r\n ConvertCameraRotationToGLTF(rotationQuaternion);\r\n }\r\n\r\n rotationQuaternion.toArray(outputToWrite);\r\n break;\r\n }\r\n }\r\n outputData.set(outputToWrite, index * elementCount);\r\n });\r\n\r\n // Create buffer view and accessor for keyed values.\r\n bufferView = bufferManager.createBufferView(outputData);\r\n accessor = bufferManager.createAccessor(bufferView, dataAccessorType, AccessorComponentType.FLOAT, animationData.outputs.length);\r\n accessors.push(accessor);\r\n dataAccessorIndex = accessors.length - 1;\r\n\r\n // create sampler\r\n animationSampler = {\r\n interpolation: animationData.samplerInterpolation,\r\n input: keyframeAccessorIndex,\r\n output: dataAccessorIndex,\r\n };\r\n glTFAnimation.samplers.push(animationSampler);\r\n\r\n // create channel\r\n animationChannel = {\r\n sampler: glTFAnimation.samplers.length - 1,\r\n target: {\r\n node: nodeIndex,\r\n path: animationChannelTargetPath,\r\n },\r\n };\r\n glTFAnimation.channels.push(animationChannel);\r\n }\r\n }\r\n\r\n /**\r\n * Create a baked animation\r\n * @param babylonTransformNode BabylonJS mesh\r\n * @param animation BabylonJS animation corresponding to the BabylonJS mesh\r\n * @param animationChannelTargetPath animation target channel\r\n * @param minFrame minimum animation frame\r\n * @param maxFrame maximum animation frame\r\n * @param fps frames per second of the animation\r\n * @param sampleRate\r\n * @param inputs input key frames of the animation\r\n * @param outputs output key frame data of the animation\r\n * @param minMaxFrames\r\n * @param minMaxFrames.min\r\n * @param minMaxFrames.max\r\n * @param useQuaternion specifies if quaternions should be used\r\n */\r\n private static _CreateBakedAnimation(\r\n babylonTransformNode: Node,\r\n animation: Animation,\r\n animationChannelTargetPath: AnimationChannelTargetPath,\r\n minFrame: number,\r\n maxFrame: number,\r\n fps: number,\r\n sampleRate: number,\r\n inputs: number[],\r\n outputs: number[][],\r\n minMaxFrames: { min: number; max: number },\r\n useQuaternion: boolean\r\n ) {\r\n let value: number | Vector3 | Quaternion;\r\n const quaternionCache: Quaternion = Quaternion.Identity();\r\n let previousTime: Nullable<number> = null;\r\n let time: number;\r\n let maxUsedFrame: Nullable<number> = null;\r\n let currKeyFrame: Nullable<IAnimationKey> = null;\r\n let nextKeyFrame: Nullable<IAnimationKey> = null;\r\n let prevKeyFrame: Nullable<IAnimationKey> = null;\r\n let endFrame: Nullable<number> = null;\r\n minMaxFrames.min = Tools.FloatRound(minFrame / fps);\r\n\r\n const keyFrames = animation.getKeys();\r\n\r\n for (let i = 0, length = keyFrames.length; i < length; ++i) {\r\n endFrame = null;\r\n currKeyFrame = keyFrames[i];\r\n\r\n if (i + 1 < length) {\r\n nextKeyFrame = keyFrames[i + 1];\r\n if ((currKeyFrame.value.equals && currKeyFrame.value.equals(nextKeyFrame.value)) || currKeyFrame.value === nextKeyFrame.value) {\r\n if (i === 0) {\r\n // set the first frame to itself\r\n endFrame = currKeyFrame.frame;\r\n } else {\r\n continue;\r\n }\r\n } else {\r\n endFrame = nextKeyFrame.frame;\r\n }\r\n } else {\r\n // at the last key frame\r\n prevKeyFrame = keyFrames[i - 1];\r\n if ((currKeyFrame.value.equals && currKeyFrame.value.equals(prevKeyFrame.value)) || currKeyFrame.value === prevKeyFrame.value) {\r\n continue;\r\n } else {\r\n endFrame = maxFrame;\r\n }\r\n }\r\n if (endFrame) {\r\n for (let f = currKeyFrame.frame; f <= endFrame; f += sampleRate) {\r\n time = Tools.FloatRound(f / fps);\r\n if (time === previousTime) {\r\n continue;\r\n }\r\n previousTime = time;\r\n maxUsedFrame = time;\r\n const state = {\r\n key: 0,\r\n repeatCount: 0,\r\n loopMode: animation.loopMode,\r\n };\r\n value = animation._interpolate(f, state);\r\n\r\n _GLTFAnimation._SetInterpolatedValue(babylonTransformNode, value, time, animation, animationChannelTargetPath, quaternionCache, inputs, outputs, useQuaternion);\r\n }\r\n }\r\n }\r\n if (maxUsedFrame) {\r\n minMaxFrames.max = maxUsedFrame;\r\n }\r\n }\r\n\r\n private static _ConvertFactorToVector3OrQuaternion(\r\n factor: number,\r\n babylonTransformNode: Node,\r\n animation: Animation,\r\n animationChannelTargetPath: AnimationChannelTargetPath,\r\n useQuaternion: boolean\r\n ): Vector3 | Quaternion {\r\n const basePositionRotationOrScale = _GLTFAnimation._GetBasePositionRotationOrScale(babylonTransformNode, animationChannelTargetPath, useQuaternion);\r\n // handles single component x, y, z or w component animation by using a base property and animating over a component.\r\n const property = animation.targetProperty.split(\".\");\r\n const componentName = property ? property[1] : \"\"; // x, y, z, or w component\r\n const value = useQuaternion ? Quaternion.FromArray(basePositionRotationOrScale).normalize() : Vector3.FromArray(basePositionRotationOrScale);\r\n\r\n switch (componentName) {\r\n case \"x\":\r\n case \"y\":\r\n case \"z\": {\r\n value[componentName] = factor;\r\n break;\r\n }\r\n case \"w\": {\r\n (value as Quaternion).w = factor;\r\n break;\r\n }\r\n default: {\r\n Tools.Error(`glTFAnimation: Unsupported component name \"${componentName}\"!`);\r\n }\r\n }\r\n\r\n return value;\r\n }\r\n\r\n private static _SetInterpolatedValue(\r\n babylonTransformNode: Node,\r\n value: number | Vector3 | Quaternion,\r\n time: number,\r\n animation: Animation,\r\n animationChannelTargetPath: AnimationChannelTargetPath,\r\n quaternionCache: Quaternion,\r\n inputs: number[],\r\n outputs: number[][],\r\n useQuaternion: boolean\r\n ) {\r\n let cacheValue: Vector3 | Quaternion | number;\r\n inputs.push(time);\r\n\r\n if (animationChannelTargetPath === AnimationChannelTargetPath.WEIGHTS) {\r\n outputs.push([value as number]);\r\n return;\r\n }\r\n\r\n if (animation.dataType === Animation.ANIMATIONTYPE_FLOAT) {\r\n value = this._ConvertFactorToVector3OrQuaternion(value as number, babylonTransformNode, animation, animationChannelTargetPath, useQuaternion);\r\n }\r\n\r\n if (animationChannelTargetPath === AnimationChannelTargetPath.ROTATION) {\r\n if (useQuaternion) {\r\n quaternionCache = value as Quaternion;\r\n } else {\r\n cacheValue = value as Vector3;\r\n Quaternion.RotationYawPitchRollToRef(cacheValue.y, cacheValue.x, cacheValue.z, quaternionCache);\r\n }\r\n outputs.push(quaternionCache.asArray());\r\n } else {\r\n // scaling and position animation\r\n cacheValue = value as Vector3;\r\n outputs.push(cacheValue.asArray());\r\n }\r\n }\r\n\r\n /**\r\n * Creates linear animation from the animation key frames\r\n * @param babylonTransformNode BabylonJS mesh\r\n * @param animation BabylonJS animation\r\n * @param animationChannelTargetPath The target animation channel\r\n * @param inputs Array to store the key frame times\r\n * @param outputs Array to store the key frame data\r\n * @param useQuaternion Specifies if quaternions are used in the animation\r\n */\r\n private static _CreateLinearOrStepAnimation(\r\n babylonTransformNode: Node,\r\n animation: Animation,\r\n animationChannelTargetPath: AnimationChannelTargetPath,\r\n inputs: number[],\r\n outputs: number[][],\r\n useQuaternion: boolean\r\n ) {\r\n for (const keyFrame of animation.getKeys()) {\r\n inputs.push(keyFrame.frame / animation.framePerSecond); // keyframes in seconds.\r\n _GLTFAnimation._AddKeyframeValue(keyFrame, animation, outputs, animationChannelTargetPath, babylonTransformNode, useQuaternion);\r\n }\r\n }\r\n\r\n /**\r\n * Creates cubic spline animation from the animation key frames\r\n * @param babylonTransformNode BabylonJS mesh\r\n * @param animation BabylonJS animation\r\n * @param animationChannelTargetPath The target animation channel\r\n * @param inputs Array to store the key frame times\r\n * @param outputs Array to store the key frame data\r\n * @param useQuaternion Specifies if quaternions are used in the animation\r\n */\r\n private static _CreateCubicSplineAnimation(\r\n babylonTransformNode: Node,\r\n animation: Animation,\r\n animationChannelTargetPath: AnimationChannelTargetPath,\r\n inputs: number[],\r\n outputs: number[][],\r\n useQuaternion: boolean\r\n ) {\r\n animation.getKeys().forEach(function (keyFrame) {\r\n inputs.push(keyFrame.frame / animation.framePerSecond); // keyframes in seconds.\r\n _GLTFAnimation._AddSplineTangent(_TangentType.INTANGENT, outputs, animationChannelTargetPath, AnimationSamplerInterpolation.CUBICSPLINE, keyFrame, useQuaternion);\r\n _GLTFAnimation._AddKeyframeValue(keyFrame, animation, outputs, animationChannelTargetPath, babylonTransformNode, useQuaternion);\r\n\r\n _GLTFAnimation._AddSplineTangent(_TangentType.OUTTANGENT, outputs, animationChannelTargetPath, AnimationSamplerInterpolation.CUBICSPLINE, keyFrame, useQuaternion);\r\n });\r\n }\r\n\r\n private static _GetBasePositionRotationOrScale(babylonTransformNode: Node, animationChannelTargetPath: AnimationChannelTargetPath, useQuaternion: boolean) {\r\n let basePositionRotationOrScale: number[];\r\n if (animationChannelTargetPath === AnimationChannelTargetPath.ROTATION) {\r\n if (useQuaternion) {\r\n const q = (babylonTransformNode as TransformNode).rotationQuaternion;\r\n basePositionRotationOrScale = (q ?? Quaternion.Identity()).asArray();\r\n } else {\r\n const r: Vector3 = (babylonTransformNode as TransformNode).rotation;\r\n basePositionRotationOrScale = (r ?? Vector3.Zero()).asArray();\r\n }\r\n } else if (animationChannelTargetPath === AnimationChannelTargetPath.TRANSLATION) {\r\n const p: Vector3 = (babylonTransformNode as TransformNode).position;\r\n basePositionRotationOrScale = (p ?? Vector3.Zero()).asArray();\r\n } else {\r\n // scale\r\n const s: Vector3 = (babylonTransformNode as TransformNode).scaling;\r\n basePositionRotationOrScale = (s ?? Vector3.One()).asArray();\r\n }\r\n return basePositionRotationOrScale;\r\n }\r\n\r\n /**\r\n * Adds a key frame value\r\n * @param keyFrame\r\n * @param animation\r\n * @param outputs\r\n * @param animationChannelTargetPath\r\n * @param babylonTransformNode\r\n * @param useQuaternion\r\n */\r\n private static _AddKeyframeValue(\r\n keyFrame: IAnimationKey,\r\n animation: Animation,\r\n outputs: number[][],\r\n animationChannelTargetPath: AnimationChannelTargetPath,\r\n babylonTransformNode: Node,\r\n useQuaternion: boolean\r\n ) {\r\n let newPositionRotationOrScale: Nullable<Vector3 | Quaternion | number>;\r\n const animationType = animation.dataType;\r\n if (animationType === Animation.ANIMATIONTYPE_VECTOR3) {\r\n let value = keyFrame.value.asArray();\r\n if (animationChannelTargetPath === AnimationChannelTargetPath.ROTATION) {\r\n const array = Vector3.FromArray(value);\r\n const rotationQuaternion = Quaternion.RotationYawPitchRoll(array.y, array.x, array.z);\r\n value = rotationQuaternion.asArray();\r\n }\r\n outputs.push(value); // scale vector.\r\n } else if (animationType === Animation.ANIMATIONTYPE_FLOAT) {\r\n if (animationChannelTargetPath === AnimationChannelTargetPath.WEIGHTS) {\r\n outputs.push([keyFrame.value]);\r\n } else {\r\n // handles single component x, y, z or w component animation by using a base property and animating over a component.\r\n newPositionRotationOrScale = this._ConvertFactorToVector3OrQuaternion(\r\n keyFrame.value as number,\r\n babylonTransformNode,\r\n animation,\r\n animationChannelTargetPath,\r\n useQuaternion\r\n );\r\n if (newPositionRotationOrScale) {\r\n if (animationChannelTargetPath === AnimationChannelTargetPath.ROTATION) {\r\n const posRotScale = useQuaternion\r\n ? (newPositionRotationOrScale as Quaternion)\r\n : Quaternion.RotationYawPitchRoll(newPositionRotationOrScale.y, newPositionRotationOrScale.x, newPositionRotationOrScale.z).normalize();\r\n outputs.push(posRotScale.asArray());\r\n }\r\n outputs.push(newPositionRotationOrScale.asArray());\r\n }\r\n }\r\n } else if (animationType === Animation.ANIMATIONTYPE_QUATERNION) {\r\n outputs.push((keyFrame.value as Quaternion).normalize().asArray());\r\n } else {\r\n Tools.Error(\"glTFAnimation: Unsupported key frame values for animation!\");\r\n }\r\n }\r\n\r\n /**\r\n * @internal\r\n * Determine the interpolation based on the key frames\r\n * @param keyFrames\r\n * @param animationChannelTargetPath\r\n * @param useQuaternion\r\n */\r\n private static _DeduceInterpolation(\r\n keyFrames: IAnimationKey[],\r\n animationChannelTargetPath: AnimationChannelTargetPath,\r\n useQuaternion: boolean\r\n ): { interpolationType: AnimationSamplerInterpolation; shouldBakeAnimation: boolean } {\r\n let interpolationType: AnimationSamplerInterpolation | undefined;\r\n let shouldBakeAnimation = false;\r\n let key: IAnimationKey;\r\n\r\n if (animationChannelTargetPath === AnimationChannelTargetPath.ROTATION && !useQuaternion) {\r\n return { interpolationType: AnimationSamplerInterpolation.LINEAR, shouldBakeAnimation: true };\r\n }\r\n\r\n for (let i = 0, length = keyFrames.length; i < length; ++i) {\r\n key = keyFrames[i];\r\n if (key.inTangent || key.outTangent) {\r\n if (interpolationType) {\r\n if (interpolationType !== AnimationSamplerInterpolation.CUBICSPLINE) {\r\n interpolationType = AnimationSamplerInterpolation.LINEAR;\r\n shouldBakeAnimation = true;\r\n break;\r\n }\r\n } else {\r\n interpolationType = AnimationSamplerInterpolation.CUBICSPLINE;\r\n }\r\n } else {\r\n if (interpolationType) {\r\n if (\r\n interpolationType === AnimationSamplerInterpolation.CUBICSPLINE ||\r\n (key.interpolation && key.interpolation === AnimationKeyInterpolation.STEP && interpolationType !== AnimationSamplerInterpolation.STEP)\r\n ) {\r\n interpolationType = AnimationSamplerInterpolation.LINEAR;\r\n shouldBakeAnimation = true;\r\n break;\r\n }\r\n } else {\r\n if (key.interpolation && key.interpolation === AnimationKeyInterpolation.STEP) {\r\n interpolationType = AnimationSamplerInterpolation.STEP;\r\n } else {\r\n interpolationType = AnimationSamplerInterpolation.LINEAR;\r\n }\r\n }\r\n }\r\n }\r\n if (!interpolationType) {\r\n interpolationType = AnimationSamplerInterpolation.LINEAR;\r\n }\r\n\r\n return { interpolationType: interpolationType, shouldBakeAnimation: shouldBakeAnimation };\r\n }\r\n\r\n /**\r\n * Adds an input tangent or output tangent to the output data\r\n * If an input tangent or output tangent is missing, it uses the zero vector or zero quaternion\r\n * @param tangentType Specifies which type of tangent to handle (inTangent or outTangent)\r\n * @param outputs The animation data by keyframe\r\n * @param animationChannelTargetPath The target animation channel\r\n * @param interpolation The interpolation type\r\n * @param keyFrame The key frame with the animation data\r\n * @param useQuaternion Specifies if quaternions are used\r\n */\r\n private static _AddSplineTangent(\r\n tangentType: _TangentType,\r\n outputs: number[][],\r\n animationChannelTargetPath: AnimationChannelTargetPath,\r\n interpolation: AnimationSamplerInterpolation,\r\n keyFrame: IAnimationKey,\r\n useQuaternion: boolean\r\n ) {\r\n let tangent: number[];\r\n const tangentValue: Vector3 | Quaternion | number = tangentType === _TangentType.INTANGENT ? keyFrame.inTangent : keyFrame.outTangent;\r\n if (interpolation === AnimationSamplerInterpolation.CUBICSPLINE) {\r\n if (animationChannelTargetPath === AnimationChannelTargetPath.ROTATION) {\r\n if (tangentValue) {\r\n if (useQuaternion) {\r\n tangent = (tangentValue as Quaternion).asArray();\r\n } else {\r\n const array = tangentValue as Vector3;\r\n tangent = Quaternion.RotationYawPitchRoll(array.y, array.x, array.z).asArray();\r\n }\r\n } else {\r\n tangent = [0, 0, 0, 0];\r\n }\r\n } else if (animationChannelTargetPath === AnimationChannelTargetPath.WEIGHTS) {\r\n if (tangentValue) {\r\n tangent = [tangentValue as number];\r\n } else {\r\n tangent = [0];\r\n }\r\n } else {\r\n if (tangentValue) {\r\n tangent = (tangentValue as Vector3).asArray();\r\n } else {\r\n tangent = [0, 0, 0];\r\n }\r\n }\r\n\r\n outputs.push(tangent);\r\n }\r\n }\r\n\r\n /**\r\n * Get the minimum and maximum key frames' frame values\r\n * @param keyFrames animation key frames\r\n * @returns the minimum and maximum key frame value\r\n */\r\n private static _CalculateMinMaxKeyFrames(keyFrames: IAnimationKey[]): { min: number; max: number } {\r\n let min: number = Infinity;\r\n let max: number = -Infinity;\r\n keyFrames.forEach(function (keyFrame) {\r\n min = Math.min(min, keyFrame.frame);\r\n max = Math.max(max, keyFrame.frame);\r\n });\r\n\r\n return { min: min, max: max };\r\n }\r\n}\r\n","import type { IBufferView, IAccessor } from \"babylonjs-gltf2interface\";\r\nimport { AccessorComponentType, AccessorType } from \"babylonjs-gltf2interface\";\r\nimport type { MorphTarget } from \"core/Morph/morphTarget\";\r\nimport type { BufferManager } from \"./bufferManager\";\r\n\r\nimport { NormalizeTangent } from \"./glTFUtilities\";\r\nimport type { AbstractMesh } from \"core/Meshes/abstractMesh\";\r\nimport { VertexBuffer } from \"core/Buffers/buffer\";\r\nimport { Vector3, Vector4 } from \"core/Maths/math.vector\";\r\nimport { Tools } from \"core/Misc/tools\";\r\n\r\n/**\r\n * Interface to store morph target information.\r\n * @internal\r\n */\r\nexport interface IMorphTargetData {\r\n attributes: Record<string, number>;\r\n influence: number;\r\n name: string;\r\n}\r\n\r\nexport function BuildMorphTargetBuffers(\r\n morphTarget: MorphTarget,\r\n mesh: AbstractMesh,\r\n bufferManager: BufferManager,\r\n bufferViews: IBufferView[],\r\n accessors: IAccessor[],\r\n convertToRightHanded: boolean\r\n): IMorphTargetData {\r\n const result: IMorphTargetData = {\r\n attributes: {},\r\n influence: morphTarget.influence,\r\n name: morphTarget.name,\r\n };\r\n\r\n const geometry = mesh.geometry;\r\n if (!geometry) {\r\n Tools.Warn(\"Attempted to export morph target data from a mesh without geometry. This should not happen.\");\r\n return result;\r\n }\r\n\r\n const flipX = convertToRightHanded ? -1 : 1;\r\n const floatSize = 4;\r\n const difference = Vector3.Zero();\r\n let vertexStart = 0;\r\n let vertexCount = 0;\r\n\r\n if (morphTarget.hasPositions) {\r\n const morphPositions = morphTarget.getPositions()!;\r\n const originalPositions = geometry.getVerticesData(VertexBuffer.PositionKind); // Bypasses any instance data of mesh\r\n\r\n if (originalPositions) {\r\n const positionData = new Float32Array(originalPositions.length);\r\n const min = [Infinity, Infinity, Infinity];\r\n const max = [-Infinity, -Infinity, -Infinity];\r\n vertexCount = originalPositions.length / 3;\r\n vertexStart = 0;\r\n for (let i = vertexStart; i < vertexCount; ++i) {\r\n const originalPosition = Vector3.FromArray(originalPositions, i * 3);\r\n const morphPosition = Vector3.FromArray(morphPositions, i * 3);\r\n morphPosition.subtractToRef(originalPosition, difference);\r\n difference.x *= flipX;\r\n\r\n min[0] = Math.min(min[0], difference.x);\r\n max[0] = Math.max(max[0], difference.x);\r\n\r\n min[1] = Math.min(min[1], difference.y);\r\n max[1] = Math.max(max[1], difference.y);\r\n\r\n min[2] = Math.min(min[2], difference.z);\r\n max[2] = Math.max(max[2], difference.z);\r\n\r\n positionData[i * 3] = difference.x;\r\n positionData[i * 3 + 1] = difference.y;\r\n positionData[i * 3 + 2] = difference.z;\r\n }\r\n\r\n const bufferView = bufferManager.createBufferView(positionData, floatSize * 3);\r\n const accessor = bufferManager.createAccessor(bufferView, AccessorType.VEC3, AccessorComponentType.FLOAT, morphPositions.length / 3, 0, { min, max });\r\n accessors.push(accessor);\r\n result.attributes[\"POSITION\"] = accessors.length - 1;\r\n } else {\r\n Tools.Warn(`Morph target positions for mesh ${mesh.name} were not exported. Mesh does not have position vertex data`);\r\n }\r\n }\r\n\r\n if (morphTarget.hasNormals) {\r\n const morphNormals = morphTarget.getNormals()!;\r\n const originalNormals = geometry.getVerticesData(VertexBuffer.NormalKind);\r\n\r\n if (originalNormals) {\r\n const normalData = new Float32Array(originalNormals.length);\r\n vertexCount = originalNormals.length / 3;\r\n vertexStart = 0;\r\n for (let i = vertexStart; i < vertexCount; ++i) {\r\n const originalNormal = Vector3.FromArray(originalNormals, i * 3).normalize();\r\n const morphNormal = Vector3.FromArray(morphNormals, i * 3).normalize();\r\n morphNormal.subtractToRef(originalNormal, difference);\r\n\r\n normalData[i * 3] = difference.x * flipX;\r\n normalData[i * 3 + 1] = difference.y;\r\n normalData[i * 3 + 2] = difference.z;\r\n }\r\n\r\n const bufferView = bufferManager.createBufferView(normalData, floatSize * 3);\r\n const accessor = bufferManager.createAccessor(bufferView, AccessorType.VEC3, AccessorComponentType.FLOAT, morphNormals.length / 3, 0);\r\n accessors.push(accessor);\r\n result.attributes[\"NORMAL\"] = accessors.length - 1;\r\n } else {\r\n Tools.Warn(`Morph target normals for mesh ${mesh.name} were not exported. Mesh does not have normals vertex data`);\r\n }\r\n }\r\n\r\n if (morphTarget.hasTangents) {\r\n const morphTangents = morphTarget.getTangents()!;\r\n const originalTangents = geometry.getVerticesData(VertexBuffer.TangentKind);\r\n\r\n if (originalTangents) {\r\n vertexCount = originalTangents.length / 4;\r\n const tangentData = new Float32Array(vertexCount * 3);\r\n vertexStart = 0;\r\n for (let i = vertexStart; i < vertexCount; ++i) {\r\n // Only read the x, y, z components and ignore w\r\n const originalTangent = Vector3.FromArray(originalTangents, i * 4);\r\n NormalizeTangent(originalTangent);\r\n\r\n // Morph target tangents omit the w component so it won't be present in the data\r\n const morphTangent = Vector3.FromArray(morphTangents, i * 3);\r\n NormalizeTangent(morphTangent);\r\n\r\n morphTangent.subtractToRef(originalTangent, difference);\r\n tangentData[i * 3] = difference.x * flipX;\r\n tangentData[i * 3 + 1] = difference.y;\r\n tangentData[i * 3 + 2] = difference.z;\r\n }\r\n const bufferView = bufferManager.createBufferView(tangentData, floatSize * 3);\r\n const accessor = bufferManager.createAccessor(bufferView, AccessorType.VEC3, AccessorComponentType.FLOAT, vertexCount, 0);\r\n accessors.push(accessor);\r\n result.attributes[\"TANGENT\"] = accessors.length - 1;\r\n } else {\r\n Tools.Warn(`Morph target tangents for mesh ${mesh.name} were not exported. Mesh does not have tangents vertex data`);\r\n }\r\n }\r\n\r\n if (morphTarget.hasColors) {\r\n const morphColors = morphTarget.getColors()!;\r\n const originalColors = geometry.getVerticesData(VertexBuffer.ColorKind);\r\n const buffer = geometry.getVertexBuffer(VertexBuffer.ColorKind);\r\n\r\n if (originalColors && buffer) {\r\n const componentSize = buffer.getSize();\r\n\r\n vertexCount = originalColors.length / componentSize;\r\n const colorData = new Float32Array(vertexCount * componentSize);\r\n vertexStart = 0;\r\n for (let i = vertexStart; i < vertexCount; ++i) {\r\n if (componentSize === 3) {\r\n const originalColor = Vector3.FromArray(originalColors, i * componentSize);\r\n const morphColor = Vector3.FromArray(morphColors, i * componentSize);\r\n\r\n morphColor.subtractToRef(originalColor, difference);\r\n colorData[i * 3] = difference.x;\r\n colorData[i * 3 + 1] = difference.y;\r\n colorData[i * 3 + 2] = difference.z;\r\n } else if (componentSize === 4) {\r\n const difference4 = new Vector4();\r\n const originalColor = Vector4.FromArray(originalColors, i * componentSize);\r\n const morphColor = Vector4.FromArray(morphColors, i * componentSize);\r\n\r\n morphColor.subtractToRef(originalColor, difference4);\r\n colorData[i * 4] = difference4.x;\r\n colorData[i * 4 + 1] = difference4.y;\r\n colorData[i * 4 + 2] = difference4.z;\r\n colorData[i * 4 + 3] = difference4.w;\r\n } else {\r\n Tools.Warn(`Unsupported number of components for color attribute: ${componentSize}`);\r\n }\r\n }\r\n const bufferView = bufferManager.createBufferView(colorData, floatSize * componentSize);\r\n const accessor = bufferManager.createAccessor(bufferView, componentSize === 3 ? AccessorType.VEC3 : AccessorType.VEC4, AccessorComponentType.FLOAT, vertexCount, 0);\r\n accessors.push(accessor);\r\n result.attributes[\"COLOR_0\"] = accessors.length - 1;\r\n } else {\r\n Tools.Warn(`Morph target colors for mesh ${mesh.name} were not exported. Mesh does not have colors vertex data`);\r\n }\r\n }\r\n\r\n return result;\r\n}\r\n","import type {\r\n IBufferView,\r\n IAccessor,\r\n INode,\r\n IScene,\r\n IMesh,\r\n IMaterial,\r\n ITexture,\r\n IImage,\r\n ISampler,\r\n IAnimation,\r\n IMeshPrimitive,\r\n IBuffer,\r\n IGLTF,\r\n ITextureInfo,\r\n ISkin,\r\n ICamera,\r\n} from \"babylonjs-gltf2interface\";\r\nimport { AccessorComponentType, AccessorType, CameraType, ImageMimeType } from \"babylonjs-gltf2interface\";\r\n\r\nimport type { FloatArray, IndicesArray, Nullable } from \"core/types\";\r\nimport { TmpVectors, Quaternion, Matrix } from \"core/Maths/math.vector\";\r\nimport { Tools } from \"core/Misc/tools\";\r\nimport type { Buffer } from \"core/Buffers/buffer\";\r\nimport { VertexBuffer } from \"core/Buffers/buffer\";\r\nimport type { Node } from \"core/node\";\r\nimport { TransformNode } from \"core/Meshes/transformNode\";\r\nimport type { SubMesh } from \"core/Meshes/subMesh\";\r\nimport type { Mesh } from \"core/Meshes/mesh\";\r\nimport { AbstractMesh } from \"core/Meshes/abstractMesh\";\r\nimport { InstancedMesh } from \"core/Meshes/instancedMesh\";\r\nimport type { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\nimport type { Texture } from \"core/Materials/Textures/texture\";\r\nimport { Material } from \"core/Materials/material\";\r\nimport { Engine } from \"core/Engines/engine\";\r\nimport type { Scene } from \"core/scene\";\r\nimport { EngineStore } from \"core/Engines/engineStore\";\r\n\r\nimport type { IGLTFExporterExtensionV2 } from \"./glTFExporterExtension\";\r\nimport { GLTFMaterialExporter } from \"./glTFMaterialExporter\";\r\nimport type { IExportOptions } from \"./glTFSerializer\";\r\nimport { GLTFData } from \"./glTFData\";\r\nimport {\r\n ConvertToRightHandedPosition,\r\n ConvertToRightHandedRotation,\r\n DataArrayToUint8Array,\r\n GetAccessorType,\r\n GetAttributeType,\r\n GetMinMax,\r\n GetPrimitiveMode,\r\n IsNoopNode,\r\n IsTriangleFillMode,\r\n IsParentAddedByImporter,\r\n ConvertToRightHandedNode,\r\n RotateNode180Y,\r\n FloatsNeed16BitInteger,\r\n IsStandardVertexAttribute,\r\n IndicesArrayToTypedArray,\r\n GetVertexBufferInfo,\r\n} from \"./glTFUtilities\";\r\nimport { BufferManager } from \"./bufferManager\";\r\nimport { Camera } from \"core/Cameras/camera\";\r\nimport { MultiMaterial } from \"core/Materials/multiMaterial\";\r\nimport { PBRMaterial } from \"core/Materials/PBR/pbrMaterial\";\r\nimport { StandardMaterial } from \"core/Materials/standardMaterial\";\r\nimport { Logger } from \"core/Misc/logger\";\r\nimport { EnumerateFloatValues, AreIndices32Bits } from \"core/Buffers/bufferUtils\";\r\nimport type { Bone, Skeleton } from \"core/Bones\";\r\nimport { _GLTFAnimation } from \"./glTFAnimation\";\r\nimport type { MorphTarget } from \"core/Morph\";\r\nimport { BuildMorphTargetBuffers } from \"./glTFMorphTargetsUtilities\";\r\nimport type { IMorphTargetData } from \"./glTFMorphTargetsUtilities\";\r\nimport { LinesMesh } from \"core/Meshes/linesMesh\";\r\nimport { GreasedLineBaseMesh } from \"core/Meshes/GreasedLine/greasedLineBaseMesh\";\r\nimport { Color3, Color4 } from \"core/Maths/math.color\";\r\n\r\nclass ExporterState {\r\n // Babylon indices array, start, count, offset, flip -> glTF accessor index\r\n private _indicesAccessorMap = new Map<Nullable<IndicesArray>, Map<number, Map<number, Map<number, Map<boolean, number>>>>>();\r\n\r\n // Babylon buffer -> glTF buffer view\r\n private _vertexBufferViewMap = new Map<Buffer, IBufferView>();\r\n\r\n // Babylon vertex buffer, start, count -> glTF accessor index\r\n private _vertexAccessorMap = new Map<VertexBuffer, Map<number, Map<number, number>>>();\r\n\r\n private _remappedBufferView = new Map<Buffer, Map<VertexBuffer, IBufferView>>();\r\n\r\n private _meshMorphTargetMap = new Map<AbstractMesh, IMorphTargetData[]>();\r\n\r\n private _vertexMapColorAlpha = new Map<VertexBuffer, boolean>();\r\n\r\n private _exportedNodes = new Set<Node>();\r\n\r\n // Babylon mesh -> glTF mesh index\r\n private _meshMap = new Map<AbstractMesh, number>();\r\n\r\n public constructor(convertToRightHanded: boolean, wasAddedByNoopNode: boolean) {\r\n this.convertToRightHanded = convertToRightHanded;\r\n this.wasAddedByNoopNode = wasAddedByNoopNode;\r\n }\r\n\r\n public readonly convertToRightHanded: boolean;\r\n\r\n public readonly wasAddedByNoopNode: boolean;\r\n\r\n // Only used when convertToRightHanded is true.\r\n public readonly convertedToRightHandedBuffers = new Map<Buffer, Uint8Array>();\r\n\r\n public getIndicesAccessor(indices: Nullable<IndicesArray>, start: number, count: number, offset: number, flip: boolean): number | undefined {\r\n return this._indicesAccessorMap.get(indices)?.get(start)?.get(count)?.get(offset)?.get(flip);\r\n }\r\n\r\n public setIndicesAccessor(indices: Nullable<IndicesArray>, start: number, count: number, offset: number, flip: boolean, accessorIndex: number): void {\r\n let map1 = this._indicesAccessorMap.get(indices);\r\n if (!map1) {\r\n map1 = new Map<number, Map<number, Map<number, Map<boolean, number>>>>();\r\n this._indicesAccessorMap.set(indices, map1);\r\n }\r\n\r\n let map2 = map1.get(start);\r\n if (!map2) {\r\n map2 = new Map<number, Map<number, Map<boolean, number>>>();\r\n map1.set(start, map2);\r\n }\r\n\r\n let map3 = map2.get(count);\r\n if (!map3) {\r\n map3 = new Map<number, Map<boolean, number>>();\r\n map2.set(count, map3);\r\n }\r\n\r\n let map4 = map3.get(offset);\r\n if (!map4) {\r\n map4 = new Map<boolean, number>();\r\n map3.set(offset, map4);\r\n }\r\n\r\n map4.set(flip, accessorIndex);\r\n }\r\n\r\n public pushExportedNode(node: Node) {\r\n if (!this._exportedNodes.has(node)) {\r\n this._exportedNodes.add(node);\r\n }\r\n }\r\n\r\n public getNodesSet(): Set<Node> {\r\n return this._exportedNodes;\r\n }\r\n\r\n public getVertexBufferView(buffer: Buffer): IBufferView | undefined {\r\n return this._vertexBufferViewMap.get(buffer);\r\n }\r\n\r\n public setVertexBufferView(buffer: Buffer, bufferView: IBufferView): void {\r\n this._vertexBufferViewMap.set(buffer, bufferView);\r\n }\r\n\r\n public setRemappedBufferView(buffer: Buffer, vertexBuffer: VertexBuffer, bufferView: IBufferView) {\r\n this._remappedBufferView.set(buffer, new Map<VertexBuffer, IBufferView>());\r\n this._remappedBufferView.get(buffer)!.set(vertexBuffer, bufferView);\r\n }\r\n\r\n public getRemappedBufferView(buffer: Buffer, vertexBuffer: VertexBuffer): IBufferView | undefined {\r\n return this._remappedBufferView.get(buffer)?.get(vertexBuffer);\r\n }\r\n\r\n public getVertexAccessor(vertexBuffer: VertexBuffer, start: number, count: number): number | undefined {\r\n return this._vertexAccessorMap.get(vertexBuffer)?.get(start)?.get(count);\r\n }\r\n\r\n public setVertexAccessor(vertexBuffer: VertexBuffer, start: number, count: number, accessorIndex: number): void {\r\n let map1 = this._vertexAccessorMap.get(vertexBuffer);\r\n if (!map1) {\r\n map1 = new Map<number, Map<number, number>>();\r\n this._vertexAccessorMap.set(vertexBuffer, map1);\r\n }\r\n\r\n let map2 = map1.get(start);\r\n if (!map2) {\r\n map2 = new Map<number, number>();\r\n map1.set(start, map2);\r\n }\r\n\r\n map2.set(count, accessorIndex);\r\n }\r\n\r\n public hasVertexColorAlpha(vertexBuffer: VertexBuffer): boolean {\r\n return this._vertexMapColorAlpha.get(vertexBuffer) || false;\r\n }\r\n\r\n public setHasVertexColorAlpha(vertexBuffer: VertexBuffer, hasAlpha: boolean) {\r\n return this._vertexMapColorAlpha.set(vertexBuffer, hasAlpha);\r\n }\r\n\r\n public getMesh(mesh: AbstractMesh): number | undefined {\r\n return this._meshMap.get(mesh);\r\n }\r\n\r\n public setMesh(mesh: AbstractMesh, meshIndex: number): void {\r\n this._meshMap.set(mesh, meshIndex);\r\n }\r\n\r\n public bindMorphDataToMesh(mesh: AbstractMesh, morphData: IMorphTargetData) {\r\n const morphTargets = this._meshMorphTargetMap.get(mesh) || [];\r\n this._meshMorphTargetMap.set(mesh, morphTargets);\r\n if (morphTargets.indexOf(morphData) === -1) {\r\n morphTargets.push(morphData);\r\n }\r\n }\r\n\r\n public getMorphTargetsFromMesh(mesh: AbstractMesh): IMorphTargetData[] | undefined {\r\n return this._meshMorphTargetMap.get(mesh);\r\n }\r\n}\r\n\r\n/** @internal */\r\nexport class GLTFExporter {\r\n public readonly _glTF: IGLTF = {\r\n asset: { generator: `Babylon.js v${Engine.Version}`, version: \"2.0\" },\r\n };\r\n\r\n public readonly _animations: IAnimation[] = [];\r\n public readonly _accessors: IAccessor[] = [];\r\n public readonly _bufferViews: IBufferView[] = [];\r\n public readonly _cameras: ICamera[] = [];\r\n public readonly _images: IImage[] = [];\r\n public readonly _materials: IMaterial[] = [];\r\n public readonly _meshes: IMesh[] = [];\r\n public readonly _nodes: INode[] = [];\r\n public readonly _samplers: ISampler[] = [];\r\n public readonly _scenes: IScene[] = [];\r\n public readonly _skins: ISkin[] = [];\r\n public readonly _textures: ITexture[] = [];\r\n\r\n public readonly _babylonScene: Scene;\r\n public readonly _imageData: { [fileName: string]: { data: ArrayBuffer; mimeType: ImageMimeType } } = {};\r\n\r\n /**\r\n * Baked animation sample rate\r\n */\r\n private _animationSampleRate: number;\r\n\r\n private readonly _options: Required<IExportOptions>;\r\n\r\n public _shouldUseGlb: boolean = false;\r\n\r\n public readonly _materialExporter = new GLTFMaterialExporter(this);\r\n\r\n private readonly _extensions: { [name: string]: IGLTFExporterExtensionV2 } = {};\r\n\r\n public readonly _bufferManager = new BufferManager();\r\n\r\n private readonly _shouldExportNodeMap = new Map<Node, boolean>();\r\n\r\n // Babylon node -> glTF node index\r\n private readonly _nodeMap = new Map<Node, number>();\r\n\r\n // Babylon material -> glTF material index\r\n public readonly _materialMap = new Map<Material, number>();\r\n private readonly _camerasMap = new Map<Camera, ICamera>();\r\n private readonly _nodesCameraMap = new Map<ICamera, INode[]>();\r\n private readonly _skinMap = new Map<Skeleton, ISkin>();\r\n private readonly _nodesSkinMap = new Map<ISkin, INode[]>();\r\n\r\n // A material in this set requires UVs\r\n public readonly _materialNeedsUVsSet = new Set<Material>();\r\n\r\n private static readonly _ExtensionNames = new Array<string>();\r\n private static readonly _ExtensionFactories: { [name: string]: (exporter: GLTFExporter) => IGLTFExporterExtensionV2 } = {};\r\n\r\n // eslint-disable-next-line @typescript-eslint/naming-convention, @typescript-eslint/promise-function-async\r\n private _ApplyExtension<T>(\r\n node: T,\r\n extensions: IGLTFExporterExtensionV2[],\r\n index: number,\r\n actionAsync: (extension: IGLTFExporterExtensionV2, node: T) => Promise<Nullable<T>> | undefined\r\n ): Promise<Nullable<T>> {\r\n if (index >= extensions.length) {\r\n return Promise.resolve(node);\r\n }\r\n\r\n const currentPromise = actionAsync(extensions[index], node);\r\n\r\n if (!currentPromise) {\r\n return this._ApplyExtension(node, extensions, index + 1, actionAsync);\r\n }\r\n\r\n // eslint-disable-next-line github/no-then\r\n return currentPromise.then(async (newNode) => (newNode ? await this._ApplyExtension(newNode, extensions, index + 1, actionAsync) : null));\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/naming-convention, @typescript-eslint/promise-function-async\r\n private _ApplyExtensions<T>(node: T, actionAsync: (extension: IGLTFExporterExtensionV2, node: T) => Promise<Nullable<T>> | undefined): Promise<Nullable<T>> {\r\n const extensions: IGLTFExporterExtensionV2[] = [];\r\n for (const name of GLTFExporter._ExtensionNames) {\r\n extensions.push(this._extensions[name]);\r\n }\r\n\r\n return this._ApplyExtension(node, extensions, 0, actionAsync);\r\n }\r\n\r\n // eslint-disable-next-line no-restricted-syntax, @typescript-eslint/promise-function-async\r\n public _extensionsPreExportTextureAsync(context: string, babylonTexture: Texture, mimeType: ImageMimeType): Promise<Nullable<BaseTexture>> {\r\n // eslint-disable-next-line @typescript-eslint/promise-function-async\r\n return this._ApplyExtensions(babylonTexture, (extension, node) => extension.preExportTextureAsync && extension.preExportTextureAsync(context, node, mimeType));\r\n }\r\n\r\n // eslint-disable-next-line no-restricted-syntax, @typescript-eslint/promise-function-async\r\n public _extensionsPostExportNodeAsync(context: string, node: INode, babylonNode: Node, nodeMap: Map<Node, number>, convertToRightHanded: boolean): Promise<Nullable<INode>> {\r\n return this._ApplyExtensions(\r\n node,\r\n // eslint-disable-next-line @typescript-eslint/promise-function-async\r\n (extension, node) => extension.postExportNodeAsync && extension.postExportNodeAsync(context, node, babylonNode, nodeMap, convertToRightHanded, this._bufferManager)\r\n );\r\n }\r\n\r\n // eslint-disable-next-line no-restricted-syntax, @typescript-eslint/promise-function-async\r\n public _extensionsPostExportMaterialAsync(context: string, material: IMaterial, babylonMaterial: Material): Promise<Nullable<IMaterial>> {\r\n // eslint-disable-next-line @typescript-eslint/promise-function-async\r\n return this._ApplyExtensions(material, (extension, node) => extension.postExportMaterialAsync && extension.postExportMaterialAsync(context, node, babylonMaterial));\r\n }\r\n\r\n public _extensionsPostExportMaterialAdditionalTextures(context: string, material: IMaterial, babylonMaterial: Material): BaseTexture[] {\r\n const output: BaseTexture[] = [];\r\n\r\n for (const name of GLTFExporter._ExtensionNames) {\r\n const extension = this._extensions[name];\r\n\r\n if (extension.postExportMaterialAdditionalTextures) {\r\n output.push(...extension.postExportMaterialAdditionalTextures(context, material, babylonMaterial));\r\n }\r\n }\r\n\r\n return output;\r\n }\r\n\r\n public _extensionsPostExportTextures(context: string, textureInfo: ITextureInfo, babylonTexture: BaseTexture): void {\r\n for (const name of GLTFExporter._ExtensionNames) {\r\n const extension = this._extensions[name];\r\n\r\n if (extension.postExportTexture) {\r\n extension.postExportTexture(context, textureInfo, babylonTexture);\r\n }\r\n }\r\n }\r\n\r\n public _extensionsPostExportMeshPrimitive(primitive: IMeshPrimitive): void {\r\n for (const name of GLTFExporter._ExtensionNames) {\r\n const extension = this._extensions[name];\r\n\r\n if (extension.postExportMeshPrimitive) {\r\n extension.postExportMeshPrimitive(primitive, this._bufferManager, this._accessors);\r\n }\r\n }\r\n }\r\n\r\n public async _extensionsPreGenerateBinaryAsync(): Promise<void> {\r\n for (const name of GLTFExporter._ExtensionNames) {\r\n const extension = this._extensions[name];\r\n\r\n if (extension.preGenerateBinaryAsync) {\r\n // eslint-disable-next-line no-await-in-loop\r\n await extension.preGenerateBinaryAsync(this._bufferManager);\r\n }\r\n }\r\n }\r\n\r\n private _forEachExtensions(action: (extension: IGLTFExporterExtensionV2) => void): void {\r\n for (const name of GLTFExporter._ExtensionNames) {\r\n const extension = this._extensions[name];\r\n if (extension.enabled) {\r\n action(extension);\r\n }\r\n }\r\n }\r\n\r\n private _extensionsOnExporting(): void {\r\n this._forEachExtensions((extension) => {\r\n if (extension.wasUsed) {\r\n this._glTF.extensionsUsed ||= [];\r\n if (this._glTF.extensionsUsed.indexOf(extension.name) === -1) {\r\n this._glTF.extensionsUsed.push(extension.name);\r\n }\r\n\r\n if (extension.required) {\r\n this._glTF.extensionsRequired ||= [];\r\n if (this._glTF.extensionsRequired.indexOf(extension.name) === -1) {\r\n this._glTF.extensionsRequired.push(extension.name);\r\n }\r\n }\r\n\r\n this._glTF.extensions ||= {};\r\n if (extension.onExporting) {\r\n extension.onExporting();\r\n }\r\n }\r\n });\r\n }\r\n\r\n private _loadExtensions(): void {\r\n for (const name of GLTFExporter._ExtensionNames) {\r\n const extension = GLTFExporter._ExtensionFactories[name](this);\r\n this._extensions[name] = extension;\r\n }\r\n }\r\n\r\n public constructor(babylonScene: Nullable<Scene> = EngineStore.LastCreatedScene, options?: IExportOptions) {\r\n if (!babylonScene) {\r\n throw new Error(\"No scene available to export\");\r\n }\r\n\r\n this._babylonScene = babylonScene;\r\n\r\n this._options = {\r\n shouldExportNode: () => true,\r\n shouldExportAnimation: () => true,\r\n metadataSelector: (metadata) => metadata?.gltf?.extras,\r\n animationSampleRate: 1 / 60,\r\n exportWithoutWaitingForScene: false,\r\n exportUnusedUVs: false,\r\n removeNoopRootNodes: true,\r\n includeCoordinateSystemConversionNodes: false,\r\n meshCompressionMethod: \"None\",\r\n ...options,\r\n };\r\n\r\n this._loadExtensions();\r\n }\r\n\r\n public dispose() {\r\n for (const key in this._extensions) {\r\n const extension = this._extensions[key];\r\n extension.dispose();\r\n }\r\n }\r\n\r\n public get options() {\r\n return this._options;\r\n }\r\n\r\n public static RegisterExtension(name: string, factory: (exporter: GLTFExporter) => IGLTFExporterExtensionV2): void {\r\n if (GLTFExporter.UnregisterExtension(name)) {\r\n Tools.Warn(`Extension with the name ${name} already exists`);\r\n }\r\n\r\n GLTFExporter._ExtensionFactories[name] = factory;\r\n GLTFExporter._ExtensionNames.push(name);\r\n }\r\n\r\n public static UnregisterExtension(name: string): boolean {\r\n if (!GLTFExporter._ExtensionFactories[name]) {\r\n return false;\r\n }\r\n delete GLTFExporter._ExtensionFactories[name];\r\n\r\n const index = GLTFExporter._ExtensionNames.indexOf(name);\r\n if (index !== -1) {\r\n GLTFExporter._ExtensionNames.splice(index, 1);\r\n }\r\n\r\n return true;\r\n }\r\n\r\n private _generateJSON(bufferByteLength: number, fileName?: string, prettyPrint?: boolean): string {\r\n const buffer: IBuffer = { byteLength: bufferByteLength };\r\n\r\n if (buffer.byteLength) {\r\n this._glTF.buffers = [buffer];\r\n }\r\n if (this._nodes && this._nodes.length) {\r\n this._glTF.nodes = this._nodes;\r\n }\r\n if (this._meshes && this._meshes.length) {\r\n this._glTF.meshes = this._meshes;\r\n }\r\n if (this._scenes && this._scenes.length) {\r\n this._glTF.scenes = this._scenes;\r\n this._glTF.scene = 0;\r\n }\r\n if (this._cameras && this._cameras.length) {\r\n this._glTF.cameras = this._cameras;\r\n }\r\n if (this._bufferViews && this._bufferViews.length) {\r\n this._glTF.bufferViews = this._bufferViews;\r\n }\r\n if (this._accessors && this._accessors.length) {\r\n this._glTF.accessors = this._accessors;\r\n }\r\n if (this._animations && this._animations.length) {\r\n this._glTF.animations = this._animations;\r\n }\r\n if (this._materials && this._materials.length) {\r\n this._glTF.materials = this._materials;\r\n }\r\n if (this._textures && this._textures.length) {\r\n this._glTF.textures = this._textures;\r\n }\r\n if (this._samplers && this._samplers.length) {\r\n this._glTF.samplers = this._samplers;\r\n }\r\n if (this._skins && this._skins.length) {\r\n this._glTF.skins = this._skins;\r\n }\r\n if (this._images && this._images.length) {\r\n this._glTF.images = this._images;\r\n }\r\n\r\n if (!this._shouldUseGlb) {\r\n buffer.uri = fileName + \".bin\";\r\n }\r\n\r\n return prettyPrint ? JSON.stringify(this._glTF, null, 2) : JSON.stringify(this._glTF);\r\n }\r\n\r\n public async generateGLTFAsync(glTFPrefix: string): Promise<GLTFData> {\r\n const binaryBuffer = await this._generateBinaryAsync();\r\n\r\n this._extensionsOnExporting();\r\n const jsonText = this._generateJSON(binaryBuffer.byteLength, glTFPrefix, true);\r\n const bin = new Blob([binaryBuffer], { type: \"application/octet-stream\" });\r\n\r\n const glTFFileName = glTFPrefix + \".gltf\";\r\n const glTFBinFile = glTFPrefix + \".bin\";\r\n\r\n const container = new GLTFData();\r\n\r\n container.files[glTFFileName] = jsonText;\r\n container.files[glTFBinFile] = bin;\r\n\r\n if (this._imageData) {\r\n for (const image in this._imageData) {\r\n container.files[image] = new Blob([this._imageData[image].data], { type: this._imageData[image].mimeType });\r\n }\r\n }\r\n\r\n return container;\r\n }\r\n\r\n private async _generateBinaryAsync(): Promise<Uint8Array> {\r\n await this._exportSceneAsync();\r\n await this._extensionsPreGenerateBinaryAsync();\r\n return this._bufferManager.generateBinary(this._bufferViews);\r\n }\r\n\r\n /**\r\n * Pads the number to a multiple of 4\r\n * @param num number to pad\r\n * @returns padded number\r\n */\r\n private _getPadding(num: number): number {\r\n const remainder = num % 4;\r\n const padding = remainder === 0 ? remainder : 4 - remainder;\r\n\r\n return padding;\r\n }\r\n\r\n public async generateGLBAsync(glTFPrefix: string): Promise<GLTFData> {\r\n this._shouldUseGlb = true;\r\n const binaryBuffer = await this._generateBinaryAsync();\r\n\r\n this._extensionsOnExporting();\r\n const jsonText = this._generateJSON(binaryBuffer.byteLength);\r\n const glbFileName = glTFPrefix + \".glb\";\r\n const headerLength = 12;\r\n const chunkLengthPrefix = 8;\r\n let jsonLength = jsonText.length;\r\n let encodedJsonText;\r\n // make use of TextEncoder when available\r\n if (typeof TextEncoder !== \"undefined\") {\r\n const encoder = new TextEncoder();\r\n encodedJsonText = encoder.encode(jsonText);\r\n jsonLength = encodedJsonText.length;\r\n }\r\n const jsonPadding = this._getPadding(jsonLength);\r\n const binPadding = this._getPadding(binaryBuffer.byteLength);\r\n\r\n const byteLength = headerLength + 2 * chunkLengthPrefix + jsonLength + jsonPadding + binaryBuffer.byteLength + binPadding;\r\n\r\n // header\r\n const headerBuffer = new ArrayBuffer(headerLength);\r\n const headerBufferView = new DataView(headerBuffer);\r\n headerBufferView.setUint32(0, 0x46546c67, true); //glTF\r\n headerBufferView.setUint32(4, 2, true); // version\r\n headerBufferView.setUint32(8, byteLength, true); // total bytes in file\r\n\r\n // json chunk\r\n const jsonChunkBuffer = new ArrayBuffer(chunkLengthPrefix + jsonLength + jsonPadding);\r\n const jsonChunkBufferView = new DataView(jsonChunkBuffer);\r\n jsonChunkBufferView.setUint32(0, jsonLength + jsonPadding, true);\r\n jsonChunkBufferView.setUint32(4, 0x4e4f534a, true);\r\n\r\n // json chunk bytes\r\n const jsonData = new Uint8Array(jsonChunkBuffer, chunkLengthPrefix);\r\n // if TextEncoder was available, we can simply copy the encoded array\r\n if (encodedJsonText) {\r\n jsonData.set(encodedJsonText);\r\n } else {\r\n const blankCharCode = \"_\".charCodeAt(0);\r\n for (let i = 0; i < jsonLength; ++i) {\r\n const charCode = jsonText.charCodeAt(i);\r\n // if the character doesn't fit into a single UTF-16 code unit, just put a blank character\r\n if (charCode != jsonText.codePointAt(i)) {\r\n jsonData[i] = blankCharCode;\r\n } else {\r\n jsonData[i] = charCode;\r\n }\r\n }\r\n }\r\n\r\n // json padding\r\n const jsonPaddingView = new Uint8Array(jsonChunkBuffer, chunkLengthPrefix + jsonLength);\r\n for (let i = 0; i < jsonPadding; ++i) {\r\n jsonPaddingView[i] = 0x20;\r\n }\r\n\r\n // binary chunk\r\n const binaryChunkBuffer = new ArrayBuffer(chunkLengthPrefix);\r\n const binaryChunkBufferView = new DataView(binaryChunkBuffer);\r\n binaryChunkBufferView.setUint32(0, binaryBuffer.byteLength + binPadding, true);\r\n binaryChunkBufferView.setUint32(4, 0x004e4942, true);\r\n\r\n // binary padding\r\n const binPaddingBuffer = new ArrayBuffer(binPadding);\r\n const binPaddingView = new Uint8Array(binPaddingBuffer);\r\n for (let i = 0; i < binPadding; ++i) {\r\n binPaddingView[i] = 0;\r\n }\r\n\r\n const glbData = [headerBuffer, jsonChunkBuffer, binaryChunkBuffer, binaryBuffer, binPaddingBuffer];\r\n const glbFile = new Blob(glbData, { type: \"application/octet-stream\" });\r\n\r\n const container = new GLTFData();\r\n container.files[glbFileName] = glbFile;\r\n\r\n return container;\r\n }\r\n\r\n private _setNodeTransformation(node: INode, babylonTransformNode: TransformNode, convertToRightHanded: boolean): void {\r\n if (!babylonTransformNode.getPivotPoint().equalsToFloats(0, 0, 0)) {\r\n Tools.Warn(\"Pivot points are not supported in the glTF serializer\");\r\n }\r\n\r\n if (!babylonTransformNode.position.equalsToFloats(0, 0, 0)) {\r\n const translation = TmpVectors.Vector3[0].copyFrom(babylonTransformNode.position);\r\n if (convertToRightHanded) {\r\n ConvertToRightHandedPosition(translation);\r\n }\r\n\r\n node.translation = translation.asArray();\r\n }\r\n\r\n if (!babylonTransformNode.scaling.equalsToFloats(1, 1, 1)) {\r\n node.scale = babylonTransformNode.scaling.asArray();\r\n }\r\n\r\n const rotationQuaternion = Quaternion.FromEulerAngles(babylonTransformNode.rotation.x, babylonTransformNode.rotation.y, babylonTransformNode.rotation.z);\r\n if (babylonTransformNode.rotationQuaternion) {\r\n rotationQuaternion.multiplyInPlace(babylonTransformNode.rotationQuaternion);\r\n }\r\n if (!Quaternion.IsIdentity(rotationQuaternion)) {\r\n if (convertToRightHanded) {\r\n ConvertToRightHandedRotation(rotationQuaternion);\r\n }\r\n\r\n node.rotation = rotationQuaternion.normalize().asArray();\r\n }\r\n }\r\n\r\n private _setCameraTransformation(node: INode, babylonCamera: Camera, convertToRightHanded: boolean, parent: Nullable<Node>): void {\r\n const translation = TmpVectors.Vector3[0];\r\n const rotation = TmpVectors.Quaternion[0];\r\n\r\n if (parent !== null) {\r\n // Camera.getWorldMatrix returns global coordinates. GLTF node must use local coordinates. If camera has parent we need to use local translation/rotation.\r\n const parentWorldMatrix = Matrix.Invert(parent.getWorldMatrix());\r\n const cameraWorldMatrix = babylonCamera.getWorldMatrix();\r\n const cameraLocal = cameraWorldMatrix.multiply(parentWorldMatrix);\r\n cameraLocal.decompose(undefined, rotation, translation);\r\n } else {\r\n babylonCamera.getWorldMatrix().decompose(undefined, rotation, translation);\r\n }\r\n\r\n if (!translation.equalsToFloats(0, 0, 0)) {\r\n node.translation = translation.asArray();\r\n }\r\n\r\n if (!Quaternion.IsIdentity(rotation)) {\r\n node.rotation = rotation.asArray();\r\n }\r\n }\r\n\r\n // Export babylon cameras to glTF cameras\r\n private _listAvailableCameras(): void {\r\n for (const camera of this._babylonScene.cameras) {\r\n const glTFCamera: ICamera = {\r\n type: camera.mode === Camera.PERSPECTIVE_CAMERA ? CameraType.PERSPECTIVE : CameraType.ORTHOGRAPHIC,\r\n };\r\n\r\n if (camera.name) {\r\n glTFCamera.name = camera.name;\r\n }\r\n\r\n if (glTFCamera.type === CameraType.PERSPECTIVE) {\r\n glTFCamera.perspective = {\r\n aspectRatio: camera.getEngine().getAspectRatio(camera),\r\n yfov: camera.fovMode === Camera.FOVMODE_VERTICAL_FIXED ? camera.fov : camera.fov * camera.getEngine().getAspectRatio(camera),\r\n znear: camera.minZ,\r\n zfar: camera.maxZ,\r\n };\r\n } else if (glTFCamera.type === CameraType.ORTHOGRAPHIC) {\r\n const halfWidth = camera.orthoLeft && camera.orthoRight ? 0.5 * (camera.orthoRight - camera.orthoLeft) : camera.getEngine().getRenderWidth() * 0.5;\r\n const halfHeight = camera.orthoBottom && camera.orthoTop ? 0.5 * (camera.orthoTop - camera.orthoBottom) : camera.getEngine().getRenderHeight() * 0.5;\r\n glTFCamera.orthographic = {\r\n xmag: halfWidth,\r\n ymag: halfHeight,\r\n znear: camera.minZ,\r\n zfar: camera.maxZ,\r\n };\r\n }\r\n this._camerasMap.set(camera, glTFCamera);\r\n }\r\n }\r\n\r\n // Cleanup unused cameras and assign index to nodes.\r\n private _exportAndAssignCameras(): void {\r\n const gltfCameras = Array.from(this._camerasMap.values());\r\n for (const gltfCamera of gltfCameras) {\r\n const usedNodes = this._nodesCameraMap.get(gltfCamera);\r\n if (usedNodes !== undefined) {\r\n this._cameras.push(gltfCamera);\r\n for (const node of usedNodes) {\r\n node.camera = this._cameras.length - 1;\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Builds all skins in the skins array so nodes can reference it during node parsing.\r\n private _listAvailableSkeletons(): void {\r\n for (const skeleton of this._babylonScene.skeletons) {\r\n if (skeleton.bones.length <= 0) {\r\n continue;\r\n }\r\n\r\n const skin: ISkin = { joints: [] };\r\n this._skinMap.set(skeleton, skin);\r\n }\r\n }\r\n\r\n private _exportAndAssignSkeletons() {\r\n for (const skeleton of this._babylonScene.skeletons) {\r\n if (skeleton.bones.length <= 0) {\r\n continue;\r\n }\r\n\r\n const skin = this._skinMap.get(skeleton);\r\n\r\n if (skin == undefined) {\r\n continue;\r\n }\r\n\r\n const boneIndexMap: { [index: number]: Bone } = {};\r\n const inverseBindMatrices: Matrix[] = [];\r\n\r\n let maxBoneIndex = -1;\r\n for (let i = 0; i < skeleton.bones.length; ++i) {\r\n const bone = skeleton.bones[i];\r\n const boneIndex = bone.getIndex() ?? i;\r\n if (boneIndex !== -1) {\r\n boneIndexMap[boneIndex] = bone;\r\n if (boneIndex > maxBoneIndex) {\r\n maxBoneIndex = boneIndex;\r\n }\r\n }\r\n }\r\n\r\n // Set joints index to scene node.\r\n for (let boneIndex = 0; boneIndex <= maxBoneIndex; ++boneIndex) {\r\n const bone = boneIndexMap[boneIndex];\r\n inverseBindMatrices.push(bone.getAbsoluteInverseBindMatrix());\r\n const transformNode = bone.getTransformNode();\r\n\r\n if (transformNode !== null) {\r\n const nodeID = this._nodeMap.get(transformNode);\r\n if (transformNode && nodeID !== null && nodeID !== undefined) {\r\n skin.joints.push(nodeID);\r\n } else {\r\n Tools.Warn(\"Exporting a bone without a linked transform node is currently unsupported\");\r\n }\r\n } else {\r\n Tools.Warn(\"Exporting a bone without a linked transform node is currently unsupported\");\r\n }\r\n }\r\n\r\n // Nodes that use this skin.\r\n const skinedNodes = this._nodesSkinMap.get(skin);\r\n\r\n // Only create skeleton if it has at least one joint and is used by a mesh.\r\n if (skin.joints.length > 0 && skinedNodes !== undefined) {\r\n // Put IBM data into TypedArraybuffer view\r\n const byteLength = inverseBindMatrices.length * 64; // Always a 4 x 4 matrix of 32 bit float\r\n const inverseBindMatricesData = new Float32Array(byteLength / 4);\r\n inverseBindMatrices.forEach((mat: Matrix, index: number) => {\r\n inverseBindMatricesData.set(mat.m, index * 16);\r\n });\r\n // Create buffer view and accessor\r\n const bufferView = this._bufferManager.createBufferView(inverseBindMatricesData);\r\n this._accessors.push(this._bufferManager.createAccessor(bufferView, AccessorType.MAT4, AccessorComponentType.FLOAT, inverseBindMatrices.length));\r\n skin.inverseBindMatrices = this._accessors.length - 1;\r\n\r\n this._skins.push(skin);\r\n for (const skinedNode of skinedNodes) {\r\n skinedNode.skin = this._skins.length - 1;\r\n }\r\n }\r\n }\r\n }\r\n\r\n private async _exportSceneAsync(): Promise<void> {\r\n const scene: IScene = { nodes: [] };\r\n\r\n // Scene metadata\r\n if (this._babylonScene.metadata) {\r\n const extras = this._options.metadataSelector(this._babylonScene.metadata);\r\n if (extras) {\r\n scene.extras = extras;\r\n }\r\n }\r\n\r\n // TODO:\r\n // deal with this from the loader:\r\n // babylonMaterial.invertNormalMapX = !this._babylonScene.useRightHandedSystem;\r\n // babylonMaterial.invertNormalMapY = this._babylonScene.useRightHandedSystem;\r\n\r\n const rootNodesRH = new Array<Node>();\r\n const rootNodesLH = new Array<Node>();\r\n const rootNoopNodesRH = new Array<Node>();\r\n\r\n for (const rootNode of this._babylonScene.rootNodes) {\r\n if (this._options.removeNoopRootNodes && !this._options.includeCoordinateSystemConversionNodes && IsNoopNode(rootNode, this._babylonScene.useRightHandedSystem)) {\r\n rootNoopNodesRH.push(...rootNode.getChildren());\r\n } else if (this._babylonScene.useRightHandedSystem) {\r\n rootNodesRH.push(rootNode);\r\n } else {\r\n rootNodesLH.push(rootNode);\r\n }\r\n }\r\n\r\n this._listAvailableCameras();\r\n this._listAvailableSkeletons();\r\n\r\n const stateLH = new ExporterState(true, false);\r\n scene.nodes.push(...(await this._exportNodesAsync(rootNodesLH, stateLH)));\r\n const stateRH = new ExporterState(false, false);\r\n scene.nodes.push(...(await this._exportNodesAsync(rootNodesRH, stateRH)));\r\n const noopRH = new ExporterState(false, true);\r\n scene.nodes.push(...(await this._exportNodesAsync(rootNoopNodesRH, noopRH)));\r\n\r\n if (scene.nodes.length) {\r\n this._scenes.push(scene);\r\n }\r\n\r\n this._exportAndAssignCameras();\r\n this._exportAndAssignSkeletons();\r\n\r\n if (this._babylonScene.animationGroups.length) {\r\n _GLTFAnimation._CreateNodeAndMorphAnimationFromAnimationGroups(\r\n this._babylonScene,\r\n this._animations,\r\n this._nodeMap,\r\n this._bufferManager,\r\n this._bufferViews,\r\n this._accessors,\r\n this._animationSampleRate,\r\n stateLH.getNodesSet(),\r\n this._options.shouldExportAnimation\r\n );\r\n }\r\n }\r\n\r\n private _shouldExportNode(babylonNode: Node): boolean {\r\n let result = this._shouldExportNodeMap.get(babylonNode);\r\n\r\n if (result === undefined) {\r\n result = this._options.shouldExportNode(babylonNode);\r\n this._shouldExportNodeMap.set(babylonNode, result);\r\n }\r\n\r\n return result;\r\n }\r\n\r\n private async _exportNodesAsync(babylonRootNodes: Node[], state: ExporterState): Promise<number[]> {\r\n const nodes = new Array<number>();\r\n\r\n this._exportBuffers(babylonRootNodes, state);\r\n\r\n for (const babylonNode of babylonRootNodes) {\r\n // eslint-disable-next-line no-await-in-loop\r\n await this._exportNodeAsync(babylonNode, nodes, state);\r\n }\r\n\r\n return nodes;\r\n }\r\n\r\n private _collectBuffers(\r\n babylonNode: Node,\r\n bufferToVertexBuffersMap: Map<Buffer, VertexBuffer[]>,\r\n vertexBufferToMeshesMap: Map<VertexBuffer, AbstractMesh[]>,\r\n morphTargetsToMeshesMap: Map<MorphTarget, AbstractMesh[]>,\r\n state: ExporterState\r\n ): void {\r\n if (this._shouldExportNode(babylonNode) && babylonNode instanceof AbstractMesh && babylonNode.geometry) {\r\n const vertexBuffers = babylonNode.geometry.getVertexBuffers();\r\n if (vertexBuffers) {\r\n for (const kind in vertexBuffers) {\r\n if (!IsStandardVertexAttribute(kind)) {\r\n continue;\r\n }\r\n const vertexBuffer = vertexBuffers[kind];\r\n state.setHasVertexColorAlpha(vertexBuffer, babylonNode.hasVertexAlpha);\r\n const buffer = vertexBuffer._buffer;\r\n const vertexBufferArray = bufferToVertexBuffersMap.get(buffer) || [];\r\n bufferToVertexBuffersMap.set(buffer, vertexBufferArray);\r\n if (vertexBufferArray.indexOf(vertexBuffer) === -1) {\r\n vertexBufferArray.push(vertexBuffer);\r\n }\r\n\r\n const meshes = vertexBufferToMeshesMap.get(vertexBuffer) || [];\r\n vertexBufferToMeshesMap.set(vertexBuffer, meshes);\r\n if (meshes.indexOf(babylonNode) === -1) {\r\n meshes.push(babylonNode);\r\n }\r\n }\r\n }\r\n\r\n const morphTargetManager = babylonNode.morphTargetManager;\r\n\r\n if (morphTargetManager) {\r\n for (let morphIndex = 0; morphIndex < morphTargetManager.numTargets; morphIndex++) {\r\n const morphTarget = morphTargetManager.getTarget(morphIndex);\r\n\r\n const meshes = morphTargetsToMeshesMap.get(morphTarget) || [];\r\n morphTargetsToMeshesMap.set(morphTarget, meshes);\r\n if (meshes.indexOf(babylonNode) === -1) {\r\n meshes.push(babylonNode);\r\n }\r\n }\r\n }\r\n }\r\n\r\n for (const babylonChildNode of babylonNode.getChildren()) {\r\n this._collectBuffers(babylonChildNode, bufferToVertexBuffersMap, vertexBufferToMeshesMap, morphTargetsToMeshesMap, state);\r\n }\r\n }\r\n\r\n private _exportBuffers(babylonRootNodes: Node[], state: ExporterState): void {\r\n const bufferToVertexBuffersMap = new Map<Buffer, VertexBuffer[]>();\r\n const vertexBufferToMeshesMap = new Map<VertexBuffer, AbstractMesh[]>();\r\n const morphTargetsMeshesMap = new Map<MorphTarget, AbstractMesh[]>();\r\n\r\n for (const babylonNode of babylonRootNodes) {\r\n this._collectBuffers(babylonNode, bufferToVertexBuffersMap, vertexBufferToMeshesMap, morphTargetsMeshesMap, state);\r\n }\r\n\r\n const buffers = Array.from(bufferToVertexBuffersMap.keys());\r\n\r\n for (const buffer of buffers) {\r\n const data = buffer.getData();\r\n if (!data) {\r\n throw new Error(\"Buffer data is not available\");\r\n }\r\n\r\n const vertexBuffers = bufferToVertexBuffersMap.get(buffer);\r\n\r\n if (!vertexBuffers) {\r\n continue;\r\n }\r\n\r\n const byteStride = vertexBuffers[0].byteStride;\r\n if (vertexBuffers.some((vertexBuffer) => vertexBuffer.byteStride !== byteStride)) {\r\n throw new Error(\"Vertex buffers pointing to the same buffer must have the same byte stride\");\r\n }\r\n\r\n const bytes = DataArrayToUint8Array(data).slice();\r\n\r\n // Apply normalizations and color corrections to buffer data in-place.\r\n for (const vertexBuffer of vertexBuffers) {\r\n const meshes = vertexBufferToMeshesMap.get(vertexBuffer)!;\r\n const { byteOffset, byteStride, componentCount, type, count, normalized, kind } = GetVertexBufferInfo(vertexBuffer, meshes);\r\n\r\n switch (kind) {\r\n // Normalize normals and tangents.\r\n case VertexBuffer.NormalKind:\r\n case VertexBuffer.TangentKind: {\r\n EnumerateFloatValues(bytes, byteOffset, byteStride, componentCount, type, count, normalized, (values) => {\r\n const length = Math.sqrt(values[0] * values[0] + values[1] * values[1] + values[2] * values[2]);\r\n if (length > 0) {\r\n const invLength = 1 / length;\r\n values[0] *= invLength;\r\n values[1] *= invLength;\r\n values[2] *= invLength;\r\n }\r\n });\r\n break;\r\n }\r\n // Convert StandardMaterial vertex colors from gamma to linear space.\r\n case VertexBuffer.ColorKind: {\r\n const stdMaterialCount = meshes.filter((mesh) => mesh.material instanceof StandardMaterial || mesh.material == null).length;\r\n if (stdMaterialCount == 0) {\r\n break; // Buffer not used by StandardMaterials, so no conversion needed.\r\n }\r\n // TODO: Implement this case.\r\n if (stdMaterialCount != meshes.length) {\r\n Logger.Warn(\"Not converting vertex color space, as buffer is shared by StandardMaterials and other material types. Results may look incorrect.\");\r\n break;\r\n }\r\n if (type == VertexBuffer.UNSIGNED_BYTE) {\r\n Logger.Warn(\"Converting uint8 vertex colors to linear space. Results may look incorrect.\");\r\n }\r\n\r\n const vertexData3 = new Color3();\r\n const vertexData4 = new Color4();\r\n const useExactSrgbConversions = this._babylonScene.getEngine().useExactSrgbConversions;\r\n\r\n EnumerateFloatValues(bytes, byteOffset, byteStride, componentCount, type, count, normalized, (values) => {\r\n // Using separate Color3 and Color4 objects to ensure the right functions are called.\r\n if (values.length === 3) {\r\n vertexData3.fromArray(values, 0);\r\n vertexData3.toLinearSpaceToRef(vertexData3, useExactSrgbConversions);\r\n vertexData3.toArray(values, 0);\r\n } else {\r\n vertexData4.fromArray(values, 0);\r\n vertexData4.toLinearSpaceToRef(vertexData4, useExactSrgbConversions);\r\n vertexData4.toArray(values, 0);\r\n }\r\n });\r\n }\r\n }\r\n }\r\n\r\n // Perform coordinate conversions, if needed, to buffer data in-place (only for positions, normals and tangents).\r\n if (state.convertToRightHanded) {\r\n for (const vertexBuffer of vertexBuffers) {\r\n const meshes = vertexBufferToMeshesMap.get(vertexBuffer)!;\r\n const { byteOffset, byteStride, componentCount, type, count, normalized, kind } = GetVertexBufferInfo(vertexBuffer, meshes);\r\n\r\n switch (kind) {\r\n case VertexBuffer.PositionKind:\r\n case VertexBuffer.NormalKind:\r\n case VertexBuffer.TangentKind: {\r\n EnumerateFloatValues(bytes, byteOffset, byteStride, componentCount, type, count, normalized, (values) => {\r\n values[0] = -values[0];\r\n });\r\n }\r\n }\r\n }\r\n\r\n // Save converted bytes for min/max computation.\r\n state.convertedToRightHandedBuffers.set(buffer, bytes);\r\n }\r\n\r\n // Create buffer view, but defer accessor creation for later. Instead, track it via ExporterState.\r\n const bufferView = this._bufferManager.createBufferView(bytes, byteStride);\r\n state.setVertexBufferView(buffer, bufferView);\r\n\r\n const floatMatricesIndices = new Map<VertexBuffer, FloatArray>();\r\n\r\n // If buffers are of type MatricesIndicesKind and have float values, we need to create a new buffer instead.\r\n for (const vertexBuffer of vertexBuffers) {\r\n const meshes = vertexBufferToMeshesMap.get(vertexBuffer)!;\r\n const { kind, totalVertices } = GetVertexBufferInfo(vertexBuffer, meshes);\r\n switch (kind) {\r\n case VertexBuffer.MatricesIndicesKind:\r\n case VertexBuffer.MatricesIndicesExtraKind: {\r\n if (vertexBuffer.type == VertexBuffer.FLOAT) {\r\n const floatData = vertexBuffer.getFloatData(totalVertices);\r\n if (floatData !== null) {\r\n floatMatricesIndices.set(vertexBuffer, floatData);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n if (floatMatricesIndices.size !== 0) {\r\n Logger.Warn(\r\n `Joints conversion needed: some joints are stored as floats in Babylon but GLTF requires UNSIGNED BYTES. We will perform the conversion but this might lead to unused data in the buffer.`\r\n );\r\n }\r\n\r\n const floatArrayVertexBuffers = Array.from(floatMatricesIndices.keys());\r\n\r\n for (const vertexBuffer of floatArrayVertexBuffers) {\r\n const array = floatMatricesIndices.get(vertexBuffer);\r\n\r\n if (!array) {\r\n continue;\r\n }\r\n\r\n const is16Bit = FloatsNeed16BitInteger(array);\r\n const newArray = new (is16Bit ? Uint16Array : Uint8Array)(array.length);\r\n for (let index = 0; index < array.length; index++) {\r\n newArray[index] = array[index];\r\n }\r\n const bufferView = this._bufferManager.createBufferView(newArray, 4 * (is16Bit ? 2 : 1));\r\n state.setRemappedBufferView(buffer, vertexBuffer, bufferView);\r\n }\r\n }\r\n\r\n // Build morph targets buffers\r\n const morphTargets = Array.from(morphTargetsMeshesMap.keys());\r\n\r\n for (const morphTarget of morphTargets) {\r\n const meshes = morphTargetsMeshesMap.get(morphTarget);\r\n\r\n if (!meshes) {\r\n continue;\r\n }\r\n\r\n const glTFMorphTarget = BuildMorphTargetBuffers(morphTarget, meshes[0], this._bufferManager, this._bufferViews, this._accessors, state.convertToRightHanded);\r\n\r\n for (const mesh of meshes) {\r\n state.bindMorphDataToMesh(mesh, glTFMorphTarget);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Processes a node to be exported to the glTF file\r\n * @returns A promise that resolves once the node has been exported\r\n * @internal\r\n */\r\n private async _exportNodeAsync(babylonNode: Node, parentNodeChildren: Array<number>, state: ExporterState): Promise<void> {\r\n let nodeIndex = this._nodeMap.get(babylonNode);\r\n if (nodeIndex !== undefined) {\r\n if (!parentNodeChildren.includes(nodeIndex)) {\r\n parentNodeChildren.push(nodeIndex);\r\n }\r\n return;\r\n }\r\n\r\n const node = await this._createNodeAsync(babylonNode, state);\r\n\r\n if (node) {\r\n nodeIndex = this._nodes.length;\r\n this._nodes.push(node);\r\n this._nodeMap.set(babylonNode, nodeIndex);\r\n state.pushExportedNode(babylonNode);\r\n parentNodeChildren.push(nodeIndex);\r\n\r\n // Process node's animations once the node has been added to nodeMap (TODO: This should be refactored)\r\n const runtimeGLTFAnimation: IAnimation = {\r\n name: \"runtime animations\",\r\n channels: [],\r\n samplers: [],\r\n };\r\n const idleGLTFAnimations: IAnimation[] = [];\r\n\r\n if (!this._babylonScene.animationGroups.length) {\r\n _GLTFAnimation._CreateMorphTargetAnimationFromMorphTargetAnimations(\r\n babylonNode,\r\n runtimeGLTFAnimation,\r\n idleGLTFAnimations,\r\n this._nodeMap,\r\n this._nodes,\r\n this._bufferManager,\r\n this._bufferViews,\r\n this._accessors,\r\n this._animationSampleRate,\r\n state.convertToRightHanded,\r\n this._options.shouldExportAnimation\r\n );\r\n if (babylonNode.animations.length) {\r\n _GLTFAnimation._CreateNodeAnimationFromNodeAnimations(\r\n babylonNode,\r\n runtimeGLTFAnimation,\r\n idleGLTFAnimations,\r\n this._nodeMap,\r\n this._nodes,\r\n this._bufferManager,\r\n this._bufferViews,\r\n this._accessors,\r\n this._animationSampleRate,\r\n state.convertToRightHanded,\r\n this._options.shouldExportAnimation\r\n );\r\n }\r\n }\r\n\r\n if (runtimeGLTFAnimation.channels.length && runtimeGLTFAnimation.samplers.length) {\r\n this._animations.push(runtimeGLTFAnimation);\r\n }\r\n idleGLTFAnimations.forEach((idleGLTFAnimation) => {\r\n if (idleGLTFAnimation.channels.length && idleGLTFAnimation.samplers.length) {\r\n this._animations.push(idleGLTFAnimation);\r\n }\r\n });\r\n }\r\n\r\n // Begin processing child nodes once parent has been added to the node list\r\n const children = node ? [] : parentNodeChildren;\r\n for (const babylonChildNode of babylonNode.getChildren()) {\r\n // eslint-disable-next-line no-await-in-loop\r\n await this._exportNodeAsync(babylonChildNode, children, state);\r\n }\r\n\r\n if (node && children.length) {\r\n node.children = children;\r\n }\r\n }\r\n\r\n /**\r\n * Creates a glTF node from a Babylon.js node. If skipped, returns null.\r\n * @internal\r\n */\r\n private async _createNodeAsync(babylonNode: Node, state: ExporterState): Promise<Nullable<INode>> {\r\n if (!this._shouldExportNode(babylonNode)) {\r\n return null;\r\n }\r\n\r\n const node: INode = {};\r\n\r\n if (babylonNode.name) {\r\n node.name = babylonNode.name;\r\n }\r\n\r\n // Node metadata\r\n if (babylonNode.metadata) {\r\n const extras = this._options.metadataSelector(babylonNode.metadata);\r\n if (extras) {\r\n node.extras = extras;\r\n }\r\n }\r\n\r\n if (babylonNode instanceof TransformNode) {\r\n this._setNodeTransformation(node, babylonNode, state.convertToRightHanded);\r\n\r\n if (babylonNode instanceof AbstractMesh) {\r\n const babylonMesh = babylonNode instanceof InstancedMesh ? babylonNode.sourceMesh : (babylonNode as Mesh);\r\n if (babylonMesh.subMeshes && babylonMesh.subMeshes.length > 0) {\r\n node.mesh = await this._exportMeshAsync(babylonMesh, state);\r\n }\r\n\r\n if (babylonNode.skeleton) {\r\n const skin = this._skinMap.get(babylonNode.skeleton);\r\n\r\n if (skin !== undefined) {\r\n if (this._nodesSkinMap.get(skin) === undefined) {\r\n this._nodesSkinMap.set(skin, []);\r\n }\r\n\r\n this._nodesSkinMap.get(skin)?.push(node);\r\n }\r\n }\r\n }\r\n }\r\n\r\n if (babylonNode instanceof Camera) {\r\n const gltfCamera = this._camerasMap.get(babylonNode);\r\n\r\n if (gltfCamera) {\r\n if (this._nodesCameraMap.get(gltfCamera) === undefined) {\r\n this._nodesCameraMap.set(gltfCamera, []);\r\n }\r\n\r\n const parentBabylonNode = babylonNode.parent;\r\n this._setCameraTransformation(node, babylonNode, state.convertToRightHanded, parentBabylonNode);\r\n\r\n // If a camera has a node that was added by the GLTF importer, we can just use the parent node transform as the \"camera\" transform.\r\n if (parentBabylonNode && IsParentAddedByImporter(babylonNode, parentBabylonNode)) {\r\n const parentNodeIndex = this._nodeMap.get(parentBabylonNode);\r\n if (parentNodeIndex) {\r\n const parentNode = this._nodes[parentNodeIndex];\r\n this._nodesCameraMap.get(gltfCamera)?.push(parentNode);\r\n return null; // Skip exporting this node\r\n }\r\n }\r\n if (state.convertToRightHanded) {\r\n ConvertToRightHandedNode(node);\r\n RotateNode180Y(node);\r\n }\r\n this._nodesCameraMap.get(gltfCamera)?.push(node);\r\n }\r\n }\r\n\r\n // Apply extensions to the node. If this resolves to null, it means we should skip exporting this node\r\n const processedNode = await this._extensionsPostExportNodeAsync(\"exportNodeAsync\", node, babylonNode, this._nodeMap, state.convertToRightHanded);\r\n if (!processedNode) {\r\n Logger.Warn(`Not exporting node ${babylonNode.name}`);\r\n return null;\r\n }\r\n\r\n return node;\r\n }\r\n\r\n private _exportIndices(\r\n indices: Nullable<IndicesArray>,\r\n is32Bits: boolean,\r\n start: number,\r\n count: number,\r\n offset: number,\r\n fillMode: number,\r\n sideOrientation: number,\r\n state: ExporterState,\r\n primitive: IMeshPrimitive\r\n ): void {\r\n let indicesToExport = indices;\r\n\r\n primitive.mode = GetPrimitiveMode(fillMode);\r\n\r\n // Flip if triangle winding order is not CCW as glTF is always CCW.\r\n const invertedMaterial = sideOrientation !== Material.CounterClockWiseSideOrientation;\r\n\r\n const flipWhenInvertedMaterial = !state.wasAddedByNoopNode && invertedMaterial;\r\n\r\n const flip = IsTriangleFillMode(fillMode) && flipWhenInvertedMaterial;\r\n\r\n if (flip) {\r\n if (fillMode === Material.TriangleStripDrawMode || fillMode === Material.TriangleFanDrawMode) {\r\n throw new Error(\"Triangle strip/fan fill mode is not implemented\");\r\n }\r\n\r\n primitive.mode = GetPrimitiveMode(fillMode);\r\n\r\n const newIndices = is32Bits ? new Uint32Array(count) : new Uint16Array(count);\r\n\r\n if (indices) {\r\n for (let i = 0; i + 2 < count; i += 3) {\r\n newIndices[i] = indices[start + i] + offset;\r\n newIndices[i + 1] = indices[start + i + 2] + offset;\r\n newIndices[i + 2] = indices[start + i + 1] + offset;\r\n }\r\n } else {\r\n for (let i = 0; i + 2 < count; i += 3) {\r\n newIndices[i] = i;\r\n newIndices[i + 1] = i + 2;\r\n newIndices[i + 2] = i + 1;\r\n }\r\n }\r\n\r\n indicesToExport = newIndices;\r\n } else if (indices && offset !== 0) {\r\n const newIndices = is32Bits ? new Uint32Array(count) : new Uint16Array(count);\r\n for (let i = 0; i < count; i++) {\r\n newIndices[i] = indices[start + i] + offset;\r\n }\r\n\r\n indicesToExport = newIndices;\r\n }\r\n\r\n if (indicesToExport) {\r\n let accessorIndex = state.getIndicesAccessor(indices, start, count, offset, flip);\r\n if (accessorIndex === undefined) {\r\n const bytes = IndicesArrayToTypedArray(indicesToExport, 0, count, is32Bits);\r\n const bufferView = this._bufferManager.createBufferView(bytes);\r\n\r\n const componentType = is32Bits ? AccessorComponentType.UNSIGNED_INT : AccessorComponentType.UNSIGNED_SHORT;\r\n this._accessors.push(this._bufferManager.createAccessor(bufferView, AccessorType.SCALAR, componentType, count, 0));\r\n accessorIndex = this._accessors.length - 1;\r\n state.setIndicesAccessor(indices, start, count, offset, flip, accessorIndex);\r\n }\r\n\r\n primitive.indices = accessorIndex;\r\n }\r\n }\r\n\r\n private _exportVertexBuffer(vertexBuffer: VertexBuffer, babylonMaterial: Material, start: number, count: number, state: ExporterState, primitive: IMeshPrimitive): void {\r\n const kind = vertexBuffer.getKind();\r\n\r\n if (!IsStandardVertexAttribute(kind)) {\r\n return;\r\n }\r\n\r\n if (kind.startsWith(\"uv\") && !this._options.exportUnusedUVs) {\r\n if (!babylonMaterial || !this._materialNeedsUVsSet.has(babylonMaterial)) {\r\n return;\r\n }\r\n }\r\n\r\n let accessorIndex = state.getVertexAccessor(vertexBuffer, start, count);\r\n\r\n if (accessorIndex === undefined) {\r\n // Get min/max from converted or original data.\r\n const data = state.convertedToRightHandedBuffers.get(vertexBuffer._buffer) || vertexBuffer._buffer.getData()!;\r\n const minMax = kind === VertexBuffer.PositionKind ? GetMinMax(data, vertexBuffer, start, count) : undefined;\r\n\r\n // For the remapped buffer views we created for float matrices indices, make sure to use their updated information.\r\n const isFloatMatricesIndices =\r\n (kind === VertexBuffer.MatricesIndicesKind || kind === VertexBuffer.MatricesIndicesExtraKind) && vertexBuffer.type === VertexBuffer.FLOAT;\r\n\r\n const vertexBufferType = isFloatMatricesIndices ? VertexBuffer.UNSIGNED_BYTE : vertexBuffer.type;\r\n const vertexBufferNormalized = isFloatMatricesIndices ? undefined : vertexBuffer.normalized;\r\n const bufferView = isFloatMatricesIndices ? state.getRemappedBufferView(vertexBuffer._buffer, vertexBuffer)! : state.getVertexBufferView(vertexBuffer._buffer)!;\r\n\r\n const byteOffset = vertexBuffer.byteOffset + start * vertexBuffer.byteStride;\r\n this._accessors.push(\r\n this._bufferManager.createAccessor(\r\n bufferView,\r\n GetAccessorType(kind, state.hasVertexColorAlpha(vertexBuffer)),\r\n vertexBufferType,\r\n count,\r\n byteOffset,\r\n minMax,\r\n vertexBufferNormalized // TODO: Find other places where this is needed.\r\n )\r\n );\r\n accessorIndex = this._accessors.length - 1;\r\n state.setVertexAccessor(vertexBuffer, start, count, accessorIndex);\r\n }\r\n\r\n primitive.attributes[GetAttributeType(kind)] = accessorIndex;\r\n }\r\n\r\n private async _exportMaterialAsync(babylonMaterial: Material, vertexBuffers: { [kind: string]: VertexBuffer }, subMesh: SubMesh, primitive: IMeshPrimitive): Promise<void> {\r\n let materialIndex = this._materialMap.get(babylonMaterial);\r\n if (materialIndex === undefined) {\r\n const hasUVs = vertexBuffers && Object.keys(vertexBuffers).some((kind) => kind.startsWith(\"uv\"));\r\n babylonMaterial = babylonMaterial instanceof MultiMaterial ? babylonMaterial.subMaterials[subMesh.materialIndex]! : babylonMaterial;\r\n if (babylonMaterial instanceof PBRMaterial) {\r\n materialIndex = await this._materialExporter.exportPBRMaterialAsync(babylonMaterial, ImageMimeType.PNG, hasUVs);\r\n } else if (babylonMaterial instanceof StandardMaterial) {\r\n materialIndex = await this._materialExporter.exportStandardMaterialAsync(babylonMaterial, ImageMimeType.PNG, hasUVs);\r\n } else {\r\n Logger.Warn(`Unsupported material '${babylonMaterial.name}' with type ${babylonMaterial.getClassName()}`);\r\n return;\r\n }\r\n\r\n this._materialMap.set(babylonMaterial, materialIndex);\r\n }\r\n\r\n primitive.material = materialIndex;\r\n }\r\n\r\n private async _exportMeshAsync(babylonMesh: Mesh, state: ExporterState): Promise<number> {\r\n let meshIndex = state.getMesh(babylonMesh);\r\n if (meshIndex !== undefined) {\r\n return meshIndex;\r\n }\r\n\r\n const mesh: IMesh = { primitives: [] };\r\n meshIndex = this._meshes.length;\r\n this._meshes.push(mesh);\r\n state.setMesh(babylonMesh, meshIndex);\r\n\r\n const indices = babylonMesh.isUnIndexed ? null : babylonMesh.getIndices();\r\n const vertexBuffers = babylonMesh.geometry?.getVertexBuffers();\r\n const morphTargets = state.getMorphTargetsFromMesh(babylonMesh);\r\n\r\n const isLinesMesh = babylonMesh instanceof LinesMesh;\r\n const isGreasedLineMesh = babylonMesh instanceof GreasedLineBaseMesh;\r\n\r\n const subMeshes = babylonMesh.subMeshes;\r\n if (vertexBuffers && subMeshes && subMeshes.length > 0) {\r\n for (const subMesh of subMeshes) {\r\n const primitive: IMeshPrimitive = { attributes: {} };\r\n\r\n const babylonMaterial = subMesh.getMaterial() || this._babylonScene.defaultMaterial;\r\n\r\n if (isGreasedLineMesh) {\r\n const material: IMaterial = {\r\n name: babylonMaterial.name,\r\n };\r\n\r\n const babylonLinesMesh = babylonMesh;\r\n\r\n const colorWhite = Color3.White();\r\n const alpha = babylonLinesMesh.material?.alpha ?? 1;\r\n const color = babylonLinesMesh.greasedLineMaterial?.color ?? colorWhite;\r\n if (!color.equals(colorWhite) || alpha < 1) {\r\n material.pbrMetallicRoughness = {\r\n baseColorFactor: [...color.asArray(), alpha],\r\n };\r\n }\r\n\r\n this._materials.push(material);\r\n primitive.material = this._materials.length - 1;\r\n } else if (isLinesMesh) {\r\n // Special case for LinesMesh\r\n const material: IMaterial = {\r\n name: babylonMaterial.name,\r\n };\r\n\r\n const babylonLinesMesh = babylonMesh;\r\n\r\n if (!babylonLinesMesh.color.equals(Color3.White()) || babylonLinesMesh.alpha < 1) {\r\n material.pbrMetallicRoughness = {\r\n baseColorFactor: [...babylonLinesMesh.color.asArray(), babylonLinesMesh.alpha],\r\n };\r\n }\r\n\r\n this._materials.push(material);\r\n primitive.material = this._materials.length - 1;\r\n } else {\r\n // Material\r\n // eslint-disable-next-line no-await-in-loop\r\n await this._exportMaterialAsync(babylonMaterial, vertexBuffers, subMesh, primitive);\r\n }\r\n\r\n // Index buffer\r\n const fillMode = isLinesMesh || isGreasedLineMesh ? Material.LineListDrawMode : (babylonMesh.overrideRenderingFillMode ?? babylonMaterial.fillMode);\r\n\r\n const sideOrientation = babylonMaterial._getEffectiveOrientation(babylonMesh);\r\n\r\n this._exportIndices(\r\n indices,\r\n indices ? AreIndices32Bits(indices, subMesh.indexCount, subMesh.indexStart, subMesh.verticesStart) : subMesh.verticesCount > 65535,\r\n indices ? subMesh.indexStart : subMesh.verticesStart,\r\n indices ? subMesh.indexCount : subMesh.verticesCount,\r\n -subMesh.verticesStart,\r\n fillMode,\r\n sideOrientation,\r\n state,\r\n primitive\r\n );\r\n\r\n // Vertex buffers\r\n for (const vertexBuffer of Object.values(vertexBuffers)) {\r\n this._exportVertexBuffer(vertexBuffer, babylonMaterial, subMesh.verticesStart, subMesh.verticesCount, state, primitive);\r\n }\r\n\r\n if (morphTargets) {\r\n primitive.targets = [];\r\n for (const gltfMorphTarget of morphTargets) {\r\n primitive.targets.push(gltfMorphTarget.attributes);\r\n }\r\n }\r\n\r\n mesh.primitives.push(primitive);\r\n this._extensionsPostExportMeshPrimitive(primitive);\r\n }\r\n }\r\n\r\n if (morphTargets) {\r\n mesh.weights = [];\r\n\r\n if (!mesh.extras) {\r\n mesh.extras = {};\r\n }\r\n mesh.extras.targetNames = [];\r\n\r\n for (const gltfMorphTarget of morphTargets) {\r\n mesh.weights.push(gltfMorphTarget.influence);\r\n mesh.extras.targetNames.push(gltfMorphTarget.name);\r\n }\r\n }\r\n\r\n return meshIndex;\r\n }\r\n}\r\n","import type { Node } from \"core/node\";\r\nimport type { Scene } from \"core/scene\";\r\nimport type { Animation } from \"core/Animations/animation\";\r\nimport type { GLTFData } from \"./glTFData\";\r\nimport { GLTFExporter } from \"./glTFExporter\";\r\n\r\n/**\r\n * Mesh compression methods.\r\n */\r\nexport type MeshCompressionMethod = \"None\" | \"Draco\";\r\n\r\n/**\r\n * Holds a collection of exporter options and parameters\r\n */\r\nexport interface IExportOptions {\r\n /**\r\n * Function which indicates whether a babylon node should be exported or not\r\n * @param node source Babylon node. It is used to check whether it should be exported to glTF or not\r\n * @returns boolean, which indicates whether the node should be exported (true) or not (false)\r\n */\r\n shouldExportNode?(node: Node): boolean;\r\n\r\n /**\r\n * Function which indicates whether an animation on the scene should be exported or not\r\n * @param animation source animation\r\n * @returns boolean, which indicates whether the animation should be exported (true) or not (false)\r\n */\r\n shouldExportAnimation?(animation: Animation): boolean;\r\n\r\n /**\r\n * Function to extract the part of the scene or node's `metadata` that will populate the corresponding\r\n * glTF object's `extras` field. If not defined, `node.metadata.gltf.extras` will be used.\r\n * @param metadata source metadata to read from\r\n * @returns the data to store into the glTF extras field\r\n */\r\n metadataSelector?(metadata: any): any;\r\n\r\n /**\r\n * The sample rate to bake animation curves. Defaults to 1 / 60.\r\n */\r\n animationSampleRate?: number;\r\n\r\n /**\r\n * Begin serialization without waiting for the scene to be ready. Defaults to false.\r\n */\r\n exportWithoutWaitingForScene?: boolean;\r\n\r\n /**\r\n * Indicates if unused vertex uv attributes should be included in export. Defaults to false.\r\n */\r\n exportUnusedUVs?: boolean;\r\n\r\n /**\r\n * Remove no-op root nodes when possible. Defaults to true.\r\n */\r\n removeNoopRootNodes?: boolean;\r\n\r\n /**\r\n * Indicates if coordinate system swapping root nodes should be included in export. Defaults to false.\r\n * @deprecated Please use removeNoopRootNodes instead\r\n */\r\n includeCoordinateSystemConversionNodes?: boolean;\r\n\r\n /**\r\n * Indicates what compression method to apply to mesh data.\r\n */\r\n meshCompressionMethod?: MeshCompressionMethod;\r\n}\r\n\r\n/**\r\n * Class for generating glTF data from a Babylon scene.\r\n */\r\nexport class GLTF2Export {\r\n /**\r\n * Exports the scene to .gltf file format\r\n * @param scene Babylon scene\r\n * @param fileName Name to use for the .gltf file\r\n * @param options Exporter options\r\n * @returns Returns the exported data\r\n */\r\n public static async GLTFAsync(scene: Scene, fileName: string, options?: IExportOptions): Promise<GLTFData> {\r\n if (!options || !options.exportWithoutWaitingForScene) {\r\n await scene.whenReadyAsync();\r\n }\r\n\r\n const exporter = new GLTFExporter(scene, options);\r\n const data = await exporter.generateGLTFAsync(fileName.replace(/\\.[^/.]+$/, \"\"));\r\n exporter.dispose();\r\n\r\n return data;\r\n }\r\n\r\n /**\r\n * Exports the scene to .glb file format\r\n * @param scene Babylon scene\r\n * @param fileName Name to use for the .glb file\r\n * @param options Exporter options\r\n * @returns Returns the exported data\r\n */\r\n public static async GLBAsync(scene: Scene, fileName: string, options?: IExportOptions): Promise<GLTFData> {\r\n if (!options || !options.exportWithoutWaitingForScene) {\r\n await scene.whenReadyAsync();\r\n }\r\n\r\n const exporter = new GLTFExporter(scene, options);\r\n const data = await exporter.generateGLBAsync(fileName.replace(/\\.[^/.]+$/, \"\"));\r\n exporter.dispose();\r\n\r\n return data;\r\n }\r\n}\r\n","import type { INode, IEXTMeshGpuInstancing } from \"babylonjs-gltf2interface\";\r\nimport { AccessorType, AccessorComponentType } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport type { BufferManager } from \"../bufferManager\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport type { Nullable } from \"core/types\";\r\nimport type { Node } from \"core/node\";\r\nimport { Mesh } from \"core/Meshes/mesh\";\r\nimport \"core/Meshes/thinInstanceMesh\";\r\nimport { TmpVectors, Quaternion, Vector3 } from \"core/Maths/math.vector\";\r\nimport { ConvertToRightHandedPosition, ConvertToRightHandedRotation } from \"../glTFUtilities\";\r\n\r\nconst NAME = \"EXT_mesh_gpu_instancing\";\r\n\r\n/**\r\n * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Vendor/EXT_mesh_gpu_instancing/README.md)\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class EXT_mesh_gpu_instancing implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n private _exporter: GLTFExporter;\r\n\r\n private _wasUsed = false;\r\n\r\n constructor(exporter: GLTFExporter) {\r\n this._exporter = exporter;\r\n }\r\n\r\n public dispose() {}\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n /**\r\n * After node is exported\r\n * @param context the GLTF context when loading the asset\r\n * @param node the node exported\r\n * @param babylonNode the corresponding babylon node\r\n * @param nodeMap map from babylon node id to node index\r\n * @param convertToRightHanded true if we need to convert data from left hand to right hand system.\r\n * @param bufferManager buffer manager\r\n * @returns nullable promise, resolves with the node\r\n */\r\n public async postExportNodeAsync(\r\n context: string,\r\n node: Nullable<INode>,\r\n babylonNode: Node,\r\n nodeMap: Map<Node, number>,\r\n convertToRightHanded: boolean,\r\n bufferManager: BufferManager\r\n ): Promise<Nullable<INode>> {\r\n return await new Promise((resolve) => {\r\n if (node && babylonNode instanceof Mesh) {\r\n if (babylonNode.hasThinInstances && this._exporter) {\r\n this._wasUsed = true;\r\n\r\n const noTranslation = Vector3.Zero();\r\n const noRotation = Quaternion.Identity();\r\n const noScale = Vector3.One();\r\n\r\n // retrieve all the instance world matrix\r\n const matrix = babylonNode.thinInstanceGetWorldMatrices();\r\n\r\n const iwt = TmpVectors.Vector3[2];\r\n const iwr = TmpVectors.Quaternion[1];\r\n const iws = TmpVectors.Vector3[3];\r\n\r\n let hasAnyInstanceWorldTranslation = false;\r\n let hasAnyInstanceWorldRotation = false;\r\n let hasAnyInstanceWorldScale = false;\r\n\r\n // prepare temp buffers\r\n const translationBuffer = new Float32Array(babylonNode.thinInstanceCount * 3);\r\n const rotationBuffer = new Float32Array(babylonNode.thinInstanceCount * 4);\r\n const scaleBuffer = new Float32Array(babylonNode.thinInstanceCount * 3);\r\n\r\n let i = 0;\r\n for (const m of matrix) {\r\n m.decompose(iws, iwr, iwt);\r\n\r\n if (convertToRightHanded) {\r\n ConvertToRightHandedPosition(iwt);\r\n ConvertToRightHandedRotation(iwr);\r\n }\r\n\r\n // fill the temp buffer\r\n translationBuffer.set(iwt.asArray(), i * 3);\r\n rotationBuffer.set(iwr.normalize().asArray(), i * 4); // ensure the quaternion is normalized\r\n scaleBuffer.set(iws.asArray(), i * 3);\r\n\r\n // this is where we decide if there is any transformation\r\n hasAnyInstanceWorldTranslation = hasAnyInstanceWorldTranslation || !iwt.equalsWithEpsilon(noTranslation);\r\n hasAnyInstanceWorldRotation = hasAnyInstanceWorldRotation || !iwr.equalsWithEpsilon(noRotation);\r\n hasAnyInstanceWorldScale = hasAnyInstanceWorldScale || !iws.equalsWithEpsilon(noScale);\r\n\r\n i++;\r\n }\r\n\r\n const extension: IEXTMeshGpuInstancing = {\r\n attributes: {},\r\n };\r\n\r\n // do we need to write TRANSLATION ?\r\n if (hasAnyInstanceWorldTranslation) {\r\n extension.attributes[\"TRANSLATION\"] = this._buildAccessor(translationBuffer, AccessorType.VEC3, babylonNode.thinInstanceCount, bufferManager);\r\n }\r\n // do we need to write ROTATION ?\r\n if (hasAnyInstanceWorldRotation) {\r\n // we decided to stay on FLOAT for now see https://github.com/BabylonJS/Babylon.js/pull/12495\r\n extension.attributes[\"ROTATION\"] = this._buildAccessor(rotationBuffer, AccessorType.VEC4, babylonNode.thinInstanceCount, bufferManager);\r\n }\r\n // do we need to write SCALE ?\r\n if (hasAnyInstanceWorldScale) {\r\n extension.attributes[\"SCALE\"] = this._buildAccessor(scaleBuffer, AccessorType.VEC3, babylonNode.thinInstanceCount, bufferManager);\r\n }\r\n\r\n /* eslint-enable @typescript-eslint/naming-convention*/\r\n node.extensions = node.extensions || {};\r\n node.extensions[NAME] = extension;\r\n }\r\n }\r\n resolve(node);\r\n });\r\n }\r\n\r\n private _buildAccessor(buffer: Float32Array, type: AccessorType, count: number, bufferManager: BufferManager): number {\r\n // build the buffer view\r\n const bv = bufferManager.createBufferView(buffer);\r\n\r\n // finally build the accessor\r\n const accessor = bufferManager.createAccessor(bv, type, AccessorComponentType.FLOAT, count);\r\n this._exporter._accessors.push(accessor);\r\n return this._exporter._accessors.length - 1;\r\n }\r\n}\r\n\r\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\r\nGLTFExporter.RegisterExtension(NAME, (exporter) => new EXT_mesh_gpu_instancing(exporter));\r\n","import type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\nimport { GLTFExporter } from \"../glTFExporter\";\nimport { MeshPrimitiveMode } from \"babylonjs-gltf2interface\";\nimport type { IAccessor, IBufferView, IKHRDracoMeshCompression, IMeshPrimitive } from \"babylonjs-gltf2interface\";\nimport type { BufferManager } from \"../bufferManager\";\nimport { DracoEncoder } from \"core/Meshes/Compression/dracoEncoder\";\nimport { GetTypedArrayData, GetTypeByteLength } from \"core/Buffers/bufferUtils\";\nimport { GetAccessorElementCount } from \"../glTFUtilities\";\nimport type { DracoAttributeName, IDracoAttributeData, IDracoEncoderOptions } from \"core/Meshes/Compression/dracoEncoder.types\";\nimport { Logger } from \"core/Misc/logger\";\nimport type { Nullable } from \"core/types\";\n\nconst NAME = \"KHR_draco_mesh_compression\";\n\nfunction GetDracoAttributeName(glTFName: string): DracoAttributeName {\n if (glTFName === \"POSITION\") {\n return \"POSITION\";\n } else if (glTFName === \"NORMAL\") {\n return \"NORMAL\";\n } else if (glTFName.startsWith(\"COLOR\")) {\n return \"COLOR\";\n } else if (glTFName.startsWith(\"TEXCOORD\")) {\n return \"TEX_COORD\";\n }\n return \"GENERIC\";\n}\n\n/**\n * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_draco_mesh_compression/README.md)\n */\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport class KHR_draco_mesh_compression implements IGLTFExporterExtensionV2 {\n /** Name of this extension */\n public readonly name = NAME;\n\n /** Defines whether this extension is enabled */\n public enabled;\n\n /** KHR_draco_mesh_compression is required, as uncompressed fallback data is not yet implemented. */\n public required = true;\n\n /** BufferViews used for Draco data, which may be eligible for removal after Draco encoding */\n private _bufferViewsUsed: Set<IBufferView> = new Set();\n\n /** Accessors that were replaced with Draco data, which may be eligible for removal after Draco encoding */\n private _accessorsUsed: Set<IAccessor> = new Set();\n\n /** Promise pool for Draco encoding work */\n private _encodePromises: Promise<void>[] = [];\n\n private _wasUsed = false;\n\n /** @internal */\n public get wasUsed() {\n return this._wasUsed;\n }\n\n /** @internal */\n constructor(exporter: GLTFExporter) {\n this.enabled = exporter.options.meshCompressionMethod === \"Draco\" && DracoEncoder.DefaultAvailable;\n }\n\n /** @internal */\n public dispose() {}\n\n /** @internal */\n public postExportMeshPrimitive(primitive: IMeshPrimitive, bufferManager: BufferManager, accessors: IAccessor[]): void {\n if (!this.enabled) {\n return;\n }\n\n if (primitive.mode !== MeshPrimitiveMode.TRIANGLES && primitive.mode !== MeshPrimitiveMode.TRIANGLE_STRIP) {\n Logger.Warn(\"Cannot compress primitive with mode \" + primitive.mode + \".\");\n return;\n }\n\n // Collect bufferViews and accessors used by this primitive\n const primitiveBufferViews: IBufferView[] = [];\n const primitiveAccessors: IAccessor[] = [];\n\n // Prepare indices for Draco encoding\n let indices: Nullable<Uint32Array | Uint16Array> = null;\n if (primitive.indices !== undefined) {\n const accessor = accessors[primitive.indices];\n const bufferView = bufferManager.getBufferView(accessor);\n // Per exportIndices, indices must be either Uint16Array or Uint32Array\n indices = bufferManager.getData(bufferView).slice() as Uint32Array | Uint16Array;\n\n primitiveBufferViews.push(bufferView);\n primitiveAccessors.push(accessor);\n }\n\n // Prepare attributes for Draco encoding\n const attributes: IDracoAttributeData[] = [];\n for (const [name, accessorIndex] of Object.entries(primitive.attributes)) {\n const accessor = accessors[accessorIndex];\n const bufferView = bufferManager.getBufferView(accessor);\n\n const size = GetAccessorElementCount(accessor.type);\n const data = GetTypedArrayData(\n bufferManager.getData(bufferView),\n size,\n accessor.componentType,\n accessor.byteOffset || 0,\n bufferView.byteStride || GetTypeByteLength(accessor.componentType) * size,\n accessor.normalized || false,\n accessor.count,\n true\n );\n\n attributes.push({ kind: name, dracoName: GetDracoAttributeName(name), size: GetAccessorElementCount(accessor.type), data: data });\n\n primitiveBufferViews.push(bufferView);\n primitiveAccessors.push(accessor);\n }\n\n // Use sequential encoding to preserve vertex order for cases like morph targets\n const options: IDracoEncoderOptions = {\n method: primitive.targets ? \"MESH_SEQUENTIAL_ENCODING\" : \"MESH_EDGEBREAKER_ENCODING\",\n };\n\n const promise = DracoEncoder.Default._encodeAsync(attributes, indices, options)\n // eslint-disable-next-line github/no-then\n .then((encodedData) => {\n if (!encodedData) {\n Logger.Error(\"Draco encoding failed for primitive.\");\n return;\n }\n\n const dracoInfo: IKHRDracoMeshCompression = {\n bufferView: -1, // bufferView will be set to a real index later, when we write the binary and decide bufferView ordering\n attributes: encodedData.attributeIds,\n };\n const bufferView = bufferManager.createBufferView(encodedData.data);\n bufferManager.setBufferView(dracoInfo, bufferView);\n\n for (const bufferView of primitiveBufferViews) {\n this._bufferViewsUsed.add(bufferView);\n }\n for (const accessor of primitiveAccessors) {\n this._accessorsUsed.add(accessor);\n }\n\n primitive.extensions ||= {};\n primitive.extensions[NAME] = dracoInfo;\n })\n // eslint-disable-next-line github/no-then\n .catch((error) => {\n Logger.Error(\"Draco encoding failed for primitive: \" + error);\n });\n\n this._encodePromises.push(promise);\n\n this._wasUsed = true;\n }\n\n /** @internal */\n public async preGenerateBinaryAsync(bufferManager: BufferManager): Promise<void> {\n if (!this.enabled) {\n return;\n }\n\n await Promise.all(this._encodePromises);\n\n // Cull obsolete bufferViews that were replaced with Draco data\n this._bufferViewsUsed.forEach((bufferView) => {\n const references = bufferManager.getPropertiesWithBufferView(bufferView);\n const onlyUsedByEncodedPrimitives = references.every((object) => {\n return this._accessorsUsed.has(object as IAccessor); // has() can handle any object, but TS doesn't know that\n });\n if (onlyUsedByEncodedPrimitives) {\n bufferManager.removeBufferView(bufferView);\n }\n });\n\n this._bufferViewsUsed.clear();\n this._accessorsUsed.clear();\n }\n}\n\nGLTFExporter.RegisterExtension(NAME, (exporter) => new KHR_draco_mesh_compression(exporter));\n","import type { SpotLight } from \"core/Lights/spotLight\";\r\nimport type { Nullable } from \"core/types\";\r\nimport { Vector3, Quaternion, TmpVectors } from \"core/Maths/math.vector\";\r\nimport { Light } from \"core/Lights/light\";\r\nimport type { Node } from \"core/node\";\r\nimport { ShadowLight } from \"core/Lights/shadowLight\";\r\nimport type { INode, IKHRLightsPunctual_LightReference, IKHRLightsPunctual_Light, IKHRLightsPunctual } from \"babylonjs-gltf2interface\";\r\nimport { KHRLightsPunctual_LightType } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport { Logger } from \"core/Misc/logger\";\r\nimport { ConvertToRightHandedPosition, OmitDefaultValues, CollapseParentNode, IsParentAddedByImporter } from \"../glTFUtilities\";\r\n\r\nconst NAME = \"KHR_lights_punctual\";\r\nconst DEFAULTS: Omit<IKHRLightsPunctual_Light, \"type\"> = {\r\n name: \"\",\r\n color: [1, 1, 1],\r\n intensity: 1,\r\n range: Number.MAX_VALUE,\r\n};\r\nconst SPOTDEFAULTS: NonNullable<IKHRLightsPunctual_Light[\"spot\"]> = {\r\n innerConeAngle: 0,\r\n outerConeAngle: Math.PI / 4.0,\r\n};\r\nconst LIGHTDIRECTION = Vector3.Backward();\r\n\r\n/**\r\n * [Specification](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_lights_punctual/README.md)\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_lights_punctual implements IGLTFExporterExtensionV2 {\r\n /** The name of this extension. */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled. */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n /** Reference to the glTF exporter */\r\n private _exporter: GLTFExporter;\r\n\r\n private _lights: IKHRLightsPunctual;\r\n\r\n /**\r\n * @internal\r\n */\r\n constructor(exporter: GLTFExporter) {\r\n this._exporter = exporter;\r\n }\r\n\r\n /** @internal */\r\n public dispose() {\r\n (this._lights as any) = null;\r\n }\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return !!this._lights;\r\n }\r\n\r\n /** @internal */\r\n public onExporting(): void {\r\n this._exporter._glTF.extensions![NAME] = this._lights;\r\n }\r\n /**\r\n * Define this method to modify the default behavior when exporting a node\r\n * @param context The context when exporting the node\r\n * @param node glTF node\r\n * @param babylonNode BabylonJS node\r\n * @param nodeMap Node mapping of babylon node to glTF node index\r\n * @param convertToRightHanded Flag to convert the values to right-handed\r\n * @returns nullable INode promise\r\n */\r\n public async postExportNodeAsync(context: string, node: INode, babylonNode: Node, nodeMap: Map<Node, number>, convertToRightHanded: boolean): Promise<Nullable<INode>> {\r\n return await new Promise((resolve) => {\r\n if (!(babylonNode instanceof ShadowLight)) {\r\n resolve(node);\r\n return;\r\n }\r\n\r\n const lightType =\r\n babylonNode.getTypeID() == Light.LIGHTTYPEID_POINTLIGHT\r\n ? KHRLightsPunctual_LightType.POINT\r\n : babylonNode.getTypeID() == Light.LIGHTTYPEID_DIRECTIONALLIGHT\r\n ? KHRLightsPunctual_LightType.DIRECTIONAL\r\n : babylonNode.getTypeID() == Light.LIGHTTYPEID_SPOTLIGHT\r\n ? KHRLightsPunctual_LightType.SPOT\r\n : null;\r\n if (!lightType) {\r\n Logger.Warn(`${context}: Light ${babylonNode.name} is not supported in ${NAME}`);\r\n resolve(node);\r\n return;\r\n }\r\n\r\n if (babylonNode.falloffType !== Light.FALLOFF_GLTF) {\r\n Logger.Warn(`${context}: Light falloff for ${babylonNode.name} does not match the ${NAME} specification!`);\r\n }\r\n\r\n // Set the node's translation and rotation here, since lights are not handled in exportNodeAsync\r\n if (!babylonNode.position.equalsToFloats(0, 0, 0)) {\r\n const translation = TmpVectors.Vector3[0].copyFrom(babylonNode.position);\r\n if (convertToRightHanded) {\r\n ConvertToRightHandedPosition(translation);\r\n }\r\n node.translation = translation.asArray();\r\n }\r\n\r\n // Babylon lights have \"constant\" rotation and variable direction, while\r\n // glTF lights have variable rotation and constant direction. Therefore,\r\n // compute a quaternion that aligns the Babylon light's direction with glTF's constant one.\r\n if (lightType !== KHRLightsPunctual_LightType.POINT) {\r\n const direction = babylonNode.direction.normalizeToRef(TmpVectors.Vector3[0]);\r\n if (convertToRightHanded) {\r\n ConvertToRightHandedPosition(direction);\r\n }\r\n const angle = Math.acos(Vector3.Dot(LIGHTDIRECTION, direction));\r\n const axis = Vector3.Cross(LIGHTDIRECTION, direction);\r\n const lightRotationQuaternion = Quaternion.RotationAxisToRef(axis, angle, TmpVectors.Quaternion[0]);\r\n if (!Quaternion.IsIdentity(lightRotationQuaternion)) {\r\n node.rotation = lightRotationQuaternion.asArray();\r\n }\r\n }\r\n\r\n const light: IKHRLightsPunctual_Light = {\r\n type: lightType,\r\n name: babylonNode.name,\r\n color: babylonNode.diffuse.asArray(),\r\n intensity: babylonNode.intensity,\r\n range: babylonNode.range,\r\n };\r\n OmitDefaultValues(light, DEFAULTS);\r\n\r\n // Separately handle the required 'spot' field for spot lights\r\n if (lightType === KHRLightsPunctual_LightType.SPOT) {\r\n const babylonSpotLight = babylonNode as SpotLight;\r\n light.spot = {\r\n innerConeAngle: babylonSpotLight.innerAngle / 2.0,\r\n outerConeAngle: babylonSpotLight.angle / 2.0,\r\n };\r\n OmitDefaultValues(light.spot, SPOTDEFAULTS);\r\n }\r\n\r\n this._lights ||= {\r\n lights: [],\r\n };\r\n this._lights.lights.push(light);\r\n\r\n const lightReference: IKHRLightsPunctual_LightReference = {\r\n light: this._lights.lights.length - 1,\r\n };\r\n\r\n // Assign the light to its parent node, if possible, to condense the glTF\r\n // Why and when: the glTF loader generates a new parent TransformNode for each light node, which we should undo on export\r\n const parentBabylonNode = babylonNode.parent;\r\n\r\n if (parentBabylonNode && IsParentAddedByImporter(babylonNode, parentBabylonNode)) {\r\n const parentNodeIndex = nodeMap.get(parentBabylonNode);\r\n if (parentNodeIndex) {\r\n // Combine the light's transformation with the parent's\r\n const parentNode = this._exporter._nodes[parentNodeIndex];\r\n CollapseParentNode(node, parentNode);\r\n parentNode.extensions ||= {};\r\n parentNode.extensions[NAME] = lightReference;\r\n\r\n // Do not export the original node\r\n resolve(null);\r\n return;\r\n }\r\n }\r\n\r\n node.extensions ||= {};\r\n node.extensions[NAME] = lightReference;\r\n resolve(node);\r\n });\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, (exporter) => new KHR_lights_punctual(exporter));\r\n","import type { IMaterial, IKHRMaterialsAnisotropy } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport { PBRBaseMaterial } from \"core/Materials/PBR/pbrBaseMaterial\";\r\nimport type { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\n\r\nconst NAME = \"KHR_materials_anisotropy\";\r\n\r\n/**\r\n * @internal\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_materials_anisotropy implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n private _exporter: GLTFExporter;\r\n\r\n private _wasUsed = false;\r\n\r\n constructor(exporter: GLTFExporter) {\r\n this._exporter = exporter;\r\n }\r\n\r\n public dispose() {}\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n public postExportMaterialAdditionalTextures?(context: string, node: IMaterial, babylonMaterial: Material): BaseTexture[] {\r\n const additionalTextures: BaseTexture[] = [];\r\n if (babylonMaterial instanceof PBRBaseMaterial) {\r\n if (babylonMaterial.anisotropy.isEnabled && !babylonMaterial.anisotropy.legacy) {\r\n if (babylonMaterial.anisotropy.texture) {\r\n additionalTextures.push(babylonMaterial.anisotropy.texture);\r\n }\r\n return additionalTextures;\r\n }\r\n }\r\n\r\n return [];\r\n }\r\n\r\n // eslint-disable-next-line no-restricted-syntax\r\n public postExportMaterialAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<IMaterial> {\r\n return new Promise((resolve) => {\r\n if (babylonMaterial instanceof PBRBaseMaterial) {\r\n if (!babylonMaterial.anisotropy.isEnabled || babylonMaterial.anisotropy.legacy) {\r\n resolve(node);\r\n return;\r\n }\r\n\r\n this._wasUsed = true;\r\n\r\n node.extensions = node.extensions || {};\r\n\r\n const anisotropyTextureInfo = this._exporter._materialExporter.getTextureInfo(babylonMaterial.anisotropy.texture);\r\n\r\n const anisotropyInfo: IKHRMaterialsAnisotropy = {\r\n anisotropyStrength: babylonMaterial.anisotropy.intensity,\r\n anisotropyRotation: babylonMaterial.anisotropy.angle,\r\n anisotropyTexture: anisotropyTextureInfo ?? undefined,\r\n };\r\n\r\n if (anisotropyInfo.anisotropyTexture !== null) {\r\n this._exporter._materialNeedsUVsSet.add(babylonMaterial);\r\n }\r\n\r\n node.extensions[NAME] = anisotropyInfo;\r\n }\r\n resolve(node);\r\n });\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, (exporter) => new KHR_materials_anisotropy(exporter));\r\n","import type { IMaterial, IKHRMaterialsClearcoat } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport { PBRBaseMaterial } from \"core/Materials/PBR/pbrBaseMaterial\";\r\nimport type { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\n\r\nimport { Tools } from \"core/Misc/tools\";\r\n\r\nconst NAME = \"KHR_materials_clearcoat\";\r\n\r\n/**\r\n * @internal\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_materials_clearcoat implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n private _exporter: GLTFExporter;\r\n\r\n private _wasUsed = false;\r\n\r\n constructor(exporter: GLTFExporter) {\r\n this._exporter = exporter;\r\n }\r\n\r\n public dispose() {}\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n public postExportMaterialAdditionalTextures?(context: string, node: IMaterial, babylonMaterial: Material): BaseTexture[] {\r\n const additionalTextures: BaseTexture[] = [];\r\n if (babylonMaterial instanceof PBRBaseMaterial) {\r\n if (babylonMaterial.clearCoat.isEnabled) {\r\n if (babylonMaterial.clearCoat.texture) {\r\n additionalTextures.push(babylonMaterial.clearCoat.texture);\r\n }\r\n if (!babylonMaterial.clearCoat.useRoughnessFromMainTexture && babylonMaterial.clearCoat.textureRoughness) {\r\n additionalTextures.push(babylonMaterial.clearCoat.textureRoughness);\r\n }\r\n if (babylonMaterial.clearCoat.bumpTexture) {\r\n additionalTextures.push(babylonMaterial.clearCoat.bumpTexture);\r\n }\r\n return additionalTextures;\r\n }\r\n }\r\n\r\n return [];\r\n }\r\n\r\n // eslint-disable-next-line no-restricted-syntax\r\n public postExportMaterialAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<IMaterial> {\r\n return new Promise((resolve) => {\r\n if (babylonMaterial instanceof PBRBaseMaterial) {\r\n if (!babylonMaterial.clearCoat.isEnabled) {\r\n resolve(node);\r\n return;\r\n }\r\n\r\n this._wasUsed = true;\r\n\r\n node.extensions = node.extensions || {};\r\n\r\n const clearCoatTextureInfo = this._exporter._materialExporter.getTextureInfo(babylonMaterial.clearCoat.texture);\r\n let clearCoatTextureRoughnessInfo;\r\n if (babylonMaterial.clearCoat.useRoughnessFromMainTexture) {\r\n clearCoatTextureRoughnessInfo = this._exporter._materialExporter.getTextureInfo(babylonMaterial.clearCoat.texture);\r\n } else {\r\n clearCoatTextureRoughnessInfo = this._exporter._materialExporter.getTextureInfo(babylonMaterial.clearCoat.textureRoughness);\r\n }\r\n\r\n if (babylonMaterial.clearCoat.isTintEnabled) {\r\n Tools.Warn(`Clear Color tint is not supported for glTF export. Ignoring for: ${babylonMaterial.name}`);\r\n }\r\n\r\n if (babylonMaterial.clearCoat.remapF0OnInterfaceChange) {\r\n Tools.Warn(`Clear Color F0 remapping is not supported for glTF export. Ignoring for: ${babylonMaterial.name}`);\r\n }\r\n\r\n const clearCoatNormalTextureInfo = this._exporter._materialExporter.getTextureInfo(babylonMaterial.clearCoat.bumpTexture);\r\n\r\n const clearCoatInfo: IKHRMaterialsClearcoat = {\r\n clearcoatFactor: babylonMaterial.clearCoat.intensity,\r\n clearcoatTexture: clearCoatTextureInfo ?? undefined,\r\n clearcoatRoughnessFactor: babylonMaterial.clearCoat.roughness,\r\n clearcoatRoughnessTexture: clearCoatTextureRoughnessInfo ?? undefined,\r\n clearcoatNormalTexture: clearCoatNormalTextureInfo ?? undefined,\r\n };\r\n\r\n if (clearCoatInfo.clearcoatTexture !== null || clearCoatInfo.clearcoatRoughnessTexture !== null || clearCoatInfo.clearcoatRoughnessTexture !== null) {\r\n this._exporter._materialNeedsUVsSet.add(babylonMaterial);\r\n }\r\n\r\n node.extensions[NAME] = clearCoatInfo;\r\n }\r\n resolve(node);\r\n });\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, (exporter) => new KHR_materials_clearcoat(exporter));\r\n","import type { IMaterial, IKHRMaterialsDiffuseTransmission } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport { PBRMaterial } from \"core/Materials/PBR/pbrMaterial\";\r\nimport type { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\nimport { Logger } from \"core/Misc/logger\";\r\nimport type { Nullable } from \"core/types\";\r\n\r\nconst NAME = \"KHR_materials_diffuse_transmission\";\r\n\r\n/**\r\n * Get the appropriate translucency intensity texture for the material.\r\n * @internal\r\n */\r\nfunction GetTranslucencyIntensityTexture(context: string, babylonMaterial: PBRMaterial): Nullable<BaseTexture> {\r\n const subs = babylonMaterial.subSurface;\r\n let texture = null;\r\n\r\n // Check if translucency intensity texture is available or can be derived from thickness texture\r\n if (subs.translucencyIntensityTexture) {\r\n texture = subs.translucencyIntensityTexture;\r\n } else if (subs.thicknessTexture && subs.useMaskFromThicknessTexture) {\r\n texture = subs.thicknessTexture;\r\n }\r\n\r\n if (texture && !subs.useGltfStyleTextures) {\r\n Logger.Warn(`${context}: Translucency intensity texture is not supported when useGltfStyleTextures = false. Ignoring for: ${babylonMaterial.name}`, 1);\r\n return null;\r\n }\r\n\r\n return texture;\r\n}\r\n\r\n/**\r\n * [Proposed Specification](https://github.com/KhronosGroup/glTF/pull/1825)\r\n * !!! Experimental Extension Subject to Changes !!!\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_materials_diffuse_transmission implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n private _exporter: GLTFExporter;\r\n\r\n private _wasUsed = false;\r\n\r\n constructor(exporter: GLTFExporter) {\r\n this._exporter = exporter;\r\n }\r\n\r\n public dispose() {}\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n /**\r\n * After exporting a material, deal with additional textures\r\n * @param context GLTF context of the material\r\n * @param node exported GLTF node\r\n * @param babylonMaterial corresponding babylon material\r\n * @returns array of additional textures to export\r\n */\r\n public postExportMaterialAdditionalTextures?(context: string, node: IMaterial, babylonMaterial: Material): BaseTexture[] {\r\n const additionalTextures: BaseTexture[] = [];\r\n\r\n if (babylonMaterial instanceof PBRMaterial && this._isExtensionEnabled(babylonMaterial)) {\r\n const translucencyIntensityTexture = GetTranslucencyIntensityTexture(context, babylonMaterial);\r\n if (translucencyIntensityTexture) {\r\n additionalTextures.push(translucencyIntensityTexture);\r\n }\r\n if (babylonMaterial.subSurface.translucencyColorTexture) {\r\n additionalTextures.push(babylonMaterial.subSurface.translucencyColorTexture);\r\n }\r\n return additionalTextures;\r\n }\r\n\r\n return additionalTextures;\r\n }\r\n\r\n private _isExtensionEnabled(mat: PBRMaterial): boolean {\r\n // This extension must not be used on a material that also uses KHR_materials_unlit\r\n if (mat.unlit) {\r\n return false;\r\n }\r\n const subs = mat.subSurface;\r\n if (!subs.isTranslucencyEnabled) {\r\n return false;\r\n }\r\n\r\n return (\r\n !mat.unlit &&\r\n !subs.useAlbedoToTintTranslucency &&\r\n subs.useGltfStyleTextures &&\r\n subs.volumeIndexOfRefraction === 1 &&\r\n subs.minimumThickness === 0 &&\r\n subs.maximumThickness === 0\r\n );\r\n }\r\n\r\n /**\r\n * After exporting a material\r\n * @param context GLTF context of the material\r\n * @param node exported GLTF node\r\n * @param babylonMaterial corresponding babylon material\r\n * @returns promise that resolves with the updated node\r\n */\r\n // eslint-disable-next-line no-restricted-syntax\r\n public postExportMaterialAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<IMaterial> {\r\n return new Promise((resolve) => {\r\n if (babylonMaterial instanceof PBRMaterial && this._isExtensionEnabled(babylonMaterial)) {\r\n this._wasUsed = true;\r\n\r\n const subs = babylonMaterial.subSurface;\r\n const translucencyIntensityTexture = GetTranslucencyIntensityTexture(context, babylonMaterial);\r\n\r\n const diffuseTransmissionFactor = subs.translucencyIntensity == 0 ? undefined : subs.translucencyIntensity;\r\n const diffuseTransmissionTexture = this._exporter._materialExporter.getTextureInfo(translucencyIntensityTexture) ?? undefined;\r\n const diffuseTransmissionColorFactor = !subs.translucencyColor || subs.translucencyColor.equalsFloats(1.0, 1.0, 1.0) ? undefined : subs.translucencyColor.asArray();\r\n const diffuseTransmissionColorTexture = this._exporter._materialExporter.getTextureInfo(subs.translucencyColorTexture) ?? undefined;\r\n\r\n const diffuseTransmissionInfo: IKHRMaterialsDiffuseTransmission = {\r\n diffuseTransmissionFactor,\r\n diffuseTransmissionTexture,\r\n diffuseTransmissionColorFactor,\r\n diffuseTransmissionColorTexture,\r\n };\r\n\r\n if (diffuseTransmissionTexture || diffuseTransmissionColorTexture) {\r\n this._exporter._materialNeedsUVsSet.add(babylonMaterial);\r\n }\r\n\r\n node.extensions = node.extensions || {};\r\n node.extensions[NAME] = diffuseTransmissionInfo;\r\n }\r\n resolve(node);\r\n });\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, (exporter) => new KHR_materials_diffuse_transmission(exporter));\r\n","import type { IMaterial, IKHRMaterialsDispersion } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport { PBRMaterial } from \"core/Materials/PBR/pbrMaterial\";\r\n\r\nconst NAME = \"KHR_materials_dispersion\";\r\n\r\n/**\r\n * [Specification](https://github.com/KhronosGroup/glTF/blob/87bd64a7f5e23c84b6aef2e6082069583ed0ddb4/extensions/2.0/Khronos/KHR_materials_dispersion/README.md)\r\n * @experimental\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_materials_dispersion implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n private _wasUsed = false;\r\n\r\n /** Constructor */\r\n constructor() {}\r\n\r\n /** Dispose */\r\n public dispose() {}\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n private _isExtensionEnabled(mat: PBRMaterial): boolean {\r\n // This extension must not be used on a material that also uses KHR_materials_unlit\r\n if (mat.unlit) {\r\n return false;\r\n }\r\n const subs = mat.subSurface;\r\n // this extension requires refraction to be enabled.\r\n if (!subs.isRefractionEnabled && !subs.isDispersionEnabled) {\r\n return false;\r\n }\r\n return true;\r\n }\r\n\r\n /**\r\n * After exporting a material\r\n * @param context GLTF context of the material\r\n * @param node exported GLTF node\r\n * @param babylonMaterial corresponding babylon material\r\n * @returns promise, resolves with the material\r\n */\r\n // eslint-disable-next-line no-restricted-syntax\r\n public postExportMaterialAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<IMaterial> {\r\n return new Promise((resolve) => {\r\n if (babylonMaterial instanceof PBRMaterial && this._isExtensionEnabled(babylonMaterial)) {\r\n this._wasUsed = true;\r\n\r\n const subs = babylonMaterial.subSurface;\r\n const dispersion = subs.dispersion;\r\n\r\n const dispersionInfo: IKHRMaterialsDispersion = {\r\n dispersion: dispersion,\r\n };\r\n node.extensions = node.extensions || {};\r\n node.extensions[NAME] = dispersionInfo;\r\n }\r\n resolve(node);\r\n });\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, () => new KHR_materials_dispersion());\r\n","import type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport { PBRMaterial } from \"core/Materials/PBR/pbrMaterial\";\r\nimport type { IMaterial, IKHRMaterialsEmissiveStrength } from \"babylonjs-gltf2interface\";\r\n\r\nconst NAME = \"KHR_materials_emissive_strength\";\r\n\r\n/**\r\n * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_emissive_strength/README.md)\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_materials_emissive_strength implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n private _wasUsed = false;\r\n\r\n /** Dispose */\r\n public dispose() {}\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n /**\r\n * After exporting a material\r\n * @param context GLTF context of the material\r\n * @param node exported GLTF node\r\n * @param babylonMaterial corresponding babylon material\r\n * @returns promise, resolves with the material\r\n */\r\n public async postExportMaterialAsync(context: string, node: IMaterial, babylonMaterial: Material): Promise<IMaterial> {\r\n return await new Promise((resolve) => {\r\n if (!(babylonMaterial instanceof PBRMaterial)) {\r\n return resolve(node);\r\n }\r\n\r\n const emissiveColor = babylonMaterial.emissiveColor.asArray();\r\n const tempEmissiveStrength = Math.max(...emissiveColor);\r\n\r\n if (tempEmissiveStrength > 1) {\r\n this._wasUsed = true;\r\n\r\n node.extensions ||= {};\r\n\r\n const emissiveStrengthInfo: IKHRMaterialsEmissiveStrength = {\r\n emissiveStrength: tempEmissiveStrength,\r\n };\r\n\r\n // Normalize each value of the emissive factor to have a max value of 1\r\n const newEmissiveFactor = babylonMaterial.emissiveColor.scale(1 / emissiveStrengthInfo.emissiveStrength);\r\n\r\n node.emissiveFactor = newEmissiveFactor.asArray();\r\n node.extensions[NAME] = emissiveStrengthInfo;\r\n }\r\n\r\n return resolve(node);\r\n });\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, (exporter) => new KHR_materials_emissive_strength());\r\n","import type { IMaterial, IKHRMaterialsIor } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport { PBRMaterial } from \"core/Materials/PBR/pbrMaterial\";\r\n\r\nconst NAME = \"KHR_materials_ior\";\r\n\r\n/**\r\n * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_ior/README.md)\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_materials_ior implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n private _wasUsed = false;\r\n\r\n constructor() {}\r\n\r\n /** Dispose */\r\n public dispose() {}\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n private _isExtensionEnabled(mat: PBRMaterial): boolean {\r\n // This extension must not be used on a material that also uses KHR_materials_unlit\r\n if (mat.unlit) {\r\n return false;\r\n }\r\n return mat.indexOfRefraction != undefined && mat.indexOfRefraction != 1.5; // 1.5 is normative default value.\r\n }\r\n\r\n /**\r\n * After exporting a material\r\n * @param context GLTF context of the material\r\n * @param node exported GLTF node\r\n * @param babylonMaterial corresponding babylon material\r\n * @returns promise, resolves with the material\r\n */\r\n // eslint-disable-next-line no-restricted-syntax\r\n public postExportMaterialAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<IMaterial> {\r\n return new Promise((resolve) => {\r\n if (babylonMaterial instanceof PBRMaterial && this._isExtensionEnabled(babylonMaterial)) {\r\n this._wasUsed = true;\r\n\r\n const iorInfo: IKHRMaterialsIor = {\r\n ior: babylonMaterial.indexOfRefraction,\r\n };\r\n node.extensions = node.extensions || {};\r\n node.extensions[NAME] = iorInfo;\r\n }\r\n resolve(node);\r\n });\r\n }\r\n}\r\n\r\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\r\nGLTFExporter.RegisterExtension(NAME, (exporter) => new KHR_materials_ior());\r\n","import type { IMaterial, IKHRMaterialsIridescence } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport { PBRBaseMaterial } from \"core/Materials/PBR/pbrBaseMaterial\";\r\nimport type { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\n\r\nconst NAME = \"KHR_materials_iridescence\";\r\n\r\n/**\r\n * @internal\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_materials_iridescence implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n private _exporter: GLTFExporter;\r\n\r\n private _wasUsed = false;\r\n\r\n constructor(exporter: GLTFExporter) {\r\n this._exporter = exporter;\r\n }\r\n\r\n public dispose() {}\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n public postExportMaterialAdditionalTextures?(context: string, node: IMaterial, babylonMaterial: Material): BaseTexture[] {\r\n const additionalTextures: BaseTexture[] = [];\r\n if (babylonMaterial instanceof PBRBaseMaterial) {\r\n if (babylonMaterial.iridescence.isEnabled) {\r\n if (babylonMaterial.iridescence.texture) {\r\n additionalTextures.push(babylonMaterial.iridescence.texture);\r\n }\r\n if (babylonMaterial.iridescence.thicknessTexture && babylonMaterial.iridescence.thicknessTexture !== babylonMaterial.iridescence.texture) {\r\n additionalTextures.push(babylonMaterial.iridescence.thicknessTexture);\r\n }\r\n return additionalTextures;\r\n }\r\n }\r\n\r\n return [];\r\n }\r\n\r\n // eslint-disable-next-line no-restricted-syntax\r\n public postExportMaterialAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<IMaterial> {\r\n return new Promise((resolve) => {\r\n if (babylonMaterial instanceof PBRBaseMaterial) {\r\n if (!babylonMaterial.iridescence.isEnabled) {\r\n resolve(node);\r\n return;\r\n }\r\n\r\n this._wasUsed = true;\r\n\r\n node.extensions = node.extensions || {};\r\n\r\n const iridescenceTextureInfo = this._exporter._materialExporter.getTextureInfo(babylonMaterial.iridescence.texture);\r\n const iridescenceThicknessTextureInfo = this._exporter._materialExporter.getTextureInfo(babylonMaterial.iridescence.thicknessTexture);\r\n\r\n const iridescenceInfo: IKHRMaterialsIridescence = {\r\n iridescenceFactor: babylonMaterial.iridescence.intensity,\r\n iridescenceIor: babylonMaterial.iridescence.indexOfRefraction,\r\n iridescenceThicknessMinimum: babylonMaterial.iridescence.minimumThickness,\r\n iridescenceThicknessMaximum: babylonMaterial.iridescence.maximumThickness,\r\n\r\n iridescenceTexture: iridescenceTextureInfo ?? undefined,\r\n iridescenceThicknessTexture: iridescenceThicknessTextureInfo ?? undefined,\r\n };\r\n\r\n if (iridescenceInfo.iridescenceTexture !== null || iridescenceInfo.iridescenceThicknessTexture !== null) {\r\n this._exporter._materialNeedsUVsSet.add(babylonMaterial);\r\n }\r\n\r\n node.extensions[NAME] = iridescenceInfo;\r\n }\r\n resolve(node);\r\n });\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, (exporter) => new KHR_materials_iridescence(exporter));\r\n","import type { IMaterial, IKHRMaterialsSheen } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport { PBRMaterial } from \"core/Materials/PBR/pbrMaterial\";\r\nimport type { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\n\r\nconst NAME = \"KHR_materials_sheen\";\r\n\r\n/**\r\n * @internal\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_materials_sheen implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n private _wasUsed = false;\r\n\r\n private _exporter: GLTFExporter;\r\n\r\n constructor(exporter: GLTFExporter) {\r\n this._exporter = exporter;\r\n }\r\n\r\n public dispose() {}\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n public postExportMaterialAdditionalTextures(context: string, node: IMaterial, babylonMaterial: Material): BaseTexture[] {\r\n if (babylonMaterial instanceof PBRMaterial) {\r\n if (babylonMaterial.sheen.isEnabled && babylonMaterial.sheen.texture) {\r\n return [babylonMaterial.sheen.texture];\r\n }\r\n }\r\n\r\n return [];\r\n }\r\n\r\n public async postExportMaterialAsync(context: string, node: IMaterial, babylonMaterial: Material): Promise<IMaterial> {\r\n return await new Promise((resolve) => {\r\n if (babylonMaterial instanceof PBRMaterial) {\r\n if (!babylonMaterial.sheen.isEnabled) {\r\n resolve(node);\r\n return;\r\n }\r\n\r\n this._wasUsed = true;\r\n\r\n if (node.extensions == null) {\r\n node.extensions = {};\r\n }\r\n const sheenInfo: IKHRMaterialsSheen = {\r\n sheenColorFactor: babylonMaterial.sheen.color.asArray(),\r\n sheenRoughnessFactor: babylonMaterial.sheen.roughness ?? 0,\r\n };\r\n\r\n if (sheenInfo.sheenColorTexture !== null || sheenInfo.sheenRoughnessTexture !== null) {\r\n this._exporter._materialNeedsUVsSet.add(babylonMaterial);\r\n }\r\n\r\n if (babylonMaterial.sheen.texture) {\r\n sheenInfo.sheenColorTexture = this._exporter._materialExporter.getTextureInfo(babylonMaterial.sheen.texture) ?? undefined;\r\n }\r\n\r\n if (babylonMaterial.sheen.textureRoughness && !babylonMaterial.sheen.useRoughnessFromMainTexture) {\r\n sheenInfo.sheenRoughnessTexture = this._exporter._materialExporter.getTextureInfo(babylonMaterial.sheen.textureRoughness) ?? undefined;\r\n } else if (babylonMaterial.sheen.texture && babylonMaterial.sheen.useRoughnessFromMainTexture) {\r\n sheenInfo.sheenRoughnessTexture = this._exporter._materialExporter.getTextureInfo(babylonMaterial.sheen.texture) ?? undefined;\r\n }\r\n\r\n node.extensions[NAME] = sheenInfo;\r\n }\r\n resolve(node);\r\n });\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, (exporter) => new KHR_materials_sheen(exporter));\r\n","import type { IMaterial, IKHRMaterialsSpecular } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport { PBRMaterial } from \"core/Materials/PBR/pbrMaterial\";\r\nimport type { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\n\r\nconst NAME = \"KHR_materials_specular\";\r\n\r\n/**\r\n * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_specular/README.md)\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_materials_specular implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n private _exporter: GLTFExporter;\r\n\r\n private _wasUsed = false;\r\n\r\n constructor(exporter: GLTFExporter) {\r\n this._exporter = exporter;\r\n }\r\n\r\n /** Dispose */\r\n public dispose() {}\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n /**\r\n * After exporting a material, deal with the additional textures\r\n * @param context GLTF context of the material\r\n * @param node exported GLTF node\r\n * @param babylonMaterial corresponding babylon material\r\n * @returns array of additional textures to export\r\n */\r\n public postExportMaterialAdditionalTextures?(context: string, node: IMaterial, babylonMaterial: Material): BaseTexture[] {\r\n const additionalTextures: BaseTexture[] = [];\r\n\r\n if (babylonMaterial instanceof PBRMaterial) {\r\n if (this._isExtensionEnabled(babylonMaterial)) {\r\n if (babylonMaterial.metallicReflectanceTexture) {\r\n additionalTextures.push(babylonMaterial.metallicReflectanceTexture);\r\n }\r\n if (babylonMaterial.reflectanceTexture) {\r\n additionalTextures.push(babylonMaterial.reflectanceTexture);\r\n }\r\n return additionalTextures;\r\n }\r\n }\r\n\r\n return additionalTextures;\r\n }\r\n\r\n private _isExtensionEnabled(mat: PBRMaterial): boolean {\r\n // This extension must not be used on a material that also uses KHR_materials_unlit\r\n if (mat.unlit) {\r\n return false;\r\n }\r\n return (\r\n (mat.metallicF0Factor != undefined && mat.metallicF0Factor != 1.0) ||\r\n (mat.metallicReflectanceColor != undefined && !mat.metallicReflectanceColor.equalsFloats(1.0, 1.0, 1.0)) ||\r\n this._hasTexturesExtension(mat)\r\n );\r\n }\r\n\r\n private _hasTexturesExtension(mat: PBRMaterial): boolean {\r\n return mat.metallicReflectanceTexture != null || mat.reflectanceTexture != null;\r\n }\r\n\r\n /**\r\n * After exporting a material\r\n * @param context GLTF context of the material\r\n * @param node exported GLTF node\r\n * @param babylonMaterial corresponding babylon material\r\n * @returns promise, resolves with the material\r\n */\r\n // eslint-disable-next-line no-restricted-syntax\r\n public postExportMaterialAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<IMaterial> {\r\n return new Promise((resolve) => {\r\n if (babylonMaterial instanceof PBRMaterial && this._isExtensionEnabled(babylonMaterial)) {\r\n this._wasUsed = true;\r\n\r\n node.extensions = node.extensions || {};\r\n\r\n const metallicReflectanceTexture = this._exporter._materialExporter.getTextureInfo(babylonMaterial.metallicReflectanceTexture) ?? undefined;\r\n const reflectanceTexture = this._exporter._materialExporter.getTextureInfo(babylonMaterial.reflectanceTexture) ?? undefined;\r\n const metallicF0Factor = babylonMaterial.metallicF0Factor == 1.0 ? undefined : babylonMaterial.metallicF0Factor;\r\n const metallicReflectanceColor = babylonMaterial.metallicReflectanceColor.equalsFloats(1.0, 1.0, 1.0)\r\n ? undefined\r\n : babylonMaterial.metallicReflectanceColor.asArray();\r\n\r\n const specularInfo: IKHRMaterialsSpecular = {\r\n specularFactor: metallicF0Factor,\r\n specularTexture: metallicReflectanceTexture,\r\n specularColorFactor: metallicReflectanceColor,\r\n specularColorTexture: reflectanceTexture,\r\n };\r\n\r\n if (this._hasTexturesExtension(babylonMaterial)) {\r\n this._exporter._materialNeedsUVsSet.add(babylonMaterial);\r\n }\r\n\r\n node.extensions[NAME] = specularInfo;\r\n }\r\n resolve(node);\r\n });\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, (exporter) => new KHR_materials_specular(exporter));\r\n","import type { IMaterial, IKHRMaterialsTransmission } from \"babylonjs-gltf2interface\";\r\nimport { ImageMimeType } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport { PBRMaterial } from \"core/Materials/PBR/pbrMaterial\";\r\nimport type { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\nimport { Logger } from \"core/Misc/logger\";\r\n\r\nconst NAME = \"KHR_materials_transmission\";\r\n\r\n/**\r\n * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_transmission/README.md)\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_materials_transmission implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n private _exporter: GLTFExporter;\r\n\r\n private _wasUsed = false;\r\n\r\n constructor(exporter: GLTFExporter) {\r\n this._exporter = exporter;\r\n }\r\n\r\n /** Dispose */\r\n public dispose() {}\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n /**\r\n * After exporting a material, deal with additional textures\r\n * @param context GLTF context of the material\r\n * @param node exported GLTF node\r\n * @param babylonMaterial corresponding babylon material\r\n * @returns array of additional textures to export\r\n */\r\n public postExportMaterialAdditionalTextures?(context: string, node: IMaterial, babylonMaterial: Material): BaseTexture[] {\r\n const additionalTextures: BaseTexture[] = [];\r\n\r\n if (babylonMaterial instanceof PBRMaterial) {\r\n if (this._isExtensionEnabled(babylonMaterial)) {\r\n if (babylonMaterial.subSurface.thicknessTexture) {\r\n additionalTextures.push(babylonMaterial.subSurface.thicknessTexture);\r\n }\r\n return additionalTextures;\r\n }\r\n }\r\n\r\n return additionalTextures;\r\n }\r\n\r\n private _isExtensionEnabled(mat: PBRMaterial): boolean {\r\n // This extension must not be used on a material that also uses KHR_materials_unlit\r\n if (mat.unlit) {\r\n return false;\r\n }\r\n const subs = mat.subSurface;\r\n return (subs.isRefractionEnabled && subs.refractionIntensity != undefined && subs.refractionIntensity != 0) || this._hasTexturesExtension(mat);\r\n }\r\n\r\n private _hasTexturesExtension(mat: PBRMaterial): boolean {\r\n return mat.subSurface.refractionIntensityTexture != null;\r\n }\r\n\r\n /**\r\n * After exporting a material\r\n * @param context GLTF context of the material\r\n * @param node exported GLTF node\r\n * @param babylonMaterial corresponding babylon material\r\n * @returns true if successful\r\n */\r\n public async postExportMaterialAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<IMaterial> {\r\n if (babylonMaterial instanceof PBRMaterial && this._isExtensionEnabled(babylonMaterial)) {\r\n this._wasUsed = true;\r\n\r\n const subSurface = babylonMaterial.subSurface;\r\n const transmissionFactor = subSurface.refractionIntensity === 0 ? undefined : subSurface.refractionIntensity;\r\n\r\n const volumeInfo: IKHRMaterialsTransmission = {\r\n transmissionFactor: transmissionFactor,\r\n };\r\n\r\n if (this._hasTexturesExtension(babylonMaterial)) {\r\n this._exporter._materialNeedsUVsSet.add(babylonMaterial);\r\n }\r\n\r\n if (subSurface.refractionIntensityTexture) {\r\n if (subSurface.useGltfStyleTextures) {\r\n const transmissionTexture = await this._exporter._materialExporter.exportTextureAsync(subSurface.refractionIntensityTexture, ImageMimeType.PNG);\r\n if (transmissionTexture) {\r\n volumeInfo.transmissionTexture = transmissionTexture;\r\n }\r\n } else {\r\n Logger.Warn(`${context}: Exporting a subsurface refraction intensity texture without \\`useGltfStyleTextures\\` is not supported`);\r\n }\r\n }\r\n\r\n node.extensions ||= {};\r\n node.extensions[NAME] = volumeInfo;\r\n }\r\n\r\n return node;\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, (exporter) => new KHR_materials_transmission(exporter));\r\n","import type { IMaterial } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport { PBRMaterial } from \"core/Materials/PBR/pbrMaterial\";\r\nimport { StandardMaterial } from \"core/Materials/standardMaterial\";\r\n\r\nconst NAME = \"KHR_materials_unlit\";\r\n\r\n/**\r\n * @internal\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_materials_unlit implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n private _wasUsed = false;\r\n\r\n constructor() {}\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n public dispose() {}\r\n\r\n // eslint-disable-next-line no-restricted-syntax\r\n public postExportMaterialAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<IMaterial> {\r\n return new Promise((resolve) => {\r\n let unlitMaterial = false;\r\n\r\n if (babylonMaterial instanceof PBRMaterial) {\r\n unlitMaterial = babylonMaterial.unlit;\r\n } else if (babylonMaterial instanceof StandardMaterial) {\r\n unlitMaterial = babylonMaterial.disableLighting;\r\n }\r\n\r\n if (unlitMaterial) {\r\n this._wasUsed = true;\r\n\r\n if (node.extensions == null) {\r\n node.extensions = {};\r\n }\r\n\r\n node.extensions[NAME] = {};\r\n }\r\n\r\n resolve(node);\r\n });\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, () => new KHR_materials_unlit());\r\n","import type { IMaterial, IKHRMaterialsVolume } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport { PBRMaterial } from \"core/Materials/PBR/pbrMaterial\";\r\nimport type { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\nimport { Color3 } from \"core/Maths/math.color\";\r\n\r\nconst NAME = \"KHR_materials_volume\";\r\n\r\n/**\r\n * [Specification](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_volume/README.md)\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_materials_volume implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n private _exporter: GLTFExporter;\r\n\r\n private _wasUsed = false;\r\n\r\n constructor(exporter: GLTFExporter) {\r\n this._exporter = exporter;\r\n }\r\n\r\n public dispose() {}\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n /**\r\n * After exporting a material, deal with additional textures\r\n * @param context GLTF context of the material\r\n * @param node exported GLTF node\r\n * @param babylonMaterial corresponding babylon material\r\n * @returns array of additional textures to export\r\n */\r\n public postExportMaterialAdditionalTextures?(context: string, node: IMaterial, babylonMaterial: Material): BaseTexture[] {\r\n const additionalTextures: BaseTexture[] = [];\r\n\r\n if (babylonMaterial instanceof PBRMaterial) {\r\n if (this._isExtensionEnabled(babylonMaterial)) {\r\n if (babylonMaterial.subSurface.thicknessTexture) {\r\n additionalTextures.push(babylonMaterial.subSurface.thicknessTexture);\r\n }\r\n return additionalTextures;\r\n }\r\n }\r\n\r\n return additionalTextures;\r\n }\r\n\r\n private _isExtensionEnabled(mat: PBRMaterial): boolean {\r\n // This extension must not be used on a material that also uses KHR_materials_unlit\r\n if (mat.unlit) {\r\n return false;\r\n }\r\n const subs = mat.subSurface;\r\n // this extension requires either the KHR_materials_transmission or KHR_materials_diffuse_transmission extensions.\r\n if (!subs.isRefractionEnabled && !subs.isTranslucencyEnabled) {\r\n return false;\r\n }\r\n return (\r\n (subs.maximumThickness != undefined && subs.maximumThickness != 0) ||\r\n (subs.tintColorAtDistance != undefined && subs.tintColorAtDistance != Number.POSITIVE_INFINITY) ||\r\n (subs.tintColor != undefined && subs.tintColor != Color3.White()) ||\r\n this._hasTexturesExtension(mat)\r\n );\r\n }\r\n\r\n private _hasTexturesExtension(mat: PBRMaterial): boolean {\r\n return mat.subSurface.thicknessTexture != null;\r\n }\r\n\r\n /**\r\n * After exporting a material\r\n * @param context GLTF context of the material\r\n * @param node exported GLTF node\r\n * @param babylonMaterial corresponding babylon material\r\n * @returns promise that resolves with the updated node\r\n */\r\n // eslint-disable-next-line no-restricted-syntax\r\n public postExportMaterialAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<IMaterial> {\r\n return new Promise((resolve) => {\r\n if (babylonMaterial instanceof PBRMaterial && this._isExtensionEnabled(babylonMaterial)) {\r\n this._wasUsed = true;\r\n\r\n const subs = babylonMaterial.subSurface;\r\n const thicknessFactor = subs.maximumThickness == 0 ? undefined : subs.maximumThickness;\r\n const thicknessTexture = this._exporter._materialExporter.getTextureInfo(subs.thicknessTexture) ?? undefined;\r\n const attenuationDistance = subs.tintColorAtDistance == Number.POSITIVE_INFINITY ? undefined : subs.tintColorAtDistance;\r\n const attenuationColor = subs.tintColor.equalsFloats(1.0, 1.0, 1.0) ? undefined : subs.tintColor.asArray();\r\n\r\n const volumeInfo: IKHRMaterialsVolume = {\r\n thicknessFactor: thicknessFactor,\r\n thicknessTexture: thicknessTexture,\r\n attenuationDistance: attenuationDistance,\r\n attenuationColor: attenuationColor,\r\n };\r\n\r\n if (this._hasTexturesExtension(babylonMaterial)) {\r\n this._exporter._materialNeedsUVsSet.add(babylonMaterial);\r\n }\r\n\r\n node.extensions = node.extensions || {};\r\n node.extensions[NAME] = volumeInfo;\r\n }\r\n resolve(node);\r\n });\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, (exporter) => new KHR_materials_volume(exporter));\r\n","import type { IMaterial, IEXTMaterialsDiffuseRoughness } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport { PBRBaseMaterial } from \"core/Materials/PBR/pbrBaseMaterial\";\r\nimport type { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\n\r\nconst NAME = \"EXT_materials_diffuse_roughness\";\r\n\r\n/**\r\n * @internal\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class EXT_materials_diffuse_roughness implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n private _exporter: GLTFExporter;\r\n\r\n private _wasUsed = false;\r\n\r\n constructor(exporter: GLTFExporter) {\r\n this._exporter = exporter;\r\n }\r\n\r\n public dispose() {}\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n public postExportMaterialAdditionalTextures?(context: string, node: IMaterial, babylonMaterial: Material): BaseTexture[] {\r\n const additionalTextures: BaseTexture[] = [];\r\n if (babylonMaterial instanceof PBRBaseMaterial) {\r\n if (babylonMaterial._baseDiffuseRoughness) {\r\n if (babylonMaterial._baseDiffuseRoughnessTexture) {\r\n additionalTextures.push(babylonMaterial._baseDiffuseRoughnessTexture);\r\n }\r\n return additionalTextures;\r\n }\r\n }\r\n\r\n return [];\r\n }\r\n\r\n // eslint-disable-next-line no-restricted-syntax\r\n public postExportMaterialAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise<IMaterial> {\r\n return new Promise((resolve) => {\r\n if (babylonMaterial instanceof PBRBaseMaterial) {\r\n if (!babylonMaterial._baseDiffuseRoughness) {\r\n resolve(node);\r\n return;\r\n }\r\n\r\n this._wasUsed = true;\r\n\r\n node.extensions = node.extensions || {};\r\n\r\n const diffuseRoughnessTextureInfo = this._exporter._materialExporter.getTextureInfo(babylonMaterial._baseDiffuseRoughnessTexture);\r\n\r\n const diffuseRoughnessInfo: IEXTMaterialsDiffuseRoughness = {\r\n diffuseRoughnessFactor: babylonMaterial._baseDiffuseRoughness,\r\n diffuseRoughnessTexture: diffuseRoughnessTextureInfo ?? undefined,\r\n };\r\n\r\n if (diffuseRoughnessInfo.diffuseRoughnessTexture !== null) {\r\n this._exporter._materialNeedsUVsSet.add(babylonMaterial);\r\n }\r\n\r\n node.extensions[NAME] = diffuseRoughnessInfo;\r\n }\r\n resolve(node);\r\n });\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, (exporter) => new EXT_materials_diffuse_roughness(exporter));\r\n","import type { ITextureInfo, IKHRTextureTransform } from \"babylonjs-gltf2interface\";\r\nimport { Tools } from \"core/Misc/tools\";\r\nimport type { Texture } from \"core/Materials/Textures/texture\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { GLTFExporter } from \"../glTFExporter\";\r\n\r\nconst NAME = \"KHR_texture_transform\";\r\n\r\n/**\r\n * Computes the adjusted offset for a rotation centered about the origin.\r\n * @internal\r\n */\r\nfunction AdjustOffsetForRotationCenter(babylonTexture: Texture): [number, number] {\r\n const { uOffset, vOffset, uRotationCenter, vRotationCenter, uScale, vScale, wAng } = babylonTexture;\r\n const cosAngle = Math.cos(wAng);\r\n const sinAngle = Math.sin(wAng);\r\n const scaledURotationCenter = uRotationCenter * uScale;\r\n const scaledVRotationCenter = vRotationCenter * vScale;\r\n const deltaU = scaledURotationCenter * (1 - cosAngle) + scaledVRotationCenter * sinAngle;\r\n const deltaV = scaledVRotationCenter * (1 - cosAngle) - scaledURotationCenter * sinAngle;\r\n return [uOffset + deltaU, vOffset + deltaV];\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport class KHR_texture_transform implements IGLTFExporterExtensionV2 {\r\n /** Name of this extension */\r\n public readonly name = NAME;\r\n\r\n /** Defines whether this extension is enabled */\r\n public enabled = true;\r\n\r\n /** Defines whether this extension is required */\r\n public required = false;\r\n\r\n /** Reference to the glTF exporter */\r\n private _wasUsed = false;\r\n\r\n constructor() {}\r\n\r\n public dispose() {}\r\n\r\n /** @internal */\r\n public get wasUsed() {\r\n return this._wasUsed;\r\n }\r\n\r\n public postExportTexture?(context: string, textureInfo: ITextureInfo, babylonTexture: Texture): void {\r\n const scene = babylonTexture.getScene();\r\n if (!scene) {\r\n Tools.Warn(`${context}: \"scene\" is not defined for Babylon texture ${babylonTexture.name}!`);\r\n }\r\n\r\n /*\r\n * The KHR_texture_transform schema only supports w rotation around the origin.\r\n * See https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_texture_transform#gltf-schema-updates.\r\n */\r\n if (babylonTexture.uAng !== 0 || babylonTexture.vAng !== 0) {\r\n Tools.Warn(`${context}: Texture ${babylonTexture.name} with rotation in the u or v axis is not supported in glTF.`);\r\n // Usually, we'd always early return here if the texture uses an unsupported combination of transform properties,\r\n // but we're making an exception here to maintain backwards compatibility.\r\n if (babylonTexture.uRotationCenter !== 0 || babylonTexture.vRotationCenter !== 0) {\r\n return;\r\n }\r\n }\r\n\r\n const textureTransform: IKHRTextureTransform = {};\r\n let transformIsRequired = false;\r\n\r\n if (babylonTexture.uOffset !== 0 || babylonTexture.vOffset !== 0) {\r\n textureTransform.offset = [babylonTexture.uOffset, babylonTexture.vOffset];\r\n transformIsRequired = true;\r\n }\r\n\r\n if (babylonTexture.uScale !== 1 || babylonTexture.vScale !== 1) {\r\n textureTransform.scale = [babylonTexture.uScale, babylonTexture.vScale];\r\n transformIsRequired = true;\r\n }\r\n\r\n if (babylonTexture.wAng !== 0) {\r\n if (babylonTexture.uRotationCenter !== 0 || babylonTexture.vRotationCenter !== 0) {\r\n // See https://github.com/mrdoob/three.js/issues/15831 for more details.\r\n if (babylonTexture.homogeneousRotationInUVTransform && babylonTexture.uScale !== babylonTexture.vScale) {\r\n Tools.Warn(\r\n `${context}: Texture ${babylonTexture.name} with homogenousRotationInUVTransform, non-uniform scaling, and non-zero rotation cannot be exported with ${NAME}.`\r\n );\r\n return;\r\n }\r\n Tools.Warn(`${context}: Texture ${babylonTexture.name} with non-origin rotation center will be exported using an adjusted offset with ${NAME}.`);\r\n textureTransform.offset = AdjustOffsetForRotationCenter(babylonTexture);\r\n }\r\n textureTransform.rotation = -babylonTexture.wAng;\r\n transformIsRequired = true;\r\n }\r\n\r\n if (babylonTexture.coordinatesIndex !== 0) {\r\n textureTransform.texCoord = babylonTexture.coordinatesIndex;\r\n transformIsRequired = true;\r\n }\r\n\r\n if (!transformIsRequired) {\r\n return;\r\n }\r\n\r\n this._wasUsed = true;\r\n if (!textureInfo.extensions) {\r\n textureInfo.extensions = {};\r\n }\r\n textureInfo.extensions[NAME] = textureTransform;\r\n }\r\n}\r\n\r\nGLTFExporter.RegisterExtension(NAME, () => new KHR_texture_transform());\r\n","/* eslint-disable import/no-internal-modules */\r\nimport * as Exporters from \"serializers/glTF/glTFFileExporter\";\r\nimport * as Datas from \"serializers/glTF/2.0/glTFData\";\r\nimport * as Serializers from \"serializers/glTF/2.0/glTFSerializer\";\r\nimport * as Extensions from \"serializers/glTF/2.0/Extensions/index\";\r\nimport * as GLTF2 from \"serializers/glTF/2.0/index\";\r\n\r\n/**\r\n * This is the entry point for the UMD module.\r\n * The entry point for a future ESM package should be index.ts\r\n */\r\nconst globalObject = typeof global !== \"undefined\" ? global : typeof window !== \"undefined\" ? window : undefined;\r\nif (typeof globalObject !== \"undefined\") {\r\n (<any>globalObject).BABYLON = (<any>globalObject).BABYLON || {};\r\n const BABYLON = (<any>globalObject).BABYLON;\r\n BABYLON.GLTF2 = BABYLON.GLTF2 || {};\r\n BABYLON.GLTF2.Exporter = BABYLON.GLTF2.Exporter || {};\r\n BABYLON.GLTF2.Exporter.Extensions = BABYLON.GLTF2.Exporter.Extensions || {};\r\n\r\n const keys = [];\r\n for (const key in Exporters) {\r\n BABYLON[key] = (<any>Exporters)[key];\r\n keys.push(key);\r\n }\r\n for (const key in Datas) {\r\n BABYLON[key] = (<any>Datas)[key];\r\n keys.push(key);\r\n }\r\n for (const key in Serializers) {\r\n BABYLON[key] = (<any>Serializers)[key];\r\n keys.push(key);\r\n }\r\n\r\n for (const key in Extensions) {\r\n BABYLON.GLTF2.Exporter.Extensions[key] = (<any>Extensions)[key];\r\n keys.push(key);\r\n }\r\n\r\n for (const key in GLTF2) {\r\n // Prevent Reassignment.\r\n if (keys.indexOf(key) > -1) {\r\n continue;\r\n }\r\n\r\n BABYLON.GLTF2.Exporter[key] = (<any>GLTF2)[key];\r\n }\r\n}\r\n\r\nexport * from \"serializers/glTF/glTFFileExporter\";\r\nexport * from \"serializers/glTF/2.0/index\";\r\n","import * as serializers from \"@lts/serializers/legacy/legacy-glTF2Serializer\";\r\nexport { serializers };\r\nexport default serializers;\r\n"],"names":["root","factory","exports","module","require","define","amd","self","global","this","__WEBPACK_EXTERNAL_MODULE__597__","leafPrototypes","getProto","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","undefined","__webpack_modules__","Object","getPrototypeOf","obj","t","value","mode","__esModule","then","ns","create","r","def","current","indexOf","getOwnPropertyNames","forEach","key","d","definition","o","defineProperty","enumerable","get","g","globalThis","Function","e","window","prop","prototype","hasOwnProperty","call","Symbol","toStringTag","__IGLTFExporterExtension","files","downloadFiles","blob","Blob","type","GetMimeType","Tools","Download","__assign","assign","s","i","n","arguments","length","p","apply","__awaiter","thisArg","_arguments","P","generator","Promise","resolve","reject","fulfilled","step","next","rejected","result","done","__generator","body","f","y","_","label","sent","trys","ops","Iterator","verb","iterator","v","op","TypeError","pop","push","__spreadArray","to","from","pack","ar","l","Array","slice","concat","SuppressedError","Epsilon","DielectricSpecular","Color3","MaxSpecularPower","White","Black","_SolveMetallic","diffuse","specular","oneMinusSpecularStrength","a","b","Scalar","Clamp","Math","sqrt","_ConvertToGLTFPBRMetallicRoughness","babylonStandardMaterial","diffuseColor","toLinearSpace","getScene","getEngine","useExactSrgbConversions","scale","opacity","alpha","specularPower","roughness","SpecularPowerToRoughness","baseColorFactor","metallicFactor","roughnessFactor","SetAlphaMode","glTFMaterial","babylonMaterial","needAlphaBlending","alphaMode","needAlphaTesting","alphaCutoff","alphaCutOff","CreateWhiteTexture","width","height","scene","data","Uint8Array","RawTexture","CreateRGBATexture","ConvertPixelArrayToFloat32","pixels","buffer","Float32Array","Error","_exporter","_textureMap","Map","_internalTextureToImage","getTextureInfo","babylonTexture","exportStandardMaterialAsync","mimeType","hasUVs","pbrMetallicRoughness","material","name","backFaceCulling","twoSidedLighting","Warn","doubleSided","promises","diffuseTexture","exportTextureAsync","textureInfo","baseColorTexture","bumpTexture","normalTexture","level","emissiveTexture","emissiveFactor","ambientTexture","occlusionTexture","index","_materialNeedsUVsSet","add","all","opacityTexture","Constants","ALPHA_COMBINE","toString","emissiveColor","equalsWithEpsilon","asArray","_finishMaterialAsync","materials","_materials","textures","_extensionsPostExportMaterialAdditionalTextures","texture","_extensionsPostExportMaterialAsync","_getImageDataAsync","textureType","TEXTURETYPE_UNSIGNED_BYTE","hostingScene","_babylonScene","engine","tempTexture","createRawTexture","TEXTUREFORMAT_RGBA","Texture","NEAREST_SAMPLINGMODE","isWebGPU","TextureTools","ApplyPostProcess","TEXTURE_NEAREST_SAMPLINGMODE","_readTexturePixels","DumpTools","DumpDataAsync","_resizeTexturesToSameDimensions","texture1","texture2","resizedTexture1","resizedTexture2","texture1Size","getSize","texture2Size","CreateResizedCopy","_convertSpecularGlossinessTexturesToMetallicRoughnessAsync","specularGlossinessTexture","factors","resizedTextures","diffuseSize","diffuseBuffer","specularGlossinessBuffer","readPixels","diffusePixels","specularPixels","byteLength","metallicRoughnessBuffer","baseColorBuffer","maxBaseColor","maxMetallic","maxRoughness","h","w","offset","multiply","specularColor","glossiness","specularGlossiness","metallicRoughness","_convertSpecularGlossinessToMetallicRoughness","max","baseColor","metallic","hasAlpha","writeOutMetallicRoughnessTexture","writeOutBaseColorTexture","destinationOffset","linearBaseColorPixel","FromInts","sRGBBaseColorPixel","toGammaSpace","metallicRoughnessTextureData","baseColorTextureData","diffusePerceivedBrightness","_getPerceivedBrightness","specularPerceivedBrightness","_getMaxComponent","baseColorFromDiffuse","baseColorFromSpecular","subtract","Lerp","clampToRef","color","_convertMetalRoughFactorsToMetallicRoughnessAsync","babylonPBRMaterial","glTFPbrMetallicRoughness","_albedoColor","_metallic","_roughness","_albedoTexture","glTFTexture","metallicTexture","_metallicTexture","metallicRoughnessTexture","_getTextureSampler","sampler","wrapS","_getGLTFTextureWrapMode","wrapU","wrapT","wrapV","samplingMode","LINEAR_LINEAR","magFilter","minFilter","LINEAR_NEAREST","NEAREST_LINEAR","NEAREST_LINEAR_MIPLINEAR","NEAREST_NEAREST","NEAREST_LINEAR_MIPNEAREST","LINEAR_NEAREST_MIPNEAREST","LINEAR_NEAREST_MIPLINEAR","NEAREST_NEAREST_MIPLINEAR","LINEAR_LINEAR_MIPLINEAR","LINEAR_LINEAR_MIPNEAREST","NEAREST_NEAREST_MIPNEAREST","wrapMode","WRAP_ADDRESSMODE","CLAMP_ADDRESSMODE","MIRROR_ADDRESSMODE","_convertSpecGlossFactorsToMetallicRoughnessAsync","specGloss","_reflectivityColor","_microSurface","albedoTexture","reflectivityTexture","_reflectivityTexture","useMicrosurfaceFromReflectivityMapAlpha","_useMicroSurfaceFromReflectivityMapAlpha","samplerIndex","_exportTextureSampler","metallicRoughnessFactors","_textures","imageIndex","_exportImage","_exportTextureInfo","coordinatesIndex","exportPBRMaterialAsync","useMetallicRoughness","isMetallicWorkflow","albedoColor","_setMetallicRoughnessPbrMaterialAsync","WithinEpsilon","_twoSidedLighting","_bumpTexture","_ambientTexture","texCoord","extensions","ambientTextureStrength","_ambientTextureStrength","strength","_emissiveTexture","_emissiveColor","_getPixelsFromTextureAsync","format","TEXTUREFORMAT_COMPRESSED_RGBA_BPTC_UNORM","TEXTUREFORMAT_COMPRESSED_SRGB_ALPHA_BPTC_UNORM","TEXTUREFORMAT_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT","TEXTUREFORMAT_COMPRESSED_RGB_BPTC_SIGNED_FLOAT","TEXTUREFORMAT_COMPRESSED_RGBA_S3TC_DXT5","TEXTUREFORMAT_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT","TEXTUREFORMAT_COMPRESSED_RGBA_S3TC_DXT3","TEXTUREFORMAT_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT","TEXTUREFORMAT_COMPRESSED_RGBA_S3TC_DXT1","TEXTUREFORMAT_COMPRESSED_RGB_S3TC_DXT1","TEXTUREFORMAT_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT","TEXTUREFORMAT_COMPRESSED_SRGB_S3TC_DXT1_EXT","TEXTUREFORMAT_COMPRESSED_RGBA_ASTC_4x4","TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR","TEXTUREFORMAT_COMPRESSED_RGB_ETC1_WEBGL","TEXTUREFORMAT_COMPRESSED_RGB8_ETC2","TEXTUREFORMAT_COMPRESSED_SRGB8_ETC2","TEXTUREFORMAT_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2","TEXTUREFORMAT_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2","TEXTUREFORMAT_COMPRESSED_RGBA8_ETC2_EAC","TEXTUREFORMAT_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC","IsCompressedTextureFormat","textureFormat","GetTextureDataAsync","_texture","extensionPromise","_extensionsPreExportTextureAsync","_exportTextureInfoAsync","textureMimeType","internalTextureToImage","internalTextureUniqueId","getInternalTexture","uniqueId","imageIndexPromise","set","_extensionsPostExportTextures","image","images","_images","_shouldUseGlb","bufferView","_bufferManager","createBufferView","setBufferView","baseName","replace","extension","GetFileExtensionFromMimeType","some","uri","RandomId","_imageData","textureIndex","findIndex","source","samplers","_samplers","ConvertHandednessMatrix","Matrix","Compose","Vector3","Quaternion","Identity","Zero","DefaultTranslation","DefaultScale","One","GetVertexBufferInfo","vertexBuffer","meshes","byteOffset","byteStride","normalized","componentCount","totalVertices","reduce","getTotalVertices","Number","MAX_VALUE","count","kind","getKind","GetAccessorElementCount","accessorType","IsStandardVertexAttribute","VertexBuffer","PositionKind","NormalKind","TangentKind","ColorKind","MatricesIndicesKind","MatricesIndicesExtraKind","MatricesWeightsKind","MatricesWeightsExtraKind","UVKind","UV2Kind","UV3Kind","UV4Kind","UV5Kind","UV6Kind","GetPrimitiveMode","fillMode","Material","TriangleFillMode","TriangleStripDrawMode","TriangleFanDrawMode","PointListDrawMode","PointFillMode","LineLoopDrawMode","LineListDrawMode","LineStripDrawMode","NormalizeTangent","tangent","x","z","ConvertToRightHandedPosition","ConvertToRightHandedRotation","absX","abs","absY","sign","absZ","absW","ConvertCameraRotationToGLTF","rotation","copyFromFloats","IsParentAddedByImporter","babylonNode","parentBabylonNode","TransformNode","getChildren","IsNoopNode","node","useRightHandedSystem","getWorldMatrix","isIdentity","multiplyToRef","TmpVectors","AbstractMesh","geometry","OmitDefaultValues","object","defaultValues","entries","defaultValue","isArray","AreArraysEqual","array1","array2","every","val","TypedArrayToWriteMethod","Int8Array","setInt8","dv","bo","setUint8","Uint8ClampedArray","Int16Array","setInt16","Uint16Array","setUint16","Int32Array","setInt32","Uint32Array","setUint32","setFloat32","Float64Array","setFloat64","_data","_dataView","DataView","_byteOffset","writeTypedArray","_checkGrowBuffer","setMethod","constructor","BYTES_PER_ELEMENT","getOutputData","writeUInt8","writeInt8","writeInt16","entry","writeUInt16","writeInt32","writeUInt32","writeFloat32","writeFloat64","newByteLength","newData","GetHighestByteAlignment","_TangentType","_bufferViewToData","_bufferViewToProperties","_accessorToBufferView","generateBinary","bufferViews","totalByteLength","dataWriter","DataWriter","keys","sort","bufferViewIndex","getPropertiesWithBufferView","delete","createAccessor","componentType","minMax","_verifyBufferView","accessor","min","removeBufferView","bv","getBufferView","getData","has","_IsTransformable","Camera","Light","_CreateNodeAnimation","babylonTransformNode","animation","animationChannelTargetPath","useQuaternion","animationSampleRate","inputs","outputs","keyFrames","getKeys","minMaxKeyFrames","_GLTFAnimation","_CalculateMinMaxKeyFrames","interpolationOrBake","_DeduceInterpolation","interpolation","interpolationType","shouldBakeAnimation","_CreateBakedAnimation","framePerSecond","_CreateLinearOrStepAnimation","_CreateCubicSplineAnimation","samplerInterpolation","inputsMin","FloatRound","inputsMax","_DeduceAnimationInfo","dataAccessorType","property","targetProperty","split","_CreateNodeAnimationFromNodeAnimations","runtimeGLTFAnimation","idleGLTFAnimations","nodeMap","nodes","bufferManager","accessors","useRightHanded","shouldExportAnimation","glTFAnimation","animations","animationInfo","channels","_AddAnimation","hasRunningRuntimeAnimations","_CreateMorphTargetAnimationFromMorphTargetAnimations","Mesh","morphTargetManager","numTargets","getTarget","combinedAnimation","Animation","dataType","loopMode","enableBlending","combinedAnimationKeys","animationKeys","j","animationKey","k","frame","setKeys","_CreateNodeAndMorphAnimationFromAnimationGroups","babylonScene","glTFAnimations","leftHandedNodes","animationGroups","animationGroup","morphAnimations","sampleAnimations","morphAnimationMeshes","Set","animationGroupFrameDiff","targetAnimation","targetedAnimations","target","convertToRightHanded","MorphTarget","morphTargetManagers","find","babylonMesh","mesh","combinedAnimationGroup","sampleAnimationKeys","numAnimationKeys","morphTarget","animationsByMorphTarget","morphTargetAnimation","ANIMATIONTYPE_FLOAT","influence","inTangent","outTangent","morphAnimationChannels","keyframeAccessorIndex","dataAccessorIndex","animationSampler","animationChannel","animationData","currentInput","newInputs","shift","nodeIndex","inputData","output","outputToWrite","FromArrayToRef","toArray","FromEulerVectorToRef","IsIdentity","input","path","minFrame","maxFrame","fps","sampleRate","minMaxFrames","time","quaternionCache","previousTime","maxUsedFrame","currKeyFrame","nextKeyFrame","prevKeyFrame","endFrame","equals","state","repeatCount","_interpolate","_SetInterpolatedValue","_ConvertFactorToVector3OrQuaternion","factor","basePositionRotationOrScale","_GetBasePositionRotationOrScale","componentName","FromArray","normalize","cacheValue","RotationYawPitchRollToRef","keyFrame","_AddKeyframeValue","_AddSplineTangent","INTANGENT","OUTTANGENT","q","rotationQuaternion","position","scaling","newPositionRotationOrScale","animationType","ANIMATIONTYPE_VECTOR3","array","RotationYawPitchRoll","posRotScale","ANIMATIONTYPE_QUATERNION","tangentType","tangentValue","Infinity","BuildMorphTargetBuffers","attributes","flipX","difference","vertexCount","hasPositions","morphPositions","getPositions","originalPositions","getVerticesData","positionData","originalPosition","subtractToRef","floatSize","hasNormals","morphNormals","getNormals","originalNormals","normalData","originalNormal","hasTangents","morphTangents","getTangents","originalTangents","tangentData","originalTangent","morphTangent","hasColors","morphColors","getColors","originalColors","getVertexBuffer","componentSize","colorData","originalColor","difference4","Vector4","wasAddedByNoopNode","_indicesAccessorMap","_vertexBufferViewMap","_vertexAccessorMap","_remappedBufferView","_meshMorphTargetMap","_vertexMapColorAlpha","_exportedNodes","_meshMap","convertedToRightHandedBuffers","getIndicesAccessor","indices","start","flip","setIndicesAccessor","accessorIndex","map1","map2","map3","map4","pushExportedNode","getNodesSet","getVertexBufferView","setVertexBufferView","setRemappedBufferView","getRemappedBufferView","getVertexAccessor","setVertexAccessor","hasVertexColorAlpha","setHasVertexColorAlpha","getMesh","setMesh","meshIndex","bindMorphDataToMesh","morphData","morphTargets","getMorphTargetsFromMesh","options","EngineStore","LastCreatedScene","_glTF","asset","Engine","Version","version","_animations","_accessors","_bufferViews","_cameras","_meshes","_nodes","_scenes","_skins","_materialExporter","GLTFMaterialExporter","_extensions","BufferManager","_shouldExportNodeMap","_nodeMap","_materialMap","_camerasMap","_nodesCameraMap","_skinMap","_nodesSkinMap","_options","shouldExportNode","metadataSelector","metadata","gltf","extras","exportWithoutWaitingForScene","exportUnusedUVs","removeNoopRootNodes","includeCoordinateSystemConversionNodes","meshCompressionMethod","_loadExtensions","_ApplyExtension","actionAsync","currentPromise","newNode","_ApplyExtensions","GLTFExporter","_ExtensionNames","context","preExportTextureAsync","_extensionsPostExportNodeAsync","postExportNodeAsync","postExportMaterialAsync","postExportMaterialAdditionalTextures","postExportTexture","_extensionsPostExportMeshPrimitive","primitive","postExportMeshPrimitive","_extensionsPreGenerateBinaryAsync","preGenerateBinaryAsync","_forEachExtensions","action","enabled","_extensionsOnExporting","wasUsed","extensionsUsed","required","extensionsRequired","onExporting","_ExtensionFactories","dispose","RegisterExtension","UnregisterExtension","splice","_generateJSON","bufferByteLength","fileName","prettyPrint","buffers","scenes","cameras","skins","JSON","stringify","generateGLTFAsync","glTFPrefix","_generateBinaryAsync","binaryBuffer","jsonText","bin","glTFFileName","glTFBinFile","container","GLTFData","_exportSceneAsync","_getPadding","num","remainder","generateGLBAsync","glbFileName","jsonLength","TextEncoder","encoder","encodedJsonText","encode","jsonPadding","binPadding","headerLength","headerBuffer","ArrayBuffer","headerBufferView","jsonChunkBuffer","jsonChunkBufferView","jsonData","blankCharCode","charCodeAt","charCode","codePointAt","jsonPaddingView","binaryChunkBuffer","binaryChunkBufferView","binPaddingBuffer","binPaddingView","glbFile","_setNodeTransformation","getPivotPoint","equalsToFloats","translation","copyFrom","FromEulerAngles","multiplyInPlace","_setCameraTransformation","babylonCamera","parent","parentWorldMatrix","Invert","decompose","_listAvailableCameras","camera","glTFCamera","PERSPECTIVE_CAMERA","perspective","aspectRatio","getAspectRatio","yfov","fovMode","FOVMODE_VERTICAL_FIXED","fov","znear","minZ","zfar","maxZ","halfWidth","orthoLeft","orthoRight","getRenderWidth","halfHeight","orthoBottom","orthoTop","getRenderHeight","orthographic","xmag","ymag","_exportAndAssignCameras","values","gltfCamera","usedNodes","_listAvailableSkeletons","skeletons","skeleton","bones","joints","_exportAndAssignSkeletons","skin","boneIndexMap","inverseBindMatrices","maxBoneIndex","bone","boneIndex","getIndex","getAbsoluteInverseBindMatrix","transformNode","getTransformNode","nodeID","skinedNodes","mat","m","rootNodesRH","rootNodesLH","rootNoopNodesRH","rootNodes","rootNode","stateLH","ExporterState","_exportNodesAsync","stateRH","noopRH","_animationSampleRate","_shouldExportNode","babylonRootNodes","_exportBuffers","_exportNodeAsync","_collectBuffers","bufferToVertexBuffersMap","vertexBufferToMeshesMap","morphTargetsToMeshesMap","vertexBuffers","getVertexBuffers","hasVertexAlpha","_buffer","vertexBufferArray","morphIndex","babylonChildNode","morphTargetsMeshesMap","bytes","floatData","isView","DataArrayToUint8Array","EnumerateFloatValues","invLength","stdMaterialCount","filter","StandardMaterial","Logger","UNSIGNED_BYTE","Color4","fromArray","toLinearSpaceToRef","floatMatricesIndices","FLOAT","getFloatData","size","is16Bit","newArray","glTFMorphTarget","parentNodeChildren","includes","_createNodeAsync","idleGLTFAnimation","children","InstancedMesh","sourceMesh","subMeshes","_exportMeshAsync","parentNodeIndex","parentNode","RotateNode180Y","_exportIndices","is32Bits","sideOrientation","indicesToExport","invertedMaterial","CounterClockWiseSideOrientation","flipWhenInvertedMaterial","IsTriangleFillMode","newIndices","subarray","IndicesArrayToTypedArray","_exportVertexBuffer","startsWith","fill","GetMinMax","isFloatMatricesIndices","vertexBufferType","vertexBufferNormalized","GetAccessorType","GetAttributeType","_exportMaterialAsync","subMesh","materialIndex","MultiMaterial","subMaterials","PBRMaterial","getClassName","primitives","isUnIndexed","getIndices","isLinesMesh","LinesMesh","isGreasedLineMesh","GreasedLineBaseMesh","getMaterial","defaultMaterial","babylonLinesMesh","colorWhite","greasedLineMaterial","overrideRenderingFillMode","_getEffectiveOrientation","AreIndices32Bits","indexCount","indexStart","verticesStart","verticesCount","targets","gltfMorphTarget","weights","targetNames","GLTFAsync","whenReadyAsync","exporter","GLBAsync","NAME","_wasUsed","hasThinInstances","noTranslation","noRotation","noScale","matrix","thinInstanceGetWorldMatrices","iwt","iwr","iws","hasAnyInstanceWorldTranslation","hasAnyInstanceWorldRotation","hasAnyInstanceWorldScale","translationBuffer","thinInstanceCount","rotationBuffer","scaleBuffer","_buildAccessor","EXT_mesh_gpu_instancing","_bufferViewsUsed","_accessorsUsed","_encodePromises","DracoEncoder","DefaultAvailable","primitiveBufferViews","primitiveAccessors","glTFName","GetTypedArrayData","GetTypeByteLength","dracoName","method","promise","Default","_encodeAsync","encodedData","dracoInfo","attributeIds","catch","error","clear","KHR_draco_mesh_compression","DEFAULTS","intensity","range","SPOTDEFAULTS","innerConeAngle","outerConeAngle","PI","LIGHTDIRECTION","Backward","_lights","ShadowLight","lightType","getTypeID","LIGHTTYPEID_POINTLIGHT","LIGHTTYPEID_DIRECTIONALLIGHT","LIGHTTYPEID_SPOTLIGHT","falloffType","FALLOFF_GLTF","direction","normalizeToRef","angle","acos","Dot","axis","Cross","lightRotationQuaternion","RotationAxisToRef","light","babylonSpotLight","spot","innerAngle","lights","lightReference","parentTranslation","parentRotation","parentScale","parentMatrix","ComposeToRef","CollapseParentNode","KHR_lights_punctual","additionalTextures","PBRBaseMaterial","anisotropy","isEnabled","legacy","anisotropyTextureInfo","anisotropyInfo","anisotropyStrength","anisotropyRotation","anisotropyTexture","KHR_materials_anisotropy","clearCoat","useRoughnessFromMainTexture","textureRoughness","clearCoatTextureRoughnessInfo","clearCoatTextureInfo","isTintEnabled","remapF0OnInterfaceChange","clearCoatNormalTextureInfo","clearCoatInfo","clearcoatFactor","clearcoatTexture","clearcoatRoughnessFactor","clearcoatRoughnessTexture","clearcoatNormalTexture","KHR_materials_clearcoat","GetTranslucencyIntensityTexture","subs","subSurface","translucencyIntensityTexture","thicknessTexture","useMaskFromThicknessTexture","useGltfStyleTextures","_isExtensionEnabled","translucencyColorTexture","unlit","isTranslucencyEnabled","useAlbedoToTintTranslucency","volumeIndexOfRefraction","minimumThickness","maximumThickness","diffuseTransmissionFactor","translucencyIntensity","diffuseTransmissionTexture","diffuseTransmissionColorFactor","translucencyColor","equalsFloats","diffuseTransmissionColorTexture","diffuseTransmissionInfo","KHR_materials_diffuse_transmission","isRefractionEnabled","isDispersionEnabled","dispersionInfo","dispersion","KHR_materials_dispersion","tempEmissiveStrength","emissiveStrengthInfo","emissiveStrength","newEmissiveFactor","KHR_materials_emissive_strength","indexOfRefraction","iorInfo","ior","KHR_materials_ior","iridescence","iridescenceTextureInfo","iridescenceThicknessTextureInfo","iridescenceInfo","iridescenceFactor","iridescenceIor","iridescenceThicknessMinimum","iridescenceThicknessMaximum","iridescenceTexture","iridescenceThicknessTexture","KHR_materials_iridescence","sheen","sheenInfo","sheenColorFactor","sheenRoughnessFactor","sheenColorTexture","sheenRoughnessTexture","KHR_materials_sheen","metallicReflectanceTexture","reflectanceTexture","metallicF0Factor","metallicReflectanceColor","_hasTexturesExtension","specularInfo","specularFactor","specularTexture","specularColorFactor","specularColorTexture","KHR_materials_specular","refractionIntensity","refractionIntensityTexture","transmissionFactor","volumeInfo","transmissionTexture","KHR_materials_transmission","unlitMaterial","disableLighting","KHR_materials_unlit","tintColorAtDistance","POSITIVE_INFINITY","tintColor","thicknessFactor","attenuationDistance","attenuationColor","KHR_materials_volume","_baseDiffuseRoughness","_baseDiffuseRoughnessTexture","diffuseRoughnessTextureInfo","diffuseRoughnessInfo","diffuseRoughnessFactor","diffuseRoughnessTexture","EXT_materials_diffuse_roughness","uAng","vAng","uRotationCenter","vRotationCenter","textureTransform","transformIsRequired","uOffset","vOffset","uScale","vScale","wAng","homogeneousRotationInUVTransform","cosAngle","cos","sinAngle","sin","scaledURotationCenter","scaledVRotationCenter","AdjustOffsetForRotationCenter","KHR_texture_transform","globalObject","BABYLON","GLTF2","Exporter","Extensions"],"sourceRoot":""}
|