{"version":3,"file":"babylonjs.serializers.min.js","mappings":"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","sources":["webpack://SERIALIZERS/webpack/universalModuleDefinition","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/../../../lts/serializers/generated/glTF/2.0/glTFAnimation.ts","webpack://SERIALIZERS/../../../lts/serializers/generated/OBJ/objSerializer.ts","webpack://SERIALIZERS/../../../lts/serializers/generated/glTF/glTFFileExporter.ts","webpack://SERIALIZERS/../../../lts/serializers/generated/glTF/2.0/glTFUtilities.ts","webpack://SERIALIZERS/../../../lts/serializers/generated/glTF/2.0/glTFData.ts","webpack://SERIALIZERS/../../../../node_modules/tslib/tslib.es6.js","webpack://SERIALIZERS/../../../lts/serializers/generated/glTF/2.0/glTFMaterialExporter.ts","webpack://SERIALIZERS/../../../lts/serializers/generated/glTF/2.0/glTFExporter.ts","webpack://SERIALIZERS/../../../lts/serializers/generated/glTF/2.0/glTFExporterExtension.ts","webpack://SERIALIZERS/../../../lts/serializers/generated/glTF/2.0/glTFSerializer.ts","webpack://SERIALIZERS/../../../lts/serializers/generated/glTF/2.0/shaders/textureTransform.fragment.ts","webpack://SERIALIZERS/../../../lts/serializers/generated/glTF/2.0/Extensions/KHR_texture_transform.ts","webpack://SERIALIZERS/../../../lts/serializers/generated/glTF/2.0/Extensions/KHR_lights_punctual.ts","webpack://SERIALIZERS/../../../lts/serializers/generated/glTF/2.0/Extensions/KHR_materials_clearcoat.ts","webpack://SERIALIZERS/../../../lts/serializers/generated/glTF/2.0/Extensions/KHR_materials_iridescence.ts","webpack://SERIALIZERS/../../../lts/serializers/generated/glTF/2.0/Extensions/KHR_materials_sheen.ts","webpack://SERIALIZERS/../../../lts/serializers/generated/glTF/2.0/Extensions/KHR_materials_unlit.ts","webpack://SERIALIZERS/../../../lts/serializers/generated/glTF/2.0/Extensions/KHR_materials_ior.ts","webpack://SERIALIZERS/../../../lts/serializers/generated/glTF/2.0/Extensions/KHR_materials_specular.ts","webpack://SERIALIZERS/../../../lts/serializers/generated/glTF/2.0/Extensions/KHR_materials_volume.ts","webpack://SERIALIZERS/../../../lts/serializers/generated/glTF/2.0/Extensions/KHR_materials_transmission.ts","webpack://SERIALIZERS/../../../lts/serializers/generated/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.ts","webpack://SERIALIZERS/../../../lts/serializers/generated/stl/stlSerializer.ts","webpack://SERIALIZERS/../../../lts/serializers/generated/legacy/legacy-glTF2Serializer.ts","webpack://SERIALIZERS/../../../lts/serializers/generated/legacy/legacy-objSerializer.ts","webpack://SERIALIZERS/../../../lts/serializers/generated/legacy/legacy-stlSerializer.ts","webpack://SERIALIZERS/./src/index.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__520__) => {\nreturn ","module.exports = __WEBPACK_EXTERNAL_MODULE__520__;","// 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};","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 { _BinaryWriter } from \"./glTFExporter\";\r\nimport { _GLTFUtilities } from \"./glTFUtilities\";\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\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 convertToRightHandedSystem - Specifies if the values should be converted to right-handed.\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 convertToRightHandedSystem: boolean,\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 const frameDelta = minMaxKeyFrames.max - minMaxKeyFrames.min;\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 convertToRightHandedSystem,\r\n useQuaternion\r\n );\r\n } else {\r\n if (interpolation === AnimationSamplerInterpolation.LINEAR || interpolation === AnimationSamplerInterpolation.STEP) {\r\n _GLTFAnimation._CreateLinearOrStepAnimation(\r\n babylonTransformNode,\r\n animation,\r\n animationChannelTargetPath,\r\n frameDelta,\r\n inputs,\r\n outputs,\r\n convertToRightHandedSystem,\r\n useQuaternion\r\n );\r\n } else if (interpolation === AnimationSamplerInterpolation.CUBICSPLINE) {\r\n _GLTFAnimation._CreateCubicSplineAnimation(\r\n babylonTransformNode,\r\n animation,\r\n animationChannelTargetPath,\r\n frameDelta,\r\n inputs,\r\n outputs,\r\n convertToRightHandedSystem,\r\n useQuaternion\r\n );\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 convertToRightHandedSystem,\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 = 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 binaryWriter\r\n * @param bufferViews\r\n * @param accessors\r\n * @param convertToRightHandedSystem\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: { [key: number]: number },\r\n nodes: INode[],\r\n binaryWriter: _BinaryWriter,\r\n bufferViews: IBufferView[],\r\n accessors: IAccessor[],\r\n convertToRightHandedSystem: boolean,\r\n animationSampleRate: number\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 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 binaryWriter,\r\n bufferViews,\r\n accessors,\r\n convertToRightHandedSystem,\r\n animationInfo.useQuaternion,\r\n animationSampleRate\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 binaryWriter\r\n * @param bufferViews\r\n * @param accessors\r\n * @param convertToRightHandedSystem\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: { [key: number]: number },\r\n nodes: INode[],\r\n binaryWriter: _BinaryWriter,\r\n bufferViews: IBufferView[],\r\n accessors: IAccessor[],\r\n convertToRightHandedSystem: boolean,\r\n animationSampleRate: number\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 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 binaryWriter,\r\n bufferViews,\r\n accessors,\r\n convertToRightHandedSystem,\r\n animationInfo.useQuaternion,\r\n animationSampleRate,\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 * @ignore\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 binaryWriter\r\n * @param bufferViews\r\n * @param accessors\r\n * @param convertToRightHandedSystemMap\r\n * @param animationSampleRate\r\n */\r\n public static _CreateNodeAndMorphAnimationFromAnimationGroups(\r\n babylonScene: Scene,\r\n glTFAnimations: IAnimation[],\r\n nodeMap: { [key: number]: number },\r\n nodes: INode[],\r\n binaryWriter: _BinaryWriter,\r\n bufferViews: IBufferView[],\r\n accessors: IAccessor[],\r\n convertToRightHandedSystemMap: { [nodeId: number]: boolean },\r\n animationSampleRate: number\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> = new Map();\r\n const sampleAnimations: Map = new Map();\r\n const morphAnimationMeshes: Set = 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 (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 const convertToRightHandedSystem = convertToRightHandedSystemMap[babylonTransformNode.uniqueId];\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 binaryWriter,\r\n bufferViews,\r\n accessors,\r\n convertToRightHandedSystem,\r\n animationInfo.useQuaternion,\r\n animationSampleRate\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 as MorphTarget) : (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 = 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 binaryWriter,\r\n bufferViews,\r\n accessors,\r\n false,\r\n animationInfo.useQuaternion,\r\n animationSampleRate,\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: { [key: number]: number },\r\n binaryWriter: _BinaryWriter,\r\n bufferViews: IBufferView[],\r\n accessors: IAccessor[],\r\n convertToRightHandedSystem: boolean,\r\n useQuaternion: boolean,\r\n animationSampleRate: number,\r\n morphAnimationChannels?: number\r\n ) {\r\n const animationData = _GLTFAnimation._CreateNodeAnimation(\r\n babylonTransformNode,\r\n animation,\r\n animationChannelTargetPath,\r\n convertToRightHandedSystem,\r\n useQuaternion,\r\n animationSampleRate\r\n );\r\n let bufferView: IBufferView;\r\n let accessor: IAccessor;\r\n let keyframeAccessorIndex: number;\r\n let dataAccessorIndex: number;\r\n let outputLength: 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[babylonTransformNode.uniqueId];\r\n\r\n // Creates buffer view and accessor for key frames.\r\n let byteLength = animationData.inputs.length * 4;\r\n bufferView = _GLTFUtilities._CreateBufferView(0, binaryWriter.getByteOffset(), byteLength, undefined, `${name} keyframe data view`);\r\n bufferViews.push(bufferView);\r\n animationData.inputs.forEach(function (input) {\r\n binaryWriter.setFloat32(input);\r\n });\r\n\r\n accessor = _GLTFUtilities._CreateAccessor(\r\n bufferViews.length - 1,\r\n `${name} keyframes`,\r\n AccessorType.SCALAR,\r\n AccessorComponentType.FLOAT,\r\n animationData.inputs.length,\r\n null,\r\n [animationData.inputsMin],\r\n [animationData.inputsMax]\r\n );\r\n accessors.push(accessor);\r\n keyframeAccessorIndex = accessors.length - 1;\r\n\r\n // create bufferview and accessor for keyed values.\r\n outputLength = animationData.outputs.length;\r\n byteLength = _GLTFUtilities._GetDataAccessorElementCount(dataAccessorType) * 4 * animationData.outputs.length;\r\n\r\n // check for in and out tangents\r\n bufferView = _GLTFUtilities._CreateBufferView(0, binaryWriter.getByteOffset(), byteLength, undefined, `${name} data view`);\r\n bufferViews.push(bufferView);\r\n\r\n animationData.outputs.forEach(function (output) {\r\n output.forEach(function (entry) {\r\n binaryWriter.setFloat32(entry);\r\n });\r\n });\r\n\r\n accessor = _GLTFUtilities._CreateAccessor(bufferViews.length - 1, `${name} data`, dataAccessorType, AccessorComponentType.FLOAT, outputLength, null, null, null);\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 convertToRightHandedSystem converts the values to right-handed\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 convertToRightHandedSystem: boolean,\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 = null;\r\n let time: number;\r\n let maxUsedFrame: Nullable = null;\r\n let currKeyFrame: Nullable = null;\r\n let nextKeyFrame: Nullable = null;\r\n let prevKeyFrame: Nullable = null;\r\n let endFrame: Nullable = 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(\r\n babylonTransformNode,\r\n value,\r\n time,\r\n animation,\r\n animationChannelTargetPath,\r\n quaternionCache,\r\n inputs,\r\n outputs,\r\n convertToRightHandedSystem,\r\n useQuaternion\r\n );\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 animationType: number,\r\n animationChannelTargetPath: AnimationChannelTargetPath,\r\n convertToRightHandedSystem: boolean,\r\n useQuaternion: boolean\r\n ): Nullable {\r\n let property: string[];\r\n let componentName: string;\r\n let value: Nullable = null;\r\n const basePositionRotationOrScale = _GLTFAnimation._GetBasePositionRotationOrScale(\r\n babylonTransformNode,\r\n animationChannelTargetPath,\r\n convertToRightHandedSystem,\r\n useQuaternion\r\n );\r\n if (animationType === Animation.ANIMATIONTYPE_FLOAT) {\r\n // handles single component x, y, z or w component animation by using a base property and animating over a component.\r\n property = animation.targetProperty.split(\".\");\r\n componentName = property ? property[1] : \"\"; // x, y, or z component\r\n value = useQuaternion ? Quaternion.FromArray(basePositionRotationOrScale).normalize() : Vector3.FromArray(basePositionRotationOrScale);\r\n\r\n switch (componentName) {\r\n case \"x\": {\r\n value[componentName] = convertToRightHandedSystem && useQuaternion && animationChannelTargetPath !== AnimationChannelTargetPath.SCALE ? -factor : factor;\r\n break;\r\n }\r\n case \"y\": {\r\n value[componentName] = convertToRightHandedSystem && useQuaternion && animationChannelTargetPath !== AnimationChannelTargetPath.SCALE ? -factor : factor;\r\n break;\r\n }\r\n case \"z\": {\r\n value[componentName] = convertToRightHandedSystem && !useQuaternion && animationChannelTargetPath !== AnimationChannelTargetPath.SCALE ? -factor : 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 type \"${componentName}\" for scale animation!`);\r\n }\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: Nullable,\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 convertToRightHandedSystem: boolean,\r\n useQuaternion: boolean\r\n ) {\r\n const animationType = animation.dataType;\r\n let cacheValue: Vector3 | Quaternion | number;\r\n inputs.push(time);\r\n\r\n if (value) {\r\n if (animationChannelTargetPath === AnimationChannelTargetPath.WEIGHTS) {\r\n outputs.push([value as number]);\r\n return;\r\n }\r\n\r\n if (typeof value === \"number\") {\r\n value = this._ConvertFactorToVector3OrQuaternion(\r\n value as number,\r\n babylonTransformNode,\r\n animation,\r\n animationType,\r\n animationChannelTargetPath,\r\n convertToRightHandedSystem,\r\n useQuaternion\r\n );\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 if (convertToRightHandedSystem) {\r\n _GLTFUtilities._GetRightHandedQuaternionFromRef(quaternionCache);\r\n\r\n if (!babylonTransformNode.parent) {\r\n quaternionCache = Quaternion.FromArray([0, 1, 0, 0]).multiply(quaternionCache);\r\n }\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 if (convertToRightHandedSystem && animationChannelTargetPath !== AnimationChannelTargetPath.SCALE) {\r\n _GLTFUtilities._GetRightHandedPositionVector3FromRef(cacheValue);\r\n if (!babylonTransformNode.parent) {\r\n cacheValue.x *= -1;\r\n cacheValue.z *= -1;\r\n }\r\n }\r\n\r\n outputs.push(cacheValue.asArray());\r\n }\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 frameDelta The difference between the last and first frame of the animation\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 convertToRightHandedSystem Specifies if the position data should be converted to right handed\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 frameDelta: number,\r\n inputs: number[],\r\n outputs: number[][],\r\n convertToRightHandedSystem: boolean,\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, convertToRightHandedSystem, 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 frameDelta The difference between the last and first frame of the animation\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 convertToRightHandedSystem Specifies if the position data should be converted to right handed\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 frameDelta: number,\r\n inputs: number[],\r\n outputs: number[][],\r\n convertToRightHandedSystem: boolean,\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(\r\n babylonTransformNode,\r\n _TangentType.INTANGENT,\r\n outputs,\r\n animationChannelTargetPath,\r\n AnimationSamplerInterpolation.CUBICSPLINE,\r\n keyFrame,\r\n frameDelta,\r\n useQuaternion,\r\n convertToRightHandedSystem\r\n );\r\n _GLTFAnimation._AddKeyframeValue(keyFrame, animation, outputs, animationChannelTargetPath, babylonTransformNode, convertToRightHandedSystem, useQuaternion);\r\n\r\n _GLTFAnimation._AddSplineTangent(\r\n babylonTransformNode,\r\n _TangentType.OUTTANGENT,\r\n outputs,\r\n animationChannelTargetPath,\r\n AnimationSamplerInterpolation.CUBICSPLINE,\r\n keyFrame,\r\n frameDelta,\r\n useQuaternion,\r\n convertToRightHandedSystem\r\n );\r\n });\r\n }\r\n\r\n private static _GetBasePositionRotationOrScale(\r\n babylonTransformNode: Node,\r\n animationChannelTargetPath: AnimationChannelTargetPath,\r\n convertToRightHandedSystem: boolean,\r\n useQuaternion: boolean\r\n ) {\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 if (convertToRightHandedSystem) {\r\n _GLTFUtilities._GetRightHandedQuaternionArrayFromRef(basePositionRotationOrScale);\r\n if (!babylonTransformNode.parent) {\r\n basePositionRotationOrScale = Quaternion.FromArray([0, 1, 0, 0]).multiply(Quaternion.FromArray(basePositionRotationOrScale)).asArray();\r\n }\r\n }\r\n } else {\r\n const r: Vector3 = (babylonTransformNode as TransformNode).rotation;\r\n basePositionRotationOrScale = (r ?? Vector3.Zero()).asArray();\r\n _GLTFUtilities._GetRightHandedNormalArray3FromRef(basePositionRotationOrScale);\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 if (convertToRightHandedSystem) {\r\n _GLTFUtilities._GetRightHandedPositionArray3FromRef(basePositionRotationOrScale);\r\n }\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 convertToRightHandedSystem\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 convertToRightHandedSystem: boolean,\r\n useQuaternion: boolean\r\n ) {\r\n let value: number[];\r\n let newPositionRotationOrScale: Nullable;\r\n const animationType = animation.dataType;\r\n if (animationType === Animation.ANIMATIONTYPE_VECTOR3) {\r\n value = keyFrame.value.asArray();\r\n if (animationChannelTargetPath === AnimationChannelTargetPath.ROTATION) {\r\n const array = Vector3.FromArray(value);\r\n let rotationQuaternion = Quaternion.RotationYawPitchRoll(array.y, array.x, array.z);\r\n if (convertToRightHandedSystem) {\r\n _GLTFUtilities._GetRightHandedQuaternionFromRef(rotationQuaternion);\r\n\r\n if (!babylonTransformNode.parent) {\r\n rotationQuaternion = Quaternion.FromArray([0, 1, 0, 0]).multiply(rotationQuaternion);\r\n }\r\n }\r\n value = rotationQuaternion.asArray();\r\n } else if (animationChannelTargetPath === AnimationChannelTargetPath.TRANSLATION) {\r\n if (convertToRightHandedSystem) {\r\n _GLTFUtilities._GetRightHandedNormalArray3FromRef(value);\r\n if (!babylonTransformNode.parent) {\r\n value[0] *= -1;\r\n value[2] *= -1;\r\n }\r\n }\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 animationType,\r\n animationChannelTargetPath,\r\n convertToRightHandedSystem,\r\n useQuaternion\r\n );\r\n if (newPositionRotationOrScale) {\r\n if (animationChannelTargetPath === AnimationChannelTargetPath.ROTATION) {\r\n let posRotScale = useQuaternion\r\n ? (newPositionRotationOrScale as Quaternion)\r\n : Quaternion.RotationYawPitchRoll(newPositionRotationOrScale.y, newPositionRotationOrScale.x, newPositionRotationOrScale.z).normalize();\r\n if (convertToRightHandedSystem) {\r\n _GLTFUtilities._GetRightHandedQuaternionFromRef(posRotScale);\r\n\r\n if (!babylonTransformNode.parent) {\r\n posRotScale = Quaternion.FromArray([0, 1, 0, 0]).multiply(posRotScale);\r\n }\r\n }\r\n outputs.push(posRotScale.asArray());\r\n } else if (animationChannelTargetPath === AnimationChannelTargetPath.TRANSLATION) {\r\n if (convertToRightHandedSystem) {\r\n _GLTFUtilities._GetRightHandedNormalVector3FromRef(newPositionRotationOrScale as Vector3);\r\n\r\n if (!babylonTransformNode.parent) {\r\n newPositionRotationOrScale.x *= -1;\r\n newPositionRotationOrScale.z *= -1;\r\n }\r\n }\r\n }\r\n outputs.push(newPositionRotationOrScale.asArray());\r\n }\r\n }\r\n } else if (animationType === Animation.ANIMATIONTYPE_QUATERNION) {\r\n value = (keyFrame.value as Quaternion).normalize().asArray();\r\n\r\n if (convertToRightHandedSystem) {\r\n _GLTFUtilities._GetRightHandedQuaternionArrayFromRef(value);\r\n\r\n if (!babylonTransformNode.parent) {\r\n value = Quaternion.FromArray([0, 1, 0, 0]).multiply(Quaternion.FromArray(value)).asArray();\r\n }\r\n }\r\n\r\n outputs.push(value);\r\n } else {\r\n Tools.Error(\"glTFAnimation: Unsupported key frame values for animation!\");\r\n }\r\n }\r\n\r\n /**\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 babylonTransformNode\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 frameDelta Time difference between two frames used to scale the tangent by the frame delta\r\n * @param useQuaternion Specifies if quaternions are used\r\n * @param convertToRightHandedSystem Specifies if the values should be converted to right-handed\r\n */\r\n private static _AddSplineTangent(\r\n babylonTransformNode: Node,\r\n tangentType: _TangentType,\r\n outputs: number[][],\r\n animationChannelTargetPath: AnimationChannelTargetPath,\r\n interpolation: AnimationSamplerInterpolation,\r\n keyFrame: IAnimationKey,\r\n frameDelta: number,\r\n useQuaternion: boolean,\r\n convertToRightHandedSystem: 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\r\n if (convertToRightHandedSystem) {\r\n _GLTFUtilities._GetRightHandedQuaternionArrayFromRef(tangent);\r\n if (!babylonTransformNode.parent) {\r\n tangent = Quaternion.FromArray([0, 1, 0, 0]).multiply(Quaternion.FromArray(tangent)).asArray();\r\n }\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 if (convertToRightHandedSystem) {\r\n if (animationChannelTargetPath === AnimationChannelTargetPath.TRANSLATION) {\r\n _GLTFUtilities._GetRightHandedPositionArray3FromRef(tangent);\r\n if (!babylonTransformNode.parent) {\r\n tangent[0] *= -1; // x\r\n tangent[2] *= -1; // z\r\n }\r\n }\r\n }\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 { Nullable } from \"core/types\";\r\nimport { Matrix } from \"core/Maths/math.vector\";\r\nimport { Tools } from \"core/Misc/tools\";\r\nimport type { StandardMaterial } from \"core/Materials/standardMaterial\";\r\nimport type { Geometry } from \"core/Meshes/geometry\";\r\nimport type { Mesh } from \"core/Meshes/mesh\";\r\n\r\n/**\r\n * Class for generating OBJ data from a Babylon scene.\r\n */\r\nexport class OBJExport {\r\n /**\r\n * Exports the geometry of a Mesh array in .OBJ file format (text)\r\n * @param mesh defines the list of meshes to serialize\r\n * @param materials defines if materials should be exported\r\n * @param matlibname defines the name of the associated mtl file\r\n * @param globalposition defines if the exported positions are globals or local to the exported mesh\r\n * @returns the OBJ content\r\n */\r\n public static OBJ(mesh: Mesh[], materials?: boolean, matlibname?: string, globalposition?: boolean): string {\r\n const output: string[] = [];\r\n let v = 1;\r\n // keep track of uv index in case mixed meshes are passed in\r\n let textureV = 1;\r\n\r\n if (materials) {\r\n if (!matlibname) {\r\n matlibname = \"mat\";\r\n }\r\n output.push(\"mtllib \" + matlibname + \".mtl\");\r\n }\r\n for (let j = 0; j < mesh.length; j++) {\r\n output.push(\"g object\" + j);\r\n output.push(\"o object_\" + j);\r\n\r\n //Uses the position of the item in the scene, to the file (this back to normal in the end)\r\n let inverseTransform: Nullable = null;\r\n if (globalposition) {\r\n const transform = mesh[j].computeWorldMatrix(true);\r\n inverseTransform = new Matrix();\r\n transform.invertToRef(inverseTransform);\r\n\r\n mesh[j].bakeTransformIntoVertices(transform);\r\n }\r\n\r\n //TODO: submeshes (groups)\r\n //TODO: smoothing groups (s 1, s off);\r\n if (materials) {\r\n const mat = mesh[j].material;\r\n\r\n if (mat) {\r\n output.push(\"usemtl \" + mat.id);\r\n }\r\n }\r\n const g: Nullable = mesh[j].geometry;\r\n\r\n if (!g) {\r\n Tools.Warn(\"No geometry is present on the mesh\");\r\n continue;\r\n }\r\n\r\n const trunkVerts = g.getVerticesData(\"position\");\r\n const trunkNormals = g.getVerticesData(\"normal\");\r\n const trunkUV = g.getVerticesData(\"uv\");\r\n const trunkFaces = g.getIndices();\r\n let currentV = 0;\r\n let currentTextureV = 0;\r\n\r\n if (!trunkVerts || !trunkFaces) {\r\n Tools.Warn(\"There are no position vertices or indices on the mesh!\");\r\n continue;\r\n }\r\n\r\n for (let i = 0; i < trunkVerts.length; i += 3) {\r\n // Babylon.js default is left handed, while OBJ default is right handed\r\n // Need to invert Z vertices unless Babylon is set to use a right handed system\r\n if (mesh[0].getScene().useRightHandedSystem) {\r\n output.push(\"v \" + trunkVerts[i] + \" \" + trunkVerts[i + 1] + \" \" + trunkVerts[i + 2]);\r\n } else {\r\n output.push(\"v \" + trunkVerts[i] + \" \" + trunkVerts[i + 1] + \" \" + -trunkVerts[i + 2]);\r\n }\r\n currentV++;\r\n }\r\n\r\n if (trunkNormals != null) {\r\n for (let i = 0; i < trunkNormals.length; i += 3) {\r\n output.push(\"vn \" + trunkNormals[i] + \" \" + trunkNormals[i + 1] + \" \" + trunkNormals[i + 2]);\r\n }\r\n }\r\n if (trunkUV != null) {\r\n for (let i = 0; i < trunkUV.length; i += 2) {\r\n output.push(\"vt \" + trunkUV[i] + \" \" + trunkUV[i + 1]);\r\n currentTextureV++;\r\n }\r\n }\r\n\r\n for (let i = 0; i < trunkFaces.length; i += 3) {\r\n const indices = [String(trunkFaces[i + 2] + v), String(trunkFaces[i + 1] + v), String(trunkFaces[i] + v)];\r\n const textureIndices = [String(trunkFaces[i + 2] + textureV), String(trunkFaces[i + 1] + textureV), String(trunkFaces[i] + textureV)];\r\n const blanks: string[] = [\"\", \"\", \"\"];\r\n\r\n const facePositions = indices;\r\n const faceUVs = trunkUV != null ? textureIndices : blanks;\r\n const faceNormals = trunkNormals != null ? indices : blanks;\r\n\r\n output.push(\r\n \"f \" +\r\n facePositions[0] +\r\n \"/\" +\r\n faceUVs[0] +\r\n \"/\" +\r\n faceNormals[0] +\r\n \" \" +\r\n facePositions[1] +\r\n \"/\" +\r\n faceUVs[1] +\r\n \"/\" +\r\n faceNormals[1] +\r\n \" \" +\r\n facePositions[2] +\r\n \"/\" +\r\n faceUVs[2] +\r\n \"/\" +\r\n faceNormals[2]\r\n );\r\n }\r\n //back de previous matrix, to not change the original mesh in the scene\r\n if (globalposition && inverseTransform) {\r\n mesh[j].bakeTransformIntoVertices(inverseTransform);\r\n }\r\n v += currentV;\r\n textureV += currentTextureV;\r\n }\r\n const text: string = output.join(\"\\n\");\r\n return text;\r\n }\r\n\r\n /**\r\n * Exports the material(s) of a mesh in .MTL file format (text)\r\n * @param mesh defines the mesh to extract the material from\r\n * @returns the mtl content\r\n */\r\n //TODO: Export the materials of mesh array\r\n public static MTL(mesh: Mesh): string {\r\n const output = [];\r\n const m = mesh.material;\r\n output.push(\"newmtl mat1\");\r\n output.push(\" Ns \" + m.specularPower.toFixed(4));\r\n output.push(\" Ni 1.5000\");\r\n output.push(\" d \" + m.alpha.toFixed(4));\r\n output.push(\" Tr 0.0000\");\r\n output.push(\" Tf 1.0000 1.0000 1.0000\");\r\n output.push(\" illum 2\");\r\n output.push(\" Ka \" + m.ambientColor.r.toFixed(4) + \" \" + m.ambientColor.g.toFixed(4) + \" \" + m.ambientColor.b.toFixed(4));\r\n output.push(\" Kd \" + m.diffuseColor.r.toFixed(4) + \" \" + m.diffuseColor.g.toFixed(4) + \" \" + m.diffuseColor.b.toFixed(4));\r\n output.push(\" Ks \" + m.specularColor.r.toFixed(4) + \" \" + m.specularColor.g.toFixed(4) + \" \" + m.specularColor.b.toFixed(4));\r\n output.push(\" Ke \" + m.emissiveColor.r.toFixed(4) + \" \" + m.emissiveColor.g.toFixed(4) + \" \" + m.emissiveColor.b.toFixed(4));\r\n\r\n //TODO: uv scale, offset, wrap\r\n //TODO: UV mirrored in Blender? second UV channel? lightMap? reflection textures?\r\n const uvscale = \"\";\r\n\r\n if (m.ambientTexture) {\r\n output.push(\" map_Ka \" + uvscale + m.ambientTexture.name);\r\n }\r\n\r\n if (m.diffuseTexture) {\r\n output.push(\" map_Kd \" + uvscale + m.diffuseTexture.name);\r\n //TODO: alpha testing, opacity in diffuse texture alpha channel (diffuseTexture.hasAlpha -> map_d)\r\n }\r\n\r\n if (m.specularTexture) {\r\n output.push(\" map_Ks \" + uvscale + m.specularTexture.name);\r\n /* TODO: glossiness = specular highlight component is in alpha channel of specularTexture. (???)\r\n if (m.useGlossinessFromSpecularMapAlpha) {\r\n output.push(\" map_Ns \"+uvscale + m.specularTexture.name);\r\n }\r\n */\r\n }\r\n\r\n /* TODO: emissive texture not in .MAT format (???)\r\n if (m.emissiveTexture) {\r\n output.push(\" map_d \"+uvscale+m.emissiveTexture.name);\r\n }\r\n */\r\n\r\n if (m.bumpTexture) {\r\n output.push(\" map_bump -imfchan z \" + uvscale + m.bumpTexture.name);\r\n }\r\n\r\n if (m.opacityTexture) {\r\n output.push(\" map_d \" + uvscale + m.opacityTexture.name);\r\n }\r\n\r\n const text = output.join(\"\\n\");\r\n return text;\r\n }\r\n}\r\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 type { IBufferView, AccessorComponentType, IAccessor } from \"babylonjs-gltf2interface\";\r\nimport { AccessorType } from \"babylonjs-gltf2interface\";\r\n\r\nimport type { FloatArray, Nullable } from \"core/types\";\r\nimport type { Vector4, Quaternion } from \"core/Maths/math.vector\";\r\nimport { Vector3 } from \"core/Maths/math.vector\";\r\n\r\n/**\r\n * @internal\r\n */\r\nexport class _GLTFUtilities {\r\n /**\r\n * Creates a buffer view based on the supplied arguments\r\n * @param bufferIndex index value of the specified buffer\r\n * @param byteOffset byte offset value\r\n * @param byteLength byte length of the bufferView\r\n * @param byteStride byte distance between conequential elements\r\n * @param name name of the buffer view\r\n * @returns bufferView for glTF\r\n */\r\n public static _CreateBufferView(bufferIndex: number, byteOffset: number, byteLength: number, byteStride?: number, name?: string): IBufferView {\r\n const bufferview: IBufferView = { buffer: bufferIndex, byteLength: byteLength };\r\n if (byteOffset) {\r\n bufferview.byteOffset = byteOffset;\r\n }\r\n if (name) {\r\n bufferview.name = name;\r\n }\r\n if (byteStride) {\r\n bufferview.byteStride = byteStride;\r\n }\r\n\r\n return bufferview;\r\n }\r\n\r\n /**\r\n * Creates an accessor based on the supplied arguments\r\n * @param bufferviewIndex The index of the bufferview referenced by this accessor\r\n * @param name The name of the accessor\r\n * @param type The type of the accessor\r\n * @param componentType The datatype of components in the attribute\r\n * @param count The number of attributes referenced by this accessor\r\n * @param byteOffset The offset relative to the start of the bufferView in bytes\r\n * @param min Minimum value of each component in this attribute\r\n * @param max Maximum value of each component in this attribute\r\n * @returns accessor for glTF\r\n */\r\n public static _CreateAccessor(\r\n bufferviewIndex: number,\r\n name: string,\r\n type: AccessorType,\r\n componentType: AccessorComponentType,\r\n count: number,\r\n byteOffset: Nullable,\r\n min: Nullable,\r\n max: Nullable\r\n ): IAccessor {\r\n const accessor: IAccessor = { name: name, bufferView: bufferviewIndex, componentType: componentType, count: count, type: type };\r\n\r\n if (min != null) {\r\n accessor.min = min;\r\n }\r\n if (max != null) {\r\n accessor.max = max;\r\n }\r\n if (byteOffset != null) {\r\n accessor.byteOffset = byteOffset;\r\n }\r\n\r\n return accessor;\r\n }\r\n\r\n /**\r\n * Calculates the minimum and maximum values of an array of position floats\r\n * @param positions Positions array of a mesh\r\n * @param vertexStart Starting vertex offset to calculate min and max values\r\n * @param vertexCount Number of vertices to check for min and max values\r\n * @param convertToRightHandedSystem\r\n * @returns min number array and max number array\r\n */\r\n public static _CalculateMinMaxPositions(\r\n positions: FloatArray,\r\n vertexStart: number,\r\n vertexCount: number,\r\n convertToRightHandedSystem: boolean\r\n ): { min: number[]; max: number[] } {\r\n const min = [Infinity, Infinity, Infinity];\r\n const max = [-Infinity, -Infinity, -Infinity];\r\n const positionStrideSize = 3;\r\n let indexOffset: number;\r\n let position: Vector3;\r\n let vector: number[];\r\n\r\n if (vertexCount) {\r\n for (let i = vertexStart, length = vertexStart + vertexCount; i < length; ++i) {\r\n indexOffset = positionStrideSize * i;\r\n\r\n position = Vector3.FromArray(positions, indexOffset);\r\n if (convertToRightHandedSystem) {\r\n _GLTFUtilities._GetRightHandedPositionVector3FromRef(position);\r\n }\r\n vector = position.asArray();\r\n\r\n for (let j = 0; j < positionStrideSize; ++j) {\r\n const num = vector[j];\r\n if (num < min[j]) {\r\n min[j] = num;\r\n }\r\n if (num > max[j]) {\r\n max[j] = num;\r\n }\r\n ++indexOffset;\r\n }\r\n }\r\n }\r\n return { min, max };\r\n }\r\n\r\n /**\r\n * Converts a new right-handed Vector3\r\n * @param vector vector3 array\r\n * @returns right-handed Vector3\r\n */\r\n public static _GetRightHandedPositionVector3(vector: Vector3): Vector3 {\r\n return new Vector3(vector.x, vector.y, -vector.z);\r\n }\r\n\r\n /**\r\n * Converts a Vector3 to right-handed\r\n * @param vector Vector3 to convert to right-handed\r\n */\r\n public static _GetRightHandedPositionVector3FromRef(vector: Vector3) {\r\n vector.z *= -1;\r\n }\r\n\r\n /**\r\n * Converts a three element number array to right-handed\r\n * @param vector number array to convert to right-handed\r\n */\r\n public static _GetRightHandedPositionArray3FromRef(vector: number[]) {\r\n vector[2] *= -1;\r\n }\r\n\r\n /**\r\n * Converts a new right-handed Vector3\r\n * @param vector vector3 array\r\n * @returns right-handed Vector3\r\n */\r\n public static _GetRightHandedNormalVector3(vector: Vector3): Vector3 {\r\n return new Vector3(vector.x, vector.y, -vector.z);\r\n }\r\n\r\n /**\r\n * Converts a Vector3 to right-handed\r\n * @param vector Vector3 to convert to right-handed\r\n */\r\n public static _GetRightHandedNormalVector3FromRef(vector: Vector3) {\r\n vector.z *= -1;\r\n }\r\n\r\n /**\r\n * Converts a three element number array to right-handed\r\n * @param vector number array to convert to right-handed\r\n */\r\n public static _GetRightHandedNormalArray3FromRef(vector: number[]) {\r\n vector[2] *= -1;\r\n }\r\n\r\n /**\r\n * Converts a Vector4 to right-handed\r\n * @param vector Vector4 to convert to right-handed\r\n */\r\n public static _GetRightHandedVector4FromRef(vector: Vector4) {\r\n vector.z *= -1;\r\n vector.w *= -1;\r\n }\r\n\r\n /**\r\n * Converts a Vector4 to right-handed\r\n * @param vector Vector4 to convert to right-handed\r\n */\r\n public static _GetRightHandedArray4FromRef(vector: number[]) {\r\n vector[2] *= -1;\r\n vector[3] *= -1;\r\n }\r\n\r\n /**\r\n * Converts a Quaternion to right-handed\r\n * @param quaternion Source quaternion to convert to right-handed\r\n */\r\n public static _GetRightHandedQuaternionFromRef(quaternion: Quaternion) {\r\n quaternion.x *= -1;\r\n quaternion.y *= -1;\r\n }\r\n\r\n /**\r\n * Converts a Quaternion to right-handed\r\n * @param quaternion Source quaternion to convert to right-handed\r\n */\r\n public static _GetRightHandedQuaternionArrayFromRef(quaternion: number[]) {\r\n quaternion[0] *= -1;\r\n quaternion[1] *= -1;\r\n }\r\n\r\n public static _NormalizeTangentFromRef(tangent: Vector4) {\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\n public static _GetDataAccessorElementCount(accessorType: AccessorType) {\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\n","import { ImageMimeType } from \"babylonjs-gltf2interface\";\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 glTFFiles: { [fileName: string]: string | Blob };\r\n\r\n /**\r\n * Initializes the glTF file object\r\n */\r\n public constructor() {\r\n this.glTFFiles = {};\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 /**\r\n * Checks for a matching suffix at the end of a string (for ES5 and lower)\r\n * @param str Source string\r\n * @param suffix Suffix to search for in the source string\r\n * @returns Boolean indicating whether the suffix was found (true) or not (false)\r\n */\r\n function endsWith(str: string, suffix: string): boolean {\r\n return str.indexOf(suffix, str.length - suffix.length) !== -1;\r\n }\r\n\r\n for (const key in this.glTFFiles) {\r\n const link = document.createElement(\"a\");\r\n document.body.appendChild(link);\r\n link.setAttribute(\"type\", \"hidden\");\r\n link.download = key;\r\n const blob = this.glTFFiles[key];\r\n let mimeType;\r\n\r\n if (endsWith(key, \".glb\")) {\r\n mimeType = { type: \"model/gltf-binary\" };\r\n } else if (endsWith(key, \".bin\")) {\r\n mimeType = { type: \"application/octet-stream\" };\r\n } else if (endsWith(key, \".gltf\")) {\r\n mimeType = { type: \"model/gltf+json\" };\r\n } else if (endsWith(key, \".jpeg\") || endsWith(key, \".jpg\")) {\r\n mimeType = { type: ImageMimeType.JPEG };\r\n } else if (endsWith(key, \".png\")) {\r\n mimeType = { type: ImageMimeType.PNG };\r\n }\r\n\r\n link.href = window.URL.createObjectURL(new Blob([blob], mimeType));\r\n link.click();\r\n }\r\n }\r\n}\r\n","/******************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise */\r\n\r\nvar extendStatics = function(d, b) {\r\n extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n if (typeof b !== \"function\" && b !== null)\r\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n }\r\n return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\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;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (_) try {\r\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;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n var desc = Object.getOwnPropertyDescriptor(m, k);\r\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\r\n desc = { enumerable: true, get: function() { return m[k]; } };\r\n }\r\n Object.defineProperty(o, k2, desc);\r\n}) : (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n o[k2] = m[k];\r\n});\r\n\r\nexport function __exportStar(m, o) {\r\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\r\n}\r\n\r\nexport function __values(o) {\r\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n if (m) return m.call(o);\r\n if (o && typeof o.length === \"number\") return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n}\r\n\r\nexport function __read(o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spreadArrays() {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n}\r\n\r\nexport function __spreadArray(to, from, pack) {\r\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\r\n if (ar || !(i in from)) {\r\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\r\n ar[i] = from[i];\r\n }\r\n }\r\n return to.concat(ar || Array.prototype.slice.call(from));\r\n}\r\n\r\nexport function __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\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);\r\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); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nvar __setModuleDefault = Object.create ? (function(o, v) {\r\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\r\n}) : function(o, v) {\r\n o[\"default\"] = v;\r\n};\r\n\r\nexport function __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\r\n __setModuleDefault(result, mod);\r\n return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n\r\nexport function __classPrivateFieldGet(receiver, state, kind, f) {\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\r\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\");\r\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\r\n}\r\n\r\nexport function __classPrivateFieldSet(receiver, state, value, kind, f) {\r\n if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\r\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\");\r\n return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\r\n}\r\n\r\nexport function __classPrivateFieldIn(state, receiver) {\r\n if (receiver === null || (typeof receiver !== \"object\" && typeof receiver !== \"function\")) throw new TypeError(\"Cannot use 'in' operator on non-object\");\r\n return typeof state === \"function\" ? receiver === state : state.has(receiver);\r\n}\r\n","import type {\r\n ITextureInfo,\r\n IMaterial,\r\n IMaterialPbrMetallicRoughness,\r\n IMaterialOcclusionTextureInfo,\r\n ISampler,\r\n ITexture,\r\n IImage,\r\n IMaterialExtension,\r\n} from \"babylonjs-gltf2interface\";\r\nimport { ImageMimeType, MaterialAlphaMode, TextureMagFilter, TextureMinFilter, TextureWrapMode } from \"babylonjs-gltf2interface\";\r\n\r\nimport type { Nullable } from \"core/types\";\r\nimport { Vector2 } from \"core/Maths/math.vector\";\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 { 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 { _Exporter } from \"./glTFExporter\";\r\nimport { Constants } from \"core/Engines/constants\";\r\n\r\ndeclare type Material = import(\"core/Materials/material\").Material;\r\ndeclare type StandardMaterial = import(\"core/Materials/standardMaterial\").StandardMaterial;\r\ndeclare type PBRBaseMaterial = import(\"core/Materials/PBR/pbrBaseMaterial\").PBRBaseMaterial;\r\ndeclare type PBRMaterial = import(\"core/Materials/PBR/pbrMaterial\").PBRMaterial;\r\n\r\n/**\r\n * Interface for storing specular glossiness factors\r\n * @internal\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\ninterface _IPBRSpecularGlossiness {\r\n /**\r\n * Represents the linear diffuse factors of the material\r\n */\r\n diffuseColor: Color3;\r\n /**\r\n * Represents the linear specular factors of the material\r\n */\r\n specularColor: Color3;\r\n /**\r\n * Represents the smoothness of the material\r\n */\r\n glossiness: number;\r\n}\r\n\r\n/**\r\n * Interface for storing metallic roughness factors\r\n * @internal\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\ninterface _IPBRMetallicRoughness {\r\n /**\r\n * Represents the albedo color of the material\r\n */\r\n baseColor: Color3;\r\n /**\r\n * Represents the metallness of the material\r\n */\r\n metallic: Nullable;\r\n /**\r\n * Represents the roughness of the material\r\n */\r\n roughness: Nullable;\r\n /**\r\n * The metallic roughness texture as a base64 string\r\n */\r\n metallicRoughnessTextureBase64?: Nullable;\r\n /**\r\n * The base color texture as a base64 string\r\n */\r\n baseColorTextureBase64?: Nullable;\r\n}\r\n\r\n/**\r\n * Utility methods for working with glTF material conversion properties. This class should only be used internally\r\n * @internal\r\n */\r\nexport class _GLTFMaterialExporter {\r\n /**\r\n * Represents the dielectric specular values for R, G and B\r\n */\r\n private static readonly _DielectricSpecular: Color3 = new Color3(0.04, 0.04, 0.04);\r\n\r\n /**\r\n * Allows the maximum specular power to be defined for material calculations\r\n */\r\n private static readonly _MaxSpecularPower = 1024;\r\n\r\n /**\r\n * Mapping to store textures\r\n */\r\n private _textureMap: { [textureId: string]: ITextureInfo } = {};\r\n\r\n /**\r\n * Numeric tolerance value\r\n */\r\n private static readonly _Epsilon = 1e-6;\r\n\r\n /**\r\n * Reference to the glTF Exporter\r\n */\r\n private _exporter: _Exporter;\r\n\r\n constructor(exporter: _Exporter) {\r\n this._textureMap = {};\r\n this._exporter = exporter;\r\n }\r\n\r\n /**\r\n * Specifies if two colors are approximately equal in value\r\n * @param color1 first color to compare to\r\n * @param color2 second color to compare to\r\n * @param epsilon threshold value\r\n */\r\n private static _FuzzyEquals(color1: Color3, color2: Color3, epsilon: number): boolean {\r\n return Scalar.WithinEpsilon(color1.r, color2.r, epsilon) && Scalar.WithinEpsilon(color1.g, color2.g, epsilon) && Scalar.WithinEpsilon(color1.b, color2.b, epsilon);\r\n }\r\n\r\n /**\r\n * Gets the materials from a Babylon scene and converts them to glTF materials\r\n * @param exportMaterials\r\n * @param mimeType texture mime type\r\n * @param hasTextureCoords specifies if texture coordinates are present on the material\r\n */\r\n public _convertMaterialsToGLTFAsync(exportMaterials: Set, mimeType: ImageMimeType, hasTextureCoords: boolean) {\r\n const promises: Promise[] = [];\r\n exportMaterials.forEach((material) => {\r\n if (material.getClassName() === \"StandardMaterial\") {\r\n promises.push(this._convertStandardMaterialAsync(material as StandardMaterial, mimeType, hasTextureCoords));\r\n } else if (material.getClassName().indexOf(\"PBR\") !== -1) {\r\n promises.push(this._convertPBRMaterialAsync(material as PBRMaterial, mimeType, hasTextureCoords));\r\n } else {\r\n Tools.Warn(`Unsupported material type: ${material.name}`);\r\n }\r\n });\r\n\r\n return Promise.all(promises).then(() => {\r\n /* do nothing */\r\n });\r\n }\r\n\r\n /**\r\n * Makes a copy of the glTF material without the texture parameters\r\n * @param originalMaterial original glTF material\r\n * @returns glTF material without texture parameters\r\n */\r\n public _stripTexturesFromMaterial(originalMaterial: IMaterial): IMaterial {\r\n const newMaterial: IMaterial = {};\r\n if (originalMaterial) {\r\n newMaterial.name = originalMaterial.name;\r\n newMaterial.doubleSided = originalMaterial.doubleSided;\r\n newMaterial.alphaMode = originalMaterial.alphaMode;\r\n newMaterial.alphaCutoff = originalMaterial.alphaCutoff;\r\n newMaterial.emissiveFactor = originalMaterial.emissiveFactor;\r\n const originalPBRMetallicRoughness = originalMaterial.pbrMetallicRoughness;\r\n if (originalPBRMetallicRoughness) {\r\n newMaterial.pbrMetallicRoughness = {};\r\n newMaterial.pbrMetallicRoughness.baseColorFactor = originalPBRMetallicRoughness.baseColorFactor;\r\n newMaterial.pbrMetallicRoughness.metallicFactor = originalPBRMetallicRoughness.metallicFactor;\r\n newMaterial.pbrMetallicRoughness.roughnessFactor = originalPBRMetallicRoughness.roughnessFactor;\r\n }\r\n }\r\n return newMaterial;\r\n }\r\n\r\n /**\r\n * Specifies if the material has any texture parameters present\r\n * @param material glTF Material\r\n * @returns boolean specifying if texture parameters are present\r\n */\r\n public _hasTexturesPresent(material: IMaterial): boolean {\r\n if (material.emissiveTexture || material.normalTexture || material.occlusionTexture) {\r\n return true;\r\n }\r\n const pbrMat = material.pbrMetallicRoughness;\r\n if (pbrMat) {\r\n if (pbrMat.baseColorTexture || pbrMat.metallicRoughnessTexture) {\r\n return true;\r\n }\r\n }\r\n\r\n if (material.extensions) {\r\n for (const extension in material.extensions) {\r\n const extensionObject = material.extensions[extension];\r\n if (extensionObject as IMaterialExtension) {\r\n return extensionObject.hasTextures?.();\r\n }\r\n }\r\n }\r\n\r\n return false;\r\n }\r\n\r\n public _getTextureInfo(babylonTexture: Nullable): Nullable {\r\n if (babylonTexture) {\r\n const textureUid = babylonTexture.uid;\r\n if (textureUid in this._textureMap) {\r\n return this._textureMap[textureUid];\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n /**\r\n * Converts a Babylon StandardMaterial to a glTF Metallic Roughness Material\r\n * @param babylonStandardMaterial\r\n * @returns glTF Metallic Roughness Material representation\r\n */\r\n public _convertToGLTFPBRMetallicRoughness(babylonStandardMaterial: StandardMaterial): IMaterialPbrMetallicRoughness {\r\n // Defines a cubic bezier curve where x is specular power and y is roughness\r\n const P0 = new Vector2(0, 1);\r\n const P1 = new Vector2(0, 0.1);\r\n const P2 = new Vector2(0, 0.1);\r\n const P3 = new Vector2(1300, 0.1);\r\n\r\n /**\r\n * Given the control points, solve for x based on a given t for a cubic bezier curve\r\n * @param t a value between 0 and 1\r\n * @param p0 first control point\r\n * @param p1 second control point\r\n * @param p2 third control point\r\n * @param p3 fourth control point\r\n * @returns number result of cubic bezier curve at the specified t\r\n */\r\n function cubicBezierCurve(t: number, p0: number, p1: number, p2: number, p3: number): number {\r\n return (1 - t) * (1 - t) * (1 - t) * p0 + 3 * (1 - t) * (1 - t) * t * p1 + 3 * (1 - t) * t * t * p2 + t * t * t * p3;\r\n }\r\n\r\n /**\r\n * Evaluates a specified specular power value to determine the appropriate roughness value,\r\n * based on a pre-defined cubic bezier curve with specular on the abscissa axis (x-axis)\r\n * and roughness on the ordinant axis (y-axis)\r\n * @param specularPower specular power of standard material\r\n * @returns Number representing the roughness value\r\n */\r\n function solveForRoughness(specularPower: number): number {\r\n // Given P0.x = 0, P1.x = 0, P2.x = 0\r\n // x = t * t * t * P3.x\r\n // t = (x / P3.x)^(1/3)\r\n const t = Math.pow(specularPower / P3.x, 0.333333);\r\n return cubicBezierCurve(t, P0.y, P1.y, P2.y, P3.y);\r\n }\r\n\r\n const diffuse = babylonStandardMaterial.diffuseColor.toLinearSpace().scale(0.5);\r\n const opacity = babylonStandardMaterial.alpha;\r\n const specularPower = Scalar.Clamp(babylonStandardMaterial.specularPower, 0, _GLTFMaterialExporter._MaxSpecularPower);\r\n\r\n const roughness = solveForRoughness(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 * Computes the metallic factor\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 */\r\n public static _SolveMetallic(diffuse: number, specular: number, oneMinusSpecularStrength: number): number {\r\n if (specular < this._DielectricSpecular.r) {\r\n this._DielectricSpecular;\r\n return 0;\r\n }\r\n\r\n const a = this._DielectricSpecular.r;\r\n const b = (diffuse * oneMinusSpecularStrength) / (1.0 - this._DielectricSpecular.r) + specular - 2.0 * this._DielectricSpecular.r;\r\n const c = this._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 * 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\n private static _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\n /**\r\n * Converts a Babylon Standard Material to a glTF Material\r\n * @param babylonStandardMaterial BJS Standard Material\r\n * @param mimeType mime type to use for the textures\r\n * @param hasTextureCoords specifies if texture coordinates are present on the submesh to determine if textures should be applied\r\n */\r\n public _convertStandardMaterialAsync(babylonStandardMaterial: StandardMaterial, mimeType: ImageMimeType, hasTextureCoords: boolean): Promise {\r\n const materialMap = this._exporter._materialMap;\r\n const materials = this._exporter._materials;\r\n const promises = [];\r\n const glTFPbrMetallicRoughness = this._convertToGLTFPBRMetallicRoughness(babylonStandardMaterial);\r\n\r\n const glTFMaterial: 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 glTFMaterial.doubleSided = true;\r\n }\r\n if (hasTextureCoords) {\r\n if (babylonStandardMaterial.diffuseTexture) {\r\n promises.push(\r\n this._exportTextureAsync(babylonStandardMaterial.diffuseTexture, mimeType).then((glTFTexture) => {\r\n if (glTFTexture) {\r\n glTFPbrMetallicRoughness.baseColorTexture = glTFTexture;\r\n }\r\n })\r\n );\r\n }\r\n if (babylonStandardMaterial.bumpTexture) {\r\n promises.push(\r\n this._exportTextureAsync(babylonStandardMaterial.bumpTexture, mimeType).then((glTFTexture) => {\r\n if (glTFTexture) {\r\n glTFMaterial.normalTexture = glTFTexture;\r\n if (babylonStandardMaterial.bumpTexture != null && babylonStandardMaterial.bumpTexture.level !== 1) {\r\n glTFMaterial.normalTexture.scale = babylonStandardMaterial.bumpTexture.level;\r\n }\r\n }\r\n })\r\n );\r\n }\r\n if (babylonStandardMaterial.emissiveTexture) {\r\n glTFMaterial.emissiveFactor = [1.0, 1.0, 1.0];\r\n\r\n promises.push(\r\n this._exportTextureAsync(babylonStandardMaterial.emissiveTexture, mimeType).then((glTFEmissiveTexture) => {\r\n if (glTFEmissiveTexture) {\r\n glTFMaterial.emissiveTexture = glTFEmissiveTexture;\r\n }\r\n })\r\n );\r\n }\r\n if (babylonStandardMaterial.ambientTexture) {\r\n promises.push(\r\n this._exportTextureAsync(babylonStandardMaterial.ambientTexture, mimeType).then((glTFTexture) => {\r\n if (glTFTexture) {\r\n const occlusionTexture: IMaterialOcclusionTextureInfo = {\r\n index: glTFTexture.index,\r\n };\r\n glTFMaterial.occlusionTexture = occlusionTexture;\r\n occlusionTexture.strength = 1.0;\r\n }\r\n })\r\n );\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 glTFMaterial.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 if (babylonStandardMaterial.emissiveColor && !_GLTFMaterialExporter._FuzzyEquals(babylonStandardMaterial.emissiveColor, Color3.Black(), _GLTFMaterialExporter._Epsilon)) {\r\n glTFMaterial.emissiveFactor = babylonStandardMaterial.emissiveColor.asArray();\r\n }\r\n\r\n glTFMaterial.pbrMetallicRoughness = glTFPbrMetallicRoughness;\r\n _GLTFMaterialExporter._SetAlphaMode(glTFMaterial, babylonStandardMaterial);\r\n\r\n materials.push(glTFMaterial);\r\n materialMap[babylonStandardMaterial.uniqueId] = materials.length - 1;\r\n\r\n return this._finishMaterial(promises, glTFMaterial, babylonStandardMaterial, mimeType);\r\n }\r\n\r\n private _finishMaterial(promises: Promise[], glTFMaterial: IMaterial, babylonMaterial: Material, mimeType: ImageMimeType) {\r\n return Promise.all(promises).then(() => {\r\n const textures = this._exporter._extensionsPostExportMaterialAdditionalTextures(\"exportMaterial\", glTFMaterial, babylonMaterial);\r\n let tasks: Nullable>[]> = null;\r\n\r\n for (const texture of textures) {\r\n if (!tasks) {\r\n tasks = [];\r\n }\r\n tasks.push(this._exportTextureAsync(texture, mimeType));\r\n }\r\n\r\n if (!tasks) {\r\n tasks = [Promise.resolve(null)];\r\n }\r\n\r\n return Promise.all(tasks).then(() => {\r\n const extensionWork = this._exporter._extensionsPostExportMaterialAsync(\"exportMaterial\", glTFMaterial, babylonMaterial);\r\n if (!extensionWork) {\r\n return glTFMaterial;\r\n }\r\n return extensionWork.then(() => glTFMaterial);\r\n });\r\n });\r\n }\r\n\r\n /**\r\n * Converts an image typed array buffer to a base64 image\r\n * @param buffer typed array buffer\r\n * @param width width of the image\r\n * @param height height of the image\r\n * @param mimeType mimetype of the image\r\n * @returns base64 image string\r\n */\r\n private _createBase64FromCanvasAsync(buffer: Uint8Array | Float32Array, width: number, height: number, mimeType: ImageMimeType): Promise {\r\n // eslint-disable-next-line no-async-promise-executor\r\n return new Promise(async (resolve) => {\r\n const textureType = Constants.TEXTURETYPE_UNSIGNED_INT;\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 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 const base64: string = await (Tools.DumpDataAsync(width, height, data, mimeType, undefined, true, false) as Promise);\r\n\r\n resolve(base64);\r\n });\r\n }\r\n\r\n /**\r\n * Generates a white texture based on the specified width and height\r\n * @param width width of the texture in pixels\r\n * @param height height of the texture in pixels\r\n * @param scene babylonjs scene\r\n * @returns white texture\r\n */\r\n private _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\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, texture2: Nullable, 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 = this._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 = this._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 * Converts an array of pixels to a Float32Array\r\n * Throws an error if the pixel format is not supported\r\n * @param pixels - array buffer containing pixel values\r\n * @returns Float32 of pixels\r\n */\r\n private _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 * 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 * @link https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/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,\r\n specularGlossinessTexture: Nullable,\r\n factors: _IPBRSpecularGlossiness,\r\n mimeType: ImageMimeType\r\n ): Promise<_IPBRMetallicRoughness> {\r\n const promises = [];\r\n if (!(diffuseTexture || specularGlossinessTexture)) {\r\n return Promise.reject(\"_ConvertSpecularGlosinessTexturesToMetallicRoughness: diffuse and specular glossiness textures are not defined!\");\r\n }\r\n\r\n const scene: Nullable = 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 = this._convertPixelArrayToFloat32(diffusePixels);\r\n } else {\r\n return Promise.reject(\"Failed to retrieve pixels from diffuse texture!\");\r\n }\r\n if (specularPixels) {\r\n specularGlossinessBuffer = this._convertPixelArrayToFloat32(specularPixels);\r\n } else {\r\n return 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 = Color3.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]).toLinearSpace().multiply(factors.diffuseColor);\r\n const specularColor = new Color3(specularGlossinessBuffer[offset], specularGlossinessBuffer[offset + 1], specularGlossinessBuffer[offset + 2])\r\n .toLinearSpace()\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 > _GLTFMaterialExporter._Epsilon ? metallicRoughnessFactors.baseColor.r : 1;\r\n baseColorBuffer[destinationOffset + 1] /= metallicRoughnessFactors.baseColor.g > _GLTFMaterialExporter._Epsilon ? metallicRoughnessFactors.baseColor.g : 1;\r\n baseColorBuffer[destinationOffset + 2] /= metallicRoughnessFactors.baseColor.b > _GLTFMaterialExporter._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();\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 (!_GLTFMaterialExporter._FuzzyEquals(sRGBBaseColorPixel, Color3.White(), _GLTFMaterialExporter._Epsilon)) {\r\n writeOutBaseColorTexture = true;\r\n }\r\n\r\n metallicRoughnessBuffer[destinationOffset + 1] /=\r\n metallicRoughnessFactors.roughness! > _GLTFMaterialExporter._Epsilon ? metallicRoughnessFactors.roughness! : 1;\r\n metallicRoughnessBuffer[destinationOffset + 2] /= metallicRoughnessFactors.metallic! > _GLTFMaterialExporter._Epsilon ? metallicRoughnessFactors.metallic! : 1;\r\n\r\n const metallicRoughnessPixel = Color3.FromInts(255, metallicRoughnessBuffer[destinationOffset + 1], metallicRoughnessBuffer[destinationOffset + 2]);\r\n\r\n if (!_GLTFMaterialExporter._FuzzyEquals(metallicRoughnessPixel, Color3.White(), _GLTFMaterialExporter._Epsilon)) {\r\n writeOutMetallicRoughnessTexture = true;\r\n }\r\n }\r\n }\r\n\r\n if (writeOutMetallicRoughnessTexture) {\r\n const promise = this._createBase64FromCanvasAsync(metallicRoughnessBuffer, width, height, mimeType).then((metallicRoughnessBase64) => {\r\n metallicRoughnessFactors.metallicRoughnessTextureBase64 = metallicRoughnessBase64;\r\n });\r\n promises.push(promise);\r\n }\r\n if (writeOutBaseColorTexture) {\r\n const promise = this._createBase64FromCanvasAsync(baseColorBuffer, width, height, mimeType).then((baseColorBase64) => {\r\n metallicRoughnessFactors.baseColorTextureBase64 = baseColorBase64;\r\n });\r\n promises.push(promise);\r\n }\r\n\r\n return Promise.all(promises).then(() => {\r\n return metallicRoughnessFactors;\r\n });\r\n } else {\r\n return 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 = _GLTFMaterialExporter._SolveMetallic(diffusePerceivedBrightness, specularPerceivedBrightness, oneMinusSpecularStrength);\r\n const baseColorFromDiffuse = specularGlossiness.diffuseColor.scale(\r\n oneMinusSpecularStrength / (1.0 - _GLTFMaterialExporter._DielectricSpecular.r) / Math.max(1 - metallic, _GLTFMaterialExporter._Epsilon)\r\n );\r\n const baseColorFromSpecular = specularGlossiness.specularColor\r\n .subtract(_GLTFMaterialExporter._DielectricSpecular.scale(1 - metallic))\r\n .scale(1 / Math.max(metallic, _GLTFMaterialExporter._Epsilon));\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 hasTextureCoords 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 _convertMetalRoughFactorsToMetallicRoughnessAsync(\r\n babylonPBRMaterial: PBRBaseMaterial,\r\n mimeType: ImageMimeType,\r\n glTFPbrMetallicRoughness: IMaterialPbrMetallicRoughness,\r\n hasTextureCoords: boolean\r\n ): Promise<_IPBRMetallicRoughness> {\r\n const promises = [];\r\n const baseColor = babylonPBRMaterial._albedoColor;\r\n const metallic = babylonPBRMaterial._metallic;\r\n const roughness = babylonPBRMaterial._roughness;\r\n const metallicRoughness: _IPBRMetallicRoughness = {\r\n baseColor: baseColor,\r\n metallic: metallic,\r\n roughness: roughness,\r\n };\r\n\r\n if (hasTextureCoords) {\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 return Promise.all(promises).then(() => {\r\n return metallicRoughness;\r\n });\r\n }\r\n\r\n private _getGLTFTextureSampler(texture: BaseTexture): ISampler {\r\n const sampler = this._getGLTFTextureWrapModesSampler(texture);\r\n\r\n const samplingMode = texture instanceof Texture ? texture.samplingMode : null;\r\n if (samplingMode != null) {\r\n switch (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 private _getGLTFTextureWrapModesSampler(texture: BaseTexture): ISampler {\r\n const wrapS = this._getGLTFTextureWrapMode(texture instanceof Texture ? texture.wrapU : Texture.WRAP_ADDRESSMODE);\r\n const wrapT = this._getGLTFTextureWrapMode(texture instanceof Texture ? texture.wrapV : Texture.WRAP_ADDRESSMODE);\r\n\r\n if (wrapS === TextureWrapMode.REPEAT && wrapT === TextureWrapMode.REPEAT) {\r\n // default wrapping mode in glTF, so omitting\r\n return {};\r\n }\r\n\r\n return { wrapS: wrapS, wrapT: wrapT };\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 glTFPbrMetallicRoughness glTF PBR Metallic Roughness interface\r\n * @param hasTextureCoords 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 _convertSpecGlossFactorsToMetallicRoughnessAsync(\r\n babylonPBRMaterial: PBRBaseMaterial,\r\n mimeType: ImageMimeType,\r\n glTFPbrMetallicRoughness: IMaterialPbrMetallicRoughness,\r\n hasTextureCoords: boolean\r\n ): Promise<_IPBRMetallicRoughness> {\r\n return Promise.resolve().then(() => {\r\n const samplers = this._exporter._samplers;\r\n const textures = this._exporter._textures;\r\n const diffuseColor = babylonPBRMaterial._albedoColor;\r\n const specularColor = babylonPBRMaterial._reflectivityColor;\r\n const glossiness = babylonPBRMaterial._microSurface;\r\n const specGloss: _IPBRSpecularGlossiness = {\r\n diffuseColor: diffuseColor,\r\n specularColor: specularColor,\r\n glossiness: glossiness,\r\n };\r\n let samplerIndex: Nullable = null;\r\n const albedoTexture = babylonPBRMaterial._albedoTexture;\r\n const reflectivityTexture = babylonPBRMaterial._reflectivityTexture;\r\n if (albedoTexture) {\r\n const sampler = this._getGLTFTextureSampler(albedoTexture);\r\n if (sampler.magFilter != null && sampler.minFilter != null && sampler.wrapS != null && sampler.wrapT != null) {\r\n samplers.push(sampler);\r\n samplerIndex = samplers.length - 1;\r\n }\r\n }\r\n\r\n const useMicrosurfaceFromReflectivityMapAlpha = babylonPBRMaterial._useMicroSurfaceFromReflectivityMapAlpha;\r\n if (reflectivityTexture && !useMicrosurfaceFromReflectivityMapAlpha) {\r\n return Promise.reject(\"_ConvertPBRMaterial: Glossiness values not included in the reflectivity texture are currently not supported\");\r\n }\r\n if ((albedoTexture || reflectivityTexture) && hasTextureCoords) {\r\n return this._convertSpecularGlossinessTexturesToMetallicRoughnessAsync(albedoTexture, reflectivityTexture, specGloss, mimeType).then((metallicRoughnessFactors) => {\r\n if (metallicRoughnessFactors.baseColorTextureBase64) {\r\n const glTFBaseColorTexture = this._getTextureInfoFromBase64(\r\n metallicRoughnessFactors.baseColorTextureBase64,\r\n \"bjsBaseColorTexture_\" + textures.length + \".png\",\r\n mimeType,\r\n albedoTexture ? albedoTexture.coordinatesIndex : null,\r\n samplerIndex\r\n );\r\n if (glTFBaseColorTexture) {\r\n glTFPbrMetallicRoughness.baseColorTexture = glTFBaseColorTexture;\r\n }\r\n }\r\n if (metallicRoughnessFactors.metallicRoughnessTextureBase64) {\r\n const glTFMRColorTexture = this._getTextureInfoFromBase64(\r\n metallicRoughnessFactors.metallicRoughnessTextureBase64,\r\n \"bjsMetallicRoughnessTexture_\" + textures.length + \".png\",\r\n mimeType,\r\n reflectivityTexture ? reflectivityTexture.coordinatesIndex : null,\r\n samplerIndex\r\n );\r\n if (glTFMRColorTexture) {\r\n glTFPbrMetallicRoughness.metallicRoughnessTexture = glTFMRColorTexture;\r\n }\r\n }\r\n\r\n return metallicRoughnessFactors;\r\n });\r\n } else {\r\n return this._convertSpecularGlossinessToMetallicRoughness(specGloss);\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Converts a Babylon PBR Base Material to a glTF Material\r\n * @param babylonPBRMaterial BJS PBR Base Material\r\n * @param mimeType mime type to use for the textures\r\n * @param hasTextureCoords specifies if texture coordinates are present on the submesh to determine if textures should be applied\r\n */\r\n public _convertPBRMaterialAsync(babylonPBRMaterial: PBRBaseMaterial, mimeType: ImageMimeType, hasTextureCoords: boolean): Promise {\r\n const glTFPbrMetallicRoughness: IMaterialPbrMetallicRoughness = {};\r\n const glTFMaterial: IMaterial = {\r\n name: babylonPBRMaterial.name,\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 return this._convertMetalRoughFactorsToMetallicRoughnessAsync(babylonPBRMaterial, mimeType, glTFPbrMetallicRoughness, hasTextureCoords).then((metallicRoughness) => {\r\n return this._setMetallicRoughnessPbrMaterial(metallicRoughness, babylonPBRMaterial, glTFMaterial, glTFPbrMetallicRoughness, mimeType, hasTextureCoords);\r\n });\r\n } else {\r\n return this._convertSpecGlossFactorsToMetallicRoughnessAsync(babylonPBRMaterial, mimeType, glTFPbrMetallicRoughness, hasTextureCoords).then((metallicRoughness) => {\r\n return this._setMetallicRoughnessPbrMaterial(metallicRoughness, babylonPBRMaterial, glTFMaterial, glTFPbrMetallicRoughness, mimeType, hasTextureCoords);\r\n });\r\n }\r\n }\r\n\r\n private _setMetallicRoughnessPbrMaterial(\r\n metallicRoughness: Nullable<_IPBRMetallicRoughness>,\r\n babylonPBRMaterial: PBRBaseMaterial,\r\n glTFMaterial: IMaterial,\r\n glTFPbrMetallicRoughness: IMaterialPbrMetallicRoughness,\r\n mimeType: ImageMimeType,\r\n hasTextureCoords: boolean\r\n ): Promise {\r\n const materialMap = this._exporter._materialMap;\r\n const materials = this._exporter._materials;\r\n const promises = [];\r\n if (metallicRoughness) {\r\n _GLTFMaterialExporter._SetAlphaMode(glTFMaterial, babylonPBRMaterial as PBRMaterial);\r\n if (\r\n !(\r\n _GLTFMaterialExporter._FuzzyEquals(metallicRoughness.baseColor, Color3.White(), _GLTFMaterialExporter._Epsilon) &&\r\n babylonPBRMaterial.alpha >= _GLTFMaterialExporter._Epsilon\r\n )\r\n ) {\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 (hasTextureCoords) {\r\n const bumpTexture = babylonPBRMaterial._bumpTexture;\r\n if (bumpTexture) {\r\n const promise = 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 promises.push(promise);\r\n }\r\n const ambientTexture = babylonPBRMaterial._ambientTexture;\r\n if (ambientTexture) {\r\n const promise = 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 };\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 promises.push(promise);\r\n }\r\n const emissiveTexture = babylonPBRMaterial._emissiveTexture;\r\n if (emissiveTexture) {\r\n const promise = this._exportTextureAsync(emissiveTexture, mimeType).then((glTFTexture) => {\r\n if (glTFTexture) {\r\n glTFMaterial.emissiveTexture = glTFTexture;\r\n }\r\n });\r\n promises.push(promise);\r\n }\r\n }\r\n const emissiveColor = babylonPBRMaterial._emissiveColor;\r\n if (!_GLTFMaterialExporter._FuzzyEquals(emissiveColor, Color3.Black(), _GLTFMaterialExporter._Epsilon)) {\r\n glTFMaterial.emissiveFactor = emissiveColor.asArray();\r\n }\r\n\r\n glTFMaterial.pbrMetallicRoughness = glTFPbrMetallicRoughness;\r\n materials.push(glTFMaterial);\r\n materialMap[babylonPBRMaterial.uniqueId] = materials.length - 1;\r\n }\r\n\r\n return this._finishMaterial(promises, glTFMaterial, babylonPBRMaterial, mimeType);\r\n }\r\n\r\n private _getPixelsFromTexture(babylonTexture: BaseTexture): Promise> {\r\n const pixels =\r\n babylonTexture.textureType === Constants.TEXTURETYPE_UNSIGNED_INT\r\n ? (babylonTexture.readPixels() as Promise)\r\n : (babylonTexture.readPixels() as Promise);\r\n return pixels;\r\n }\r\n\r\n /**\r\n * Extracts a texture from a Babylon texture into file data and glTF data\r\n * @param babylonTexture Babylon texture to extract\r\n * @param mimeType Mime Type of the babylonTexture\r\n * @returns glTF texture info, or null if the texture format is not supported\r\n */\r\n public _exportTextureAsync(babylonTexture: BaseTexture, mimeType: ImageMimeType): Promise> {\r\n const extensionPromise = this._exporter._extensionsPreExportTextureAsync(\"exporter\", babylonTexture as Texture, mimeType);\r\n if (!extensionPromise) {\r\n return this._exportTextureInfoAsync(babylonTexture, mimeType);\r\n }\r\n\r\n return extensionPromise.then((texture) => {\r\n if (!texture) {\r\n return this._exportTextureInfoAsync(babylonTexture, mimeType);\r\n }\r\n return this._exportTextureInfoAsync(texture, mimeType);\r\n });\r\n }\r\n\r\n public _exportTextureInfoAsync(babylonTexture: BaseTexture, mimeType: ImageMimeType): Promise> {\r\n return Promise.resolve().then(async () => {\r\n const textureUid = babylonTexture.uid;\r\n if (textureUid in this._textureMap) {\r\n return this._textureMap[textureUid];\r\n } else {\r\n const pixels = await this._getPixelsFromTexture(babylonTexture);\r\n if (!pixels) {\r\n return null;\r\n }\r\n\r\n const samplers = this._exporter._samplers;\r\n const sampler = this._getGLTFTextureSampler(babylonTexture);\r\n let samplerIndex: Nullable = null;\r\n\r\n // if a pre-existing sampler with identical parameters exists, then reuse the previous sampler\r\n let foundSamplerIndex: Nullable = null;\r\n for (let i = 0; i < samplers.length; ++i) {\r\n const s = samplers[i];\r\n if (s.minFilter === sampler.minFilter && s.magFilter === sampler.magFilter && s.wrapS === sampler.wrapS && s.wrapT === sampler.wrapT) {\r\n foundSamplerIndex = i;\r\n break;\r\n }\r\n }\r\n\r\n if (foundSamplerIndex == null) {\r\n samplers.push(sampler);\r\n samplerIndex = samplers.length - 1;\r\n } else {\r\n samplerIndex = foundSamplerIndex;\r\n }\r\n const size = babylonTexture.getSize();\r\n\r\n // Preserve texture mime type if defined\r\n if ((babylonTexture as Texture).mimeType) {\r\n switch ((babylonTexture as Texture).mimeType) {\r\n case \"image/jpeg\":\r\n mimeType = ImageMimeType.JPEG;\r\n break;\r\n case \"image/png\":\r\n mimeType = ImageMimeType.PNG;\r\n break;\r\n }\r\n }\r\n\r\n return this._createBase64FromCanvasAsync(pixels, size.width, size.height, mimeType).then((base64Data) => {\r\n const textureInfo = this._getTextureInfoFromBase64(\r\n base64Data,\r\n babylonTexture.name.replace(/\\.\\/|\\/|\\.\\\\|\\\\/g, \"_\"),\r\n mimeType,\r\n babylonTexture.coordinatesIndex,\r\n samplerIndex\r\n );\r\n if (textureInfo) {\r\n this._textureMap[textureUid] = textureInfo;\r\n this._exporter._extensionsPostExportTextures(\"linkTextureInfo\", textureInfo, babylonTexture);\r\n }\r\n\r\n return textureInfo;\r\n });\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Builds a texture from base64 string\r\n * @param base64Texture base64 texture string\r\n * @param baseTextureName Name to use for the texture\r\n * @param mimeType image mime type for the texture\r\n * @param texCoordIndex\r\n * @param samplerIndex\r\n * @returns glTF texture info, or null if the texture format is not supported\r\n */\r\n private _getTextureInfoFromBase64(\r\n base64Texture: string,\r\n baseTextureName: string,\r\n mimeType: ImageMimeType,\r\n texCoordIndex: Nullable,\r\n samplerIndex: Nullable\r\n ): Nullable {\r\n const textures = this._exporter._textures;\r\n const images = this._exporter._images;\r\n const imageData = this._exporter._imageData;\r\n let textureInfo: Nullable = null;\r\n\r\n const glTFTexture: ITexture = {\r\n source: images.length,\r\n name: baseTextureName,\r\n };\r\n if (samplerIndex != null) {\r\n glTFTexture.sampler = samplerIndex;\r\n }\r\n\r\n const binStr = atob(base64Texture.split(\",\")[1]);\r\n const arrBuff = new ArrayBuffer(binStr.length);\r\n const arr = new Uint8Array(arrBuff);\r\n for (let i = 0, length = binStr.length; i < length; ++i) {\r\n arr[i] = binStr.charCodeAt(i);\r\n }\r\n const imageValues = { data: arr, mimeType: mimeType };\r\n\r\n const extension = mimeType === ImageMimeType.JPEG ? \".jpeg\" : \".png\";\r\n let textureName = baseTextureName + extension;\r\n const originalTextureName = textureName;\r\n if (textureName in imageData) {\r\n textureName = `${baseTextureName}_${Tools.RandomId()}${extension}`;\r\n }\r\n\r\n imageData[textureName] = imageValues;\r\n if (mimeType === ImageMimeType.JPEG || mimeType === ImageMimeType.PNG) {\r\n const glTFImage: IImage = {\r\n name: baseTextureName,\r\n uri: textureName,\r\n };\r\n let foundIndex: Nullable = null;\r\n for (let i = 0; i < images.length; ++i) {\r\n if (images[i].uri === originalTextureName) {\r\n foundIndex = i;\r\n break;\r\n }\r\n }\r\n if (foundIndex == null) {\r\n images.push(glTFImage);\r\n glTFTexture.source = images.length - 1;\r\n } else {\r\n glTFTexture.source = foundIndex;\r\n }\r\n textures.push(glTFTexture);\r\n textureInfo = {\r\n index: textures.length - 1,\r\n };\r\n if (texCoordIndex != null) {\r\n textureInfo.texCoord = texCoordIndex;\r\n }\r\n } else {\r\n Tools.Error(`Unsupported texture mime type ${mimeType}`);\r\n }\r\n\r\n return textureInfo;\r\n }\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 { AccessorType, ImageMimeType, MeshPrimitiveMode, AccessorComponentType, CameraType } from \"babylonjs-gltf2interface\";\r\n\r\nimport type { FloatArray, Nullable, IndicesArray } from \"core/types\";\r\nimport type { Matrix } from \"core/Maths/math.vector\";\r\nimport { Vector2, Vector3, Vector4, Quaternion } from \"core/Maths/math.vector\";\r\nimport { Color3, Color4 } from \"core/Maths/math.color\";\r\nimport { Tools } from \"core/Misc/tools\";\r\nimport { VertexBuffer } from \"core/Buffers/buffer\";\r\nimport type { Node } from \"core/node\";\r\nimport { TransformNode } from \"core/Meshes/transformNode\";\r\nimport type { AbstractMesh } from \"core/Meshes/abstractMesh\";\r\nimport type { SubMesh } from \"core/Meshes/subMesh\";\r\nimport { Mesh } from \"core/Meshes/mesh\";\r\nimport type { MorphTarget } from \"core/Morph/morphTarget\";\r\nimport { LinesMesh } from \"core/Meshes/linesMesh\";\r\nimport { InstancedMesh } from \"core/Meshes/instancedMesh\";\r\nimport type { Bone } from \"core/Bones/bone\";\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\n\r\nimport type { IGLTFExporterExtensionV2 } from \"./glTFExporterExtension\";\r\nimport { _GLTFMaterialExporter } from \"./glTFMaterialExporter\";\r\nimport type { IExportOptions } from \"./glTFSerializer\";\r\nimport { _GLTFUtilities } from \"./glTFUtilities\";\r\nimport { GLTFData } from \"./glTFData\";\r\nimport { _GLTFAnimation } from \"./glTFAnimation\";\r\nimport { Camera } from \"core/Cameras/camera\";\r\nimport { EngineStore } from \"core/Engines/engineStore\";\r\nimport { MultiMaterial } from \"core/Materials/multiMaterial\";\r\n\r\n/**\r\n * Utility interface for storing vertex attribute data\r\n * @internal\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\ninterface _IVertexAttributeData {\r\n /**\r\n * Specifies the Babylon Vertex Buffer Type (Position, Normal, Color, etc.)\r\n */\r\n kind: string;\r\n\r\n /**\r\n * Specifies the glTF Accessor Type (VEC2, VEC3, etc.)\r\n */\r\n accessorType: AccessorType;\r\n\r\n /**\r\n * Specifies the glTF Accessor Component Type (BYTE, UNSIGNED_BYTE, FLOAT, SHORT, INT, etc..)\r\n */\r\n accessorComponentType: AccessorComponentType;\r\n\r\n /**\r\n * Specifies the BufferView index for the vertex attribute data\r\n */\r\n bufferViewIndex?: number;\r\n\r\n byteStride?: number;\r\n}\r\n/**\r\n * Converts Babylon Scene into glTF 2.0.\r\n * @internal\r\n */\r\nexport class _Exporter {\r\n /**\r\n * Stores the glTF to export\r\n */\r\n public _glTF: IGLTF;\r\n /**\r\n * Stores all generated buffer views, which represents views into the main glTF buffer data\r\n */\r\n public _bufferViews: IBufferView[];\r\n /**\r\n * Stores all the generated accessors, which is used for accessing the data within the buffer views in glTF\r\n */\r\n public _accessors: IAccessor[];\r\n /**\r\n * Stores all the generated nodes, which contains transform and/or mesh information per node\r\n */\r\n public _nodes: INode[];\r\n /**\r\n * Stores all the generated glTF scenes, which stores multiple node hierarchies\r\n */\r\n private _scenes: IScene[];\r\n /**\r\n * Stores all the generated glTF cameras\r\n */\r\n private _cameras: ICamera[];\r\n /**\r\n * Stores all the generated mesh information, each containing a set of primitives to render in glTF\r\n */\r\n private _meshes: IMesh[];\r\n /**\r\n * Stores all the generated material information, which represents the appearance of each primitive\r\n */\r\n public _materials: IMaterial[];\r\n\r\n public _materialMap: { [materialID: number]: number };\r\n /**\r\n * Stores all the generated texture information, which is referenced by glTF materials\r\n */\r\n public _textures: ITexture[];\r\n /**\r\n * Stores all the generated image information, which is referenced by glTF textures\r\n */\r\n public _images: IImage[];\r\n\r\n /**\r\n * Stores all the texture samplers\r\n */\r\n public _samplers: ISampler[];\r\n /**\r\n * Stores all the generated glTF skins\r\n */\r\n public _skins: ISkin[];\r\n /**\r\n * Stores all the generated animation samplers, which is referenced by glTF animations\r\n */\r\n /**\r\n * Stores the animations for glTF models\r\n */\r\n private _animations: IAnimation[];\r\n /**\r\n * Stores the total amount of bytes stored in the glTF buffer\r\n */\r\n private _totalByteLength: number;\r\n /**\r\n * Stores a reference to the Babylon scene containing the source geometry and material information\r\n */\r\n public _babylonScene: Scene;\r\n /**\r\n * Stores a map of the image data, where the key is the file name and the value\r\n * is the image data\r\n */\r\n public _imageData: { [fileName: string]: { data: Uint8Array; mimeType: ImageMimeType } };\r\n\r\n protected _orderedImageData: Array<{ data: Uint8Array; mimeType: ImageMimeType }>;\r\n\r\n /**\r\n * Stores a map of the unique id of a node to its index in the node array\r\n */\r\n public _nodeMap: { [key: number]: number };\r\n\r\n /**\r\n * Specifies if the source Babylon scene was left handed, and needed conversion.\r\n */\r\n public _convertToRightHandedSystem: boolean;\r\n\r\n /**\r\n * Specifies if a Babylon node should be converted to right-handed on export\r\n */\r\n public _convertToRightHandedSystemMap: { [nodeId: number]: boolean };\r\n\r\n /*\r\n * Specifies if root Babylon empty nodes that act as a coordinate space transform should be included in export\r\n */\r\n public _includeCoordinateSystemConversionNodes: boolean = false;\r\n\r\n /**\r\n * Baked animation sample rate\r\n */\r\n private _animationSampleRate: number;\r\n\r\n private _options: IExportOptions;\r\n\r\n private _localEngine: Engine;\r\n\r\n public _glTFMaterialExporter: _GLTFMaterialExporter;\r\n\r\n private _extensions: { [name: string]: IGLTFExporterExtensionV2 } = {};\r\n\r\n private static _ExtensionNames = new Array();\r\n private static _ExtensionFactories: { [name: string]: (exporter: _Exporter) => IGLTFExporterExtensionV2 } = {};\r\n\r\n private _applyExtension(\r\n node: Nullable,\r\n extensions: IGLTFExporterExtensionV2[],\r\n index: number,\r\n actionAsync: (extension: IGLTFExporterExtensionV2, node: Nullable) => Promise> | undefined\r\n ): Promise> {\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 return currentPromise.then((newNode) => this._applyExtension(newNode, extensions, index + 1, actionAsync));\r\n }\r\n\r\n private _applyExtensions(\r\n node: Nullable,\r\n actionAsync: (extension: IGLTFExporterExtensionV2, node: Nullable) => Promise> | undefined\r\n ): Promise> {\r\n const extensions: IGLTFExporterExtensionV2[] = [];\r\n for (const name of _Exporter._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 public _extensionsPreExportTextureAsync(context: string, babylonTexture: Nullable, mimeType: ImageMimeType): Promise> {\r\n return this._applyExtensions(babylonTexture, (extension, node) => extension.preExportTextureAsync && extension.preExportTextureAsync(context, node, mimeType));\r\n }\r\n\r\n public _extensionsPostExportMeshPrimitiveAsync(\r\n context: string,\r\n meshPrimitive: IMeshPrimitive,\r\n babylonSubMesh: SubMesh,\r\n binaryWriter: _BinaryWriter\r\n ): Promise> {\r\n return this._applyExtensions(\r\n meshPrimitive,\r\n (extension, node) => extension.postExportMeshPrimitiveAsync && extension.postExportMeshPrimitiveAsync(context, node, babylonSubMesh, binaryWriter)\r\n );\r\n }\r\n\r\n public _extensionsPostExportNodeAsync(\r\n context: string,\r\n node: Nullable,\r\n babylonNode: Node,\r\n nodeMap?: { [key: number]: number },\r\n binaryWriter?: _BinaryWriter\r\n ): Promise> {\r\n return this._applyExtensions(node, (extension, node) => extension.postExportNodeAsync && extension.postExportNodeAsync(context, node, babylonNode, nodeMap, binaryWriter));\r\n }\r\n\r\n public _extensionsPostExportMaterialAsync(context: string, material: Nullable, babylonMaterial: Material): Promise> {\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 _Exporter._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 _Exporter._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 private _forEachExtensions(action: (extension: IGLTFExporterExtensionV2) => void): void {\r\n for (const name of _Exporter._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 if (this._glTF.extensionsUsed == null) {\r\n this._glTF.extensionsUsed = [];\r\n }\r\n\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 if (this._glTF.extensionsRequired == null) {\r\n this._glTF.extensionsRequired = [];\r\n }\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 if (this._glTF.extensions == null) {\r\n this._glTF.extensions = {};\r\n }\r\n\r\n if (extension.onExporting) {\r\n extension.onExporting();\r\n }\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Load glTF serializer extensions\r\n */\r\n private _loadExtensions(): void {\r\n for (const name of _Exporter._ExtensionNames) {\r\n const extension = _Exporter._ExtensionFactories[name](this);\r\n this._extensions[name] = extension;\r\n }\r\n }\r\n\r\n /**\r\n * Creates a glTF Exporter instance, which can accept optional exporter options\r\n * @param babylonScene Babylon scene object\r\n * @param options Options to modify the behavior of the exporter\r\n */\r\n public constructor(babylonScene?: Nullable, options?: IExportOptions) {\r\n this._glTF = {\r\n asset: { generator: `Babylon.js v${Engine.Version}`, version: \"2.0\" },\r\n };\r\n babylonScene = babylonScene || EngineStore.LastCreatedScene;\r\n if (!babylonScene) {\r\n return;\r\n }\r\n this._babylonScene = babylonScene;\r\n this._bufferViews = [];\r\n this._accessors = [];\r\n this._meshes = [];\r\n this._scenes = [];\r\n this._cameras = [];\r\n this._nodes = [];\r\n this._images = [];\r\n this._materials = [];\r\n this._materialMap = [];\r\n this._textures = [];\r\n this._samplers = [];\r\n this._skins = [];\r\n this._animations = [];\r\n this._imageData = {};\r\n this._orderedImageData = [];\r\n this._options = options || {};\r\n this._animationSampleRate = options && options.animationSampleRate ? options.animationSampleRate : 1 / 60;\r\n this._includeCoordinateSystemConversionNodes = options && options.includeCoordinateSystemConversionNodes ? true : false;\r\n\r\n this._glTFMaterialExporter = new _GLTFMaterialExporter(this);\r\n this._loadExtensions();\r\n }\r\n\r\n public dispose() {\r\n for (const extensionKey in this._extensions) {\r\n const extension = this._extensions[extensionKey];\r\n\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 /**\r\n * Registers a glTF exporter extension\r\n * @param name Name of the extension to export\r\n * @param factory The factory function that creates the exporter extension\r\n */\r\n public static RegisterExtension(name: string, factory: (exporter: _Exporter) => IGLTFExporterExtensionV2): void {\r\n if (_Exporter.UnregisterExtension(name)) {\r\n Tools.Warn(`Extension with the name ${name} already exists`);\r\n }\r\n\r\n _Exporter._ExtensionFactories[name] = factory;\r\n _Exporter._ExtensionNames.push(name);\r\n }\r\n\r\n /**\r\n * Un-registers an exporter extension\r\n * @param name The name fo the exporter extension\r\n * @returns A boolean indicating whether the extension has been un-registered\r\n */\r\n public static UnregisterExtension(name: string): boolean {\r\n if (!_Exporter._ExtensionFactories[name]) {\r\n return false;\r\n }\r\n delete _Exporter._ExtensionFactories[name];\r\n\r\n const index = _Exporter._ExtensionNames.indexOf(name);\r\n if (index !== -1) {\r\n _Exporter._ExtensionNames.splice(index, 1);\r\n }\r\n\r\n return true;\r\n }\r\n\r\n private _reorderIndicesBasedOnPrimitiveMode(submesh: SubMesh, primitiveMode: number, babylonIndices: IndicesArray, byteOffset: number, binaryWriter: _BinaryWriter) {\r\n switch (primitiveMode) {\r\n case Material.TriangleFillMode: {\r\n if (!byteOffset) {\r\n byteOffset = 0;\r\n }\r\n for (let i = submesh.indexStart, length = submesh.indexStart + submesh.indexCount; i < length; i = i + 3) {\r\n const index = byteOffset + i * 4;\r\n // swap the second and third indices\r\n const secondIndex = binaryWriter.getUInt32(index + 4);\r\n const thirdIndex = binaryWriter.getUInt32(index + 8);\r\n binaryWriter.setUInt32(thirdIndex, index + 4);\r\n binaryWriter.setUInt32(secondIndex, index + 8);\r\n }\r\n break;\r\n }\r\n case Material.TriangleFanDrawMode: {\r\n for (let i = submesh.indexStart + submesh.indexCount - 1, start = submesh.indexStart; i >= start; --i) {\r\n binaryWriter.setUInt32(babylonIndices[i], byteOffset);\r\n byteOffset += 4;\r\n }\r\n break;\r\n }\r\n case Material.TriangleStripDrawMode: {\r\n if (submesh.indexCount >= 3) {\r\n binaryWriter.setUInt32(babylonIndices[submesh.indexStart + 2], byteOffset + 4);\r\n binaryWriter.setUInt32(babylonIndices[submesh.indexStart + 1], byteOffset + 8);\r\n }\r\n break;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Reorders the vertex attribute data based on the primitive mode. This is necessary when indices are not available and the winding order is\r\n * clock-wise during export to glTF\r\n * @param submesh BabylonJS submesh\r\n * @param primitiveMode Primitive mode of the mesh\r\n * @param sideOrientation the winding order of the submesh\r\n * @param vertexBufferKind The type of vertex attribute\r\n * @param meshAttributeArray The vertex attribute data\r\n * @param byteOffset The offset to the binary data\r\n * @param binaryWriter The binary data for the glTF file\r\n * @param convertToRightHandedSystem Converts the values to right-handed\r\n */\r\n private _reorderVertexAttributeDataBasedOnPrimitiveMode(\r\n submesh: SubMesh,\r\n primitiveMode: number,\r\n sideOrientation: number,\r\n vertexBufferKind: string,\r\n meshAttributeArray: FloatArray,\r\n byteOffset: number,\r\n binaryWriter: _BinaryWriter,\r\n convertToRightHandedSystem: boolean\r\n ): void {\r\n if (convertToRightHandedSystem && sideOrientation === Material.ClockWiseSideOrientation) {\r\n switch (primitiveMode) {\r\n case Material.TriangleFillMode: {\r\n this._reorderTriangleFillMode(\r\n submesh,\r\n primitiveMode,\r\n sideOrientation,\r\n vertexBufferKind,\r\n meshAttributeArray,\r\n byteOffset,\r\n binaryWriter,\r\n convertToRightHandedSystem\r\n );\r\n break;\r\n }\r\n case Material.TriangleStripDrawMode: {\r\n this._reorderTriangleStripDrawMode(\r\n submesh,\r\n primitiveMode,\r\n sideOrientation,\r\n vertexBufferKind,\r\n meshAttributeArray,\r\n byteOffset,\r\n binaryWriter,\r\n convertToRightHandedSystem\r\n );\r\n break;\r\n }\r\n case Material.TriangleFanDrawMode: {\r\n this._reorderTriangleFanMode(\r\n submesh,\r\n primitiveMode,\r\n sideOrientation,\r\n vertexBufferKind,\r\n meshAttributeArray,\r\n byteOffset,\r\n binaryWriter,\r\n convertToRightHandedSystem\r\n );\r\n break;\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Reorders the vertex attributes in the correct triangle mode order . This is necessary when indices are not available and the winding order is\r\n * clock-wise during export to glTF\r\n * @param submesh BabylonJS submesh\r\n * @param primitiveMode Primitive mode of the mesh\r\n * @param sideOrientation the winding order of the submesh\r\n * @param vertexBufferKind The type of vertex attribute\r\n * @param meshAttributeArray The vertex attribute data\r\n * @param byteOffset The offset to the binary data\r\n * @param binaryWriter The binary data for the glTF file\r\n * @param convertToRightHandedSystem Converts the values to right-handed\r\n */\r\n private _reorderTriangleFillMode(\r\n submesh: SubMesh,\r\n primitiveMode: number,\r\n sideOrientation: number,\r\n vertexBufferKind: string,\r\n meshAttributeArray: FloatArray,\r\n byteOffset: number,\r\n binaryWriter: _BinaryWriter,\r\n convertToRightHandedSystem: boolean\r\n ) {\r\n const vertexBuffer = this._getVertexBufferFromMesh(vertexBufferKind, submesh.getMesh() as Mesh);\r\n if (vertexBuffer) {\r\n const stride = vertexBuffer.byteStride / VertexBuffer.GetTypeByteLength(vertexBuffer.type);\r\n if (submesh.verticesCount % 3 !== 0) {\r\n Tools.Error(\"The submesh vertices for the triangle fill mode is not divisible by 3!\");\r\n } else {\r\n const vertexData: Vector2[] | Vector3[] | Vector4[] = [];\r\n let index = 0;\r\n switch (vertexBufferKind) {\r\n case VertexBuffer.PositionKind:\r\n case VertexBuffer.NormalKind: {\r\n for (let x = submesh.verticesStart; x < submesh.verticesStart + submesh.verticesCount; x = x + 3) {\r\n index = x * stride;\r\n (vertexData as Vector3[]).push(Vector3.FromArray(meshAttributeArray, index));\r\n (vertexData as Vector3[]).push(Vector3.FromArray(meshAttributeArray, index + 2 * stride));\r\n (vertexData as Vector3[]).push(Vector3.FromArray(meshAttributeArray, index + stride));\r\n }\r\n break;\r\n }\r\n case VertexBuffer.TangentKind: {\r\n for (let x = submesh.verticesStart; x < submesh.verticesStart + submesh.verticesCount; x = x + 3) {\r\n index = x * stride;\r\n (vertexData as Vector4[]).push(Vector4.FromArray(meshAttributeArray, index));\r\n (vertexData as Vector4[]).push(Vector4.FromArray(meshAttributeArray, index + 2 * stride));\r\n (vertexData as Vector4[]).push(Vector4.FromArray(meshAttributeArray, index + stride));\r\n }\r\n break;\r\n }\r\n case VertexBuffer.ColorKind: {\r\n const size = vertexBuffer.getSize();\r\n for (let x = submesh.verticesStart; x < submesh.verticesStart + submesh.verticesCount; x = x + size) {\r\n index = x * stride;\r\n if (size === 4) {\r\n (vertexData as Vector4[]).push(Vector4.FromArray(meshAttributeArray, index));\r\n (vertexData as Vector4[]).push(Vector4.FromArray(meshAttributeArray, index + 2 * stride));\r\n (vertexData as Vector4[]).push(Vector4.FromArray(meshAttributeArray, index + stride));\r\n } else {\r\n (vertexData as Vector3[]).push(Vector3.FromArray(meshAttributeArray, index));\r\n (vertexData as Vector3[]).push(Vector3.FromArray(meshAttributeArray, index + 2 * stride));\r\n (vertexData as Vector3[]).push(Vector3.FromArray(meshAttributeArray, index + stride));\r\n }\r\n }\r\n break;\r\n }\r\n case VertexBuffer.UVKind:\r\n case VertexBuffer.UV2Kind: {\r\n for (let x = submesh.verticesStart; x < submesh.verticesStart + submesh.verticesCount; x = x + 3) {\r\n index = x * stride;\r\n (vertexData as Vector2[]).push(Vector2.FromArray(meshAttributeArray, index));\r\n (vertexData as Vector2[]).push(Vector2.FromArray(meshAttributeArray, index + 2 * stride));\r\n (vertexData as Vector2[]).push(Vector2.FromArray(meshAttributeArray, index + stride));\r\n }\r\n break;\r\n }\r\n default: {\r\n Tools.Error(`Unsupported Vertex Buffer type: ${vertexBufferKind}`);\r\n }\r\n }\r\n this._writeVertexAttributeData(vertexData, byteOffset, vertexBufferKind, meshAttributeArray, binaryWriter, convertToRightHandedSystem);\r\n }\r\n } else {\r\n Tools.Warn(`reorderTriangleFillMode: Vertex Buffer Kind ${vertexBufferKind} not present!`);\r\n }\r\n }\r\n\r\n /**\r\n * Reorders the vertex attributes in the correct triangle strip order. This is necessary when indices are not available and the winding order is\r\n * clock-wise during export to glTF\r\n * @param submesh BabylonJS submesh\r\n * @param primitiveMode Primitive mode of the mesh\r\n * @param sideOrientation the winding order of the submesh\r\n * @param vertexBufferKind The type of vertex attribute\r\n * @param meshAttributeArray The vertex attribute data\r\n * @param byteOffset The offset to the binary data\r\n * @param binaryWriter The binary data for the glTF file\r\n * @param convertToRightHandedSystem Converts the values to right-handed\r\n */\r\n private _reorderTriangleStripDrawMode(\r\n submesh: SubMesh,\r\n primitiveMode: number,\r\n sideOrientation: number,\r\n vertexBufferKind: string,\r\n meshAttributeArray: FloatArray,\r\n byteOffset: number,\r\n binaryWriter: _BinaryWriter,\r\n convertToRightHandedSystem: boolean\r\n ) {\r\n const vertexBuffer = this._getVertexBufferFromMesh(vertexBufferKind, submesh.getMesh() as Mesh);\r\n if (vertexBuffer) {\r\n const stride = vertexBuffer.byteStride / VertexBuffer.GetTypeByteLength(vertexBuffer.type);\r\n\r\n const vertexData: Vector2[] | Vector3[] | Vector4[] = [];\r\n let index = 0;\r\n switch (vertexBufferKind) {\r\n case VertexBuffer.PositionKind:\r\n case VertexBuffer.NormalKind: {\r\n index = submesh.verticesStart;\r\n (vertexData as Vector3[]).push(Vector3.FromArray(meshAttributeArray, index + 2 * stride));\r\n (vertexData as Vector3[]).push(Vector3.FromArray(meshAttributeArray, index + stride));\r\n break;\r\n }\r\n case VertexBuffer.TangentKind: {\r\n for (let x = submesh.verticesStart + submesh.verticesCount - 1; x >= submesh.verticesStart; --x) {\r\n index = x * stride;\r\n (vertexData as Vector4[]).push(Vector4.FromArray(meshAttributeArray, index));\r\n }\r\n break;\r\n }\r\n case VertexBuffer.ColorKind: {\r\n for (let x = submesh.verticesStart + submesh.verticesCount - 1; x >= submesh.verticesStart; --x) {\r\n index = x * stride;\r\n vertexBuffer.getSize() === 4\r\n ? (vertexData as Vector4[]).push(Vector4.FromArray(meshAttributeArray, index))\r\n : (vertexData as Vector3[]).push(Vector3.FromArray(meshAttributeArray, index));\r\n }\r\n break;\r\n }\r\n case VertexBuffer.UVKind:\r\n case VertexBuffer.UV2Kind: {\r\n for (let x = submesh.verticesStart + submesh.verticesCount - 1; x >= submesh.verticesStart; --x) {\r\n index = x * stride;\r\n (vertexData as Vector2[]).push(Vector2.FromArray(meshAttributeArray, index));\r\n }\r\n break;\r\n }\r\n default: {\r\n Tools.Error(`Unsupported Vertex Buffer type: ${vertexBufferKind}`);\r\n }\r\n }\r\n this._writeVertexAttributeData(vertexData, byteOffset + 12, vertexBufferKind, meshAttributeArray, binaryWriter, convertToRightHandedSystem);\r\n } else {\r\n Tools.Warn(`reorderTriangleStripDrawMode: Vertex buffer kind ${vertexBufferKind} not present!`);\r\n }\r\n }\r\n\r\n /**\r\n * Reorders the vertex attributes in the correct triangle fan order. This is necessary when indices are not available and the winding order is\r\n * clock-wise during export to glTF\r\n * @param submesh BabylonJS submesh\r\n * @param primitiveMode Primitive mode of the mesh\r\n * @param sideOrientation the winding order of the submesh\r\n * @param vertexBufferKind The type of vertex attribute\r\n * @param meshAttributeArray The vertex attribute data\r\n * @param byteOffset The offset to the binary data\r\n * @param binaryWriter The binary data for the glTF file\r\n * @param convertToRightHandedSystem Converts the values to right-handed\r\n */\r\n private _reorderTriangleFanMode(\r\n submesh: SubMesh,\r\n primitiveMode: number,\r\n sideOrientation: number,\r\n vertexBufferKind: string,\r\n meshAttributeArray: FloatArray,\r\n byteOffset: number,\r\n binaryWriter: _BinaryWriter,\r\n convertToRightHandedSystem: boolean\r\n ) {\r\n const vertexBuffer = this._getVertexBufferFromMesh(vertexBufferKind, submesh.getMesh() as Mesh);\r\n if (vertexBuffer) {\r\n const stride = vertexBuffer.byteStride / VertexBuffer.GetTypeByteLength(vertexBuffer.type);\r\n\r\n const vertexData: Vector2[] | Vector3[] | Vector4[] = [];\r\n let index = 0;\r\n switch (vertexBufferKind) {\r\n case VertexBuffer.PositionKind:\r\n case VertexBuffer.NormalKind: {\r\n for (let x = submesh.verticesStart + submesh.verticesCount - 1; x >= submesh.verticesStart; --x) {\r\n index = x * stride;\r\n (vertexData as Vector3[]).push(Vector3.FromArray(meshAttributeArray, index));\r\n }\r\n break;\r\n }\r\n case VertexBuffer.TangentKind: {\r\n for (let x = submesh.verticesStart + submesh.verticesCount - 1; x >= submesh.verticesStart; --x) {\r\n index = x * stride;\r\n (vertexData as Vector4[]).push(Vector4.FromArray(meshAttributeArray, index));\r\n }\r\n break;\r\n }\r\n case VertexBuffer.ColorKind: {\r\n for (let x = submesh.verticesStart + submesh.verticesCount - 1; x >= submesh.verticesStart; --x) {\r\n index = x * stride;\r\n (vertexData as Vector4[]).push(Vector4.FromArray(meshAttributeArray, index));\r\n vertexBuffer.getSize() === 4\r\n ? (vertexData as Vector4[]).push(Vector4.FromArray(meshAttributeArray, index))\r\n : (vertexData as Vector3[]).push(Vector3.FromArray(meshAttributeArray, index));\r\n }\r\n break;\r\n }\r\n case VertexBuffer.UVKind:\r\n case VertexBuffer.UV2Kind: {\r\n for (let x = submesh.verticesStart + submesh.verticesCount - 1; x >= submesh.verticesStart; --x) {\r\n index = x * stride;\r\n (vertexData as Vector2[]).push(Vector2.FromArray(meshAttributeArray, index));\r\n }\r\n break;\r\n }\r\n default: {\r\n Tools.Error(`Unsupported Vertex Buffer type: ${vertexBufferKind}`);\r\n }\r\n }\r\n this._writeVertexAttributeData(vertexData, byteOffset, vertexBufferKind, meshAttributeArray, binaryWriter, convertToRightHandedSystem);\r\n } else {\r\n Tools.Warn(`reorderTriangleFanMode: Vertex buffer kind ${vertexBufferKind} not present!`);\r\n }\r\n }\r\n\r\n /**\r\n * Writes the vertex attribute data to binary\r\n * @param vertices The vertices to write to the binary writer\r\n * @param byteOffset The offset into the binary writer to overwrite binary data\r\n * @param vertexAttributeKind The vertex attribute type\r\n * @param meshAttributeArray The vertex attribute data\r\n * @param binaryWriter The writer containing the binary data\r\n * @param convertToRightHandedSystem Converts the values to right-handed\r\n */\r\n private _writeVertexAttributeData(\r\n vertices: Vector2[] | Vector3[] | Vector4[],\r\n byteOffset: number,\r\n vertexAttributeKind: string,\r\n meshAttributeArray: FloatArray,\r\n binaryWriter: _BinaryWriter,\r\n convertToRightHandedSystem: boolean\r\n ) {\r\n for (const vertex of vertices) {\r\n if (convertToRightHandedSystem && !(vertexAttributeKind === VertexBuffer.ColorKind) && !(vertex instanceof Vector2)) {\r\n if (vertex instanceof Vector3) {\r\n if (vertexAttributeKind === VertexBuffer.NormalKind) {\r\n _GLTFUtilities._GetRightHandedNormalVector3FromRef(vertex);\r\n } else if (vertexAttributeKind === VertexBuffer.PositionKind) {\r\n _GLTFUtilities._GetRightHandedPositionVector3FromRef(vertex);\r\n } else {\r\n Tools.Error(\"Unsupported vertex attribute kind!\");\r\n }\r\n } else {\r\n _GLTFUtilities._GetRightHandedVector4FromRef(vertex);\r\n }\r\n }\r\n if (vertexAttributeKind === VertexBuffer.NormalKind) {\r\n vertex.normalize();\r\n } else if (vertexAttributeKind === VertexBuffer.TangentKind && vertex instanceof Vector4) {\r\n _GLTFUtilities._NormalizeTangentFromRef(vertex);\r\n }\r\n\r\n for (const component of vertex.asArray()) {\r\n binaryWriter.setFloat32(component, byteOffset);\r\n byteOffset += 4;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Writes mesh attribute data to a data buffer\r\n * Returns the bytelength of the data\r\n * @param vertexBufferKind Indicates what kind of vertex data is being passed in\r\n * @param attributeComponentKind\r\n * @param meshAttributeArray Array containing the attribute data\r\n * @param stride Specifies the space between data\r\n * @param binaryWriter The buffer to write the binary data to\r\n * @param convertToRightHandedSystem Converts the values to right-handed\r\n * @param babylonTransformNode\r\n */\r\n public _writeAttributeData(\r\n vertexBufferKind: string,\r\n attributeComponentKind: AccessorComponentType,\r\n meshAttributeArray: FloatArray,\r\n stride: number,\r\n binaryWriter: _BinaryWriter,\r\n convertToRightHandedSystem: boolean,\r\n babylonTransformNode: TransformNode\r\n ) {\r\n let vertexAttributes: number[][] = [];\r\n let index: number;\r\n\r\n switch (vertexBufferKind) {\r\n case VertexBuffer.PositionKind: {\r\n for (let k = 0, length = meshAttributeArray.length / stride; k < length; ++k) {\r\n index = k * stride;\r\n const vertexData = Vector3.FromArray(meshAttributeArray, index);\r\n if (convertToRightHandedSystem) {\r\n _GLTFUtilities._GetRightHandedPositionVector3FromRef(vertexData);\r\n }\r\n vertexAttributes.push(vertexData.asArray());\r\n }\r\n break;\r\n }\r\n case VertexBuffer.NormalKind: {\r\n for (let k = 0, length = meshAttributeArray.length / stride; k < length; ++k) {\r\n index = k * stride;\r\n const vertexData = Vector3.FromArray(meshAttributeArray, index);\r\n if (convertToRightHandedSystem) {\r\n _GLTFUtilities._GetRightHandedNormalVector3FromRef(vertexData);\r\n }\r\n vertexData.normalize();\r\n vertexAttributes.push(vertexData.asArray());\r\n }\r\n break;\r\n }\r\n case VertexBuffer.TangentKind: {\r\n for (let k = 0, length = meshAttributeArray.length / stride; k < length; ++k) {\r\n index = k * stride;\r\n const vertexData = Vector4.FromArray(meshAttributeArray, index);\r\n if (convertToRightHandedSystem) {\r\n _GLTFUtilities._GetRightHandedVector4FromRef(vertexData);\r\n }\r\n _GLTFUtilities._NormalizeTangentFromRef(vertexData);\r\n\r\n vertexAttributes.push(vertexData.asArray());\r\n }\r\n break;\r\n }\r\n case VertexBuffer.ColorKind: {\r\n const meshMaterial = (babylonTransformNode as Mesh).material;\r\n const convertToLinear = meshMaterial ? meshMaterial.getClassName() === \"StandardMaterial\" : true;\r\n const vertexData: Color3 | Color4 = stride === 3 ? new Color3() : new Color4();\r\n for (let k = 0, length = meshAttributeArray.length / stride; k < length; ++k) {\r\n index = k * stride;\r\n if (stride === 3) {\r\n Color3.FromArrayToRef(meshAttributeArray, index, vertexData as Color3);\r\n if (convertToLinear) {\r\n (vertexData as Color3).toLinearSpaceToRef(vertexData as Color3);\r\n }\r\n } else {\r\n Color4.FromArrayToRef(meshAttributeArray, index, vertexData as Color4);\r\n if (convertToLinear) {\r\n (vertexData as Color4).toLinearSpaceToRef(vertexData as Color4);\r\n }\r\n }\r\n vertexAttributes.push(vertexData.asArray());\r\n }\r\n break;\r\n }\r\n case VertexBuffer.UVKind:\r\n case VertexBuffer.UV2Kind: {\r\n for (let k = 0, length = meshAttributeArray.length / stride; k < length; ++k) {\r\n index = k * stride;\r\n vertexAttributes.push(\r\n convertToRightHandedSystem ? [meshAttributeArray[index], meshAttributeArray[index + 1]] : [meshAttributeArray[index], meshAttributeArray[index + 1]]\r\n );\r\n }\r\n break;\r\n }\r\n case VertexBuffer.MatricesIndicesKind:\r\n case VertexBuffer.MatricesIndicesExtraKind: {\r\n for (let k = 0, length = meshAttributeArray.length / stride; k < length; ++k) {\r\n index = k * stride;\r\n const vertexData = Vector4.FromArray(meshAttributeArray, index);\r\n vertexAttributes.push(vertexData.asArray());\r\n }\r\n break;\r\n }\r\n case VertexBuffer.MatricesWeightsKind:\r\n case VertexBuffer.MatricesWeightsExtraKind: {\r\n for (let k = 0, length = meshAttributeArray.length / stride; k < length; ++k) {\r\n index = k * stride;\r\n const vertexData = Vector4.FromArray(meshAttributeArray, index);\r\n vertexAttributes.push(vertexData.asArray());\r\n }\r\n break;\r\n }\r\n default: {\r\n Tools.Warn(\"Unsupported Vertex Buffer Type: \" + vertexBufferKind);\r\n vertexAttributes = [];\r\n }\r\n }\r\n\r\n let writeBinaryFunc;\r\n switch (attributeComponentKind) {\r\n case AccessorComponentType.UNSIGNED_BYTE: {\r\n writeBinaryFunc = binaryWriter.setUInt8.bind(binaryWriter);\r\n break;\r\n }\r\n case AccessorComponentType.UNSIGNED_SHORT: {\r\n writeBinaryFunc = binaryWriter.setUInt16.bind(binaryWriter);\r\n break;\r\n }\r\n case AccessorComponentType.UNSIGNED_INT: {\r\n writeBinaryFunc = binaryWriter.setUInt32.bind(binaryWriter);\r\n break;\r\n }\r\n case AccessorComponentType.FLOAT: {\r\n writeBinaryFunc = binaryWriter.setFloat32.bind(binaryWriter);\r\n break;\r\n }\r\n default: {\r\n Tools.Warn(\"Unsupported Attribute Component kind: \" + attributeComponentKind);\r\n return;\r\n }\r\n }\r\n\r\n for (const vertexAttribute of vertexAttributes) {\r\n for (const component of vertexAttribute) {\r\n writeBinaryFunc(component);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Writes mesh attribute data to a data buffer\r\n * Returns the bytelength of the data\r\n * @param vertexBufferKind Indicates what kind of vertex data is being passed in\r\n * @param attributeComponentKind\r\n * @param meshPrimitive\r\n * @param morphTarget\r\n * @param meshAttributeArray Array containing the attribute data\r\n * @param morphTargetAttributeArray\r\n * @param stride Specifies the space between data\r\n * @param binaryWriter The buffer to write the binary data to\r\n * @param convertToRightHandedSystem Converts the values to right-handed\r\n * @param minMax\r\n */\r\n public writeMorphTargetAttributeData(\r\n vertexBufferKind: string,\r\n attributeComponentKind: AccessorComponentType,\r\n meshPrimitive: SubMesh,\r\n morphTarget: MorphTarget,\r\n meshAttributeArray: FloatArray,\r\n morphTargetAttributeArray: FloatArray,\r\n stride: number,\r\n binaryWriter: _BinaryWriter,\r\n convertToRightHandedSystem: boolean,\r\n minMax?: any\r\n ) {\r\n let vertexAttributes: number[][] = [];\r\n let index: number;\r\n let difference: Vector3 = new Vector3();\r\n let difference4: Vector4 = new Vector4(0, 0, 0, 0);\r\n\r\n switch (vertexBufferKind) {\r\n case VertexBuffer.PositionKind: {\r\n for (let k = meshPrimitive.verticesStart; k < meshPrimitive.verticesCount; ++k) {\r\n index = meshPrimitive.indexStart + k * stride;\r\n const vertexData = Vector3.FromArray(meshAttributeArray, index);\r\n const morphData = Vector3.FromArray(morphTargetAttributeArray, index);\r\n difference = morphData.subtractToRef(vertexData, difference);\r\n if (convertToRightHandedSystem) {\r\n _GLTFUtilities._GetRightHandedPositionVector3FromRef(difference);\r\n }\r\n if (minMax) {\r\n minMax.min.copyFromFloats(Math.min(difference.x, minMax.min.x), Math.min(difference.y, minMax.min.y), Math.min(difference.z, minMax.min.z));\r\n minMax.max.copyFromFloats(Math.max(difference.x, minMax.max.x), Math.max(difference.y, minMax.max.y), Math.max(difference.z, minMax.max.z));\r\n }\r\n vertexAttributes.push(difference.asArray());\r\n }\r\n break;\r\n }\r\n case VertexBuffer.NormalKind: {\r\n for (let k = meshPrimitive.verticesStart; k < meshPrimitive.verticesCount; ++k) {\r\n index = meshPrimitive.indexStart + k * stride;\r\n const vertexData = Vector3.FromArray(meshAttributeArray, index);\r\n vertexData.normalize();\r\n const morphData = Vector3.FromArray(morphTargetAttributeArray, index);\r\n morphData.normalize();\r\n difference = morphData.subtractToRef(vertexData, difference);\r\n if (convertToRightHandedSystem) {\r\n _GLTFUtilities._GetRightHandedNormalVector3FromRef(difference);\r\n }\r\n vertexAttributes.push(difference.asArray());\r\n }\r\n break;\r\n }\r\n case VertexBuffer.TangentKind: {\r\n for (let k = meshPrimitive.verticesStart; k < meshPrimitive.verticesCount; ++k) {\r\n index = meshPrimitive.indexStart + k * (stride + 1);\r\n const vertexData = Vector4.FromArray(meshAttributeArray, index);\r\n _GLTFUtilities._NormalizeTangentFromRef(vertexData);\r\n const morphData = Vector4.FromArray(morphTargetAttributeArray, index);\r\n _GLTFUtilities._NormalizeTangentFromRef(morphData);\r\n difference4 = morphData.subtractToRef(vertexData, difference4);\r\n if (convertToRightHandedSystem) {\r\n _GLTFUtilities._GetRightHandedVector4FromRef(difference4);\r\n }\r\n vertexAttributes.push([difference4.x, difference4.y, difference4.z]);\r\n }\r\n break;\r\n }\r\n default: {\r\n Tools.Warn(\"Unsupported Vertex Buffer Type: \" + vertexBufferKind);\r\n vertexAttributes = [];\r\n }\r\n }\r\n\r\n let writeBinaryFunc;\r\n switch (attributeComponentKind) {\r\n case AccessorComponentType.UNSIGNED_BYTE: {\r\n writeBinaryFunc = binaryWriter.setUInt8.bind(binaryWriter);\r\n break;\r\n }\r\n case AccessorComponentType.UNSIGNED_SHORT: {\r\n writeBinaryFunc = binaryWriter.setUInt16.bind(binaryWriter);\r\n break;\r\n }\r\n case AccessorComponentType.UNSIGNED_INT: {\r\n writeBinaryFunc = binaryWriter.setUInt32.bind(binaryWriter);\r\n break;\r\n }\r\n case AccessorComponentType.FLOAT: {\r\n writeBinaryFunc = binaryWriter.setFloat32.bind(binaryWriter);\r\n break;\r\n }\r\n default: {\r\n Tools.Warn(\"Unsupported Attribute Component kind: \" + attributeComponentKind);\r\n return;\r\n }\r\n }\r\n\r\n for (const vertexAttribute of vertexAttributes) {\r\n for (const component of vertexAttribute) {\r\n writeBinaryFunc(component);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Generates glTF json data\r\n * @param shouldUseGlb Indicates whether the json should be written for a glb file\r\n * @param glTFPrefix Text to use when prefixing a glTF file\r\n * @param prettyPrint Indicates whether the json file should be pretty printed (true) or not (false)\r\n * @returns json data as string\r\n */\r\n private _generateJSON(shouldUseGlb: boolean, glTFPrefix?: string, prettyPrint?: boolean): string {\r\n const buffer: IBuffer = { byteLength: this._totalByteLength };\r\n let imageName: string;\r\n let imageData: { data: Uint8Array; mimeType: ImageMimeType };\r\n let bufferView: IBufferView;\r\n let byteOffset: number = this._totalByteLength;\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 if (!shouldUseGlb) {\r\n this._glTF.images = this._images;\r\n } else {\r\n this._glTF.images = [];\r\n\r\n this._images.forEach((image) => {\r\n if (image.uri) {\r\n imageData = this._imageData[image.uri];\r\n this._orderedImageData.push(imageData);\r\n imageName = image.uri.split(\".\")[0] + \" image\";\r\n bufferView = _GLTFUtilities._CreateBufferView(0, byteOffset, imageData.data.length, undefined, imageName);\r\n byteOffset += imageData.data.buffer.byteLength;\r\n this._bufferViews.push(bufferView);\r\n image.bufferView = this._bufferViews.length - 1;\r\n image.name = imageName;\r\n image.mimeType = imageData.mimeType;\r\n image.uri = undefined;\r\n if (!this._glTF.images) {\r\n this._glTF.images = [];\r\n }\r\n this._glTF.images.push(image);\r\n }\r\n });\r\n // Replace uri with bufferview and mime type for glb\r\n buffer.byteLength = byteOffset;\r\n }\r\n }\r\n\r\n if (!shouldUseGlb) {\r\n buffer.uri = glTFPrefix + \".bin\";\r\n }\r\n\r\n const jsonText = prettyPrint ? JSON.stringify(this._glTF, null, 2) : JSON.stringify(this._glTF);\r\n\r\n return jsonText;\r\n }\r\n\r\n /**\r\n * Generates data for .gltf and .bin files based on the glTF prefix string\r\n * @param glTFPrefix Text to use when prefixing a glTF file\r\n * @param dispose Dispose the exporter\r\n * @returns GLTFData with glTF file data\r\n */\r\n public _generateGLTFAsync(glTFPrefix: string, dispose = true): Promise {\r\n return this._generateBinaryAsync().then((binaryBuffer) => {\r\n this._extensionsOnExporting();\r\n const jsonText = this._generateJSON(false, 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.glTFFiles[glTFFileName] = jsonText;\r\n container.glTFFiles[glTFBinFile] = bin;\r\n\r\n if (this._imageData) {\r\n for (const image in this._imageData) {\r\n container.glTFFiles[image] = new Blob([this._imageData[image].data], { type: this._imageData[image].mimeType });\r\n }\r\n }\r\n\r\n if (dispose) {\r\n this.dispose();\r\n }\r\n\r\n return container;\r\n });\r\n }\r\n\r\n /**\r\n * Creates a binary buffer for glTF\r\n * @returns array buffer for binary data\r\n */\r\n private _generateBinaryAsync(): Promise {\r\n const binaryWriter = new _BinaryWriter(4);\r\n return this._createSceneAsync(this._babylonScene, binaryWriter).then(() => {\r\n if (this._localEngine) {\r\n this._localEngine.dispose();\r\n }\r\n return binaryWriter.getArrayBuffer();\r\n });\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 /**\r\n * @internal\r\n */\r\n public _generateGLBAsync(glTFPrefix: string, dispose = true): Promise {\r\n return this._generateBinaryAsync().then((binaryBuffer) => {\r\n this._extensionsOnExporting();\r\n const jsonText = this._generateJSON(true);\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 let imageByteLength = 0;\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 for (let i = 0; i < this._orderedImageData.length; ++i) {\r\n imageByteLength += this._orderedImageData[i].data.byteLength;\r\n }\r\n const jsonPadding = this._getPadding(jsonLength);\r\n const binPadding = this._getPadding(binaryBuffer.byteLength);\r\n const imagePadding = this._getPadding(imageByteLength);\r\n\r\n const byteLength = headerLength + 2 * chunkLengthPrefix + jsonLength + jsonPadding + binaryBuffer.byteLength + binPadding + imageByteLength + imagePadding;\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 + imageByteLength + imagePadding, 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 imagePaddingBuffer = new ArrayBuffer(imagePadding);\r\n const imagePaddingView = new Uint8Array(imagePaddingBuffer);\r\n for (let i = 0; i < imagePadding; ++i) {\r\n imagePaddingView[i] = 0;\r\n }\r\n\r\n const glbData = [headerBuffer, jsonChunkBuffer, binaryChunkBuffer, binaryBuffer];\r\n\r\n // binary data\r\n for (let i = 0; i < this._orderedImageData.length; ++i) {\r\n glbData.push(this._orderedImageData[i].data.buffer);\r\n }\r\n\r\n glbData.push(binPaddingBuffer);\r\n\r\n glbData.push(imagePaddingBuffer);\r\n\r\n const glbFile = new Blob(glbData, { type: \"application/octet-stream\" });\r\n\r\n const container = new GLTFData();\r\n container.glTFFiles[glbFileName] = glbFile;\r\n\r\n if (this._localEngine != null) {\r\n this._localEngine.dispose();\r\n }\r\n\r\n if (dispose) {\r\n this.dispose();\r\n }\r\n\r\n return container;\r\n });\r\n }\r\n\r\n /**\r\n * Sets the TRS for each node\r\n * @param node glTF Node for storing the transformation data\r\n * @param babylonTransformNode Babylon mesh used as the source for the transformation data\r\n * @param convertToRightHandedSystem Converts the values to right-handed\r\n */\r\n private _setNodeTransformation(node: INode, babylonTransformNode: TransformNode, convertToRightHandedSystem: 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 if (!babylonTransformNode.position.equalsToFloats(0, 0, 0)) {\r\n node.translation = convertToRightHandedSystem\r\n ? _GLTFUtilities._GetRightHandedPositionVector3(babylonTransformNode.position).asArray()\r\n : babylonTransformNode.position.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.RotationYawPitchRoll(babylonTransformNode.rotation.y, babylonTransformNode.rotation.x, 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 (convertToRightHandedSystem) {\r\n _GLTFUtilities._GetRightHandedQuaternionFromRef(rotationQuaternion);\r\n }\r\n node.rotation = rotationQuaternion.normalize().asArray();\r\n }\r\n }\r\n\r\n private _setCameraTransformation(node: INode, babylonCamera: Camera, convertToRightHandedSystem: boolean): void {\r\n if (!babylonCamera.position.equalsToFloats(0, 0, 0)) {\r\n node.translation = convertToRightHandedSystem ? _GLTFUtilities._GetRightHandedPositionVector3(babylonCamera.position).asArray() : babylonCamera.position.asArray();\r\n }\r\n\r\n const rotationQuaternion = (babylonCamera).rotationQuaternion; // we target the local transformation if one.\r\n\r\n if (rotationQuaternion && !Quaternion.IsIdentity(rotationQuaternion)) {\r\n if (convertToRightHandedSystem) {\r\n _GLTFUtilities._GetRightHandedQuaternionFromRef(rotationQuaternion);\r\n }\r\n node.rotation = rotationQuaternion.normalize().asArray();\r\n }\r\n }\r\n\r\n private _getVertexBufferFromMesh(attributeKind: string, bufferMesh: Mesh): Nullable {\r\n if (bufferMesh.isVerticesDataPresent(attributeKind)) {\r\n const vertexBuffer = bufferMesh.getVertexBuffer(attributeKind);\r\n if (vertexBuffer) {\r\n return vertexBuffer;\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n /**\r\n * Creates a bufferview based on the vertices type for the Babylon mesh\r\n * @param kind Indicates the type of vertices data\r\n * @param attributeComponentKind Indicates the numerical type used to store the data\r\n * @param babylonTransformNode The Babylon mesh to get the vertices data from\r\n * @param binaryWriter The buffer to write the bufferview data to\r\n * @param byteStride\r\n * @param convertToRightHandedSystem Converts the values to right-handed\r\n */\r\n private _createBufferViewKind(\r\n kind: string,\r\n attributeComponentKind: AccessorComponentType,\r\n babylonTransformNode: TransformNode,\r\n binaryWriter: _BinaryWriter,\r\n byteStride: number,\r\n convertToRightHandedSystem: boolean\r\n ) {\r\n const bufferMesh =\r\n babylonTransformNode instanceof Mesh\r\n ? (babylonTransformNode as Mesh)\r\n : babylonTransformNode instanceof InstancedMesh\r\n ? (babylonTransformNode as InstancedMesh).sourceMesh\r\n : null;\r\n\r\n if (bufferMesh) {\r\n const vertexBuffer = bufferMesh.getVertexBuffer(kind);\r\n const vertexData = bufferMesh.getVerticesData(kind);\r\n\r\n if (vertexBuffer && vertexData) {\r\n const typeByteLength = VertexBuffer.GetTypeByteLength(attributeComponentKind);\r\n const byteLength = vertexData.length * typeByteLength;\r\n const bufferView = _GLTFUtilities._CreateBufferView(0, binaryWriter.getByteOffset(), byteLength, byteStride, kind + \" - \" + bufferMesh.name);\r\n this._bufferViews.push(bufferView);\r\n\r\n this._writeAttributeData(kind, attributeComponentKind, vertexData, byteStride / typeByteLength, binaryWriter, convertToRightHandedSystem, babylonTransformNode);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Creates a bufferview based on the vertices type for the Babylon mesh\r\n * @param babylonSubMesh The Babylon submesh that the morph target is applied to\r\n * @param meshPrimitive\r\n * @param babylonMorphTarget the morph target to be exported\r\n * @param binaryWriter The buffer to write the bufferview data to\r\n * @param convertToRightHandedSystem Converts the values to right-handed\r\n */\r\n private _setMorphTargetAttributes(\r\n babylonSubMesh: SubMesh,\r\n meshPrimitive: IMeshPrimitive,\r\n babylonMorphTarget: MorphTarget,\r\n binaryWriter: _BinaryWriter,\r\n convertToRightHandedSystem: boolean\r\n ) {\r\n if (babylonMorphTarget) {\r\n if (!meshPrimitive.targets) {\r\n meshPrimitive.targets = [];\r\n }\r\n const target: { [attribute: string]: number } = {};\r\n if (babylonMorphTarget.hasNormals) {\r\n const vertexNormals = babylonSubMesh.getMesh().getVerticesData(VertexBuffer.NormalKind)!;\r\n const morphNormals = babylonMorphTarget.getNormals()!;\r\n const count = babylonSubMesh.verticesCount;\r\n const byteStride = 12; // 3 x 4 byte floats\r\n const byteLength = count * byteStride;\r\n const bufferView = _GLTFUtilities._CreateBufferView(0, binaryWriter.getByteOffset(), byteLength, byteStride, babylonMorphTarget.name + \"_NORMAL\");\r\n this._bufferViews.push(bufferView);\r\n\r\n const bufferViewIndex = this._bufferViews.length - 1;\r\n const accessor = _GLTFUtilities._CreateAccessor(\r\n bufferViewIndex,\r\n babylonMorphTarget.name + \" - \" + \"NORMAL\",\r\n AccessorType.VEC3,\r\n AccessorComponentType.FLOAT,\r\n count,\r\n 0,\r\n null,\r\n null\r\n );\r\n this._accessors.push(accessor);\r\n target.NORMAL = this._accessors.length - 1;\r\n\r\n this.writeMorphTargetAttributeData(\r\n VertexBuffer.NormalKind,\r\n AccessorComponentType.FLOAT,\r\n babylonSubMesh,\r\n babylonMorphTarget,\r\n vertexNormals,\r\n morphNormals,\r\n byteStride / 4,\r\n binaryWriter,\r\n convertToRightHandedSystem\r\n );\r\n }\r\n if (babylonMorphTarget.hasPositions) {\r\n const vertexPositions = babylonSubMesh.getMesh().getVerticesData(VertexBuffer.PositionKind)!;\r\n const morphPositions = babylonMorphTarget.getPositions()!;\r\n const count = babylonSubMesh.verticesCount;\r\n const byteStride = 12; // 3 x 4 byte floats\r\n const byteLength = count * byteStride;\r\n const bufferView = _GLTFUtilities._CreateBufferView(0, binaryWriter.getByteOffset(), byteLength, byteStride, babylonMorphTarget.name + \"_POSITION\");\r\n this._bufferViews.push(bufferView);\r\n\r\n const bufferViewIndex = this._bufferViews.length - 1;\r\n const minMax = { min: new Vector3(Infinity, Infinity, Infinity), max: new Vector3(-Infinity, -Infinity, -Infinity) };\r\n const accessor = _GLTFUtilities._CreateAccessor(\r\n bufferViewIndex,\r\n babylonMorphTarget.name + \" - \" + \"POSITION\",\r\n AccessorType.VEC3,\r\n AccessorComponentType.FLOAT,\r\n count,\r\n 0,\r\n null,\r\n null\r\n );\r\n this._accessors.push(accessor);\r\n target.POSITION = this._accessors.length - 1;\r\n\r\n this.writeMorphTargetAttributeData(\r\n VertexBuffer.PositionKind,\r\n AccessorComponentType.FLOAT,\r\n babylonSubMesh,\r\n babylonMorphTarget,\r\n vertexPositions,\r\n morphPositions,\r\n byteStride / 4,\r\n binaryWriter,\r\n convertToRightHandedSystem,\r\n minMax\r\n );\r\n accessor.min = minMax.min!.asArray();\r\n accessor.max = minMax.max!.asArray();\r\n }\r\n if (babylonMorphTarget.hasTangents) {\r\n const vertexTangents = babylonSubMesh.getMesh().getVerticesData(VertexBuffer.TangentKind)!;\r\n const morphTangents = babylonMorphTarget.getTangents()!;\r\n const count = babylonSubMesh.verticesCount;\r\n const byteStride = 12; // 3 x 4 byte floats\r\n const byteLength = count * byteStride;\r\n const bufferView = _GLTFUtilities._CreateBufferView(0, binaryWriter.getByteOffset(), byteLength, byteStride, babylonMorphTarget.name + \"_NORMAL\");\r\n this._bufferViews.push(bufferView);\r\n\r\n const bufferViewIndex = this._bufferViews.length - 1;\r\n const accessor = _GLTFUtilities._CreateAccessor(\r\n bufferViewIndex,\r\n babylonMorphTarget.name + \" - \" + \"TANGENT\",\r\n AccessorType.VEC3,\r\n AccessorComponentType.FLOAT,\r\n count,\r\n 0,\r\n null,\r\n null\r\n );\r\n this._accessors.push(accessor);\r\n target.TANGENT = this._accessors.length - 1;\r\n\r\n this.writeMorphTargetAttributeData(\r\n VertexBuffer.TangentKind,\r\n AccessorComponentType.FLOAT,\r\n babylonSubMesh,\r\n babylonMorphTarget,\r\n vertexTangents,\r\n morphTangents,\r\n byteStride / 4,\r\n binaryWriter,\r\n convertToRightHandedSystem\r\n );\r\n }\r\n meshPrimitive.targets.push(target);\r\n }\r\n }\r\n\r\n /**\r\n * The primitive mode of the Babylon mesh\r\n * @param babylonMesh The BabylonJS mesh\r\n */\r\n private _getMeshPrimitiveMode(babylonMesh: AbstractMesh): number {\r\n if (babylonMesh instanceof LinesMesh) {\r\n return Material.LineListDrawMode;\r\n }\r\n return babylonMesh.material ? babylonMesh.material.fillMode : Material.TriangleFillMode;\r\n }\r\n\r\n /**\r\n * Sets the primitive mode of the glTF mesh primitive\r\n * @param meshPrimitive glTF mesh primitive\r\n * @param primitiveMode The primitive mode\r\n */\r\n private _setPrimitiveMode(meshPrimitive: IMeshPrimitive, primitiveMode: number) {\r\n switch (primitiveMode) {\r\n case Material.TriangleFillMode: {\r\n // glTF defaults to using Triangle Mode\r\n break;\r\n }\r\n case Material.TriangleStripDrawMode: {\r\n meshPrimitive.mode = MeshPrimitiveMode.TRIANGLE_STRIP;\r\n break;\r\n }\r\n case Material.TriangleFanDrawMode: {\r\n meshPrimitive.mode = MeshPrimitiveMode.TRIANGLE_FAN;\r\n break;\r\n }\r\n case Material.PointListDrawMode: {\r\n meshPrimitive.mode = MeshPrimitiveMode.POINTS;\r\n break;\r\n }\r\n case Material.PointFillMode: {\r\n meshPrimitive.mode = MeshPrimitiveMode.POINTS;\r\n break;\r\n }\r\n case Material.LineLoopDrawMode: {\r\n meshPrimitive.mode = MeshPrimitiveMode.LINE_LOOP;\r\n break;\r\n }\r\n case Material.LineListDrawMode: {\r\n meshPrimitive.mode = MeshPrimitiveMode.LINES;\r\n break;\r\n }\r\n case Material.LineStripDrawMode: {\r\n meshPrimitive.mode = MeshPrimitiveMode.LINE_STRIP;\r\n break;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Sets the vertex attribute accessor based of the glTF mesh primitive\r\n * @param meshPrimitive glTF mesh primitive\r\n * @param attributeKind vertex attribute\r\n * @returns boolean specifying if uv coordinates are present\r\n */\r\n private _setAttributeKind(meshPrimitive: IMeshPrimitive, attributeKind: string): void {\r\n switch (attributeKind) {\r\n case VertexBuffer.PositionKind: {\r\n meshPrimitive.attributes.POSITION = this._accessors.length - 1;\r\n break;\r\n }\r\n case VertexBuffer.NormalKind: {\r\n meshPrimitive.attributes.NORMAL = this._accessors.length - 1;\r\n break;\r\n }\r\n case VertexBuffer.ColorKind: {\r\n meshPrimitive.attributes.COLOR_0 = this._accessors.length - 1;\r\n break;\r\n }\r\n case VertexBuffer.TangentKind: {\r\n meshPrimitive.attributes.TANGENT = this._accessors.length - 1;\r\n break;\r\n }\r\n case VertexBuffer.UVKind: {\r\n meshPrimitive.attributes.TEXCOORD_0 = this._accessors.length - 1;\r\n break;\r\n }\r\n case VertexBuffer.UV2Kind: {\r\n meshPrimitive.attributes.TEXCOORD_1 = this._accessors.length - 1;\r\n break;\r\n }\r\n case VertexBuffer.MatricesIndicesKind: {\r\n meshPrimitive.attributes.JOINTS_0 = this._accessors.length - 1;\r\n break;\r\n }\r\n case VertexBuffer.MatricesIndicesExtraKind: {\r\n meshPrimitive.attributes.JOINTS_1 = this._accessors.length - 1;\r\n break;\r\n }\r\n case VertexBuffer.MatricesWeightsKind: {\r\n meshPrimitive.attributes.WEIGHTS_0 = this._accessors.length - 1;\r\n break;\r\n }\r\n case VertexBuffer.MatricesWeightsExtraKind: {\r\n meshPrimitive.attributes.WEIGHTS_1 = this._accessors.length - 1;\r\n break;\r\n }\r\n default: {\r\n Tools.Warn(\"Unsupported Vertex Buffer Type: \" + attributeKind);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Sets data for the primitive attributes of each submesh\r\n * @param mesh glTF Mesh object to store the primitive attribute information\r\n * @param babylonTransformNode Babylon mesh to get the primitive attribute data from\r\n * @param binaryWriter Buffer to write the attribute data to\r\n * @param convertToRightHandedSystem Converts the values to right-handed\r\n */\r\n private _setPrimitiveAttributesAsync(mesh: IMesh, babylonTransformNode: TransformNode, binaryWriter: _BinaryWriter, convertToRightHandedSystem: boolean): Promise {\r\n const promises: Promise[] = [];\r\n let bufferMesh: Nullable = null;\r\n let bufferView: IBufferView;\r\n let minMax: { min: Nullable; max: Nullable };\r\n\r\n if (babylonTransformNode instanceof Mesh) {\r\n bufferMesh = babylonTransformNode as Mesh;\r\n } else if (babylonTransformNode instanceof InstancedMesh) {\r\n bufferMesh = (babylonTransformNode as InstancedMesh).sourceMesh;\r\n }\r\n const attributeData: _IVertexAttributeData[] = [\r\n { kind: VertexBuffer.PositionKind, accessorType: AccessorType.VEC3, accessorComponentType: AccessorComponentType.FLOAT, byteStride: 12 },\r\n { kind: VertexBuffer.NormalKind, accessorType: AccessorType.VEC3, accessorComponentType: AccessorComponentType.FLOAT, byteStride: 12 },\r\n { kind: VertexBuffer.ColorKind, accessorType: AccessorType.VEC4, accessorComponentType: AccessorComponentType.FLOAT, byteStride: 16 },\r\n { kind: VertexBuffer.TangentKind, accessorType: AccessorType.VEC4, accessorComponentType: AccessorComponentType.FLOAT, byteStride: 16 },\r\n { kind: VertexBuffer.UVKind, accessorType: AccessorType.VEC2, accessorComponentType: AccessorComponentType.FLOAT, byteStride: 8 },\r\n { kind: VertexBuffer.UV2Kind, accessorType: AccessorType.VEC2, accessorComponentType: AccessorComponentType.FLOAT, byteStride: 8 },\r\n { kind: VertexBuffer.MatricesIndicesKind, accessorType: AccessorType.VEC4, accessorComponentType: AccessorComponentType.UNSIGNED_SHORT, byteStride: 8 },\r\n { kind: VertexBuffer.MatricesIndicesExtraKind, accessorType: AccessorType.VEC4, accessorComponentType: AccessorComponentType.UNSIGNED_SHORT, byteStride: 8 },\r\n { kind: VertexBuffer.MatricesWeightsKind, accessorType: AccessorType.VEC4, accessorComponentType: AccessorComponentType.FLOAT, byteStride: 16 },\r\n { kind: VertexBuffer.MatricesWeightsExtraKind, accessorType: AccessorType.VEC4, accessorComponentType: AccessorComponentType.FLOAT, byteStride: 16 },\r\n ];\r\n\r\n if (bufferMesh) {\r\n let indexBufferViewIndex: Nullable = null;\r\n const primitiveMode = this._getMeshPrimitiveMode(bufferMesh);\r\n const vertexAttributeBufferViews: { [attributeKind: string]: number } = {};\r\n const morphTargetManager = bufferMesh.morphTargetManager;\r\n\r\n // For each BabylonMesh, create bufferviews for each 'kind'\r\n for (const attribute of attributeData) {\r\n const attributeKind = attribute.kind;\r\n const attributeComponentKind = attribute.accessorComponentType;\r\n if (bufferMesh.isVerticesDataPresent(attributeKind)) {\r\n const vertexBuffer = this._getVertexBufferFromMesh(attributeKind, bufferMesh);\r\n attribute.byteStride = vertexBuffer\r\n ? vertexBuffer.getSize() * VertexBuffer.GetTypeByteLength(attribute.accessorComponentType)\r\n : VertexBuffer.DeduceStride(attributeKind) * 4;\r\n if (attribute.byteStride === 12) {\r\n attribute.accessorType = AccessorType.VEC3;\r\n }\r\n\r\n this._createBufferViewKind(attributeKind, attributeComponentKind, babylonTransformNode, binaryWriter, attribute.byteStride, convertToRightHandedSystem);\r\n attribute.bufferViewIndex = this._bufferViews.length - 1;\r\n vertexAttributeBufferViews[attributeKind] = attribute.bufferViewIndex;\r\n }\r\n }\r\n\r\n if (bufferMesh.getTotalIndices()) {\r\n const indices = bufferMesh.getIndices();\r\n if (indices) {\r\n const byteLength = indices.length * 4;\r\n bufferView = _GLTFUtilities._CreateBufferView(0, binaryWriter.getByteOffset(), byteLength, undefined, \"Indices - \" + bufferMesh.name);\r\n this._bufferViews.push(bufferView);\r\n indexBufferViewIndex = this._bufferViews.length - 1;\r\n\r\n for (let k = 0, length = indices.length; k < length; ++k) {\r\n binaryWriter.setUInt32(indices[k]);\r\n }\r\n }\r\n }\r\n\r\n if (bufferMesh.subMeshes) {\r\n // go through all mesh primitives (submeshes)\r\n for (const submesh of bufferMesh.subMeshes) {\r\n let babylonMaterial = submesh.getMaterial() || bufferMesh.getScene().defaultMaterial;\r\n\r\n let materialIndex: Nullable = null;\r\n if (babylonMaterial) {\r\n if (bufferMesh instanceof LinesMesh) {\r\n // get the color from the lines mesh and set it in the material\r\n const material: IMaterial = {\r\n name: bufferMesh.name + \" material\",\r\n };\r\n if (!bufferMesh.color.equals(Color3.White()) || bufferMesh.alpha < 1) {\r\n material.pbrMetallicRoughness = {\r\n baseColorFactor: bufferMesh.color.asArray().concat([bufferMesh.alpha]),\r\n };\r\n }\r\n this._materials.push(material);\r\n materialIndex = this._materials.length - 1;\r\n } else if (babylonMaterial instanceof MultiMaterial) {\r\n const subMaterial = babylonMaterial.subMaterials[submesh.materialIndex];\r\n if (subMaterial) {\r\n babylonMaterial = subMaterial;\r\n materialIndex = this._materialMap[babylonMaterial.uniqueId];\r\n }\r\n } else {\r\n materialIndex = this._materialMap[babylonMaterial.uniqueId];\r\n }\r\n }\r\n\r\n const glTFMaterial: Nullable = materialIndex != null ? this._materials[materialIndex] : null;\r\n\r\n const meshPrimitive: IMeshPrimitive = { attributes: {} };\r\n this._setPrimitiveMode(meshPrimitive, primitiveMode);\r\n\r\n for (const attribute of attributeData) {\r\n const attributeKind = attribute.kind;\r\n if ((attributeKind === VertexBuffer.UVKind || attributeKind === VertexBuffer.UV2Kind) && !this._options.exportUnusedUVs) {\r\n if (!glTFMaterial || !this._glTFMaterialExporter._hasTexturesPresent(glTFMaterial)) {\r\n continue;\r\n }\r\n }\r\n const vertexData = bufferMesh.getVerticesData(attributeKind);\r\n if (vertexData) {\r\n const vertexBuffer = this._getVertexBufferFromMesh(attributeKind, bufferMesh);\r\n if (vertexBuffer) {\r\n const stride = vertexBuffer.getSize();\r\n const bufferViewIndex = attribute.bufferViewIndex;\r\n if (bufferViewIndex != undefined) {\r\n // check to see if bufferviewindex has a numeric value assigned.\r\n minMax = { min: null, max: null };\r\n if (attributeKind == VertexBuffer.PositionKind) {\r\n minMax = _GLTFUtilities._CalculateMinMaxPositions(vertexData, 0, vertexData.length / stride, convertToRightHandedSystem);\r\n }\r\n const accessor = _GLTFUtilities._CreateAccessor(\r\n bufferViewIndex,\r\n attributeKind + \" - \" + babylonTransformNode.name,\r\n attribute.accessorType,\r\n attribute.accessorComponentType,\r\n vertexData.length / stride,\r\n 0,\r\n minMax.min,\r\n minMax.max\r\n );\r\n this._accessors.push(accessor);\r\n this._setAttributeKind(meshPrimitive, attributeKind);\r\n }\r\n }\r\n }\r\n }\r\n if (indexBufferViewIndex) {\r\n // Create accessor\r\n const accessor = _GLTFUtilities._CreateAccessor(\r\n indexBufferViewIndex,\r\n \"indices - \" + babylonTransformNode.name,\r\n AccessorType.SCALAR,\r\n AccessorComponentType.UNSIGNED_INT,\r\n submesh.indexCount,\r\n submesh.indexStart * 4,\r\n null,\r\n null\r\n );\r\n this._accessors.push(accessor);\r\n meshPrimitive.indices = this._accessors.length - 1;\r\n }\r\n if (materialIndex != null && Object.keys(meshPrimitive.attributes).length > 0) {\r\n const sideOrientation = bufferMesh.overrideMaterialSideOrientation !== null ? bufferMesh.overrideMaterialSideOrientation : babylonMaterial.sideOrientation;\r\n\r\n if (\r\n (sideOrientation == Material.ClockWiseSideOrientation && this._babylonScene.useRightHandedSystem) ||\r\n (sideOrientation == Material.ClockWiseSideOrientation &&\r\n convertToRightHandedSystem &&\r\n bufferMesh.overrideMaterialSideOrientation !== bufferMesh.material?.sideOrientation)\r\n ) {\r\n let byteOffset = indexBufferViewIndex != null ? this._bufferViews[indexBufferViewIndex].byteOffset : null;\r\n if (byteOffset == null) {\r\n byteOffset = 0;\r\n }\r\n let babylonIndices: Nullable = null;\r\n if (indexBufferViewIndex != null) {\r\n babylonIndices = bufferMesh.getIndices();\r\n }\r\n if (babylonIndices) {\r\n this._reorderIndicesBasedOnPrimitiveMode(submesh, primitiveMode, babylonIndices, byteOffset, binaryWriter);\r\n } else {\r\n for (const attribute of attributeData) {\r\n const vertexData = bufferMesh.getVerticesData(attribute.kind);\r\n if (vertexData) {\r\n let byteOffset = this._bufferViews[vertexAttributeBufferViews[attribute.kind]].byteOffset;\r\n if (!byteOffset) {\r\n byteOffset = 0;\r\n }\r\n this._reorderVertexAttributeDataBasedOnPrimitiveMode(\r\n submesh,\r\n primitiveMode,\r\n sideOrientation,\r\n attribute.kind,\r\n vertexData,\r\n byteOffset,\r\n binaryWriter,\r\n convertToRightHandedSystem\r\n );\r\n }\r\n }\r\n }\r\n }\r\n\r\n meshPrimitive.material = materialIndex;\r\n }\r\n if (morphTargetManager) {\r\n let target;\r\n for (let i = 0; i < morphTargetManager.numTargets; ++i) {\r\n target = morphTargetManager.getTarget(i);\r\n this._setMorphTargetAttributes(submesh, meshPrimitive, target, binaryWriter, convertToRightHandedSystem);\r\n }\r\n }\r\n\r\n mesh.primitives.push(meshPrimitive);\r\n\r\n this._extensionsPostExportMeshPrimitiveAsync(\"postExport\", meshPrimitive, submesh, binaryWriter);\r\n promises.push();\r\n }\r\n }\r\n }\r\n return Promise.all(promises).then(() => {\r\n /* do nothing */\r\n });\r\n }\r\n\r\n /**\r\n * Check if the node is used to convert its descendants from a right handed coordinate system to the Babylon scene's coordinate system.\r\n * @param node The node to check\r\n * @returns True if the node is used to convert its descendants from right-handed to left-handed. False otherwise\r\n */\r\n private _isBabylonCoordinateSystemConvertingNode(node: Node): boolean {\r\n if (node instanceof TransformNode) {\r\n if (node.name !== \"__root__\") {\r\n return false;\r\n }\r\n\r\n // Transform\r\n const matrix = node.getWorldMatrix();\r\n\r\n if (matrix.determinant() === 1) {\r\n return false;\r\n }\r\n\r\n // Geometry\r\n if ((node instanceof Mesh && node.geometry !== null) || (node instanceof InstancedMesh && node.sourceMesh.geometry !== null)) {\r\n return false;\r\n }\r\n\r\n if (this._includeCoordinateSystemConversionNodes) {\r\n return false;\r\n }\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n /**\r\n * Creates a glTF scene based on the array of meshes\r\n * Returns the the total byte offset\r\n * @param babylonScene Babylon scene to get the mesh data from\r\n * @param binaryWriter Buffer to write binary data to\r\n */\r\n private _createSceneAsync(babylonScene: Scene, binaryWriter: _BinaryWriter): Promise {\r\n const scene: IScene = { nodes: [] };\r\n let glTFNodeIndex: number;\r\n let glTFNode: INode;\r\n let directDescendents: Node[];\r\n const nodes: Node[] = [...babylonScene.transformNodes, ...babylonScene.meshes, ...babylonScene.lights, ...babylonScene.cameras];\r\n const rootNodesToLeftHanded: Node[] = [];\r\n\r\n this._convertToRightHandedSystem = !babylonScene.useRightHandedSystem;\r\n this._convertToRightHandedSystemMap = {};\r\n\r\n // Set default values for all nodes\r\n babylonScene.rootNodes.forEach((rootNode) => {\r\n this._convertToRightHandedSystemMap[rootNode.uniqueId] = this._convertToRightHandedSystem;\r\n rootNode.getDescendants(false).forEach((descendant) => {\r\n this._convertToRightHandedSystemMap[descendant.uniqueId] = this._convertToRightHandedSystem;\r\n });\r\n });\r\n\r\n // Check if root nodes converting to left-handed are present\r\n babylonScene.rootNodes.forEach((rootNode) => {\r\n if (this._isBabylonCoordinateSystemConvertingNode(rootNode)) {\r\n rootNodesToLeftHanded.push(rootNode);\r\n\r\n // Exclude the node from list of nodes to export\r\n const indexRootNode = nodes.indexOf(rootNode);\r\n if (indexRootNode !== -1) {\r\n // should always be true\r\n nodes.splice(indexRootNode, 1);\r\n }\r\n\r\n // Cancel conversion to right handed system\r\n rootNode.getDescendants(false).forEach((descendant) => {\r\n this._convertToRightHandedSystemMap[descendant.uniqueId] = false;\r\n });\r\n }\r\n });\r\n\r\n // Export babylon cameras to glTFCamera\r\n const cameraMap = new Map();\r\n babylonScene.cameras.forEach((camera) => {\r\n if (!this._options.shouldExportNode || this._options.shouldExportNode(camera)) {\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\r\n cameraMap.set(camera, this._cameras.length);\r\n this._cameras.push(glTFCamera);\r\n }\r\n });\r\n\r\n const [exportNodes, exportMaterials] = this._getExportNodes(nodes);\r\n return this._glTFMaterialExporter._convertMaterialsToGLTFAsync(exportMaterials, ImageMimeType.PNG, true).then(() => {\r\n return this._createNodeMapAndAnimationsAsync(babylonScene, exportNodes, binaryWriter).then((nodeMap) => {\r\n return this._createSkinsAsync(babylonScene, nodeMap, binaryWriter).then((skinMap) => {\r\n this._nodeMap = nodeMap;\r\n\r\n this._totalByteLength = binaryWriter.getByteOffset();\r\n if (this._totalByteLength == undefined) {\r\n throw new Error(\"undefined byte length!\");\r\n }\r\n\r\n // Build Hierarchy with the node map.\r\n for (const babylonNode of nodes) {\r\n glTFNodeIndex = this._nodeMap[babylonNode.uniqueId];\r\n if (glTFNodeIndex !== undefined) {\r\n glTFNode = this._nodes[glTFNodeIndex];\r\n\r\n if (babylonNode.metadata) {\r\n if (this._options.metadataSelector) {\r\n glTFNode.extras = this._options.metadataSelector(babylonNode.metadata);\r\n } else if (babylonNode.metadata.gltf) {\r\n glTFNode.extras = babylonNode.metadata.gltf.extras;\r\n }\r\n }\r\n\r\n if (babylonNode instanceof Camera) {\r\n glTFNode.camera = cameraMap.get(babylonNode);\r\n }\r\n\r\n if (!babylonNode.parent || rootNodesToLeftHanded.indexOf(babylonNode.parent) !== -1) {\r\n if (this._options.shouldExportNode && !this._options.shouldExportNode(babylonNode)) {\r\n Tools.Log(\"Omitting \" + babylonNode.name + \" from scene.\");\r\n } else {\r\n const convertToRightHandedSystem = this._convertToRightHandedSystemMap[babylonNode.uniqueId];\r\n if (convertToRightHandedSystem) {\r\n if (glTFNode.translation) {\r\n glTFNode.translation[2] *= -1;\r\n glTFNode.translation[0] *= -1;\r\n }\r\n glTFNode.rotation = glTFNode.rotation\r\n ? Quaternion.FromArray([0, 1, 0, 0]).multiply(Quaternion.FromArray(glTFNode.rotation)).asArray()\r\n : Quaternion.FromArray([0, 1, 0, 0]).asArray();\r\n }\r\n\r\n scene.nodes.push(glTFNodeIndex);\r\n }\r\n }\r\n\r\n if (babylonNode instanceof Mesh) {\r\n const babylonMesh: Mesh = babylonNode;\r\n if (babylonMesh.skeleton) {\r\n glTFNode.skin = skinMap[babylonMesh.skeleton.uniqueId];\r\n }\r\n }\r\n\r\n directDescendents = babylonNode.getDescendants(true);\r\n if (!glTFNode.children && directDescendents && directDescendents.length) {\r\n const children: number[] = [];\r\n for (const descendent of directDescendents) {\r\n if (this._nodeMap[descendent.uniqueId] != null) {\r\n children.push(this._nodeMap[descendent.uniqueId]);\r\n }\r\n }\r\n if (children.length) {\r\n glTFNode.children = children;\r\n }\r\n }\r\n }\r\n }\r\n if (scene.nodes.length) {\r\n this._scenes.push(scene);\r\n }\r\n });\r\n });\r\n });\r\n }\r\n\r\n /**\r\n * Getting the nodes and materials that would be exported.\r\n * @param nodes Babylon transform nodes\r\n * @returns Array of nodes which would be exported.\r\n * @returns Set of materials which would be exported.\r\n */\r\n private _getExportNodes(nodes: Node[]): [Node[], Set] {\r\n const exportNodes: Node[] = [];\r\n const exportMaterials: Set = new Set();\r\n\r\n for (const babylonNode of nodes) {\r\n if (!this._options.shouldExportNode || this._options.shouldExportNode(babylonNode)) {\r\n exportNodes.push(babylonNode);\r\n\r\n const babylonMesh = babylonNode as AbstractMesh;\r\n if (babylonMesh.subMeshes && babylonMesh.subMeshes.length > 0) {\r\n const material = babylonMesh.material || babylonMesh.getScene().defaultMaterial;\r\n if (material instanceof MultiMaterial) {\r\n for (const subMaterial of material.subMaterials) {\r\n if (subMaterial) {\r\n exportMaterials.add(subMaterial);\r\n }\r\n }\r\n } else {\r\n exportMaterials.add(material);\r\n }\r\n }\r\n } else {\r\n `Excluding node ${babylonNode.name}`;\r\n }\r\n }\r\n\r\n return [exportNodes, exportMaterials];\r\n }\r\n\r\n /**\r\n * Creates a mapping of Node unique id to node index and handles animations\r\n * @param babylonScene Babylon Scene\r\n * @param nodes Babylon transform nodes\r\n * @param binaryWriter Buffer to write binary data to\r\n * @returns Node mapping of unique id to index\r\n */\r\n private _createNodeMapAndAnimationsAsync(babylonScene: Scene, nodes: Node[], binaryWriter: _BinaryWriter): Promise<{ [key: number]: number }> {\r\n let promiseChain = Promise.resolve();\r\n const nodeMap: { [key: number]: number } = {};\r\n let nodeIndex: number;\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 for (const babylonNode of nodes) {\r\n promiseChain = promiseChain.then(() => {\r\n const convertToRightHandedSystem = this._convertToRightHandedSystemMap[babylonNode.uniqueId];\r\n return this._createNodeAsync(babylonNode, binaryWriter, convertToRightHandedSystem).then((node) => {\r\n const promise = this._extensionsPostExportNodeAsync(\"createNodeAsync\", node, babylonNode, nodeMap, binaryWriter);\r\n if (promise == null) {\r\n Tools.Warn(`Not exporting node ${babylonNode.name}`);\r\n return Promise.resolve();\r\n } else {\r\n return promise.then((node) => {\r\n if (!node) {\r\n return;\r\n }\r\n this._nodes.push(node);\r\n nodeIndex = this._nodes.length - 1;\r\n nodeMap[babylonNode.uniqueId] = nodeIndex;\r\n\r\n if (!babylonScene.animationGroups.length) {\r\n _GLTFAnimation._CreateMorphTargetAnimationFromMorphTargetAnimations(\r\n babylonNode,\r\n runtimeGLTFAnimation,\r\n idleGLTFAnimations,\r\n nodeMap,\r\n this._nodes,\r\n binaryWriter,\r\n this._bufferViews,\r\n this._accessors,\r\n convertToRightHandedSystem,\r\n this._animationSampleRate\r\n );\r\n if (babylonNode.animations.length) {\r\n _GLTFAnimation._CreateNodeAnimationFromNodeAnimations(\r\n babylonNode,\r\n runtimeGLTFAnimation,\r\n idleGLTFAnimations,\r\n nodeMap,\r\n this._nodes,\r\n binaryWriter,\r\n this._bufferViews,\r\n this._accessors,\r\n convertToRightHandedSystem,\r\n this._animationSampleRate\r\n );\r\n }\r\n }\r\n });\r\n }\r\n });\r\n });\r\n }\r\n\r\n return promiseChain.then(() => {\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 if (babylonScene.animationGroups.length) {\r\n _GLTFAnimation._CreateNodeAndMorphAnimationFromAnimationGroups(\r\n babylonScene,\r\n this._animations,\r\n nodeMap,\r\n this._nodes,\r\n binaryWriter,\r\n this._bufferViews,\r\n this._accessors,\r\n this._convertToRightHandedSystemMap,\r\n this._animationSampleRate\r\n );\r\n }\r\n\r\n return nodeMap;\r\n });\r\n }\r\n\r\n /**\r\n * Creates a glTF node from a Babylon mesh\r\n * @param babylonNode Source Babylon mesh\r\n * @param binaryWriter Buffer for storing geometry data\r\n * @param convertToRightHandedSystem Converts the values to right-handed\r\n * @returns glTF node\r\n */\r\n private _createNodeAsync(babylonNode: Node, binaryWriter: _BinaryWriter, convertToRightHandedSystem: boolean): Promise {\r\n return Promise.resolve().then(() => {\r\n // create node to hold translation/rotation/scale and the mesh\r\n const node: INode = {};\r\n // create mesh\r\n const mesh: IMesh = { primitives: [] };\r\n\r\n if (babylonNode.name) {\r\n node.name = babylonNode.name;\r\n }\r\n\r\n if (babylonNode instanceof TransformNode) {\r\n // Set transformation\r\n this._setNodeTransformation(node, babylonNode, convertToRightHandedSystem);\r\n if (babylonNode instanceof Mesh) {\r\n const morphTargetManager = babylonNode.morphTargetManager;\r\n if (morphTargetManager && morphTargetManager.numTargets > 0) {\r\n mesh.weights = [];\r\n for (let i = 0; i < morphTargetManager.numTargets; ++i) {\r\n mesh.weights.push(morphTargetManager.getTarget(i).influence);\r\n }\r\n }\r\n }\r\n return this._setPrimitiveAttributesAsync(mesh, babylonNode, binaryWriter, convertToRightHandedSystem).then(() => {\r\n if (mesh.primitives.length) {\r\n this._meshes.push(mesh);\r\n node.mesh = this._meshes.length - 1;\r\n }\r\n return node;\r\n });\r\n } else if (babylonNode instanceof Camera) {\r\n this._setCameraTransformation(node, babylonNode, convertToRightHandedSystem);\r\n return node;\r\n } else {\r\n return node;\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Creates a glTF skin from a Babylon skeleton\r\n * @param babylonScene Babylon Scene\r\n * @param nodeMap Babylon transform nodes\r\n * @param binaryWriter Buffer to write binary data to\r\n * @returns Node mapping of unique id to index\r\n */\r\n private _createSkinsAsync(babylonScene: Scene, nodeMap: { [key: number]: number }, binaryWriter: _BinaryWriter): Promise<{ [key: number]: number }> {\r\n const promiseChain = Promise.resolve();\r\n const skinMap: { [key: number]: number } = {};\r\n for (const skeleton of babylonScene.skeletons) {\r\n if (skeleton.bones.length <= 0) {\r\n continue;\r\n }\r\n // create skin\r\n const skin: ISkin = { joints: [] };\r\n const inverseBindMatrices: Matrix[] = [];\r\n\r\n const boneIndexMap: { [index: number]: Bone } = {};\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 for (let boneIndex = 0; boneIndex <= maxBoneIndex; ++boneIndex) {\r\n const bone = boneIndexMap[boneIndex];\r\n inverseBindMatrices.push(bone.getInvertedAbsoluteTransform());\r\n\r\n const transformNode = bone.getTransformNode();\r\n if (transformNode) {\r\n skin.joints.push(nodeMap[transformNode.uniqueId]);\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 // create buffer view for inverse bind matrices\r\n const byteStride = 64; // 4 x 4 matrix of 32 bit float\r\n const byteLength = inverseBindMatrices.length * byteStride;\r\n const bufferViewOffset = binaryWriter.getByteOffset();\r\n const bufferView = _GLTFUtilities._CreateBufferView(0, bufferViewOffset, byteLength, undefined, \"InverseBindMatrices\" + \" - \" + skeleton.name);\r\n this._bufferViews.push(bufferView);\r\n const bufferViewIndex = this._bufferViews.length - 1;\r\n const bindMatrixAccessor = _GLTFUtilities._CreateAccessor(\r\n bufferViewIndex,\r\n \"InverseBindMatrices\" + \" - \" + skeleton.name,\r\n AccessorType.MAT4,\r\n AccessorComponentType.FLOAT,\r\n inverseBindMatrices.length,\r\n null,\r\n null,\r\n null\r\n );\r\n const inverseBindAccessorIndex = this._accessors.push(bindMatrixAccessor) - 1;\r\n skin.inverseBindMatrices = inverseBindAccessorIndex;\r\n this._skins.push(skin);\r\n skinMap[skeleton.uniqueId] = this._skins.length - 1;\r\n\r\n inverseBindMatrices.forEach((mat) => {\r\n mat.m.forEach((cell: number) => {\r\n binaryWriter.setFloat32(cell);\r\n });\r\n });\r\n }\r\n return promiseChain.then(() => {\r\n return skinMap;\r\n });\r\n }\r\n}\r\n\r\n/**\r\n * @internal\r\n *\r\n * Stores glTF binary data. If the array buffer byte length is exceeded, it doubles in size dynamically\r\n */\r\nexport class _BinaryWriter {\r\n /**\r\n * Array buffer which stores all binary data\r\n */\r\n private _arrayBuffer: ArrayBuffer;\r\n /**\r\n * View of the array buffer\r\n */\r\n private _dataView: DataView;\r\n /**\r\n * byte offset of data in array buffer\r\n */\r\n private _byteOffset: number;\r\n /**\r\n * Initialize binary writer with an initial byte length\r\n * @param byteLength Initial byte length of the array buffer\r\n */\r\n constructor(byteLength: number) {\r\n this._arrayBuffer = new ArrayBuffer(byteLength);\r\n this._dataView = new DataView(this._arrayBuffer);\r\n this._byteOffset = 0;\r\n }\r\n /**\r\n * Resize the array buffer to the specified byte length\r\n * @param byteLength\r\n */\r\n private _resizeBuffer(byteLength: number): ArrayBuffer {\r\n const newBuffer = new ArrayBuffer(byteLength);\r\n const oldUint8Array = new Uint8Array(this._arrayBuffer);\r\n const newUint8Array = new Uint8Array(newBuffer);\r\n for (let i = 0, length = newUint8Array.byteLength; i < length; ++i) {\r\n newUint8Array[i] = oldUint8Array[i];\r\n }\r\n this._arrayBuffer = newBuffer;\r\n this._dataView = new DataView(this._arrayBuffer);\r\n\r\n return newBuffer;\r\n }\r\n /**\r\n * Get an array buffer with the length of the byte offset\r\n * @returns ArrayBuffer resized to the byte offset\r\n */\r\n public getArrayBuffer(): ArrayBuffer {\r\n return this._resizeBuffer(this.getByteOffset());\r\n }\r\n /**\r\n * Get the byte offset of the array buffer\r\n * @returns byte offset\r\n */\r\n public getByteOffset(): number {\r\n if (this._byteOffset == undefined) {\r\n throw new Error(\"Byte offset is undefined!\");\r\n }\r\n return this._byteOffset;\r\n }\r\n /**\r\n * Stores an UInt8 in the array buffer\r\n * @param entry\r\n * @param byteOffset If defined, specifies where to set the value as an offset.\r\n */\r\n public setUInt8(entry: number, byteOffset?: number) {\r\n if (byteOffset != null) {\r\n if (byteOffset < this._byteOffset) {\r\n this._dataView.setUint8(byteOffset, entry);\r\n } else {\r\n Tools.Error(\"BinaryWriter: byteoffset is greater than the current binary buffer length!\");\r\n }\r\n } else {\r\n if (this._byteOffset + 1 > this._arrayBuffer.byteLength) {\r\n this._resizeBuffer(this._arrayBuffer.byteLength * 2);\r\n }\r\n this._dataView.setUint8(this._byteOffset, entry);\r\n this._byteOffset += 1;\r\n }\r\n }\r\n\r\n /**\r\n * Stores an UInt16 in the array buffer\r\n * @param entry\r\n * @param byteOffset If defined, specifies where to set the value as an offset.\r\n */\r\n public setUInt16(entry: number, byteOffset?: number) {\r\n if (byteOffset != null) {\r\n if (byteOffset < this._byteOffset) {\r\n this._dataView.setUint16(byteOffset, entry, true);\r\n } else {\r\n Tools.Error(\"BinaryWriter: byteoffset is greater than the current binary buffer length!\");\r\n }\r\n } else {\r\n if (this._byteOffset + 2 > this._arrayBuffer.byteLength) {\r\n this._resizeBuffer(this._arrayBuffer.byteLength * 2);\r\n }\r\n this._dataView.setUint16(this._byteOffset, entry, true);\r\n this._byteOffset += 2;\r\n }\r\n }\r\n\r\n /**\r\n * Gets an UInt32 in the array buffer\r\n * @param byteOffset If defined, specifies where to set the value as an offset.\r\n */\r\n public getUInt32(byteOffset: number): number {\r\n if (byteOffset < this._byteOffset) {\r\n return this._dataView.getUint32(byteOffset, true);\r\n } else {\r\n Tools.Error(\"BinaryWriter: byteoffset is greater than the current binary buffer length!\");\r\n throw new Error(\"BinaryWriter: byteoffset is greater than the current binary buffer length!\");\r\n }\r\n }\r\n\r\n public getVector3Float32FromRef(vector3: Vector3, byteOffset: number): void {\r\n if (byteOffset + 8 > this._byteOffset) {\r\n Tools.Error(`BinaryWriter: byteoffset is greater than the current binary buffer length!`);\r\n } else {\r\n vector3.x = this._dataView.getFloat32(byteOffset, true);\r\n vector3.y = this._dataView.getFloat32(byteOffset + 4, true);\r\n vector3.z = this._dataView.getFloat32(byteOffset + 8, true);\r\n }\r\n }\r\n\r\n public setVector3Float32FromRef(vector3: Vector3, byteOffset: number): void {\r\n if (byteOffset + 8 > this._byteOffset) {\r\n Tools.Error(`BinaryWriter: byteoffset is greater than the current binary buffer length!`);\r\n } else {\r\n this._dataView.setFloat32(byteOffset, vector3.x, true);\r\n this._dataView.setFloat32(byteOffset + 4, vector3.y, true);\r\n this._dataView.setFloat32(byteOffset + 8, vector3.z, true);\r\n }\r\n }\r\n\r\n public getVector4Float32FromRef(vector4: Vector4, byteOffset: number): void {\r\n if (byteOffset + 12 > this._byteOffset) {\r\n Tools.Error(`BinaryWriter: byteoffset is greater than the current binary buffer length!`);\r\n } else {\r\n vector4.x = this._dataView.getFloat32(byteOffset, true);\r\n vector4.y = this._dataView.getFloat32(byteOffset + 4, true);\r\n vector4.z = this._dataView.getFloat32(byteOffset + 8, true);\r\n vector4.w = this._dataView.getFloat32(byteOffset + 12, true);\r\n }\r\n }\r\n\r\n public setVector4Float32FromRef(vector4: Vector4, byteOffset: number): void {\r\n if (byteOffset + 12 > this._byteOffset) {\r\n Tools.Error(`BinaryWriter: byteoffset is greater than the current binary buffer length!`);\r\n } else {\r\n this._dataView.setFloat32(byteOffset, vector4.x, true);\r\n this._dataView.setFloat32(byteOffset + 4, vector4.y, true);\r\n this._dataView.setFloat32(byteOffset + 8, vector4.z, true);\r\n this._dataView.setFloat32(byteOffset + 12, vector4.w, true);\r\n }\r\n }\r\n /**\r\n * Stores a Float32 in the array buffer\r\n * @param entry\r\n * @param byteOffset\r\n */\r\n public setFloat32(entry: number, byteOffset?: number) {\r\n if (isNaN(entry)) {\r\n Tools.Error(\"Invalid data being written!\");\r\n }\r\n if (byteOffset != null) {\r\n if (byteOffset < this._byteOffset) {\r\n this._dataView.setFloat32(byteOffset, entry, true);\r\n } else {\r\n Tools.Error(\"BinaryWriter: byteoffset is greater than the current binary length!\");\r\n }\r\n }\r\n if (this._byteOffset + 4 > this._arrayBuffer.byteLength) {\r\n this._resizeBuffer(this._arrayBuffer.byteLength * 2);\r\n }\r\n this._dataView.setFloat32(this._byteOffset, entry, true);\r\n this._byteOffset += 4;\r\n }\r\n /**\r\n * Stores an UInt32 in the array buffer\r\n * @param entry\r\n * @param byteOffset If defined, specifies where to set the value as an offset.\r\n */\r\n public setUInt32(entry: number, byteOffset?: number) {\r\n if (byteOffset != null) {\r\n if (byteOffset < this._byteOffset) {\r\n this._dataView.setUint32(byteOffset, entry, true);\r\n } else {\r\n Tools.Error(\"BinaryWriter: byteoffset is greater than the current binary buffer length!\");\r\n }\r\n } else {\r\n if (this._byteOffset + 4 > this._arrayBuffer.byteLength) {\r\n this._resizeBuffer(this._arrayBuffer.byteLength * 2);\r\n }\r\n this._dataView.setUint32(this._byteOffset, entry, true);\r\n this._byteOffset += 4;\r\n }\r\n }\r\n /**\r\n * Stores an Int16 in the array buffer\r\n * @param entry\r\n * @param byteOffset If defined, specifies where to set the value as an offset.\r\n */\r\n public setInt16(entry: number, byteOffset?: number) {\r\n if (byteOffset != null) {\r\n if (byteOffset < this._byteOffset) {\r\n this._dataView.setInt16(byteOffset, entry, true);\r\n } else {\r\n Tools.Error(\"BinaryWriter: byteoffset is greater than the current binary buffer length!\");\r\n }\r\n } else {\r\n if (this._byteOffset + 2 > this._arrayBuffer.byteLength) {\r\n this._resizeBuffer(this._arrayBuffer.byteLength * 2);\r\n }\r\n this._dataView.setInt16(this._byteOffset, entry, true);\r\n this._byteOffset += 2;\r\n }\r\n }\r\n /**\r\n * Stores a byte in the array buffer\r\n * @param entry\r\n * @param byteOffset If defined, specifies where to set the value as an offset.\r\n */\r\n public setByte(entry: number, byteOffset?: number) {\r\n if (byteOffset != null) {\r\n if (byteOffset < this._byteOffset) {\r\n this._dataView.setInt8(byteOffset, entry);\r\n } else {\r\n Tools.Error(\"BinaryWriter: byteoffset is greater than the current binary buffer length!\");\r\n }\r\n } else {\r\n if (this._byteOffset + 1 > this._arrayBuffer.byteLength) {\r\n this._resizeBuffer(this._arrayBuffer.byteLength * 2);\r\n }\r\n this._dataView.setInt8(this._byteOffset, entry);\r\n this._byteOffset++;\r\n }\r\n }\r\n}\r\n","import type { ImageMimeType, IMeshPrimitive, INode, IMaterial, ITextureInfo } from \"babylonjs-gltf2interface\";\r\nimport type { Node } from \"core/node\";\r\nimport type { Nullable } from \"core/types\";\r\n\r\nimport type { Texture } from \"core/Materials/Textures/texture\";\r\nimport type { SubMesh } from \"core/Meshes/subMesh\";\r\nimport type { IDisposable } from \"core/scene\";\r\n\r\nimport type { _BinaryWriter } from \"./glTFExporter\";\r\nimport type { IGLTFExporterExtension } from \"../glTFFileExporter\";\r\nimport type { Material } from \"core/Materials/material\";\r\nimport type { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\n\r\n/** @internal */\r\n// eslint-disable-next-line no-var, @typescript-eslint/naming-convention\r\nexport var __IGLTFExporterExtensionV2 = 0; // I am here to allow dts to be created\r\n\r\n/**\r\n * Interface for a glTF exporter extension\r\n * @internal\r\n */\r\nexport interface IGLTFExporterExtensionV2 extends IGLTFExporterExtension, IDisposable {\r\n /**\r\n * Define this method to modify the default behavior before exporting a texture\r\n * @param context The context when loading the asset\r\n * @param babylonTexture The Babylon.js texture\r\n * @param mimeType The mime-type of the generated image\r\n * @returns A promise that resolves with the exported texture\r\n */\r\n preExportTextureAsync?(context: string, babylonTexture: Nullable, mimeType: ImageMimeType): Promise;\r\n\r\n /**\r\n * Define this method to get notified when a texture info is created\r\n * @param context The context when loading the asset\r\n * @param textureInfo The glTF texture info\r\n * @param babylonTexture The Babylon.js texture\r\n */\r\n postExportTexture?(context: string, textureInfo: ITextureInfo, babylonTexture: BaseTexture): void;\r\n\r\n /**\r\n * Define this method to modify the default behavior when exporting texture info\r\n * @param context The context when loading the asset\r\n * @param meshPrimitive glTF mesh primitive\r\n * @param babylonSubMesh Babylon submesh\r\n * @param binaryWriter glTF serializer binary writer instance\r\n * @returns nullable IMeshPrimitive promise\r\n */\r\n postExportMeshPrimitiveAsync?(context: string, meshPrimitive: Nullable, babylonSubMesh: SubMesh, binaryWriter: _BinaryWriter): Promise;\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 * @returns nullable INode promise\r\n */\r\n postExportNodeAsync?(context: string, node: Nullable, babylonNode: Node, nodeMap?: { [key: number]: number }, binaryWriter?: _BinaryWriter): Promise>;\r\n\r\n /**\r\n * Define this method to modify the default behavior when exporting a material\r\n * @param material glTF material\r\n * @param babylonMaterial BabylonJS material\r\n * @returns nullable IMaterial promise\r\n */\r\n postExportMaterialAsync?(context: string, node: Nullable, babylonMaterial: Material): Promise;\r\n\r\n /**\r\n * Define this method to return additional textures to export from a material\r\n * @param material glTF material\r\n * @param babylonMaterial BabylonJS material\r\n * @returns List of textures\r\n */\r\n postExportMaterialAdditionalTextures?(context: string, node: IMaterial, babylonMaterial: Material): BaseTexture[];\r\n\r\n /** Gets a boolean indicating that this extension was used */\r\n wasUsed: boolean;\r\n\r\n /** Gets a boolean indicating that this extension is required for the file to work */\r\n required: boolean;\r\n\r\n /**\r\n * Called after the exporter state changes to EXPORTING\r\n */\r\n onExporting?(): void;\r\n}\r\n","import type { Node } from \"core/node\";\r\nimport type { Scene } from \"core/scene\";\r\nimport type { GLTFData } from \"./glTFData\";\r\nimport { _Exporter } from \"./glTFExporter\";\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 used to extract the part of node's metadata that will be exported into glTF node extras\r\n * @param metadata source metadata to read from\r\n * @returns the data to store to glTF node extras\r\n */\r\n metadataSelector?(metadata: any): any;\r\n\r\n /**\r\n * The sample rate to bake animation curves\r\n */\r\n animationSampleRate?: number;\r\n\r\n /**\r\n * Begin serialization without waiting for the scene to be ready\r\n */\r\n exportWithoutWaitingForScene?: boolean;\r\n\r\n /**\r\n * Indicates if unused vertex uv attributes should be included in export\r\n */\r\n exportUnusedUVs?: boolean;\r\n\r\n /**\r\n * Indicates if coordinate system swapping root nodes should be included in export\r\n */\r\n includeCoordinateSystemConversionNodes?: boolean;\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 geometry of the scene to .gltf file format asynchronously\r\n * @param scene Babylon scene with scene hierarchy information\r\n * @param filePrefix File prefix to use when generating the glTF file\r\n * @param options Exporter options\r\n * @returns Returns an object with a .gltf file and associates texture names\r\n * as keys and their data and paths as values\r\n */\r\n public static GLTFAsync(scene: Scene, filePrefix: string, options?: IExportOptions): Promise {\r\n return scene.whenReadyAsync().then(() => {\r\n const glTFPrefix = filePrefix.replace(/\\.[^/.]+$/, \"\");\r\n const gltfGenerator = new _Exporter(scene, options);\r\n return gltfGenerator._generateGLTFAsync(glTFPrefix);\r\n });\r\n }\r\n\r\n private static _PreExportAsync(scene: Scene, options?: IExportOptions): Promise {\r\n return Promise.resolve().then(() => {\r\n if (options && options.exportWithoutWaitingForScene) {\r\n return Promise.resolve();\r\n } else {\r\n return scene.whenReadyAsync();\r\n }\r\n });\r\n }\r\n\r\n private static _PostExportAsync(scene: Scene, glTFData: GLTFData, options?: IExportOptions): Promise {\r\n return Promise.resolve().then(() => {\r\n if (options && options.exportWithoutWaitingForScene) {\r\n return glTFData;\r\n } else {\r\n return glTFData;\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Exports the geometry of the scene to .glb file format asychronously\r\n * @param scene Babylon scene with scene hierarchy information\r\n * @param filePrefix File prefix to use when generating glb file\r\n * @param options Exporter options\r\n * @returns Returns an object with a .glb filename as key and data as value\r\n */\r\n public static GLBAsync(scene: Scene, filePrefix: string, options?: IExportOptions): Promise {\r\n return this._PreExportAsync(scene, options).then(() => {\r\n const glTFPrefix = filePrefix.replace(/\\.[^/.]+$/, \"\");\r\n const gltfGenerator = new _Exporter(scene, options);\r\n return gltfGenerator._generateGLBAsync(glTFPrefix).then((glTFData) => {\r\n return this._PostExportAsync(scene, glTFData, options);\r\n });\r\n });\r\n }\r\n}\r\n","// Do not edit.\nimport { ShaderStore } from \"core/Engines/shaderStore\";\n\nconst name = \"textureTransformPixelShader\";\nconst shader = `precision highp float;varying vec2 vUV;uniform sampler2D textureSampler;uniform mat4 textureTransformMat;void main(void) {\n#define CUSTOM_FRAGMENT_MAIN_BEGIN\nvec2 uvTransformed=(textureTransformMat*vec4(vUV.xy,1,1)).xy;gl_FragColor=texture2D(textureSampler,uvTransformed);\n#define CUSTOM_FRAGMENT_MAIN_END\n}`;\n// Sideeffect\nShaderStore.ShadersStore[name] = shader;\n/** @internal */\nexport const textureTransformPixelShader = { name, shader };\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 { ProceduralTexture } from \"core/Materials/Textures/Procedurals/proceduralTexture\";\r\nimport type { Scene } from \"core/scene\";\r\n\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { _Exporter } from \"../glTFExporter\";\r\n\r\nconst NAME = \"KHR_texture_transform\";\r\n\r\nimport \"../shaders/textureTransform.fragment\";\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 private _recordedTextures: ProceduralTexture[] = [];\r\n\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 for (const texture of this._recordedTextures) {\r\n texture.dispose();\r\n }\r\n }\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 canUseExtension =\r\n babylonTexture &&\r\n ((babylonTexture.uAng === 0 && babylonTexture.wAng === 0 && babylonTexture.vAng === 0) ||\r\n (babylonTexture.uRotationCenter === 0 && babylonTexture.vRotationCenter === 0));\r\n\r\n if (canUseExtension) {\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 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\n public preExportTextureAsync(context: string, babylonTexture: Texture): Promise {\r\n return new Promise((resolve, reject) => {\r\n const scene = babylonTexture.getScene();\r\n if (!scene) {\r\n reject(`${context}: \"scene\" is not defined for Babylon texture ${babylonTexture.name}!`);\r\n return;\r\n }\r\n\r\n let bakeTextureTransform = false;\r\n\r\n /*\r\n * The KHR_texture_transform schema only supports rotation around the origin.\r\n * the texture must be baked to preserve appearance.\r\n * see: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_texture_transform#gltf-schema-updates\r\n */\r\n if (\r\n (babylonTexture.uAng !== 0 || babylonTexture.wAng !== 0 || babylonTexture.vAng !== 0) &&\r\n (babylonTexture.uRotationCenter !== 0 || babylonTexture.vRotationCenter !== 0)\r\n ) {\r\n bakeTextureTransform = true;\r\n }\r\n\r\n if (!bakeTextureTransform) {\r\n resolve(babylonTexture);\r\n return;\r\n }\r\n\r\n return this._textureTransformTextureAsync(babylonTexture, scene)\r\n .then((proceduralTexture) => {\r\n resolve(proceduralTexture);\r\n })\r\n .catch((e) => {\r\n reject(e);\r\n });\r\n });\r\n }\r\n\r\n /**\r\n * Transform the babylon texture by the offset, rotation and scale parameters using a procedural texture\r\n * @param babylonTexture\r\n * @param scene\r\n */\r\n private _textureTransformTextureAsync(babylonTexture: Texture, scene: Scene): Promise {\r\n return new Promise((resolve) => {\r\n const proceduralTexture = new ProceduralTexture(`${babylonTexture.name}`, babylonTexture.getSize(), \"textureTransform\", scene);\r\n if (!proceduralTexture) {\r\n Tools.Log(`Cannot create procedural texture for ${babylonTexture.name}!`);\r\n resolve(babylonTexture);\r\n }\r\n\r\n proceduralTexture.reservedDataStore = {\r\n hidden: true,\r\n source: babylonTexture,\r\n };\r\n\r\n this._recordedTextures.push(proceduralTexture);\r\n\r\n proceduralTexture.coordinatesIndex = babylonTexture.coordinatesIndex;\r\n proceduralTexture.setTexture(\"textureSampler\", babylonTexture);\r\n proceduralTexture.setMatrix(\"textureTransformMat\", babylonTexture.getTextureMatrix());\r\n\r\n // isReady trigger creation of effect if it doesnt exist yet\r\n if (proceduralTexture.isReady()) {\r\n proceduralTexture.render();\r\n resolve(proceduralTexture);\r\n } else {\r\n proceduralTexture.getEffect().executeWhenCompiled(() => {\r\n proceduralTexture.render();\r\n resolve(proceduralTexture);\r\n });\r\n }\r\n });\r\n }\r\n}\r\n\r\n_Exporter.RegisterExtension(NAME, () => new KHR_texture_transform());\r\n","import type { SpotLight } from \"core/Lights/spotLight\";\r\nimport type { Nullable } from \"core/types\";\r\nimport { Vector3, Quaternion, TmpVectors, Matrix } from \"core/Maths/math.vector\";\r\nimport { Color3 } from \"core/Maths/math.color\";\r\nimport { Light } from \"core/Lights/light\";\r\nimport { DirectionalLight } from \"core/Lights/directionalLight\";\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 { _Exporter } from \"../glTFExporter\";\r\nimport { Logger } from \"core/Misc/logger\";\r\nimport { _GLTFUtilities } from \"../glTFUtilities\";\r\n\r\nconst NAME = \"KHR_lights_punctual\";\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: _Exporter;\r\n\r\n private _lights: IKHRLightsPunctual;\r\n\r\n /**\r\n * @internal\r\n */\r\n constructor(exporter: _Exporter) {\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 unique id to glTF node index\r\n * @returns nullable INode promise\r\n */\r\n public postExportNodeAsync(context: string, node: Nullable, babylonNode: Node, nodeMap?: { [key: number]: number }): Promise> {\r\n return new Promise((resolve) => {\r\n if (node && babylonNode instanceof ShadowLight) {\r\n const babylonLight: ShadowLight = babylonNode;\r\n let light: IKHRLightsPunctual_Light;\r\n\r\n const lightType =\r\n babylonLight.getTypeID() == Light.LIGHTTYPEID_POINTLIGHT\r\n ? KHRLightsPunctual_LightType.POINT\r\n : babylonLight.getTypeID() == Light.LIGHTTYPEID_DIRECTIONALLIGHT\r\n ? KHRLightsPunctual_LightType.DIRECTIONAL\r\n : babylonLight.getTypeID() == Light.LIGHTTYPEID_SPOTLIGHT\r\n ? KHRLightsPunctual_LightType.SPOT\r\n : null;\r\n if (lightType == null) {\r\n Logger.Warn(`${context}: Light ${babylonLight.name} is not supported in ${NAME}`);\r\n } else {\r\n const lightPosition = babylonLight.position.clone();\r\n const convertToRightHandedSystem = this._exporter._convertToRightHandedSystemMap[babylonNode.uniqueId];\r\n if (!lightPosition.equals(Vector3.Zero())) {\r\n if (convertToRightHandedSystem) {\r\n _GLTFUtilities._GetRightHandedPositionVector3FromRef(lightPosition);\r\n }\r\n node.translation = lightPosition.asArray();\r\n }\r\n if (lightType !== KHRLightsPunctual_LightType.POINT) {\r\n const localAxis = babylonLight.direction;\r\n const yaw = -Math.atan2(localAxis.z * (this._exporter._babylonScene.useRightHandedSystem ? -1 : 1), localAxis.x) + Math.PI / 2;\r\n const len = Math.sqrt(localAxis.x * localAxis.x + localAxis.z * localAxis.z);\r\n const pitch = -Math.atan2(localAxis.y, len);\r\n const lightRotationQuaternion = Quaternion.RotationYawPitchRoll(yaw, pitch, 0);\r\n if (convertToRightHandedSystem) {\r\n _GLTFUtilities._GetRightHandedQuaternionFromRef(lightRotationQuaternion);\r\n }\r\n if (!lightRotationQuaternion.equals(Quaternion.Identity())) {\r\n node.rotation = lightRotationQuaternion.asArray();\r\n }\r\n }\r\n\r\n if (babylonLight.falloffType !== Light.FALLOFF_GLTF) {\r\n Logger.Warn(`${context}: Light falloff for ${babylonLight.name} does not match the ${NAME} specification!`);\r\n }\r\n light = {\r\n type: lightType,\r\n };\r\n if (!babylonLight.diffuse.equals(Color3.White())) {\r\n light.color = babylonLight.diffuse.asArray();\r\n }\r\n if (babylonLight.intensity !== 1.0) {\r\n light.intensity = babylonLight.intensity;\r\n }\r\n if (babylonLight.range !== Number.MAX_VALUE) {\r\n light.range = babylonLight.range;\r\n }\r\n\r\n if (lightType === KHRLightsPunctual_LightType.SPOT) {\r\n const babylonSpotLight = babylonLight as SpotLight;\r\n if (babylonSpotLight.angle !== Math.PI / 2.0) {\r\n if (light.spot == null) {\r\n light.spot = {};\r\n }\r\n light.spot.outerConeAngle = babylonSpotLight.angle / 2.0;\r\n }\r\n if (babylonSpotLight.innerAngle !== 0) {\r\n if (light.spot == null) {\r\n light.spot = {};\r\n }\r\n light.spot.innerConeAngle = babylonSpotLight.innerAngle / 2.0;\r\n }\r\n }\r\n\r\n if (this._lights == null) {\r\n this._lights = {\r\n lights: [],\r\n };\r\n }\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 // Avoid duplicating the Light's parent node if possible.\r\n const parentBabylonNode = babylonNode.parent;\r\n if (parentBabylonNode && parentBabylonNode.getChildren().length == 1) {\r\n const parentNode = this._exporter._nodes[nodeMap![parentBabylonNode.uniqueId]];\r\n if (parentNode) {\r\n const parentNodeLocalMatrix = TmpVectors.Matrix[0];\r\n const parentInvertNodeLocalMatrix = TmpVectors.Matrix[1];\r\n const parentNodeLocalTranslation = parentNode.translation\r\n ? new Vector3(parentNode.translation[0], parentNode.translation[1], parentNode.translation[2])\r\n : Vector3.Zero();\r\n const parentNodeLocalRotation = parentNode.rotation\r\n ? new Quaternion(parentNode.rotation[0], parentNode.rotation[1], parentNode.rotation[2], parentNode.rotation[3])\r\n : Quaternion.Identity();\r\n const parentNodeLocalScale = parentNode.scale ? new Vector3(parentNode.scale[0], parentNode.scale[1], parentNode.scale[2]) : Vector3.One();\r\n\r\n Matrix.ComposeToRef(parentNodeLocalScale, parentNodeLocalRotation, parentNodeLocalTranslation, parentNodeLocalMatrix);\r\n parentNodeLocalMatrix.invertToRef(parentInvertNodeLocalMatrix);\r\n\r\n // Convert light local matrix to local matrix relative to grandparent, facing -Z\r\n const lightLocalMatrix = TmpVectors.Matrix[2];\r\n const nodeLocalTranslation = node.translation ? new Vector3(node.translation[0], node.translation[1], node.translation[2]) : Vector3.Zero();\r\n\r\n // Undo directional light positional offset\r\n if (babylonLight instanceof DirectionalLight) {\r\n nodeLocalTranslation.subtractInPlace(\r\n this._exporter._babylonScene.useRightHandedSystem\r\n ? babylonLight.direction\r\n : _GLTFUtilities._GetRightHandedPositionVector3(babylonLight.direction)\r\n );\r\n }\r\n const nodeLocalRotation = this._exporter._babylonScene.useRightHandedSystem ? Quaternion.Identity() : new Quaternion(0, 1, 0, 0);\r\n if (node.rotation) {\r\n nodeLocalRotation.multiplyInPlace(new Quaternion(node.rotation[0], node.rotation[1], node.rotation[2], node.rotation[3]));\r\n }\r\n const nodeLocalScale = node.scale ? new Vector3(node.scale[0], node.scale[1], node.scale[2]) : Vector3.One();\r\n\r\n Matrix.ComposeToRef(nodeLocalScale, nodeLocalRotation, nodeLocalTranslation, lightLocalMatrix);\r\n lightLocalMatrix.multiplyToRef(parentInvertNodeLocalMatrix, lightLocalMatrix);\r\n const parentNewScale = TmpVectors.Vector3[0];\r\n const parentNewRotationQuaternion = TmpVectors.Quaternion[0];\r\n const parentNewTranslation = TmpVectors.Vector3[1];\r\n\r\n lightLocalMatrix.decompose(parentNewScale, parentNewRotationQuaternion, parentNewTranslation);\r\n parentNode.scale = parentNewScale.asArray();\r\n parentNode.rotation = parentNewRotationQuaternion.asArray();\r\n parentNode.translation = parentNewTranslation.asArray();\r\n\r\n if (parentNode.extensions == null) {\r\n parentNode.extensions = {};\r\n }\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 if (node.extensions == null) {\r\n node.extensions = {};\r\n }\r\n\r\n node.extensions[NAME] = lightReference;\r\n }\r\n }\r\n resolve(node);\r\n });\r\n }\r\n}\r\n\r\n_Exporter.RegisterExtension(NAME, (exporter) => new KHR_lights_punctual(exporter));\r\n","import type { IMaterial, IKHRMaterialsClearcoat } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { _Exporter } 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: _Exporter;\r\n\r\n private _wasUsed = false;\r\n\r\n constructor(exporter: _Exporter) {\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 public postExportMaterialAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise {\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._glTFMaterialExporter._getTextureInfo(babylonMaterial.clearCoat.texture);\r\n let clearCoatTextureRoughnessInfo;\r\n if (babylonMaterial.clearCoat.useRoughnessFromMainTexture) {\r\n clearCoatTextureRoughnessInfo = this._exporter._glTFMaterialExporter._getTextureInfo(babylonMaterial.clearCoat.texture);\r\n } else {\r\n clearCoatTextureRoughnessInfo = this._exporter._glTFMaterialExporter._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._glTFMaterialExporter._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 hasTextures: () => {\r\n return clearCoatInfo.clearcoatTexture !== null || clearCoatInfo.clearcoatRoughnessTexture !== null || clearCoatInfo.clearcoatRoughnessTexture !== null;\r\n },\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\n_Exporter.RegisterExtension(NAME, (exporter) => new KHR_materials_clearcoat(exporter));\r\n","import type { IMaterial, IKHRMaterialsIridescence } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { _Exporter } 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: _Exporter;\r\n\r\n private _wasUsed = false;\r\n\r\n constructor(exporter: _Exporter) {\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 public postExportMaterialAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise {\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._glTFMaterialExporter._getTextureInfo(babylonMaterial.iridescence.texture);\r\n const iridescenceThicknessTextureInfo = this._exporter._glTFMaterialExporter._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 hasTextures: () => {\r\n return iridescenceInfo.iridescenceTexture !== null || iridescenceInfo.iridescenceThicknessTexture !== null;\r\n },\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\n_Exporter.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 { _Exporter } 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: _Exporter;\r\n\r\n constructor(exporter: _Exporter) {\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 postExportMaterialAsync(context: string, node: IMaterial, babylonMaterial: Material): Promise {\r\n return 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 hasTextures: () => {\r\n return sheenInfo.sheenColorTexture !== null || sheenInfo.sheenRoughnessTexture !== null;\r\n },\r\n };\r\n\r\n if (babylonMaterial.sheen.texture) {\r\n sheenInfo.sheenColorTexture = this._exporter._glTFMaterialExporter._getTextureInfo(babylonMaterial.sheen.texture) ?? undefined;\r\n }\r\n\r\n if (babylonMaterial.sheen.textureRoughness && !babylonMaterial.sheen.useRoughnessFromMainTexture) {\r\n sheenInfo.sheenRoughnessTexture = this._exporter._glTFMaterialExporter._getTextureInfo(babylonMaterial.sheen.textureRoughness) ?? undefined;\r\n } else if (babylonMaterial.sheen.texture && babylonMaterial.sheen.useRoughnessFromMainTexture) {\r\n sheenInfo.sheenRoughnessTexture = this._exporter._glTFMaterialExporter._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\n_Exporter.RegisterExtension(NAME, (exporter) => new KHR_materials_sheen(exporter));\r\n","import type { IMaterial } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { _Exporter } 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 public postExportMaterialAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise {\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\n_Exporter.RegisterExtension(NAME, () => new KHR_materials_unlit());\r\n","import type { IMaterial, IKHRMaterialsIor } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { _Exporter } 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 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 public postExportMaterialAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise {\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\n_Exporter.RegisterExtension(NAME, (exporter) => new KHR_materials_ior());\r\n","import type { IMaterial, IKHRMaterialsSpecular } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { _Exporter } 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: _Exporter;\r\n\r\n private _wasUsed = false;\r\n\r\n constructor(exporter: _Exporter) {\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\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 public postExportMaterialAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise {\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._glTFMaterialExporter._getTextureInfo(babylonMaterial.metallicReflectanceTexture) ?? undefined;\r\n const reflectanceTexture = this._exporter._glTFMaterialExporter._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 hasTextures: () => {\r\n return this._hasTexturesExtension(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\n_Exporter.RegisterExtension(NAME, (exporter) => new KHR_materials_specular(exporter));\r\n","import type { IMaterial, IKHRMaterialsVolume } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { _Exporter } 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: _Exporter;\r\n\r\n private _wasUsed = false;\r\n\r\n constructor(exporter: _Exporter) {\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\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_translucency 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 public postExportMaterialAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise {\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._glTFMaterialExporter._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 hasTextures: () => {\r\n return this._hasTexturesExtension(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\n_Exporter.RegisterExtension(NAME, (exporter) => new KHR_materials_volume(exporter));\r\n","import type { IMaterial, IKHRMaterialsTransmission } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport { _Exporter } 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_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: _Exporter;\r\n\r\n private _wasUsed = false;\r\n\r\n constructor(exporter: _Exporter) {\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\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 public postExportMaterialAsync?(context: string, node: IMaterial, babylonMaterial: Material): Promise {\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 transmissionFactor = subs.refractionIntensity === 0 ? undefined : subs.refractionIntensity;\r\n\r\n const transmissionTexture = this._exporter._glTFMaterialExporter._getTextureInfo(subs.refractionIntensityTexture) ?? undefined;\r\n\r\n const volumeInfo: IKHRMaterialsTransmission = {\r\n transmissionFactor: transmissionFactor,\r\n transmissionTexture: transmissionTexture,\r\n hasTextures: () => {\r\n return this._hasTexturesExtension(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\n_Exporter.RegisterExtension(NAME, (exporter) => new KHR_materials_transmission(exporter));\r\n","import type { IBufferView, IAccessor, INode, IEXTMeshGpuInstancing } from \"babylonjs-gltf2interface\";\r\nimport { AccessorType, AccessorComponentType } from \"babylonjs-gltf2interface\";\r\nimport type { IGLTFExporterExtensionV2 } from \"../glTFExporterExtension\";\r\nimport type { _BinaryWriter } from \"../glTFExporter\";\r\nimport { _Exporter } 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 { VertexBuffer } from \"core/Buffers/buffer\";\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: _Exporter;\r\n\r\n private _wasUsed = false;\r\n\r\n constructor(exporter: _Exporter) {\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 postExportNodeAsync?(\r\n context: string,\r\n node: Nullable,\r\n babylonNode: Node,\r\n nodeMap?: { [key: number]: number },\r\n binaryWriter?: _BinaryWriter\r\n ): Promise> {\r\n return new Promise((resolve) => {\r\n if (node && babylonNode instanceof Mesh) {\r\n if (babylonNode.hasThinInstances && binaryWriter) {\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 // retreive 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 // 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(\r\n translationBuffer,\r\n AccessorType.VEC3,\r\n babylonNode.thinInstanceCount,\r\n binaryWriter,\r\n AccessorComponentType.FLOAT\r\n );\r\n }\r\n // do we need to write ROTATION ?\r\n if (hasAnyInstanceWorldRotation) {\r\n const componentType = AccessorComponentType.FLOAT; // 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, binaryWriter, componentType);\r\n }\r\n // do we need to write SCALE ?\r\n if (hasAnyInstanceWorldScale) {\r\n extension.attributes[\"SCALE\"] = this._buildAccessor(\r\n scaleBuffer,\r\n AccessorType.VEC3,\r\n babylonNode.thinInstanceCount,\r\n binaryWriter,\r\n AccessorComponentType.FLOAT\r\n );\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, binaryWriter: _BinaryWriter, componentType: AccessorComponentType): number {\r\n // write the buffer\r\n const bufferOffset = binaryWriter.getByteOffset();\r\n switch (componentType) {\r\n case AccessorComponentType.FLOAT: {\r\n for (let i = 0; i != buffer.length; i++) {\r\n binaryWriter.setFloat32(buffer[i]);\r\n }\r\n break;\r\n }\r\n case AccessorComponentType.BYTE: {\r\n for (let i = 0; i != buffer.length; i++) {\r\n binaryWriter.setByte(buffer[i] * 127);\r\n }\r\n break;\r\n }\r\n case AccessorComponentType.SHORT: {\r\n for (let i = 0; i != buffer.length; i++) {\r\n binaryWriter.setInt16(buffer[i] * 32767);\r\n }\r\n\r\n break;\r\n }\r\n }\r\n // build the buffer view\r\n const bv: IBufferView = { buffer: 0, byteOffset: bufferOffset, byteLength: buffer.length * VertexBuffer.GetTypeByteLength(componentType) };\r\n const bufferViewIndex = this._exporter._bufferViews.length;\r\n this._exporter._bufferViews.push(bv);\r\n\r\n // finally build the accessor\r\n const accessorIndex = this._exporter._accessors.length;\r\n const accessor: IAccessor = {\r\n bufferView: bufferViewIndex,\r\n componentType: componentType,\r\n count: count,\r\n type: type,\r\n normalized: componentType == AccessorComponentType.BYTE || componentType == AccessorComponentType.SHORT,\r\n };\r\n this._exporter._accessors.push(accessor);\r\n return accessorIndex;\r\n }\r\n}\r\n\r\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n_Exporter.RegisterExtension(NAME, (exporter) => new EXT_mesh_gpu_instancing(exporter));\r\n","import type { Mesh } from \"core/Meshes/mesh\";\r\nimport { VertexBuffer } from \"core/Buffers/buffer\";\r\nimport { Vector3 } from \"core/Maths/math.vector\";\r\n\r\n/**\r\n * Class for generating STL data from a Babylon scene.\r\n */\r\nexport class STLExport {\r\n /**\r\n * Exports the geometry of a Mesh array in .STL file format (ASCII)\r\n * @param meshes list defines the mesh to serialize\r\n * @param download triggers the automatic download of the file.\r\n * @param fileName changes the downloads fileName.\r\n * @param binary changes the STL to a binary type.\r\n * @param isLittleEndian toggle for binary type exporter.\r\n * @param doNotBakeTransform toggle if meshes transforms should be baked or not.\r\n * @returns the STL as UTF8 string\r\n */\r\n public static CreateSTL(\r\n meshes: Mesh[],\r\n download: boolean = true,\r\n fileName: string = \"stlmesh\",\r\n binary: boolean = false,\r\n isLittleEndian: boolean = true,\r\n doNotBakeTransform: boolean = false\r\n ): any {\r\n //Binary support adapted from https://gist.github.com/paulkaplan/6d5f0ab2c7e8fdc68a61\r\n\r\n const getFaceData = function (indices: any, vertices: any, i: number) {\r\n const id = [indices[i] * 3, indices[i + 1] * 3, indices[i + 2] * 3];\r\n const v = [\r\n new Vector3(vertices[id[0]], vertices[id[0] + 2], vertices[id[0] + 1]),\r\n new Vector3(vertices[id[1]], vertices[id[1] + 2], vertices[id[1] + 1]),\r\n new Vector3(vertices[id[2]], vertices[id[2] + 2], vertices[id[2] + 1]),\r\n ];\r\n const p1p2 = v[0].subtract(v[1]);\r\n const p3p2 = v[2].subtract(v[1]);\r\n const n = Vector3.Cross(p3p2, p1p2).normalize();\r\n\r\n return { v, n };\r\n };\r\n\r\n const writeVector = function (dataview: any, offset: number, vector: Vector3, isLittleEndian: boolean) {\r\n offset = writeFloat(dataview, offset, vector.x, isLittleEndian);\r\n offset = writeFloat(dataview, offset, vector.y, isLittleEndian);\r\n return writeFloat(dataview, offset, vector.z, isLittleEndian);\r\n };\r\n\r\n const writeFloat = function (dataview: any, offset: number, value: number, isLittleEndian: boolean) {\r\n dataview.setFloat32(offset, value, isLittleEndian);\r\n return offset + 4;\r\n };\r\n\r\n let data;\r\n\r\n let faceCount = 0;\r\n let offset = 0;\r\n\r\n if (binary) {\r\n for (let i = 0; i < meshes.length; i++) {\r\n const mesh = meshes[i];\r\n const indices = mesh.getIndices();\r\n faceCount += indices ? indices.length / 3 : 0;\r\n }\r\n\r\n const bufferSize = 84 + 50 * faceCount;\r\n const buffer = new ArrayBuffer(bufferSize);\r\n data = new DataView(buffer);\r\n\r\n offset += 80;\r\n data.setUint32(offset, faceCount, isLittleEndian);\r\n offset += 4;\r\n } else {\r\n data = \"solid stlmesh\\r\\n\";\r\n }\r\n\r\n for (let i = 0; i < meshes.length; i++) {\r\n const mesh = meshes[i];\r\n if (!doNotBakeTransform) {\r\n mesh.bakeCurrentTransformIntoVertices();\r\n }\r\n const vertices = mesh.getVerticesData(VertexBuffer.PositionKind) || [];\r\n const indices = mesh.getIndices() || [];\r\n\r\n for (let i = 0; i < indices.length; i += 3) {\r\n const fd = getFaceData(indices, vertices, i);\r\n\r\n if (binary) {\r\n offset = writeVector(data, offset, fd.n, isLittleEndian);\r\n offset = writeVector(data, offset, fd.v[0], isLittleEndian);\r\n offset = writeVector(data, offset, fd.v[1], isLittleEndian);\r\n offset = writeVector(data, offset, fd.v[2], isLittleEndian);\r\n offset += 2;\r\n } else {\r\n data += \"facet normal \" + fd.n.x + \" \" + fd.n.y + \" \" + fd.n.z + \"\\r\\n\";\r\n data += \"\\touter loop\\r\\n\";\r\n data += \"\\t\\tvertex \" + fd.v[0].x + \" \" + fd.v[0].y + \" \" + fd.v[0].z + \"\\r\\n\";\r\n data += \"\\t\\tvertex \" + fd.v[1].x + \" \" + fd.v[1].y + \" \" + fd.v[1].z + \"\\r\\n\";\r\n data += \"\\t\\tvertex \" + fd.v[2].x + \" \" + fd.v[2].y + \" \" + fd.v[2].z + \"\\r\\n\";\r\n data += \"\\tendloop\\r\\n\";\r\n data += \"endfacet\\r\\n\";\r\n }\r\n }\r\n }\r\n\r\n if (!binary) {\r\n data += \"endsolid stlmesh\";\r\n }\r\n\r\n if (download) {\r\n const a = document.createElement(\"a\");\r\n const blob = new Blob([data], { type: \"application/octet-stream\" });\r\n a.href = window.URL.createObjectURL(blob);\r\n a.download = fileName + \".stl\";\r\n a.click();\r\n }\r\n\r\n return data;\r\n }\r\n}\r\n","/* eslint-disable import/no-internal-modules */\nimport * as Exporters from \"../glTF/glTFFileExporter\";\nimport * as Datas from \"../glTF/2.0/glTFData\";\nimport * as Serializers from \"../glTF/2.0/glTFSerializer\";\nimport * as Extensions from \"../glTF/2.0/Extensions/index\";\nimport * as GLTF2 from \"../glTF/2.0/index\";\n/**\n * This is the entry point for the UMD module.\n * The entry point for a future ESM package should be index.ts\n */\nconst globalObject = typeof global !== \"undefined\" ? global : typeof window !== \"undefined\" ? window : undefined;\nif (typeof globalObject !== \"undefined\") {\n (globalObject).BABYLON = (globalObject).BABYLON || {};\n const BABYLON = (globalObject).BABYLON;\n BABYLON.GLTF2 = BABYLON.GLTF2 || {};\n BABYLON.GLTF2.Exporter = BABYLON.GLTF2.Exporter || {};\n BABYLON.GLTF2.Exporter.Extensions = BABYLON.GLTF2.Exporter.Extensions || {};\n const keys = [];\n for (const key in Exporters) {\n BABYLON[key] = (Exporters)[key];\n keys.push(key);\n }\n for (const key in Datas) {\n BABYLON[key] = (Datas)[key];\n keys.push(key);\n }\n for (const key in Serializers) {\n BABYLON[key] = (Serializers)[key];\n keys.push(key);\n }\n for (const key in Extensions) {\n BABYLON.GLTF2.Exporter.Extensions[key] = (Extensions)[key];\n keys.push(key);\n }\n for (const key in GLTF2) {\n // Prevent Reassignment.\n if (keys.indexOf(key) > -1) {\n continue;\n }\n BABYLON.GLTF2.Exporter[key] = (GLTF2)[key];\n }\n}\nexport * from \"../glTF/glTFFileExporter\";\nexport * from \"../glTF/2.0/index\";\n","/* eslint-disable import/no-internal-modules */\nimport * as Serializers from \"../OBJ/index\";\n/**\n * This is the entry point for the UMD module.\n * The entry point for a future ESM package should be index.ts\n */\nconst globalObject = typeof global !== \"undefined\" ? global : typeof window !== \"undefined\" ? window : undefined;\nif (typeof globalObject !== \"undefined\") {\n for (const serializer in Serializers) {\n (globalObject).BABYLON[serializer] = (Serializers)[serializer];\n }\n}\nexport * from \"../OBJ/index\";\n","/* eslint-disable import/no-internal-modules */\nimport * as Serializers from \"../stl/index\";\n/**\n * This is the entry point for the UMD module.\n * The entry point for a future ESM package should be index.ts\n */\nconst globalObject = typeof global !== \"undefined\" ? global : typeof window !== \"undefined\" ? window : undefined;\nif (typeof globalObject !== \"undefined\") {\n for (const serializer in Serializers) {\n (globalObject).BABYLON[serializer] = (Serializers)[serializer];\n }\n}\nexport * from \"../stl/index\";\n","import * as serializers from \"serializers/legacy/legacy\";\r\nexport { serializers };\r\nexport default serializers;\r\n"],"names":["root","factory","exports","module","require","define","amd","self","global","this","__WEBPACK_EXTERNAL_MODULE__520__","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","undefined","__webpack_modules__","d","definition","key","o","Object","defineProperty","enumerable","get","g","globalThis","Function","e","window","obj","prop","prototype","hasOwnProperty","call","r","Symbol","toStringTag","value","_TangentType","OBJ","mesh","materials","matlibname","globalposition","output","v","textureV","push","j","length","inverseTransform","transform","computeWorldMatrix","Matrix","invertToRef","bakeTransformIntoVertices","mat","material","id","geometry","trunkVerts","getVerticesData","trunkNormals","trunkUV","trunkFaces","getIndices","currentV","currentTextureV","i","getScene","useRightHandedSystem","indices","String","textureIndices","blanks","facePositions","faceUVs","faceNormals","Tools","join","MTL","m","specularPower","toFixed","alpha","ambientColor","b","diffuseColor","specularColor","emissiveColor","ambientTexture","name","diffuseTexture","specularTexture","bumpTexture","opacityTexture","__IGLTFExporterExtension","_CreateBufferView","bufferIndex","byteOffset","byteLength","byteStride","bufferview","buffer","_CreateAccessor","bufferviewIndex","type","componentType","count","min","max","accessor","bufferView","_CalculateMinMaxPositions","positions","vertexStart","vertexCount","convertToRightHandedSystem","indexOffset","position","vector","Infinity","Vector3","_GLTFUtilities","_GetRightHandedPositionVector3FromRef","asArray","num","_GetRightHandedPositionVector3","x","y","z","_GetRightHandedPositionArray3FromRef","_GetRightHandedNormalVector3","_GetRightHandedNormalVector3FromRef","_GetRightHandedNormalArray3FromRef","_GetRightHandedVector4FromRef","w","_GetRightHandedArray4FromRef","_GetRightHandedQuaternionFromRef","quaternion","_GetRightHandedQuaternionArrayFromRef","_NormalizeTangentFromRef","tangent","Math","sqrt","_GetDataAccessorElementCount","accessorType","_IsTransformable","babylonNode","TransformNode","Camera","Light","_CreateNodeAnimation","babylonTransformNode","animation","animationChannelTargetPath","useQuaternion","animationSampleRate","inputs","outputs","keyFrames","getKeys","minMaxKeyFrames","_GLTFAnimation","_CalculateMinMaxKeyFrames","interpolationOrBake","_DeduceInterpolation","frameDelta","interpolation","interpolationType","shouldBakeAnimation","_CreateBakedAnimation","framePerSecond","_CreateLinearOrStepAnimation","_CreateCubicSplineAnimation","samplerInterpolation","inputsMin","inputsMax","_DeduceAnimationInfo","dataAccessorType","property","targetProperty","split","_CreateNodeAnimationFromNodeAnimations","runtimeGLTFAnimation","idleGLTFAnimations","nodeMap","nodes","binaryWriter","bufferViews","accessors","glTFAnimation","animations","animationInfo","samplers","channels","_AddAnimation","hasRunningRuntimeAnimations","_CreateMorphTargetAnimationFromMorphTargetAnimations","Mesh","morphTargetManager","numTargets","getTarget","combinedAnimation","Animation","dataType","loopMode","enableBlending","combinedAnimationKeys","animationKeys","animationKey","k","frame","setKeys","_CreateNodeAndMorphAnimationFromAnimationGroups","babylonScene","glTFAnimations","convertToRightHandedSystemMap","animationGroups","animationGroup","morphAnimations","Map","sampleAnimations","morphAnimationMeshes","Set","animationGroupFrameDiff","to","from","targetAnimation","targetedAnimations","target","uniqueId","MorphTarget","morphTargetManagers","find","babylonMesh","meshes","has","set","add","forEach","combinedAnimationGroup","sampleAnimationKeys","numAnimationKeys","morphTarget","animationsByMorphTarget","morphTargetAnimation","influence","inTangent","outTangent","morphAnimationChannels","keyframeAccessorIndex","dataAccessorIndex","outputLength","animationSampler","animationChannel","animationData","index","currentInput","newInputs","shift","nodeIndex","getByteOffset","input","setFloat32","entry","sampler","node","path","minFrame","maxFrame","fps","sampleRate","minMaxFrames","time","quaternionCache","Quaternion","previousTime","maxUsedFrame","currKeyFrame","nextKeyFrame","prevKeyFrame","endFrame","equals","f","state","repeatCount","_interpolate","_SetInterpolatedValue","_ConvertFactorToVector3OrQuaternion","factor","animationType","componentName","basePositionRotationOrScale","_GetBasePositionRotationOrScale","normalize","cacheValue","parent","multiply","keyFrame","_AddKeyframeValue","_AddSplineTangent","INTANGENT","OUTTANGENT","q","rotationQuaternion","rotation","p","s","scaling","newPositionRotationOrScale","array","posRotScale","AnimationKeyInterpolation","tangentType","tangentValue","glTFFiles","downloadFiles","endsWith","str","suffix","indexOf","link","document","createElement","body","appendChild","setAttribute","download","blob","mimeType","href","URL","createObjectURL","Blob","click","__awaiter","thisArg","_arguments","P","generator","Promise","resolve","reject","fulfilled","step","next","rejected","result","done","then","apply","__generator","t","_","label","sent","trys","ops","verb","iterator","n","op","TypeError","pop","__spreadArray","pack","arguments","ar","l","Array","slice","concat","create","exporter","_textureMap","_exporter","_FuzzyEquals","color1","color2","epsilon","Scalar","_convertMaterialsToGLTFAsync","exportMaterials","hasTextureCoords","promises","getClassName","_convertStandardMaterialAsync","_convertPBRMaterialAsync","all","_stripTexturesFromMaterial","originalMaterial","newMaterial","doubleSided","alphaMode","alphaCutoff","emissiveFactor","originalPBRMetallicRoughness","pbrMetallicRoughness","baseColorFactor","metallicFactor","roughnessFactor","_hasTexturesPresent","emissiveTexture","normalTexture","occlusionTexture","pbrMat","baseColorTexture","metallicRoughnessTexture","extensions","extension","extensionObject","hasTextures","_getTextureInfo","babylonTexture","textureUid","uid","_convertToGLTFPBRMetallicRoughness","babylonStandardMaterial","p0","p1","p2","p3","P0","Vector2","P1","P2","P3","diffuse","toLinearSpace","scale","opacity","roughness","_GLTFMaterialExporter","_MaxSpecularPower","pow","_SolveMetallic","specular","oneMinusSpecularStrength","_DielectricSpecular","a","D","_SetAlphaMode","glTFMaterial","babylonMaterial","needAlphaBlending","needAlphaTesting","alphaCutOff","materialMap","_materialMap","_materials","glTFPbrMetallicRoughness","backFaceCulling","twoSidedLighting","_exportTextureAsync","glTFTexture","level","glTFEmissiveTexture","strength","Constants","toString","Color3","_Epsilon","_finishMaterial","tasks","_extensionsPostExportMaterialAdditionalTextures","texture","extensionWork","_extensionsPostExportMaterialAsync","_createBase64FromCanvasAsync","width","height","textureType","hostingScene","_babylonScene","engine","getEngine","tempTexture","createRawTexture","Texture","TextureTools","_readTexturePixels","data","base64","_createWhiteTexture","scene","Uint8Array","RawTexture","_resizeTexturesToSameDimensions","texture1","texture2","resizedTexture1","resizedTexture2","texture1Size","getSize","texture2Size","_convertPixelArrayToFloat32","pixels","Float32Array","Error","_convertSpecularGlossinessTexturesToMetallicRoughnessAsync","specularGlossinessTexture","factors","resizedTextures","diffuseSize","diffuseBuffer","specularGlossinessBuffer","readPixels","diffusePixels","specularPixels","metallicRoughnessBuffer","baseColorBuffer","maxBaseColor","maxMetallic","maxRoughness","h","offset","glossiness","specularGlossiness","metallicRoughness","_convertSpecularGlossinessToMetallicRoughness","baseColor","metallic","hasAlpha","writeOutMetallicRoughnessTexture","writeOutBaseColorTexture","destinationOffset","linearBaseColorPixel","sRGBBaseColorPixel","toGammaSpace","metallicRoughnessPixel","promise","metallicRoughnessBase64","metallicRoughnessTextureBase64","baseColorBase64","baseColorTextureBase64","diffusePerceivedBrightness","_getPerceivedBrightness","specularPerceivedBrightness","_getMaxComponent","baseColorFromDiffuse","baseColorFromSpecular","subtract","clampToRef","color","_convertMetalRoughFactorsToMetallicRoughnessAsync","babylonPBRMaterial","_albedoColor","_metallic","_roughness","_albedoTexture","metallicTexture","_metallicTexture","_getGLTFTextureSampler","_getGLTFTextureWrapModesSampler","samplingMode","magFilter","minFilter","_getGLTFTextureWrapMode","wrapMode","wrapS","wrapU","wrapT","wrapV","_convertSpecGlossFactorsToMetallicRoughnessAsync","_samplers","textures","_textures","specGloss","_reflectivityColor","_microSurface","samplerIndex","albedoTexture","reflectivityTexture","_reflectivityTexture","useMicrosurfaceFromReflectivityMapAlpha","_useMicroSurfaceFromReflectivityMapAlpha","metallicRoughnessFactors","glTFBaseColorTexture","_getTextureInfoFromBase64","coordinatesIndex","glTFMRColorTexture","isMetallicWorkflow","albedoColor","_setMetallicRoughnessPbrMaterial","_twoSidedLighting","_bumpTexture","_ambientTexture","texCoord","ambientTextureStrength","_ambientTextureStrength","_emissiveTexture","_emissiveColor","_getPixelsFromTexture","extensionPromise","_extensionsPreExportTextureAsync","_exportTextureInfoAsync","foundSamplerIndex","size","base64Data","textureInfo","replace","_extensionsPostExportTextures","base64Texture","baseTextureName","texCoordIndex","images","_images","imageData","_imageData","source","binStr","atob","arrBuff","ArrayBuffer","arr","charCodeAt","imageValues","textureName","originalTextureName","glTFImage","uri","foundIndex","options","_includeCoordinateSystemConversionNodes","_extensions","_glTF","asset","Engine","version","EngineStore","_bufferViews","_accessors","_meshes","_scenes","_cameras","_nodes","_skins","_animations","_orderedImageData","_options","_animationSampleRate","includeCoordinateSystemConversionNodes","_glTFMaterialExporter","_loadExtensions","_applyExtension","actionAsync","currentPromise","newNode","_applyExtensions","_Exporter","_ExtensionNames","context","preExportTextureAsync","_extensionsPostExportMeshPrimitiveAsync","meshPrimitive","babylonSubMesh","postExportMeshPrimitiveAsync","_extensionsPostExportNodeAsync","postExportNodeAsync","postExportMaterialAsync","postExportMaterialAdditionalTextures","postExportTexture","_forEachExtensions","action","enabled","_extensionsOnExporting","wasUsed","extensionsUsed","required","extensionsRequired","onExporting","_ExtensionFactories","dispose","extensionKey","RegisterExtension","UnregisterExtension","splice","_reorderIndicesBasedOnPrimitiveMode","submesh","primitiveMode","babylonIndices","Material","indexStart","indexCount","secondIndex","getUInt32","thirdIndex","setUInt32","start","_reorderVertexAttributeDataBasedOnPrimitiveMode","sideOrientation","vertexBufferKind","meshAttributeArray","_reorderTriangleFillMode","_reorderTriangleStripDrawMode","_reorderTriangleFanMode","vertexBuffer","_getVertexBufferFromMesh","getMesh","stride","VertexBuffer","verticesCount","vertexData","verticesStart","Vector4","_writeVertexAttributeData","vertices","vertexAttributeKind","vertex","component","_writeAttributeData","attributeComponentKind","writeBinaryFunc","vertexAttributes","meshMaterial","convertToLinear","Color4","toLinearSpaceToRef","setUInt8","bind","setUInt16","writeMorphTargetAttributeData","morphTargetAttributeArray","minMax","difference","difference4","morphData","subtractToRef","copyFromFloats","_generateJSON","shouldUseGlb","glTFPrefix","prettyPrint","imageName","_totalByteLength","buffers","scenes","cameras","skins","image","JSON","stringify","_generateGLTFAsync","_generateBinaryAsync","binaryBuffer","jsonText","bin","glTFFileName","glTFBinFile","container","GLTFData","_BinaryWriter","_createSceneAsync","_localEngine","getArrayBuffer","_getPadding","remainder","_generateGLBAsync","encodedJsonText","glbFileName","jsonLength","imageByteLength","TextEncoder","encode","jsonPadding","binPadding","imagePadding","headerLength","headerBuffer","headerBufferView","DataView","setUint32","jsonChunkBuffer","jsonChunkBufferView","jsonData","blankCharCode","charCode","codePointAt","jsonPaddingView","binaryChunkBuffer","binaryChunkBufferView","binPaddingBuffer","binPaddingView","imagePaddingBuffer","imagePaddingView","glbData","glbFile","_setNodeTransformation","getPivotPoint","equalsToFloats","translation","multiplyInPlace","_setCameraTransformation","babylonCamera","attributeKind","bufferMesh","isVerticesDataPresent","getVertexBuffer","_createBufferViewKind","kind","InstancedMesh","sourceMesh","typeByteLength","_setMorphTargetAttributes","babylonMorphTarget","targets","hasNormals","vertexNormals","morphNormals","getNormals","bufferViewIndex","NORMAL","hasPositions","vertexPositions","morphPositions","getPositions","POSITION","hasTangents","vertexTangents","morphTangents","getTangents","TANGENT","_getMeshPrimitiveMode","LinesMesh","fillMode","_setPrimitiveMode","mode","_setAttributeKind","attributes","COLOR_0","TEXCOORD_0","TEXCOORD_1","JOINTS_0","JOINTS_1","WEIGHTS_0","WEIGHTS_1","_setPrimitiveAttributesAsync","attributeData","accessorComponentType","indexBufferViewIndex","vertexAttributeBufferViews","attribute","getTotalIndices","subMeshes","getMaterial","defaultMaterial","materialIndex","MultiMaterial","subMaterial","subMaterials","exportUnusedUVs","keys","overrideMaterialSideOrientation","primitives","_isBabylonCoordinateSystemConvertingNode","getWorldMatrix","determinant","glTFNodeIndex","glTFNode","directDescendents","transformNodes","lights","rootNodesToLeftHanded","_convertToRightHandedSystem","_convertToRightHandedSystemMap","rootNodes","rootNode","getDescendants","descendant","indexRootNode","cameraMap","camera","shouldExportNode","glTFCamera","perspective","aspectRatio","getAspectRatio","yfov","fovMode","fov","znear","minZ","zfar","maxZ","halfWidth","orthoLeft","orthoRight","getRenderWidth","halfHeight","orthoBottom","orthoTop","getRenderHeight","orthographic","xmag","ymag","_getExportNodes","exportNodes","_createNodeMapAndAnimationsAsync","_createSkinsAsync","skinMap","_nodeMap","metadata","metadataSelector","extras","gltf","skeleton","skin","children","descendent","promiseChain","_createNodeAsync","idleGLTFAnimation","weights","skeletons","bones","joints","inverseBindMatrices","boneIndexMap","maxBoneIndex","boneIndex","bone","getIndex","getInvertedAbsoluteTransform","transformNode","getTransformNode","bufferViewOffset","bindMatrixAccessor","inverseBindAccessorIndex","cell","_arrayBuffer","_dataView","_byteOffset","_resizeBuffer","newBuffer","oldUint8Array","newUint8Array","setUint8","setUint16","getUint32","getVector3Float32FromRef","vector3","getFloat32","setVector3Float32FromRef","getVector4Float32FromRef","vector4","setVector4Float32FromRef","isNaN","setInt16","setByte","setInt8","__IGLTFExporterExtensionV2","GLTFAsync","filePrefix","whenReadyAsync","_PreExportAsync","exportWithoutWaitingForScene","_PostExportAsync","glTFData","GLBAsync","ShaderStore","NAME","_recordedTextures","_wasUsed","uAng","wAng","vAng","uRotationCenter","vRotationCenter","textureTransform","transformIsRequired","uOffset","vOffset","uScale","vScale","bakeTextureTransform","_textureTransformTextureAsync","proceduralTexture","catch","ProceduralTexture","reservedDataStore","hidden","setTexture","setMatrix","getTextureMatrix","isReady","render","getEffect","executeWhenCompiled","KHR_texture_transform","_lights","ShadowLight","babylonLight","light","lightType","getTypeID","Logger","lightPosition","clone","localAxis","direction","yaw","atan2","PI","len","pitch","lightRotationQuaternion","falloffType","intensity","range","Number","MAX_VALUE","babylonSpotLight","angle","spot","outerConeAngle","innerAngle","innerConeAngle","lightReference","parentBabylonNode","getChildren","parentNode","parentNodeLocalMatrix","TmpVectors","parentInvertNodeLocalMatrix","parentNodeLocalTranslation","parentNodeLocalRotation","parentNodeLocalScale","lightLocalMatrix","nodeLocalTranslation","DirectionalLight","subtractInPlace","nodeLocalRotation","nodeLocalScale","multiplyToRef","parentNewScale","parentNewRotationQuaternion","parentNewTranslation","decompose","KHR_lights_punctual","additionalTextures","PBRBaseMaterial","clearCoat","isEnabled","useRoughnessFromMainTexture","textureRoughness","clearCoatTextureRoughnessInfo","clearCoatTextureInfo","isTintEnabled","remapF0OnInterfaceChange","clearCoatNormalTextureInfo","clearcoatFactor","clearcoatTexture","clearcoatRoughnessFactor","clearcoatRoughnessTexture","clearcoatNormalTexture","KHR_materials_clearcoat","iridescence","thicknessTexture","iridescenceTextureInfo","iridescenceThicknessTextureInfo","iridescenceFactor","iridescenceIor","indexOfRefraction","iridescenceThicknessMinimum","minimumThickness","iridescenceThicknessMaximum","maximumThickness","iridescenceTexture","iridescenceThicknessTexture","KHR_materials_iridescence","PBRMaterial","sheen","sheenColorFactor","sheenRoughnessFactor","sheenColorTexture","sheenRoughnessTexture","KHR_materials_sheen","unlitMaterial","unlit","StandardMaterial","disableLighting","KHR_materials_unlit","_isExtensionEnabled","iorInfo","ior","KHR_materials_ior","metallicReflectanceTexture","reflectanceTexture","metallicF0Factor","metallicReflectanceColor","equalsFloats","_hasTexturesExtension","specularInfo","specularFactor","specularColorFactor","specularColorTexture","KHR_materials_specular","subSurface","subs","isRefractionEnabled","isTranslucencyEnabled","tintColorAtDistance","POSITIVE_INFINITY","tintColor","volumeInfo","thicknessFactor","attenuationDistance","attenuationColor","KHR_materials_volume","refractionIntensity","refractionIntensityTexture","transmissionFactor","transmissionTexture","KHR_materials_transmission","hasThinInstances","noTranslation","noRotation","noScale","matrix","thinInstanceGetWorldMatrices","iwt","iwr","iws","hasAnyInstanceWorldTranslation","hasAnyInstanceWorldRotation","hasAnyInstanceWorldScale","translationBuffer","thinInstanceCount","rotationBuffer","scaleBuffer","equalsWithEpsilon","_buildAccessor","bufferOffset","bv","accessorIndex","normalized","EXT_mesh_gpu_instancing","CreateSTL","fileName","binary","isLittleEndian","doNotBakeTransform","getFaceData","p1p2","p3p2","writeVector","dataview","writeFloat","faceCount","bakeCurrentTransformIntoVertices","fd","globalObject","BABYLON","GLTF2","Exporter","Extensions","serializer"],"sourceRoot":""}