{"version":3,"file":"static/js/vendor.async.non-landing~75dbb454.618337b1.chunk.js","mappings":"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","sources":["../../../../../dev/core/src/Collisions/pickingInfo.ts","../../../../../../dev/core/src/Materials/Textures/baseTexture.ts","../../../../../dev/core/src/Misc/copyTools.ts","../../../../../dev/core/src/Compat/compatibilityOptions.ts","../../../../../../dev/core/src/Materials/Textures/texture.ts","../../../../../dev/core/src/Materials/uniformBuffer.ts","../../../../../dev/core/src/Maths/math.axis.ts","../../../../../dev/core/src/Maths/math.color.ts","../../../../../dev/core/src/Maths/math.constants.ts","../../../../../dev/core/src/Maths/math.frustum.ts","../../../../../dev/core/src/Maths/math.plane.ts","../../../../../dev/core/src/Maths/math.scalar.functions.ts","../../../../../dev/core/src/Maths/math.vector.ts","../../../../../dev/core/src/Maths/math.path.ts","../../../../../dev/core/src/Maths/sphericalPolynomial.ts","../../../../../../dev/core/src/Misc/HighDynamicRange/cubemapToSphericalPolynomial.ts","../../../../../dev/core/src/Misc/arrayTools.ts","../../../../../../dev/core/src/Engines/AbstractEngine/abstractEngine.cubeTexture.ts","../../../../../dev/core/src/Misc/dds.ts","../../../../../dev/core/src/Misc/decorators.functions.ts","../../../../../dev/core/src/Misc/decorators.ts","../../../../../dev/core/src/Misc/decorators.serialization.ts","../../../../../dev/core/src/Misc/dumpTools.ts","../../../../../dev/core/src/Misc/perfCounter.ts","../../../../../dev/core/src/Misc/smartArray.ts","../../../../../dev/core/src/Misc/andOrNotEvaluator.ts","../../../../../dev/core/src/Misc/tags.ts","../../../../../dev/core/src/Rendering/objectRenderer.ts","../../../../../../dev/core/src/Materials/Textures/renderTargetTexture.ts","../../../../../dev/core/src/Misc/performanceMonitor.ts","../../../../../../dev/core/src/Engines/Extensions/engine.readTexture.ts","../../../../../../dev/core/src/Engines/Extensions/engine.dynamicBuffer.ts","../../../../../../dev/core/src/Engines/Extensions/engine.cubeTexture.ts","../../../../../../dev/core/src/Engines/Extensions/engine.renderTargetTexture.ts","../../../../../../dev/core/src/Engines/Extensions/engine.renderTargetCube.ts","../../../../../../dev/core/src/Engines/Extensions/engine.prefilteredCubeTexture.ts","../../../../../../dev/core/src/Engines/Extensions/engine.uniformBuffer.ts","../../../../../../dev/core/src/Engines/AbstractEngine/abstractEngine.loadingScreen.ts","../../../../../../dev/core/src/Engines/AbstractEngine/abstractEngine.dom.ts","../../../../../../dev/core/src/Engines/AbstractEngine/abstractEngine.alpha.ts","../../../../../../dev/core/src/Engines/AbstractEngine/abstractEngine.states.ts","../../../../../../dev/core/src/Engines/AbstractEngine/abstractEngine.renderPass.ts","../../../../../dev/core/src/Engines/engine.common.ts","../../../../../dev/core/src/Audio/audioEngine.ts","../../../../../dev/core/src/Engines/engine.ts","../../../../../dev/core/src/PostProcesses/thinPassPostProcess.ts","../../../../../dev/core/src/PostProcesses/passPostProcess.ts","../../../../../dev/core/src/Misc/textureTools.ts","../../../../../dev/core/src/PostProcesses/postProcess.ts","../../../../../dev/core/src/PostProcesses/postProcessManager.ts","../../../../../dev/core/src/Rendering/renderingGroup.ts","../../../../../dev/core/src/Rendering/renderingManager.ts","../../../../../../dev/core/src/ShadersWGSL/ShadersInclude/helperFunctions.ts","../../../../../../dev/core/src/Shaders/ShadersInclude/helperFunctions.ts","../../../../node_modules/.pnpm/@babylonjs+core@7.47.2/node_modules/@babylonjs/core/tslib.es6.js"],"sourcesContent":["import type { Nullable, FloatArray } from \"../types\";\r\nimport { Vector3, Vector2, TmpVectors } from \"../Maths/math.vector\";\r\nimport type { AbstractMesh } from \"../Meshes/abstractMesh\";\r\nimport type { TransformNode } from \"../Meshes/transformNode\";\r\nimport { VertexBuffer } from \"../Buffers/buffer\";\r\nimport type { Sprite } from \"../Sprites/sprite\";\r\n\r\nimport type { Ray } from \"../Culling/ray\";\r\n\r\n/**\r\n * Information about the result of picking within a scene\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/interactions/picking_collisions\r\n */\r\nexport class PickingInfo {\r\n /**\r\n * If the pick collided with an object\r\n */\r\n public hit = false;\r\n /**\r\n * Distance away where the pick collided\r\n */\r\n public distance = 0;\r\n /**\r\n * The location of pick collision\r\n */\r\n public pickedPoint: Nullable = null;\r\n /**\r\n * The mesh corresponding the pick collision\r\n */\r\n public pickedMesh: Nullable = null;\r\n /** (See getTextureCoordinates) The barycentric U coordinate that is used when calculating the texture coordinates of the collision.*/\r\n public bu = 0;\r\n /** (See getTextureCoordinates) The barycentric V coordinate that is used when calculating the texture coordinates of the collision.*/\r\n public bv = 0;\r\n /** The index of the face on the mesh that was picked, or the index of the Line if the picked Mesh is a LinesMesh */\r\n public faceId = -1;\r\n /** The index of the face on the subMesh that was picked, or the index of the Line if the picked Mesh is a LinesMesh */\r\n public subMeshFaceId = -1;\r\n /** Id of the submesh that was picked */\r\n public subMeshId = 0;\r\n /** If a sprite was picked, this will be the sprite the pick collided with */\r\n public pickedSprite: Nullable = null;\r\n /** If we are picking a mesh with thin instance, this will give you the picked thin instance */\r\n public thinInstanceIndex = -1;\r\n /**\r\n * The ray that was used to perform the picking.\r\n */\r\n public ray: Nullable = null;\r\n /**\r\n * If a mesh was used to do the picking (eg. 6dof controller) as a \"near interaction\", this will be populated.\r\n */\r\n public originMesh: Nullable = null;\r\n /**\r\n * The aim-space transform of the input used for picking, if it is an XR input source.\r\n */\r\n public aimTransform: Nullable = null;\r\n /**\r\n * The grip-space transform of the input used for picking, if it is an XR input source.\r\n * Some XR sources, such as input coming from head mounted displays, do not have this.\r\n */\r\n public gripTransform: Nullable = null;\r\n\r\n /**\r\n * Gets the normal corresponding to the face the pick collided with\r\n * @param useWorldCoordinates If the resulting normal should be relative to the world (default: false)\r\n * @param useVerticesNormals If the vertices normals should be used to calculate the normal instead of the normal map (default: true)\r\n * @returns The normal corresponding to the face the pick collided with\r\n * @remarks Note that the returned normal will always point towards the picking ray.\r\n */\r\n public getNormal(useWorldCoordinates = false, useVerticesNormals = true): Nullable {\r\n if (!this.pickedMesh || (useVerticesNormals && !this.pickedMesh.isVerticesDataPresent(VertexBuffer.NormalKind))) {\r\n return null;\r\n }\r\n\r\n let indices = this.pickedMesh.getIndices();\r\n\r\n if (indices?.length === 0) {\r\n indices = null;\r\n }\r\n\r\n let result: Vector3;\r\n\r\n const tmp0 = TmpVectors.Vector3[0];\r\n const tmp1 = TmpVectors.Vector3[1];\r\n const tmp2 = TmpVectors.Vector3[2];\r\n\r\n if (useVerticesNormals) {\r\n const normals = this.pickedMesh.getVerticesData(VertexBuffer.NormalKind);\r\n\r\n let normal0 = indices\r\n ? Vector3.FromArrayToRef(normals, indices[this.faceId * 3] * 3, tmp0)\r\n : tmp0.copyFromFloats(normals[this.faceId * 3 * 3], normals[this.faceId * 3 * 3 + 1], normals[this.faceId * 3 * 3 + 2]);\r\n let normal1 = indices\r\n ? Vector3.FromArrayToRef(normals, indices[this.faceId * 3 + 1] * 3, tmp1)\r\n : tmp1.copyFromFloats(normals[(this.faceId * 3 + 1) * 3], normals[(this.faceId * 3 + 1) * 3 + 1], normals[(this.faceId * 3 + 1) * 3 + 2]);\r\n let normal2 = indices\r\n ? Vector3.FromArrayToRef(normals, indices[this.faceId * 3 + 2] * 3, tmp2)\r\n : tmp2.copyFromFloats(normals[(this.faceId * 3 + 2) * 3], normals[(this.faceId * 3 + 2) * 3 + 1], normals[(this.faceId * 3 + 2) * 3 + 2]);\r\n\r\n normal0 = normal0.scale(this.bu);\r\n normal1 = normal1.scale(this.bv);\r\n normal2 = normal2.scale(1.0 - this.bu - this.bv);\r\n\r\n result = new Vector3(normal0.x + normal1.x + normal2.x, normal0.y + normal1.y + normal2.y, normal0.z + normal1.z + normal2.z);\r\n } else {\r\n const positions = this.pickedMesh.getVerticesData(VertexBuffer.PositionKind);\r\n\r\n const vertex1 = indices\r\n ? Vector3.FromArrayToRef(positions, indices[this.faceId * 3] * 3, tmp0)\r\n : tmp0.copyFromFloats(positions[this.faceId * 3 * 3], positions[this.faceId * 3 * 3 + 1], positions[this.faceId * 3 * 3 + 2]);\r\n const vertex2 = indices\r\n ? Vector3.FromArrayToRef(positions, indices[this.faceId * 3 + 1] * 3, tmp1)\r\n : tmp1.copyFromFloats(positions[(this.faceId * 3 + 1) * 3], positions[(this.faceId * 3 + 1) * 3 + 1], positions[(this.faceId * 3 + 1) * 3 + 2]);\r\n const vertex3 = indices\r\n ? Vector3.FromArrayToRef(positions, indices[this.faceId * 3 + 2] * 3, tmp2)\r\n : tmp2.copyFromFloats(positions[(this.faceId * 3 + 2) * 3], positions[(this.faceId * 3 + 2) * 3 + 1], positions[(this.faceId * 3 + 2) * 3 + 2]);\r\n\r\n const p1p2 = vertex1.subtract(vertex2);\r\n const p3p2 = vertex3.subtract(vertex2);\r\n\r\n result = Vector3.Cross(p1p2, p3p2);\r\n }\r\n\r\n const transformNormalToWorld = (pickedMesh: AbstractMesh, n: Vector3) => {\r\n let wm = pickedMesh.getWorldMatrix();\r\n\r\n if (pickedMesh.nonUniformScaling) {\r\n TmpVectors.Matrix[0].copyFrom(wm);\r\n wm = TmpVectors.Matrix[0];\r\n wm.setTranslationFromFloats(0, 0, 0);\r\n wm.invert();\r\n wm.transposeToRef(TmpVectors.Matrix[1]);\r\n\r\n wm = TmpVectors.Matrix[1];\r\n }\r\n\r\n Vector3.TransformNormalToRef(n, wm, n);\r\n };\r\n\r\n if (useWorldCoordinates) {\r\n transformNormalToWorld(this.pickedMesh, result);\r\n }\r\n\r\n if (this.ray) {\r\n const normalForDirectionChecking = TmpVectors.Vector3[0].copyFrom(result);\r\n\r\n if (!useWorldCoordinates) {\r\n // the normal has not been transformed to world space as part as the normal processing, so we must do it now\r\n transformNormalToWorld(this.pickedMesh, normalForDirectionChecking);\r\n }\r\n\r\n // Flip the normal if the picking ray is in the same direction.\r\n if (Vector3.Dot(normalForDirectionChecking, this.ray.direction) > 0) {\r\n result.negateInPlace();\r\n }\r\n }\r\n\r\n result.normalize();\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Gets the texture coordinates of where the pick occurred\r\n * @param uvSet The UV set to use to calculate the texture coordinates (default: VertexBuffer.UVKind)\r\n * @returns The vector containing the coordinates of the texture\r\n */\r\n public getTextureCoordinates(uvSet = VertexBuffer.UVKind): Nullable {\r\n if (!this.pickedMesh || !this.pickedMesh.isVerticesDataPresent(uvSet)) {\r\n return null;\r\n }\r\n\r\n const indices = this.pickedMesh.getIndices();\r\n if (!indices) {\r\n return null;\r\n }\r\n\r\n const uvs = this.pickedMesh.getVerticesData(uvSet);\r\n if (!uvs) {\r\n return null;\r\n }\r\n\r\n let uv0 = Vector2.FromArray(uvs, indices[this.faceId * 3] * 2);\r\n let uv1 = Vector2.FromArray(uvs, indices[this.faceId * 3 + 1] * 2);\r\n let uv2 = Vector2.FromArray(uvs, indices[this.faceId * 3 + 2] * 2);\r\n\r\n uv0 = uv0.scale(this.bu);\r\n uv1 = uv1.scale(this.bv);\r\n uv2 = uv2.scale(1.0 - this.bu - this.bv);\r\n\r\n return new Vector2(uv0.x + uv1.x + uv2.x, uv0.y + uv1.y + uv2.y);\r\n }\r\n}\r\n","import { serialize, serializeAsTexture } from \"../../Misc/decorators\";\r\nimport type { Observer } from \"../../Misc/observable\";\r\nimport { Observable } from \"../../Misc/observable\";\r\nimport type { Nullable } from \"../../types\";\r\nimport type { Scene } from \"../../scene\";\r\nimport { Matrix } from \"../../Maths/math.vector\";\r\nimport { EngineStore } from \"../../Engines/engineStore\";\r\nimport type { InternalTexture } from \"../../Materials/Textures/internalTexture\";\r\nimport { Constants } from \"../../Engines/constants\";\r\nimport type { IAnimatable } from \"../../Animations/animatable.interface\";\r\nimport { RandomGUID } from \"../../Misc/guid\";\r\n\r\nimport \"../../Misc/fileTools\";\r\nimport type { AbstractEngine } from \"../../Engines/abstractEngine\";\r\nimport { ThinTexture } from \"./thinTexture\";\r\n\r\nimport type { Animation } from \"../../Animations/animation\";\r\nimport { SerializationHelper } from \"../../Misc/decorators.serialization\";\r\nimport type { IAssetContainer } from \"core/IAssetContainer\";\r\n\r\n/**\r\n * Base class of all the textures in babylon.\r\n * It groups all the common properties the materials, post process, lights... might need\r\n * in order to make a correct use of the texture.\r\n */\r\nexport class BaseTexture extends ThinTexture implements IAnimatable {\r\n /**\r\n * Default anisotropic filtering level for the application.\r\n * It is set to 4 as a good tradeoff between perf and quality.\r\n */\r\n public static DEFAULT_ANISOTROPIC_FILTERING_LEVEL = 4;\r\n\r\n /**\r\n * Gets or sets the unique id of the texture\r\n */\r\n @serialize()\r\n public uniqueId: number;\r\n\r\n /**\r\n * Define the name of the texture.\r\n */\r\n @serialize()\r\n public name: string;\r\n\r\n /**\r\n * Define the display name of the texture, which is used as tree item name of the dedicated node in the inspector\r\n */\r\n @serialize()\r\n public displayName: string;\r\n\r\n /**\r\n * Gets or sets an object used to store user defined information.\r\n */\r\n @serialize()\r\n public metadata: any = null;\r\n\r\n /** @internal */\r\n public _internalMetadata: any;\r\n\r\n /**\r\n * For internal use only. Please do not use.\r\n */\r\n public reservedDataStore: any = null;\r\n\r\n @serialize(\"hasAlpha\")\r\n private _hasAlpha = false;\r\n /**\r\n * Define if the texture is having a usable alpha value (can be use for transparency or glossiness for instance).\r\n */\r\n public set hasAlpha(value: boolean) {\r\n if (this._hasAlpha === value) {\r\n return;\r\n }\r\n this._hasAlpha = value;\r\n if (this._scene) {\r\n this._scene.markAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag, (mat) => {\r\n return mat.hasTexture(this);\r\n });\r\n }\r\n }\r\n public get hasAlpha(): boolean {\r\n return this._hasAlpha;\r\n }\r\n\r\n @serialize(\"getAlphaFromRGB\")\r\n private _getAlphaFromRGB = false;\r\n /**\r\n * Defines if the alpha value should be determined via the rgb values.\r\n * If true the luminance of the pixel might be used to find the corresponding alpha value.\r\n */\r\n public set getAlphaFromRGB(value: boolean) {\r\n if (this._getAlphaFromRGB === value) {\r\n return;\r\n }\r\n this._getAlphaFromRGB = value;\r\n if (this._scene) {\r\n this._scene.markAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag, (mat) => {\r\n return mat.hasTexture(this);\r\n });\r\n }\r\n }\r\n public get getAlphaFromRGB(): boolean {\r\n return this._getAlphaFromRGB;\r\n }\r\n\r\n /**\r\n * Intensity or strength of the texture.\r\n * It is commonly used by materials to fine tune the intensity of the texture\r\n */\r\n @serialize()\r\n public level = 1;\r\n\r\n @serialize(\"coordinatesIndex\")\r\n protected _coordinatesIndex = 0;\r\n\r\n /**\r\n * Gets or sets a boolean indicating that the texture should try to reduce shader code if there is no UV manipulation.\r\n * (ie. when texture.getTextureMatrix().isIdentityAs3x2() returns true)\r\n */\r\n @serialize()\r\n public optimizeUVAllocation = true;\r\n\r\n /**\r\n * Define the UV channel to use starting from 0 and defaulting to 0.\r\n * This is part of the texture as textures usually maps to one uv set.\r\n */\r\n public set coordinatesIndex(value: number) {\r\n if (this._coordinatesIndex === value) {\r\n return;\r\n }\r\n this._coordinatesIndex = value;\r\n if (this._scene) {\r\n this._scene.markAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag, (mat) => {\r\n return mat.hasTexture(this);\r\n });\r\n }\r\n }\r\n public get coordinatesIndex(): number {\r\n return this._coordinatesIndex;\r\n }\r\n\r\n @serialize(\"coordinatesMode\")\r\n protected _coordinatesMode = Constants.TEXTURE_EXPLICIT_MODE;\r\n\r\n /**\r\n * How a texture is mapped.\r\n *\r\n * | Value | Type | Description |\r\n * | ----- | ----------------------------------- | ----------- |\r\n * | 0 | EXPLICIT_MODE | |\r\n * | 1 | SPHERICAL_MODE | |\r\n * | 2 | PLANAR_MODE | |\r\n * | 3 | CUBIC_MODE | |\r\n * | 4 | PROJECTION_MODE | |\r\n * | 5 | SKYBOX_MODE | |\r\n * | 6 | INVCUBIC_MODE | |\r\n * | 7 | EQUIRECTANGULAR_MODE | |\r\n * | 8 | FIXED_EQUIRECTANGULAR_MODE | |\r\n * | 9 | FIXED_EQUIRECTANGULAR_MIRRORED_MODE | |\r\n */\r\n public override set coordinatesMode(value: number) {\r\n if (this._coordinatesMode === value) {\r\n return;\r\n }\r\n this._coordinatesMode = value;\r\n if (this._scene) {\r\n this._scene.markAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag, (mat) => {\r\n return mat.hasTexture(this);\r\n });\r\n }\r\n }\r\n public override get coordinatesMode(): number {\r\n return this._coordinatesMode;\r\n }\r\n\r\n /**\r\n * | Value | Type | Description |\r\n * | ----- | ------------------ | ----------- |\r\n * | 0 | CLAMP_ADDRESSMODE | |\r\n * | 1 | WRAP_ADDRESSMODE | |\r\n * | 2 | MIRROR_ADDRESSMODE | |\r\n */\r\n @serialize()\r\n public override get wrapU() {\r\n return this._wrapU;\r\n }\r\n public override set wrapU(value: number) {\r\n this._wrapU = value;\r\n }\r\n\r\n /**\r\n * | Value | Type | Description |\r\n * | ----- | ------------------ | ----------- |\r\n * | 0 | CLAMP_ADDRESSMODE | |\r\n * | 1 | WRAP_ADDRESSMODE | |\r\n * | 2 | MIRROR_ADDRESSMODE | |\r\n */\r\n @serialize()\r\n public override get wrapV() {\r\n return this._wrapV;\r\n }\r\n public override set wrapV(value: number) {\r\n this._wrapV = value;\r\n }\r\n\r\n /**\r\n * | Value | Type | Description |\r\n * | ----- | ------------------ | ----------- |\r\n * | 0 | CLAMP_ADDRESSMODE | |\r\n * | 1 | WRAP_ADDRESSMODE | |\r\n * | 2 | MIRROR_ADDRESSMODE | |\r\n */\r\n @serialize()\r\n public override wrapR = Constants.TEXTURE_WRAP_ADDRESSMODE;\r\n\r\n /**\r\n * With compliant hardware and browser (supporting anisotropic filtering)\r\n * this defines the level of anisotropic filtering in the texture.\r\n * The higher the better but the slower. This defaults to 4 as it seems to be the best tradeoff.\r\n */\r\n @serialize()\r\n public override anisotropicFilteringLevel = BaseTexture.DEFAULT_ANISOTROPIC_FILTERING_LEVEL;\r\n\r\n /** @internal */\r\n public _isCube = false;\r\n /**\r\n * Define if the texture is a cube texture or if false a 2d texture.\r\n */\r\n @serialize()\r\n public override get isCube(): boolean {\r\n if (!this._texture) {\r\n return this._isCube;\r\n }\r\n\r\n return this._texture.isCube;\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n protected override set isCube(value: boolean) {\r\n if (!this._texture) {\r\n this._isCube = value;\r\n } else {\r\n this._texture.isCube = value;\r\n }\r\n }\r\n\r\n /**\r\n * Define if the texture is a 3d texture (webgl 2) or if false a 2d texture.\r\n */\r\n @serialize()\r\n public override get is3D(): boolean {\r\n if (!this._texture) {\r\n return false;\r\n }\r\n\r\n return this._texture.is3D;\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n protected override set is3D(value: boolean) {\r\n if (!this._texture) {\r\n return;\r\n }\r\n\r\n this._texture.is3D = value;\r\n }\r\n\r\n /**\r\n * Define if the texture is a 2d array texture (webgl 2) or if false a 2d texture.\r\n */\r\n @serialize()\r\n public override get is2DArray(): boolean {\r\n if (!this._texture) {\r\n return false;\r\n }\r\n\r\n return this._texture.is2DArray;\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n protected override set is2DArray(value: boolean) {\r\n if (!this._texture) {\r\n return;\r\n }\r\n\r\n this._texture.is2DArray = value;\r\n }\r\n\r\n /** @internal */\r\n protected _gammaSpace = true;\r\n /**\r\n * Define if the texture contains data in gamma space (most of the png/jpg aside bump).\r\n * HDR texture are usually stored in linear space.\r\n * This only impacts the PBR and Background materials\r\n */\r\n @serialize()\r\n public get gammaSpace(): boolean {\r\n if (!this._texture) {\r\n return this._gammaSpace;\r\n } else {\r\n if (this._texture._gammaSpace === null) {\r\n this._texture._gammaSpace = this._gammaSpace;\r\n }\r\n }\r\n\r\n return this._texture._gammaSpace && !this._texture._useSRGBBuffer;\r\n }\r\n\r\n public set gammaSpace(gamma: boolean) {\r\n if (!this._texture) {\r\n if (this._gammaSpace === gamma) {\r\n return;\r\n }\r\n\r\n this._gammaSpace = gamma;\r\n } else {\r\n if (this._texture._gammaSpace === gamma) {\r\n return;\r\n }\r\n this._texture._gammaSpace = gamma;\r\n }\r\n\r\n this.getScene()?.markAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag, (mat) => {\r\n return mat.hasTexture(this);\r\n });\r\n }\r\n\r\n /**\r\n * Gets or sets whether or not the texture contains RGBD data.\r\n */\r\n public get isRGBD(): boolean {\r\n return this._texture != null && this._texture._isRGBD;\r\n }\r\n public set isRGBD(value: boolean) {\r\n if (value === this.isRGBD) {\r\n return;\r\n }\r\n\r\n if (this._texture) {\r\n this._texture._isRGBD = value;\r\n }\r\n\r\n this.getScene()?.markAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag, (mat) => {\r\n return mat.hasTexture(this);\r\n });\r\n }\r\n\r\n /**\r\n * Is Z inverted in the texture (useful in a cube texture).\r\n */\r\n @serialize()\r\n public invertZ = false;\r\n\r\n /**\r\n * Are mip maps generated for this texture or not.\r\n */\r\n public get noMipmap(): boolean {\r\n return false;\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n @serialize()\r\n public lodLevelInAlpha = false;\r\n\r\n /**\r\n * With prefiltered texture, defined the offset used during the prefiltering steps.\r\n */\r\n @serialize()\r\n public get lodGenerationOffset(): number {\r\n if (this._texture) {\r\n return this._texture._lodGenerationOffset;\r\n }\r\n\r\n return 0.0;\r\n }\r\n public set lodGenerationOffset(value: number) {\r\n if (this._texture) {\r\n this._texture._lodGenerationOffset = value;\r\n }\r\n }\r\n\r\n /**\r\n * With prefiltered texture, defined the scale used during the prefiltering steps.\r\n */\r\n @serialize()\r\n public get lodGenerationScale(): number {\r\n if (this._texture) {\r\n return this._texture._lodGenerationScale;\r\n }\r\n\r\n return 0.0;\r\n }\r\n public set lodGenerationScale(value: number) {\r\n if (this._texture) {\r\n this._texture._lodGenerationScale = value;\r\n }\r\n }\r\n\r\n /**\r\n * With prefiltered texture, defined if the specular generation is based on a linear ramp.\r\n * By default we are using a log2 of the linear roughness helping to keep a better resolution for\r\n * average roughness values.\r\n */\r\n @serialize()\r\n public get linearSpecularLOD(): boolean {\r\n if (this._texture) {\r\n return this._texture._linearSpecularLOD;\r\n }\r\n\r\n return false;\r\n }\r\n public set linearSpecularLOD(value: boolean) {\r\n if (this._texture) {\r\n this._texture._linearSpecularLOD = value;\r\n }\r\n }\r\n\r\n /**\r\n * In case a better definition than spherical harmonics is required for the diffuse part of the environment.\r\n * You can set the irradiance texture to rely on a texture instead of the spherical approach.\r\n * This texture need to have the same characteristics than its parent (Cube vs 2d, coordinates mode, Gamma/Linear, RGBD).\r\n */\r\n @serializeAsTexture()\r\n public get irradianceTexture(): Nullable {\r\n if (this._texture) {\r\n return this._texture._irradianceTexture;\r\n }\r\n\r\n return null;\r\n }\r\n public set irradianceTexture(value: Nullable) {\r\n if (this._texture) {\r\n this._texture._irradianceTexture = value;\r\n }\r\n }\r\n\r\n /**\r\n * Define if the texture is a render target.\r\n */\r\n @serialize()\r\n public isRenderTarget = false;\r\n\r\n /**\r\n * Define the unique id of the texture in the scene.\r\n */\r\n public get uid(): string {\r\n if (!this._uid) {\r\n this._uid = RandomGUID();\r\n }\r\n return this._uid;\r\n }\r\n\r\n /** @internal */\r\n public _prefiltered: boolean = false;\r\n /** @internal */\r\n public _forceSerialize: boolean = false;\r\n\r\n /**\r\n * Return a string representation of the texture.\r\n * @returns the texture as a string\r\n */\r\n public override toString(): string {\r\n return this.name;\r\n }\r\n\r\n /**\r\n * Get the class name of the texture.\r\n * @returns \"BaseTexture\"\r\n */\r\n public override getClassName(): string {\r\n return \"BaseTexture\";\r\n }\r\n\r\n /**\r\n * Define the list of animation attached to the texture.\r\n */\r\n public animations: Animation[] = [];\r\n\r\n /**\r\n * An event triggered when the texture is disposed.\r\n */\r\n public onDisposeObservable = new Observable();\r\n\r\n private _onDisposeObserver: Nullable> = null;\r\n /**\r\n * Callback triggered when the texture has been disposed.\r\n * Kept for back compatibility, you can use the onDisposeObservable instead.\r\n */\r\n public set onDispose(callback: () => void) {\r\n if (this._onDisposeObserver) {\r\n this.onDisposeObservable.remove(this._onDisposeObserver);\r\n }\r\n this._onDisposeObserver = this.onDisposeObservable.add(callback);\r\n }\r\n\r\n protected _scene: Nullable = null;\r\n\r\n /** @internal */\r\n private _uid: Nullable = null;\r\n\r\n /**\r\n * Define if the texture is preventing a material to render or not.\r\n * If not and the texture is not ready, the engine will use a default black texture instead.\r\n */\r\n public get isBlocking(): boolean {\r\n return true;\r\n }\r\n\r\n /** @internal */\r\n public _parentContainer: Nullable = null;\r\n\r\n protected _loadingError: boolean = false;\r\n protected _errorObject?: {\r\n message?: string;\r\n exception?: any;\r\n };\r\n\r\n /**\r\n * Was there any loading error?\r\n */\r\n public get loadingError(): boolean {\r\n return this._loadingError;\r\n }\r\n\r\n /**\r\n * If a loading error occurred this object will be populated with information about the error.\r\n */\r\n public get errorObject():\r\n | {\r\n message?: string;\r\n exception?: any;\r\n }\r\n | undefined {\r\n return this._errorObject;\r\n }\r\n\r\n /**\r\n * Instantiates a new BaseTexture.\r\n * Base class of all the textures in babylon.\r\n * It groups all the common properties the materials, post process, lights... might need\r\n * in order to make a correct use of the texture.\r\n * @param sceneOrEngine Define the scene or engine the texture belongs to\r\n * @param internalTexture Define the internal texture associated with the texture\r\n */\r\n constructor(sceneOrEngine?: Nullable, internalTexture: Nullable = null) {\r\n super(null);\r\n\r\n if (sceneOrEngine) {\r\n if (BaseTexture._IsScene(sceneOrEngine)) {\r\n this._scene = sceneOrEngine;\r\n } else {\r\n this._engine = sceneOrEngine;\r\n }\r\n } else {\r\n this._scene = EngineStore.LastCreatedScene;\r\n }\r\n\r\n if (this._scene) {\r\n this.uniqueId = this._scene.getUniqueId();\r\n this._scene.addTexture(this);\r\n this._engine = this._scene.getEngine();\r\n }\r\n\r\n this._texture = internalTexture;\r\n\r\n this._uid = null;\r\n }\r\n\r\n /**\r\n * Get the scene the texture belongs to.\r\n * @returns the scene or null if undefined\r\n */\r\n public getScene(): Nullable {\r\n return this._scene;\r\n }\r\n\r\n /** @internal */\r\n protected _getEngine(): Nullable {\r\n return this._engine;\r\n }\r\n\r\n /**\r\n * Get the texture transform matrix used to offset tile the texture for instance.\r\n * @returns the transformation matrix\r\n */\r\n public getTextureMatrix(): Matrix {\r\n return Matrix.IdentityReadOnly;\r\n }\r\n\r\n /**\r\n * Get the texture reflection matrix used to rotate/transform the reflection.\r\n * @returns the reflection matrix\r\n */\r\n public getReflectionTextureMatrix(): Matrix {\r\n return Matrix.IdentityReadOnly;\r\n }\r\n\r\n /**\r\n * Gets a suitable rotate/transform matrix when the texture is used for refraction.\r\n * There's a separate function from getReflectionTextureMatrix because refraction requires a special configuration of the matrix in right-handed mode.\r\n * @returns The refraction matrix\r\n */\r\n public getRefractionTextureMatrix(): Matrix {\r\n return this.getReflectionTextureMatrix();\r\n }\r\n\r\n /**\r\n * Get if the texture is ready to be consumed (either it is ready or it is not blocking)\r\n * @returns true if ready, not blocking or if there was an error loading the texture\r\n */\r\n public isReadyOrNotBlocking(): boolean {\r\n return !this.isBlocking || this.isReady() || this.loadingError;\r\n }\r\n\r\n /**\r\n * Scales the texture if is `canRescale()`\r\n * @param ratio the resize factor we want to use to rescale\r\n */\r\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n public scale(ratio: number): void {}\r\n\r\n /**\r\n * Get if the texture can rescale.\r\n */\r\n public get canRescale(): boolean {\r\n return false;\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n public _getFromCache(url: Nullable, noMipmap: boolean, sampling?: number, invertY?: boolean, useSRGBBuffer?: boolean, isCube?: boolean): Nullable {\r\n const engine = this._getEngine();\r\n if (!engine) {\r\n return null;\r\n }\r\n\r\n const correctedUseSRGBBuffer = engine._getUseSRGBBuffer(!!useSRGBBuffer, noMipmap);\r\n\r\n const texturesCache = engine.getLoadedTexturesCache();\r\n for (let index = 0; index < texturesCache.length; index++) {\r\n const texturesCacheEntry = texturesCache[index];\r\n\r\n if (useSRGBBuffer === undefined || correctedUseSRGBBuffer === texturesCacheEntry._useSRGBBuffer) {\r\n if (invertY === undefined || invertY === texturesCacheEntry.invertY) {\r\n if (texturesCacheEntry.url === url && texturesCacheEntry.generateMipMaps === !noMipmap) {\r\n if (!sampling || sampling === texturesCacheEntry.samplingMode) {\r\n if (isCube === undefined || isCube === texturesCacheEntry.isCube) {\r\n texturesCacheEntry.incrementReferences();\r\n return texturesCacheEntry;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n return null;\r\n }\r\n\r\n /** @internal */\r\n public _rebuild(_fromContextLost = false): void {}\r\n\r\n /**\r\n * Clones the texture.\r\n * @returns the cloned texture\r\n */\r\n public clone(): Nullable {\r\n return null;\r\n }\r\n\r\n /**\r\n * Get the texture underlying type (INT, FLOAT...)\r\n */\r\n public get textureType(): number {\r\n if (!this._texture) {\r\n return Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n }\r\n\r\n return this._texture.type !== undefined ? this._texture.type : Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n }\r\n\r\n /**\r\n * Get the texture underlying format (RGB, RGBA...)\r\n */\r\n public get textureFormat(): number {\r\n if (!this._texture) {\r\n return Constants.TEXTUREFORMAT_RGBA;\r\n }\r\n\r\n return this._texture.format !== undefined ? this._texture.format : Constants.TEXTUREFORMAT_RGBA;\r\n }\r\n\r\n /**\r\n * Indicates that textures need to be re-calculated for all materials\r\n */\r\n protected _markAllSubMeshesAsTexturesDirty() {\r\n const scene = this.getScene();\r\n\r\n if (!scene) {\r\n return;\r\n }\r\n\r\n scene.markAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag);\r\n }\r\n\r\n /**\r\n * Reads the pixels stored in the webgl texture and returns them as an ArrayBuffer.\r\n * This will returns an RGBA array buffer containing either in values (0-255) or\r\n * float values (0-1) depending of the underlying buffer type.\r\n * @param faceIndex defines the face of the texture to read (in case of cube texture)\r\n * @param level defines the LOD level of the texture to read (in case of Mip Maps)\r\n * @param buffer defines a user defined buffer to fill with data (can be null)\r\n * @param flushRenderer true to flush the renderer from the pending commands before reading the pixels\r\n * @param noDataConversion false to convert the data to Uint8Array (if texture type is UNSIGNED_BYTE) or to Float32Array (if texture type is anything but UNSIGNED_BYTE). If true, the type of the generated buffer (if buffer==null) will depend on the type of the texture\r\n * @param x defines the region x coordinates to start reading from (default to 0)\r\n * @param y defines the region y coordinates to start reading from (default to 0)\r\n * @param width defines the region width to read from (default to the texture size at level)\r\n * @param height defines the region width to read from (default to the texture size at level)\r\n * @returns The Array buffer promise containing the pixels data.\r\n */\r\n public readPixels(\r\n faceIndex = 0,\r\n level = 0,\r\n buffer: Nullable = null,\r\n flushRenderer = true,\r\n noDataConversion = false,\r\n x = 0,\r\n y = 0,\r\n width = Number.MAX_VALUE,\r\n height = Number.MAX_VALUE\r\n ): Nullable> {\r\n if (!this._texture) {\r\n return null;\r\n }\r\n\r\n const engine = this._getEngine();\r\n if (!engine) {\r\n return null;\r\n }\r\n\r\n const size = this.getSize();\r\n let maxWidth = size.width;\r\n let maxHeight = size.height;\r\n if (level !== 0) {\r\n maxWidth = maxWidth / Math.pow(2, level);\r\n maxHeight = maxHeight / Math.pow(2, level);\r\n maxWidth = Math.round(maxWidth);\r\n maxHeight = Math.round(maxHeight);\r\n }\r\n\r\n width = Math.min(maxWidth, width);\r\n height = Math.min(maxHeight, height);\r\n\r\n try {\r\n if (this._texture.isCube) {\r\n return engine._readTexturePixels(this._texture, width, height, faceIndex, level, buffer, flushRenderer, noDataConversion, x, y);\r\n }\r\n\r\n return engine._readTexturePixels(this._texture, width, height, -1, level, buffer, flushRenderer, noDataConversion, x, y);\r\n } catch (e) {\r\n return null;\r\n }\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n public _readPixelsSync(faceIndex = 0, level = 0, buffer: Nullable = null, flushRenderer = true, noDataConversion = false): Nullable {\r\n if (!this._texture) {\r\n return null;\r\n }\r\n\r\n const size = this.getSize();\r\n let width = size.width;\r\n let height = size.height;\r\n\r\n const engine = this._getEngine();\r\n if (!engine) {\r\n return null;\r\n }\r\n\r\n if (level != 0) {\r\n width = width / Math.pow(2, level);\r\n height = height / Math.pow(2, level);\r\n\r\n width = Math.round(width);\r\n height = Math.round(height);\r\n }\r\n\r\n try {\r\n if (this._texture.isCube) {\r\n return engine._readTexturePixelsSync(this._texture, width, height, faceIndex, level, buffer, flushRenderer, noDataConversion);\r\n }\r\n\r\n return engine._readTexturePixelsSync(this._texture, width, height, -1, level, buffer, flushRenderer, noDataConversion);\r\n } catch (e) {\r\n return null;\r\n }\r\n }\r\n\r\n /** @internal */\r\n public get _lodTextureHigh(): Nullable {\r\n if (this._texture) {\r\n return this._texture._lodTextureHigh;\r\n }\r\n return null;\r\n }\r\n\r\n /** @internal */\r\n public get _lodTextureMid(): Nullable {\r\n if (this._texture) {\r\n return this._texture._lodTextureMid;\r\n }\r\n return null;\r\n }\r\n\r\n /** @internal */\r\n public get _lodTextureLow(): Nullable {\r\n if (this._texture) {\r\n return this._texture._lodTextureLow;\r\n }\r\n return null;\r\n }\r\n\r\n /**\r\n * Dispose the texture and release its associated resources.\r\n */\r\n public override dispose(): void {\r\n if (this._scene) {\r\n // Animations\r\n if (this._scene.stopAnimation) {\r\n this._scene.stopAnimation(this);\r\n }\r\n\r\n // Remove from scene\r\n this._scene.removePendingData(this);\r\n const index = this._scene.textures.indexOf(this);\r\n\r\n if (index >= 0) {\r\n this._scene.textures.splice(index, 1);\r\n }\r\n this._scene.onTextureRemovedObservable.notifyObservers(this);\r\n this._scene = null;\r\n\r\n if (this._parentContainer) {\r\n const index = this._parentContainer.textures.indexOf(this);\r\n if (index > -1) {\r\n this._parentContainer.textures.splice(index, 1);\r\n }\r\n this._parentContainer = null;\r\n }\r\n }\r\n\r\n // Callback\r\n this.onDisposeObservable.notifyObservers(this);\r\n this.onDisposeObservable.clear();\r\n\r\n this.metadata = null;\r\n\r\n super.dispose();\r\n }\r\n\r\n /**\r\n * Serialize the texture into a JSON representation that can be parsed later on.\r\n * @param allowEmptyName True to force serialization even if name is empty. Default: false\r\n * @returns the JSON representation of the texture\r\n */\r\n public serialize(allowEmptyName = false): any {\r\n if (!this.name && !allowEmptyName) {\r\n return null;\r\n }\r\n\r\n const serializationObject = SerializationHelper.Serialize(this);\r\n\r\n // Animations\r\n SerializationHelper.AppendSerializedAnimations(this, serializationObject);\r\n\r\n return serializationObject;\r\n }\r\n\r\n /**\r\n * Helper function to be called back once a list of texture contains only ready textures.\r\n * @param textures Define the list of textures to wait for\r\n * @param callback Define the callback triggered once the entire list will be ready\r\n */\r\n public static WhenAllReady(textures: BaseTexture[], callback: () => void): void {\r\n let numRemaining = textures.length;\r\n if (numRemaining === 0) {\r\n callback();\r\n return;\r\n }\r\n\r\n for (let i = 0; i < textures.length; i++) {\r\n const texture = textures[i];\r\n\r\n if (texture.isReady()) {\r\n if (--numRemaining === 0) {\r\n callback();\r\n }\r\n } else {\r\n const onLoadObservable = (texture as any).onLoadObservable as Observable;\r\n\r\n if (onLoadObservable) {\r\n onLoadObservable.addOnce(() => {\r\n if (--numRemaining === 0) {\r\n callback();\r\n }\r\n });\r\n } else {\r\n if (--numRemaining === 0) {\r\n callback();\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n private static _IsScene(sceneOrEngine: Scene | AbstractEngine): sceneOrEngine is Scene {\r\n return sceneOrEngine.getClassName() === \"Scene\";\r\n }\r\n}\r\n","/* eslint-disable @typescript-eslint/naming-convention */\r\nimport type { ISize } from \"../Maths/math.size\";\r\nimport type { Nullable } from \"../types\";\r\n\r\nimport type { BaseTexture } from \"../Materials/Textures/baseTexture\";\r\n\r\n/**\r\n * Transform some pixel data to a base64 string\r\n * @param pixels defines the pixel data to transform to base64\r\n * @param size defines the width and height of the (texture) data\r\n * @param invertY true if the data must be inverted for the Y coordinate during the conversion\r\n * @returns The base64 encoded string or null\r\n */\r\nexport function GenerateBase64StringFromPixelData(pixels: ArrayBufferView, size: ISize, invertY = false): Nullable {\r\n const width = size.width;\r\n const height = size.height;\r\n\r\n if (pixels instanceof Float32Array) {\r\n let len = pixels.byteLength / pixels.BYTES_PER_ELEMENT;\r\n const npixels = new Uint8Array(len);\r\n\r\n while (--len >= 0) {\r\n let val = pixels[len];\r\n if (val < 0) {\r\n val = 0;\r\n } else if (val > 1) {\r\n val = 1;\r\n }\r\n npixels[len] = val * 255;\r\n }\r\n\r\n pixels = npixels;\r\n }\r\n\r\n const canvas = document.createElement(\"canvas\");\r\n canvas.width = width;\r\n canvas.height = height;\r\n\r\n const ctx = canvas.getContext(\"2d\");\r\n if (!ctx) {\r\n return null;\r\n }\r\n\r\n const imageData = ctx.createImageData(width, height);\r\n const castData = imageData.data;\r\n castData.set(pixels);\r\n ctx.putImageData(imageData, 0, 0);\r\n\r\n if (invertY) {\r\n const canvas2 = document.createElement(\"canvas\");\r\n canvas2.width = width;\r\n canvas2.height = height;\r\n\r\n const ctx2 = canvas2.getContext(\"2d\");\r\n if (!ctx2) {\r\n return null;\r\n }\r\n\r\n ctx2.translate(0, height);\r\n ctx2.scale(1, -1);\r\n ctx2.drawImage(canvas, 0, 0);\r\n\r\n return canvas2.toDataURL(\"image/png\");\r\n }\r\n\r\n return canvas.toDataURL(\"image/png\");\r\n}\r\n\r\n/**\r\n * Reads the pixels stored in the webgl texture and returns them as a base64 string\r\n * @param texture defines the texture to read pixels from\r\n * @param faceIndex defines the face of the texture to read (in case of cube texture)\r\n * @param level defines the LOD level of the texture to read (in case of Mip Maps)\r\n * @returns The base64 encoded string or null\r\n */\r\nexport function GenerateBase64StringFromTexture(texture: BaseTexture, faceIndex = 0, level = 0): Nullable {\r\n const internalTexture = texture.getInternalTexture();\r\n if (!internalTexture) {\r\n return null;\r\n }\r\n\r\n const pixels = texture._readPixelsSync(faceIndex, level);\r\n if (!pixels) {\r\n return null;\r\n }\r\n\r\n return GenerateBase64StringFromPixelData(pixels, texture.getSize(), internalTexture.invertY);\r\n}\r\n\r\n/**\r\n * Reads the pixels stored in the webgl texture and returns them as a base64 string\r\n * @param texture defines the texture to read pixels from\r\n * @param faceIndex defines the face of the texture to read (in case of cube texture)\r\n * @param level defines the LOD level of the texture to read (in case of Mip Maps)\r\n * @returns The base64 encoded string or null wrapped in a promise\r\n */\r\nexport async function GenerateBase64StringFromTextureAsync(texture: BaseTexture, faceIndex = 0, level = 0): Promise> {\r\n const internalTexture = texture.getInternalTexture();\r\n if (!internalTexture) {\r\n return null;\r\n }\r\n\r\n const pixels = await texture.readPixels(faceIndex, level);\r\n if (!pixels) {\r\n return null;\r\n }\r\n\r\n return GenerateBase64StringFromPixelData(pixels, texture.getSize(), internalTexture.invertY);\r\n}\r\n\r\n/**\r\n * Class used to host copy specific utilities\r\n * (Back-compat)\r\n */\r\nexport const CopyTools = {\r\n /**\r\n * Transform some pixel data to a base64 string\r\n * @param pixels defines the pixel data to transform to base64\r\n * @param size defines the width and height of the (texture) data\r\n * @param invertY true if the data must be inverted for the Y coordinate during the conversion\r\n * @returns The base64 encoded string or null\r\n */\r\n GenerateBase64StringFromPixelData,\r\n\r\n /**\r\n * Reads the pixels stored in the webgl texture and returns them as a base64 string\r\n * @param texture defines the texture to read pixels from\r\n * @param faceIndex defines the face of the texture to read (in case of cube texture)\r\n * @param level defines the LOD level of the texture to read (in case of Mip Maps)\r\n * @returns The base64 encoded string or null\r\n */\r\n GenerateBase64StringFromTexture,\r\n\r\n /**\r\n * Reads the pixels stored in the webgl texture and returns them as a base64 string\r\n * @param texture defines the texture to read pixels from\r\n * @param faceIndex defines the face of the texture to read (in case of cube texture)\r\n * @param level defines the LOD level of the texture to read (in case of Mip Maps)\r\n * @returns The base64 encoded string or null wrapped in a promise\r\n */\r\n GenerateBase64StringFromTextureAsync,\r\n};\r\n","/**\r\n * Defines if the system should use OpenGL convention for UVs when creating geometry or loading .babylon files (false by default)\r\n */\r\nexport let useOpenGLOrientationForUV = false;\r\n\r\n/**\r\n * Sets whether to use OpenGL convention for UVs\r\n * @param value the new value\r\n */\r\nexport function setOpenGLOrientationForUV(value: boolean) {\r\n useOpenGLOrientationForUV = value;\r\n}\r\n\r\n/**\r\n * Options used to control default behaviors regarding compatibility support\r\n * @deprecated please use named exports\r\n */\r\nexport const CompatibilityOptions = {\r\n /* eslint-disable @typescript-eslint/naming-convention */\r\n get UseOpenGLOrientationForUV() {\r\n return useOpenGLOrientationForUV;\r\n },\r\n set UseOpenGLOrientationForUV(value) {\r\n useOpenGLOrientationForUV = value;\r\n },\r\n /* eslint-enable @typescript-eslint/naming-convention */\r\n};\r\n","import { serialize } from \"../../Misc/decorators\";\r\nimport { Observable } from \"../../Misc/observable\";\r\nimport type { Nullable } from \"../../types\";\r\nimport { Matrix, TmpVectors, Vector3 } from \"../../Maths/math.vector\";\r\nimport { BaseTexture } from \"../../Materials/Textures/baseTexture\";\r\nimport { Constants } from \"../../Engines/constants\";\r\nimport { GetClass, RegisterClass } from \"../../Misc/typeStore\";\r\nimport { _WarnImport } from \"../../Misc/devTools\";\r\nimport type { IInspectable } from \"../../Misc/iInspectable\";\r\nimport type { AbstractEngine } from \"../../Engines/abstractEngine\";\r\nimport { TimingTools } from \"../../Misc/timingTools\";\r\nimport { InstantiationTools } from \"../../Misc/instantiationTools\";\r\nimport { Plane } from \"../../Maths/math.plane\";\r\nimport { EncodeArrayBufferToBase64 } from \"../../Misc/stringTools\";\r\nimport { GenerateBase64StringFromTexture, GenerateBase64StringFromTextureAsync } from \"../../Misc/copyTools\";\r\nimport { useOpenGLOrientationForUV } from \"../../Compat/compatibilityOptions\";\r\nimport type { InternalTexture } from \"./internalTexture\";\r\n\r\nimport type { CubeTexture } from \"../../Materials/Textures/cubeTexture\";\r\nimport type { MirrorTexture } from \"../../Materials/Textures/mirrorTexture\";\r\nimport type { RenderTargetTexture } from \"../../Materials/Textures/renderTargetTexture\";\r\nimport type { Scene } from \"../../scene\";\r\nimport type { VideoTexture, VideoTextureSettings } from \"./videoTexture\";\r\n\r\nimport { SerializationHelper } from \"../../Misc/decorators.serialization\";\r\n\r\n/**\r\n * Defines the available options when creating a texture\r\n */\r\nexport interface ITextureCreationOptions {\r\n /** Defines if the texture will require mip maps or not (default: false) */\r\n noMipmap?: boolean;\r\n\r\n /** Defines if the texture needs to be inverted on the y axis during loading (default: true) */\r\n invertY?: boolean;\r\n\r\n /** Defines the sampling mode we want for the texture while fetching from it (Texture.NEAREST_SAMPLINGMODE...) (default: Texture.TRILINEAR_SAMPLINGMODE) */\r\n samplingMode?: number;\r\n\r\n /** Defines a callback triggered when the texture has been loaded (default: null) */\r\n onLoad?: Nullable<() => void>;\r\n\r\n /** Defines a callback triggered when an error occurred during the loading session (default: null) */\r\n onError?: Nullable<(message?: string, exception?: any) => void>;\r\n\r\n /** Defines the buffer to load the texture from in case the texture is loaded from a buffer representation (default: null) */\r\n buffer?: Nullable;\r\n\r\n /** Defines if the buffer we are loading the texture from should be deleted after load (default: false) */\r\n deleteBuffer?: boolean;\r\n\r\n /** Defines the format of the texture we are trying to load (Engine.TEXTUREFORMAT_RGBA...) (default: ) */\r\n format?: number;\r\n\r\n /** Defines an optional mime type information (default: undefined) */\r\n mimeType?: string;\r\n\r\n /** Options to be passed to the loader (default: undefined) */\r\n loaderOptions?: any;\r\n\r\n /** Specific flags to use when creating the texture (Constants.TEXTURE_CREATIONFLAG_STORAGE for storage textures, for eg) (default: undefined) */\r\n creationFlags?: number;\r\n\r\n /** Defines if the texture must be loaded in a sRGB GPU buffer (if supported by the GPU) (default: false) */\r\n useSRGBBuffer?: boolean;\r\n\r\n /** Defines the underlying texture from an already existing one */\r\n internalTexture?: InternalTexture;\r\n\r\n /** Defines the underlying texture texture space */\r\n gammaSpace?: boolean;\r\n\r\n /** Defines the extension to use to pick the right loader */\r\n forcedExtension?: string;\r\n}\r\n\r\n/**\r\n * This represents a texture in babylon. It can be easily loaded from a network, base64 or html input.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/materials_introduction#texture\r\n */\r\nexport class Texture extends BaseTexture {\r\n /**\r\n * Gets or sets a general boolean used to indicate that textures containing direct data (buffers) must be saved as part of the serialization process\r\n */\r\n public static SerializeBuffers = true;\r\n\r\n /**\r\n * Gets or sets a general boolean used to indicate that texture buffers must be saved as part of the serialization process.\r\n * If no buffer exists, one will be created as base64 string from the internal webgl data.\r\n */\r\n public static ForceSerializeBuffers = false;\r\n\r\n /**\r\n * This observable will notify when any texture had a loading error\r\n */\r\n public static OnTextureLoadErrorObservable = new Observable();\r\n\r\n /** @internal */\r\n public static _SerializeInternalTextureUniqueId = false;\r\n\r\n /**\r\n * @internal\r\n */\r\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n public static _CubeTextureParser = (jsonTexture: any, scene: Scene, rootUrl: string): CubeTexture => {\r\n throw _WarnImport(\"CubeTexture\");\r\n };\r\n /**\r\n * @internal\r\n */\r\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n public static _CreateMirror = (name: string, renderTargetSize: number, scene: Scene, generateMipMaps: boolean): MirrorTexture => {\r\n throw _WarnImport(\"MirrorTexture\");\r\n };\r\n /**\r\n * @internal\r\n */\r\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n public static _CreateRenderTargetTexture = (name: string, renderTargetSize: number, scene: Scene, generateMipMaps: boolean, creationFlags?: number): RenderTargetTexture => {\r\n throw _WarnImport(\"RenderTargetTexture\");\r\n };\r\n\r\n /**\r\n * @internal\r\n */\r\n public static _CreateVideoTexture(\r\n name: Nullable,\r\n src: string | string[] | HTMLVideoElement,\r\n scene: Nullable,\r\n generateMipMaps = false,\r\n invertY = false,\r\n samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE,\r\n settings: Partial = {},\r\n onError?: Nullable<(message?: string, exception?: any) => void>,\r\n format: number = Constants.TEXTUREFORMAT_RGBA\r\n ): VideoTexture {\r\n throw _WarnImport(\"VideoTexture\");\r\n }\r\n\r\n /** nearest is mag = nearest and min = nearest and no mip */\r\n public static readonly NEAREST_SAMPLINGMODE = Constants.TEXTURE_NEAREST_SAMPLINGMODE;\r\n /** nearest is mag = nearest and min = nearest and mip = linear */\r\n public static readonly NEAREST_NEAREST_MIPLINEAR = Constants.TEXTURE_NEAREST_NEAREST_MIPLINEAR; // nearest is mag = nearest and min = nearest and mip = linear\r\n\r\n /** Bilinear is mag = linear and min = linear and no mip */\r\n public static readonly BILINEAR_SAMPLINGMODE = Constants.TEXTURE_BILINEAR_SAMPLINGMODE;\r\n /** Bilinear is mag = linear and min = linear and mip = nearest */\r\n public static readonly LINEAR_LINEAR_MIPNEAREST = Constants.TEXTURE_LINEAR_LINEAR_MIPNEAREST; // Bilinear is mag = linear and min = linear and mip = nearest\r\n\r\n /** Trilinear is mag = linear and min = linear and mip = linear */\r\n public static readonly TRILINEAR_SAMPLINGMODE = Constants.TEXTURE_TRILINEAR_SAMPLINGMODE;\r\n /** Trilinear is mag = linear and min = linear and mip = linear */\r\n public static readonly LINEAR_LINEAR_MIPLINEAR = Constants.TEXTURE_LINEAR_LINEAR_MIPLINEAR; // Trilinear is mag = linear and min = linear and mip = linear\r\n\r\n /** mag = nearest and min = nearest and mip = nearest */\r\n public static readonly NEAREST_NEAREST_MIPNEAREST = Constants.TEXTURE_NEAREST_NEAREST_MIPNEAREST;\r\n /** mag = nearest and min = linear and mip = nearest */\r\n public static readonly NEAREST_LINEAR_MIPNEAREST = Constants.TEXTURE_NEAREST_LINEAR_MIPNEAREST;\r\n /** mag = nearest and min = linear and mip = linear */\r\n public static readonly NEAREST_LINEAR_MIPLINEAR = Constants.TEXTURE_NEAREST_LINEAR_MIPLINEAR;\r\n /** mag = nearest and min = linear and mip = none */\r\n public static readonly NEAREST_LINEAR = Constants.TEXTURE_NEAREST_LINEAR;\r\n /** mag = nearest and min = nearest and mip = none */\r\n public static readonly NEAREST_NEAREST = Constants.TEXTURE_NEAREST_NEAREST;\r\n /** mag = linear and min = nearest and mip = nearest */\r\n public static readonly LINEAR_NEAREST_MIPNEAREST = Constants.TEXTURE_LINEAR_NEAREST_MIPNEAREST;\r\n /** mag = linear and min = nearest and mip = linear */\r\n public static readonly LINEAR_NEAREST_MIPLINEAR = Constants.TEXTURE_LINEAR_NEAREST_MIPLINEAR;\r\n /** mag = linear and min = linear and mip = none */\r\n public static readonly LINEAR_LINEAR = Constants.TEXTURE_LINEAR_LINEAR;\r\n /** mag = linear and min = nearest and mip = none */\r\n public static readonly LINEAR_NEAREST = Constants.TEXTURE_LINEAR_NEAREST;\r\n\r\n /** Explicit coordinates mode */\r\n public static readonly EXPLICIT_MODE = Constants.TEXTURE_EXPLICIT_MODE;\r\n /** Spherical coordinates mode */\r\n public static readonly SPHERICAL_MODE = Constants.TEXTURE_SPHERICAL_MODE;\r\n /** Planar coordinates mode */\r\n public static readonly PLANAR_MODE = Constants.TEXTURE_PLANAR_MODE;\r\n /** Cubic coordinates mode */\r\n public static readonly CUBIC_MODE = Constants.TEXTURE_CUBIC_MODE;\r\n /** Projection coordinates mode */\r\n public static readonly PROJECTION_MODE = Constants.TEXTURE_PROJECTION_MODE;\r\n /** Inverse Cubic coordinates mode */\r\n public static readonly SKYBOX_MODE = Constants.TEXTURE_SKYBOX_MODE;\r\n /** Inverse Cubic coordinates mode */\r\n public static readonly INVCUBIC_MODE = Constants.TEXTURE_INVCUBIC_MODE;\r\n /** Equirectangular coordinates mode */\r\n public static readonly EQUIRECTANGULAR_MODE = Constants.TEXTURE_EQUIRECTANGULAR_MODE;\r\n /** Equirectangular Fixed coordinates mode */\r\n public static readonly FIXED_EQUIRECTANGULAR_MODE = Constants.TEXTURE_FIXED_EQUIRECTANGULAR_MODE;\r\n /** Equirectangular Fixed Mirrored coordinates mode */\r\n public static readonly FIXED_EQUIRECTANGULAR_MIRRORED_MODE = Constants.TEXTURE_FIXED_EQUIRECTANGULAR_MIRRORED_MODE;\r\n\r\n /** Texture is not repeating outside of 0..1 UVs */\r\n public static readonly CLAMP_ADDRESSMODE = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n /** Texture is repeating outside of 0..1 UVs */\r\n public static readonly WRAP_ADDRESSMODE = Constants.TEXTURE_WRAP_ADDRESSMODE;\r\n /** Texture is repeating and mirrored */\r\n public static readonly MIRROR_ADDRESSMODE = Constants.TEXTURE_MIRROR_ADDRESSMODE;\r\n\r\n /**\r\n * Gets or sets a boolean which defines if the texture url must be build from the serialized URL instead of just using the name and loading them side by side with the scene file\r\n */\r\n public static UseSerializedUrlIfAny = false;\r\n\r\n /**\r\n * Define the url of the texture.\r\n */\r\n @serialize()\r\n public url: Nullable = null;\r\n\r\n /**\r\n * Define an offset on the texture to offset the u coordinates of the UVs\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/moreMaterials#offsetting\r\n */\r\n @serialize()\r\n public uOffset = 0;\r\n\r\n /**\r\n * Define an offset on the texture to offset the v coordinates of the UVs\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/moreMaterials#offsetting\r\n */\r\n @serialize()\r\n public vOffset = 0;\r\n\r\n /**\r\n * Define an offset on the texture to scale the u coordinates of the UVs\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/moreMaterials#tiling\r\n */\r\n @serialize()\r\n public uScale = 1.0;\r\n\r\n /**\r\n * Define an offset on the texture to scale the v coordinates of the UVs\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/moreMaterials#tiling\r\n */\r\n @serialize()\r\n public vScale = 1.0;\r\n\r\n /**\r\n * Define an offset on the texture to rotate around the u coordinates of the UVs\r\n * The angle is defined in radians.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/moreMaterials\r\n */\r\n @serialize()\r\n public uAng = 0;\r\n\r\n /**\r\n * Define an offset on the texture to rotate around the v coordinates of the UVs\r\n * The angle is defined in radians.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/moreMaterials\r\n */\r\n @serialize()\r\n public vAng = 0;\r\n\r\n /**\r\n * Define an offset on the texture to rotate around the w coordinates of the UVs (in case of 3d texture)\r\n * The angle is defined in radians.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/moreMaterials\r\n */\r\n @serialize()\r\n public wAng = 0;\r\n\r\n /**\r\n * Defines the center of rotation (U)\r\n */\r\n @serialize()\r\n public uRotationCenter = 0.5;\r\n\r\n /**\r\n * Defines the center of rotation (V)\r\n */\r\n @serialize()\r\n public vRotationCenter = 0.5;\r\n\r\n /**\r\n * Defines the center of rotation (W)\r\n */\r\n @serialize()\r\n public wRotationCenter = 0.5;\r\n\r\n /**\r\n * Sets this property to true to avoid deformations when rotating the texture with non-uniform scaling\r\n */\r\n @serialize()\r\n public homogeneousRotationInUVTransform = false;\r\n\r\n /**\r\n * Are mip maps generated for this texture or not.\r\n */\r\n override get noMipmap(): boolean {\r\n return this._noMipmap;\r\n }\r\n\r\n /**\r\n * List of inspectable custom properties (used by the Inspector)\r\n * @see https://doc.babylonjs.com/toolsAndResources/inspector#extensibility\r\n */\r\n public inspectableCustomProperties: Nullable = null;\r\n\r\n /** @internal */\r\n public _noMipmap: boolean = false;\r\n /** @internal */\r\n public _invertY: boolean = false;\r\n private _rowGenerationMatrix: Nullable = null;\r\n private _cachedTextureMatrix: Nullable = null;\r\n private _projectionModeMatrix: Nullable = null;\r\n private _t0: Nullable = null;\r\n private _t1: Nullable = null;\r\n private _t2: Nullable = null;\r\n\r\n private _cachedUOffset: number = -1;\r\n private _cachedVOffset: number = -1;\r\n private _cachedUScale: number = 0;\r\n private _cachedVScale: number = 0;\r\n private _cachedUAng: number = -1;\r\n private _cachedVAng: number = -1;\r\n private _cachedWAng: number = -1;\r\n private _cachedReflectionProjectionMatrixId: number = -1;\r\n private _cachedURotationCenter: number = -1;\r\n private _cachedVRotationCenter: number = -1;\r\n private _cachedWRotationCenter: number = -1;\r\n private _cachedHomogeneousRotationInUVTransform: boolean = false;\r\n private _cachedIdentity3x2: boolean = true;\r\n\r\n private _cachedReflectionTextureMatrix: Nullable = null;\r\n private _cachedReflectionUOffset = -1;\r\n private _cachedReflectionVOffset = -1;\r\n private _cachedReflectionUScale = 0;\r\n private _cachedReflectionVScale = 0;\r\n private _cachedReflectionCoordinatesMode = -1;\r\n\r\n /** @internal */\r\n public _buffer: Nullable = null;\r\n private _deleteBuffer: boolean = false;\r\n protected _format: Nullable = null;\r\n private _delayedOnLoad: Nullable<() => void> = null;\r\n private _delayedOnError: Nullable<() => void> = null;\r\n private _mimeType?: string;\r\n private _loaderOptions?: any;\r\n private _creationFlags?: number;\r\n /** @internal */\r\n public _useSRGBBuffer?: boolean;\r\n private _forcedExtension?: string;\r\n\r\n /** Returns the texture mime type if it was defined by a loader (undefined else) */\r\n public get mimeType() {\r\n return this._mimeType;\r\n }\r\n\r\n /**\r\n * Observable triggered once the texture has been loaded.\r\n */\r\n public onLoadObservable: Observable = new Observable();\r\n\r\n protected _isBlocking: boolean = true;\r\n /**\r\n * Is the texture preventing material to render while loading.\r\n * If false, a default texture will be used instead of the loading one during the preparation step.\r\n */\r\n public override set isBlocking(value: boolean) {\r\n this._isBlocking = value;\r\n }\r\n @serialize()\r\n public override get isBlocking(): boolean {\r\n return this._isBlocking;\r\n }\r\n\r\n /**\r\n * Gets a boolean indicating if the texture needs to be inverted on the y axis during loading\r\n */\r\n public get invertY(): boolean {\r\n return this._invertY;\r\n }\r\n\r\n /**\r\n * Instantiates a new texture.\r\n * This represents a texture in babylon. It can be easily loaded from a network, base64 or html input.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/using/materials_introduction#texture\r\n * @param url defines the url of the picture to load as a texture\r\n * @param sceneOrEngine defines the scene or engine the texture will belong to\r\n * @param noMipmapOrOptions defines if the texture will require mip maps or not or set of all options to create the texture\r\n * @param invertY defines if the texture needs to be inverted on the y axis during loading\r\n * @param samplingMode defines the sampling mode we want for the texture while fetching from it (Texture.NEAREST_SAMPLINGMODE...)\r\n * @param onLoad defines a callback triggered when the texture has been loaded\r\n * @param onError defines a callback triggered when an error occurred during the loading session\r\n * @param buffer defines the buffer to load the texture from in case the texture is loaded from a buffer representation\r\n * @param deleteBuffer defines if the buffer we are loading the texture from should be deleted after load\r\n * @param format defines the format of the texture we are trying to load (Engine.TEXTUREFORMAT_RGBA...)\r\n * @param mimeType defines an optional mime type information\r\n * @param loaderOptions options to be passed to the loader\r\n * @param creationFlags specific flags to use when creating the texture (Constants.TEXTURE_CREATIONFLAG_STORAGE for storage textures, for eg)\r\n * @param forcedExtension defines the extension to use to pick the right loader\r\n */\r\n constructor(\r\n url: Nullable,\r\n sceneOrEngine?: Nullable,\r\n noMipmapOrOptions?: boolean | ITextureCreationOptions,\r\n invertY?: boolean,\r\n samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE,\r\n onLoad: Nullable<() => void> = null,\r\n onError: Nullable<(message?: string, exception?: any) => void> = null,\r\n buffer: Nullable = null,\r\n deleteBuffer: boolean = false,\r\n format?: number,\r\n mimeType?: string,\r\n loaderOptions?: any,\r\n creationFlags?: number,\r\n forcedExtension?: string\r\n ) {\r\n super(sceneOrEngine);\r\n\r\n this.name = url || \"\";\r\n this.url = url;\r\n\r\n let noMipmap: boolean;\r\n let useSRGBBuffer: boolean = false;\r\n let internalTexture: Nullable = null;\r\n let gammaSpace = true;\r\n\r\n if (typeof noMipmapOrOptions === \"object\" && noMipmapOrOptions !== null) {\r\n noMipmap = noMipmapOrOptions.noMipmap ?? false;\r\n invertY = noMipmapOrOptions.invertY ?? !useOpenGLOrientationForUV;\r\n samplingMode = noMipmapOrOptions.samplingMode ?? Texture.TRILINEAR_SAMPLINGMODE;\r\n onLoad = noMipmapOrOptions.onLoad ?? null;\r\n onError = noMipmapOrOptions.onError ?? null;\r\n buffer = noMipmapOrOptions.buffer ?? null;\r\n deleteBuffer = noMipmapOrOptions.deleteBuffer ?? false;\r\n format = noMipmapOrOptions.format;\r\n mimeType = noMipmapOrOptions.mimeType;\r\n loaderOptions = noMipmapOrOptions.loaderOptions;\r\n creationFlags = noMipmapOrOptions.creationFlags;\r\n useSRGBBuffer = noMipmapOrOptions.useSRGBBuffer ?? false;\r\n internalTexture = noMipmapOrOptions.internalTexture ?? null;\r\n gammaSpace = noMipmapOrOptions.gammaSpace ?? gammaSpace;\r\n forcedExtension = noMipmapOrOptions.forcedExtension ?? forcedExtension;\r\n } else {\r\n noMipmap = !!noMipmapOrOptions;\r\n }\r\n\r\n this._gammaSpace = gammaSpace;\r\n this._noMipmap = noMipmap;\r\n this._invertY = invertY === undefined ? !useOpenGLOrientationForUV : invertY;\r\n this._initialSamplingMode = samplingMode;\r\n this._buffer = buffer;\r\n this._deleteBuffer = deleteBuffer;\r\n this._mimeType = mimeType;\r\n this._loaderOptions = loaderOptions;\r\n this._creationFlags = creationFlags;\r\n this._useSRGBBuffer = useSRGBBuffer;\r\n this._forcedExtension = forcedExtension;\r\n if (format) {\r\n this._format = format;\r\n }\r\n\r\n const scene = this.getScene();\r\n const engine = this._getEngine();\r\n if (!engine) {\r\n return;\r\n }\r\n\r\n engine.onBeforeTextureInitObservable.notifyObservers(this);\r\n\r\n const load = () => {\r\n if (this._texture) {\r\n if (this._texture._invertVScale) {\r\n this.vScale *= -1;\r\n this.vOffset += 1;\r\n }\r\n\r\n // Update texture to match internal texture's wrapping\r\n if (this._texture._cachedWrapU !== null) {\r\n this.wrapU = this._texture._cachedWrapU;\r\n this._texture._cachedWrapU = null;\r\n }\r\n if (this._texture._cachedWrapV !== null) {\r\n this.wrapV = this._texture._cachedWrapV;\r\n this._texture._cachedWrapV = null;\r\n }\r\n if (this._texture._cachedWrapR !== null) {\r\n this.wrapR = this._texture._cachedWrapR;\r\n this._texture._cachedWrapR = null;\r\n }\r\n }\r\n\r\n if (this.onLoadObservable.hasObservers()) {\r\n this.onLoadObservable.notifyObservers(this);\r\n }\r\n if (onLoad) {\r\n onLoad();\r\n }\r\n\r\n if (!this.isBlocking && scene) {\r\n scene.resetCachedMaterial();\r\n }\r\n };\r\n\r\n const errorHandler = (message?: string, exception?: any) => {\r\n this._loadingError = true;\r\n this._errorObject = { message, exception };\r\n if (onError) {\r\n onError(message, exception);\r\n }\r\n Texture.OnTextureLoadErrorObservable.notifyObservers(this);\r\n };\r\n\r\n if (!this.url && !internalTexture) {\r\n this._delayedOnLoad = load;\r\n this._delayedOnError = errorHandler;\r\n return;\r\n }\r\n\r\n this._texture = internalTexture ?? this._getFromCache(this.url, noMipmap, samplingMode, this._invertY, useSRGBBuffer, this.isCube);\r\n\r\n if (!this._texture) {\r\n if (!scene || !scene.useDelayedTextureLoading) {\r\n try {\r\n this._texture = engine.createTexture(\r\n this.url,\r\n noMipmap,\r\n this._invertY,\r\n scene,\r\n samplingMode,\r\n load,\r\n errorHandler,\r\n this._buffer,\r\n undefined,\r\n this._format,\r\n this._forcedExtension,\r\n mimeType,\r\n loaderOptions,\r\n creationFlags,\r\n useSRGBBuffer\r\n );\r\n } catch (e) {\r\n errorHandler(\"error loading\", e);\r\n throw e;\r\n }\r\n if (deleteBuffer) {\r\n this._buffer = null;\r\n }\r\n } else {\r\n this.delayLoadState = Constants.DELAYLOADSTATE_NOTLOADED;\r\n\r\n this._delayedOnLoad = load;\r\n this._delayedOnError = errorHandler;\r\n }\r\n } else {\r\n if (this._texture.isReady) {\r\n TimingTools.SetImmediate(() => load());\r\n } else {\r\n const loadObserver = this._texture.onLoadedObservable.add(load);\r\n this._texture.onErrorObservable.add((e) => {\r\n errorHandler(e.message, e.exception);\r\n this._texture?.onLoadedObservable.remove(loadObserver);\r\n });\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Update the url (and optional buffer) of this texture if url was null during construction.\r\n * @param url the url of the texture\r\n * @param buffer the buffer of the texture (defaults to null)\r\n * @param onLoad callback called when the texture is loaded (defaults to null)\r\n * @param forcedExtension defines the extension to use to pick the right loader\r\n */\r\n public updateURL(\r\n url: string,\r\n buffer: Nullable = null,\r\n onLoad?: () => void,\r\n forcedExtension?: string\r\n ): void {\r\n if (this.url) {\r\n this.releaseInternalTexture();\r\n this.getScene()!.markAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag, (mat) => {\r\n return mat.hasTexture(this);\r\n });\r\n }\r\n\r\n if (!this.name || this.name.startsWith(\"data:\")) {\r\n this.name = url;\r\n }\r\n this.url = url;\r\n this._buffer = buffer;\r\n this._forcedExtension = forcedExtension;\r\n this.delayLoadState = Constants.DELAYLOADSTATE_NOTLOADED;\r\n\r\n if (onLoad) {\r\n this._delayedOnLoad = onLoad;\r\n }\r\n this.delayLoad();\r\n }\r\n\r\n /**\r\n * Finish the loading sequence of a texture flagged as delayed load.\r\n * @internal\r\n */\r\n public override delayLoad(): void {\r\n if (this.delayLoadState !== Constants.DELAYLOADSTATE_NOTLOADED) {\r\n return;\r\n }\r\n\r\n const scene = this.getScene();\r\n if (!scene) {\r\n return;\r\n }\r\n\r\n this.delayLoadState = Constants.DELAYLOADSTATE_LOADED;\r\n this._texture = this._getFromCache(this.url, this._noMipmap, this.samplingMode, this._invertY, this._useSRGBBuffer, this.isCube);\r\n\r\n if (!this._texture) {\r\n this._texture = scene\r\n .getEngine()\r\n .createTexture(\r\n this.url,\r\n this._noMipmap,\r\n this._invertY,\r\n scene,\r\n this.samplingMode,\r\n this._delayedOnLoad,\r\n this._delayedOnError,\r\n this._buffer,\r\n null,\r\n this._format,\r\n this._forcedExtension,\r\n this._mimeType,\r\n this._loaderOptions,\r\n this._creationFlags,\r\n this._useSRGBBuffer\r\n );\r\n if (this._deleteBuffer) {\r\n this._buffer = null;\r\n }\r\n } else {\r\n if (this._delayedOnLoad) {\r\n if (this._texture.isReady) {\r\n TimingTools.SetImmediate(this._delayedOnLoad);\r\n } else {\r\n this._texture.onLoadedObservable.add(this._delayedOnLoad);\r\n }\r\n }\r\n }\r\n\r\n this._delayedOnLoad = null;\r\n this._delayedOnError = null;\r\n }\r\n\r\n private _prepareRowForTextureGeneration(x: number, y: number, z: number, t: Vector3): void {\r\n x *= this._cachedUScale;\r\n y *= this._cachedVScale;\r\n\r\n x -= this.uRotationCenter * this._cachedUScale;\r\n y -= this.vRotationCenter * this._cachedVScale;\r\n z -= this.wRotationCenter;\r\n\r\n Vector3.TransformCoordinatesFromFloatsToRef(x, y, z, this._rowGenerationMatrix!, t);\r\n\r\n t.x += this.uRotationCenter * this._cachedUScale + this._cachedUOffset;\r\n t.y += this.vRotationCenter * this._cachedVScale + this._cachedVOffset;\r\n t.z += this.wRotationCenter;\r\n }\r\n\r\n /**\r\n * Get the current texture matrix which includes the requested offsetting, tiling and rotation components.\r\n * @param uBase The horizontal base offset multiplier (1 by default)\r\n * @returns the transform matrix of the texture.\r\n */\r\n public override getTextureMatrix(uBase = 1): Matrix {\r\n if (\r\n this.uOffset === this._cachedUOffset &&\r\n this.vOffset === this._cachedVOffset &&\r\n this.uScale * uBase === this._cachedUScale &&\r\n this.vScale === this._cachedVScale &&\r\n this.uAng === this._cachedUAng &&\r\n this.vAng === this._cachedVAng &&\r\n this.wAng === this._cachedWAng &&\r\n this.uRotationCenter === this._cachedURotationCenter &&\r\n this.vRotationCenter === this._cachedVRotationCenter &&\r\n this.wRotationCenter === this._cachedWRotationCenter &&\r\n this.homogeneousRotationInUVTransform === this._cachedHomogeneousRotationInUVTransform\r\n ) {\r\n return this._cachedTextureMatrix!;\r\n }\r\n\r\n this._cachedUOffset = this.uOffset;\r\n this._cachedVOffset = this.vOffset;\r\n this._cachedUScale = this.uScale * uBase;\r\n this._cachedVScale = this.vScale;\r\n this._cachedUAng = this.uAng;\r\n this._cachedVAng = this.vAng;\r\n this._cachedWAng = this.wAng;\r\n this._cachedURotationCenter = this.uRotationCenter;\r\n this._cachedVRotationCenter = this.vRotationCenter;\r\n this._cachedWRotationCenter = this.wRotationCenter;\r\n this._cachedHomogeneousRotationInUVTransform = this.homogeneousRotationInUVTransform;\r\n\r\n if (!this._cachedTextureMatrix || !this._rowGenerationMatrix) {\r\n this._cachedTextureMatrix = Matrix.Zero();\r\n this._rowGenerationMatrix = new Matrix();\r\n this._t0 = Vector3.Zero();\r\n this._t1 = Vector3.Zero();\r\n this._t2 = Vector3.Zero();\r\n }\r\n\r\n Matrix.RotationYawPitchRollToRef(this.vAng, this.uAng, this.wAng, this._rowGenerationMatrix!);\r\n\r\n if (this.homogeneousRotationInUVTransform) {\r\n Matrix.TranslationToRef(-this._cachedURotationCenter, -this._cachedVRotationCenter, -this._cachedWRotationCenter, TmpVectors.Matrix[0]);\r\n Matrix.TranslationToRef(this._cachedURotationCenter, this._cachedVRotationCenter, this._cachedWRotationCenter, TmpVectors.Matrix[1]);\r\n Matrix.ScalingToRef(this._cachedUScale, this._cachedVScale, 0, TmpVectors.Matrix[2]);\r\n Matrix.TranslationToRef(this._cachedUOffset, this._cachedVOffset, 0, TmpVectors.Matrix[3]);\r\n\r\n TmpVectors.Matrix[0].multiplyToRef(this._rowGenerationMatrix!, this._cachedTextureMatrix);\r\n this._cachedTextureMatrix.multiplyToRef(TmpVectors.Matrix[1], this._cachedTextureMatrix);\r\n this._cachedTextureMatrix.multiplyToRef(TmpVectors.Matrix[2], this._cachedTextureMatrix);\r\n this._cachedTextureMatrix.multiplyToRef(TmpVectors.Matrix[3], this._cachedTextureMatrix);\r\n\r\n // copy the translation row to the 3rd row of the matrix so that we don't need to update the shaders (which expects the translation to be on the 3rd row)\r\n this._cachedTextureMatrix.setRowFromFloats(2, this._cachedTextureMatrix.m[12], this._cachedTextureMatrix.m[13], this._cachedTextureMatrix.m[14], 1);\r\n } else {\r\n this._prepareRowForTextureGeneration(0, 0, 0, this._t0!);\r\n this._prepareRowForTextureGeneration(1.0, 0, 0, this._t1!);\r\n this._prepareRowForTextureGeneration(0, 1.0, 0, this._t2!);\r\n\r\n this._t1!.subtractInPlace(this._t0!);\r\n this._t2!.subtractInPlace(this._t0!);\r\n\r\n Matrix.FromValuesToRef(\r\n this._t1!.x,\r\n this._t1!.y,\r\n this._t1!.z,\r\n 0.0,\r\n this._t2!.x,\r\n this._t2!.y,\r\n this._t2!.z,\r\n 0.0,\r\n this._t0!.x,\r\n this._t0!.y,\r\n this._t0!.z,\r\n 0.0,\r\n 0.0,\r\n 0.0,\r\n 0.0,\r\n 1.0,\r\n this._cachedTextureMatrix\r\n );\r\n }\r\n\r\n const scene = this.getScene();\r\n\r\n if (!scene) {\r\n return this._cachedTextureMatrix;\r\n }\r\n\r\n const previousIdentity3x2 = this._cachedIdentity3x2;\r\n this._cachedIdentity3x2 = this._cachedTextureMatrix.isIdentityAs3x2();\r\n\r\n if (this.optimizeUVAllocation && previousIdentity3x2 !== this._cachedIdentity3x2) {\r\n // We flag the materials that are using this texture as \"texture dirty\" because depending on the fact that the matrix is the identity or not, some defines\r\n // will get different values (see PrepareDefinesForMergedUV), meaning we should regenerate the effect accordingly\r\n scene.markAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag, (mat) => {\r\n return mat.hasTexture(this);\r\n });\r\n }\r\n\r\n return this._cachedTextureMatrix;\r\n }\r\n\r\n /**\r\n * Get the current matrix used to apply reflection. This is useful to rotate an environment texture for instance.\r\n * @returns The reflection texture transform\r\n */\r\n public override getReflectionTextureMatrix(): Matrix {\r\n const scene = this.getScene();\r\n\r\n if (!scene) {\r\n return this._cachedReflectionTextureMatrix!;\r\n }\r\n\r\n if (\r\n this.uOffset === this._cachedReflectionUOffset &&\r\n this.vOffset === this._cachedReflectionVOffset &&\r\n this.uScale === this._cachedReflectionUScale &&\r\n this.vScale === this._cachedReflectionVScale &&\r\n this.coordinatesMode === this._cachedReflectionCoordinatesMode\r\n ) {\r\n if (this.coordinatesMode === Texture.PROJECTION_MODE) {\r\n if (this._cachedReflectionProjectionMatrixId === scene.getProjectionMatrix().updateFlag) {\r\n return this._cachedReflectionTextureMatrix!;\r\n }\r\n } else {\r\n return this._cachedReflectionTextureMatrix!;\r\n }\r\n }\r\n\r\n if (!this._cachedReflectionTextureMatrix) {\r\n this._cachedReflectionTextureMatrix = Matrix.Zero();\r\n }\r\n\r\n if (!this._projectionModeMatrix) {\r\n this._projectionModeMatrix = Matrix.Zero();\r\n }\r\n\r\n const flagMaterialsAsTextureDirty = this._cachedReflectionCoordinatesMode !== this.coordinatesMode;\r\n\r\n this._cachedReflectionUOffset = this.uOffset;\r\n this._cachedReflectionVOffset = this.vOffset;\r\n this._cachedReflectionUScale = this.uScale;\r\n this._cachedReflectionVScale = this.vScale;\r\n this._cachedReflectionCoordinatesMode = this.coordinatesMode;\r\n\r\n switch (this.coordinatesMode) {\r\n case Texture.PLANAR_MODE: {\r\n Matrix.IdentityToRef(this._cachedReflectionTextureMatrix);\r\n (this._cachedReflectionTextureMatrix)[0] = this.uScale;\r\n (this._cachedReflectionTextureMatrix)[5] = this.vScale;\r\n (this._cachedReflectionTextureMatrix)[12] = this.uOffset;\r\n (this._cachedReflectionTextureMatrix)[13] = this.vOffset;\r\n break;\r\n }\r\n case Texture.PROJECTION_MODE: {\r\n Matrix.FromValuesToRef(0.5, 0.0, 0.0, 0.0, 0.0, -0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.5, 1.0, 1.0, this._projectionModeMatrix);\r\n\r\n const projectionMatrix = scene.getProjectionMatrix();\r\n this._cachedReflectionProjectionMatrixId = projectionMatrix.updateFlag;\r\n projectionMatrix.multiplyToRef(this._projectionModeMatrix, this._cachedReflectionTextureMatrix);\r\n break;\r\n }\r\n default:\r\n Matrix.IdentityToRef(this._cachedReflectionTextureMatrix);\r\n break;\r\n }\r\n\r\n if (flagMaterialsAsTextureDirty) {\r\n // We flag the materials that are using this texture as \"texture dirty\" if the coordinatesMode has changed.\r\n // Indeed, this property is used to set the value of some defines used to generate the effect (in material.isReadyForSubMesh), so we must make sure this code will be re-executed and the effect recreated if necessary\r\n scene.markAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag, (mat) => {\r\n return mat.hasTexture(this);\r\n });\r\n }\r\n\r\n return this._cachedReflectionTextureMatrix;\r\n }\r\n\r\n /**\r\n * Clones the texture.\r\n * @returns the cloned texture\r\n */\r\n public override clone(): Texture {\r\n const options: ITextureCreationOptions = {\r\n noMipmap: this._noMipmap,\r\n invertY: this._invertY,\r\n samplingMode: this.samplingMode,\r\n onLoad: undefined,\r\n onError: undefined,\r\n buffer: this._texture ? this._texture._buffer : undefined,\r\n deleteBuffer: this._deleteBuffer,\r\n format: this.textureFormat,\r\n mimeType: this.mimeType,\r\n loaderOptions: this._loaderOptions,\r\n creationFlags: this._creationFlags,\r\n useSRGBBuffer: this._useSRGBBuffer,\r\n };\r\n\r\n return SerializationHelper.Clone(() => {\r\n return new Texture(this._texture ? this._texture.url : null, this.getScene(), options);\r\n }, this);\r\n }\r\n\r\n /**\r\n * Serialize the texture to a JSON representation we can easily use in the respective Parse function.\r\n * @returns The JSON representation of the texture\r\n */\r\n public override serialize(): any {\r\n const savedName = this.name;\r\n\r\n if (!Texture.SerializeBuffers) {\r\n if (this.name.startsWith(\"data:\")) {\r\n this.name = \"\";\r\n }\r\n }\r\n\r\n if (this.name.startsWith(\"data:\") && this.url === this.name) {\r\n this.url = \"\";\r\n }\r\n\r\n const serializationObject = super.serialize(Texture._SerializeInternalTextureUniqueId);\r\n\r\n if (!serializationObject) {\r\n return null;\r\n }\r\n\r\n if (Texture.SerializeBuffers || Texture.ForceSerializeBuffers) {\r\n if (typeof this._buffer === \"string\" && (this._buffer as string).substring(0, 5) === \"data:\") {\r\n serializationObject.base64String = this._buffer;\r\n serializationObject.name = serializationObject.name.replace(\"data:\", \"\");\r\n } else if (this.url && this.url.startsWith(\"data:\") && this._buffer instanceof Uint8Array) {\r\n serializationObject.base64String = \"data:image/png;base64,\" + EncodeArrayBufferToBase64(this._buffer);\r\n } else if (Texture.ForceSerializeBuffers || (this.url && this.url.startsWith(\"blob:\")) || this._forceSerialize) {\r\n serializationObject.base64String =\r\n !this._engine || this._engine._features.supportSyncTextureRead ? GenerateBase64StringFromTexture(this) : GenerateBase64StringFromTextureAsync(this);\r\n }\r\n }\r\n\r\n serializationObject.invertY = this._invertY;\r\n serializationObject.samplingMode = this.samplingMode;\r\n serializationObject._creationFlags = this._creationFlags;\r\n serializationObject._useSRGBBuffer = this._useSRGBBuffer;\r\n if (Texture._SerializeInternalTextureUniqueId) {\r\n serializationObject.internalTextureUniqueId = this._texture?.uniqueId;\r\n }\r\n serializationObject.internalTextureLabel = this._texture?.label;\r\n serializationObject.noMipmap = this._noMipmap;\r\n\r\n this.name = savedName;\r\n\r\n return serializationObject;\r\n }\r\n\r\n /**\r\n * Get the current class name of the texture useful for serialization or dynamic coding.\r\n * @returns \"Texture\"\r\n */\r\n public override getClassName(): string {\r\n return \"Texture\";\r\n }\r\n\r\n /**\r\n * Dispose the texture and release its associated resources.\r\n */\r\n public override dispose(): void {\r\n super.dispose();\r\n\r\n this.onLoadObservable.clear();\r\n\r\n this._delayedOnLoad = null;\r\n this._delayedOnError = null;\r\n this._buffer = null;\r\n }\r\n\r\n /**\r\n * Parse the JSON representation of a texture in order to recreate the texture in the given scene.\r\n * @param parsedTexture Define the JSON representation of the texture\r\n * @param scene Define the scene the parsed texture should be instantiated in\r\n * @param rootUrl Define the root url of the parsing sequence in the case of relative dependencies\r\n * @returns The parsed texture if successful\r\n */\r\n public static Parse(parsedTexture: any, scene: Scene, rootUrl: string): Nullable {\r\n if (parsedTexture.customType) {\r\n const customTexture = InstantiationTools.Instantiate(parsedTexture.customType);\r\n // Update Sampling Mode\r\n const parsedCustomTexture: any = customTexture.Parse(parsedTexture, scene, rootUrl);\r\n if (parsedTexture.samplingMode && parsedCustomTexture.updateSamplingMode && parsedCustomTexture._samplingMode) {\r\n if (parsedCustomTexture._samplingMode !== parsedTexture.samplingMode) {\r\n parsedCustomTexture.updateSamplingMode(parsedTexture.samplingMode);\r\n }\r\n }\r\n return parsedCustomTexture;\r\n }\r\n\r\n if (parsedTexture.isCube && !parsedTexture.isRenderTarget) {\r\n return Texture._CubeTextureParser(parsedTexture, scene, rootUrl);\r\n }\r\n\r\n const hasInternalTextureUniqueId = parsedTexture.internalTextureUniqueId !== undefined;\r\n\r\n if (!parsedTexture.name && !parsedTexture.isRenderTarget && !hasInternalTextureUniqueId) {\r\n return null;\r\n }\r\n\r\n let internalTexture: InternalTexture | undefined;\r\n\r\n if (hasInternalTextureUniqueId) {\r\n const cache = scene.getEngine().getLoadedTexturesCache();\r\n for (const texture of cache) {\r\n if (texture.uniqueId === parsedTexture.internalTextureUniqueId) {\r\n internalTexture = texture;\r\n break;\r\n }\r\n }\r\n }\r\n\r\n const onLoaded = (texture: Texture | null) => {\r\n // Clear cache\r\n if (texture && texture._texture) {\r\n texture._texture._cachedWrapU = null;\r\n texture._texture._cachedWrapV = null;\r\n texture._texture._cachedWrapR = null;\r\n }\r\n\r\n // Update Sampling Mode\r\n if (parsedTexture.samplingMode) {\r\n const sampling: number = parsedTexture.samplingMode;\r\n if (texture && texture.samplingMode !== sampling) {\r\n texture.updateSamplingMode(sampling);\r\n }\r\n }\r\n // Animations\r\n if (texture && parsedTexture.animations) {\r\n for (let animationIndex = 0; animationIndex < parsedTexture.animations.length; animationIndex++) {\r\n const parsedAnimation = parsedTexture.animations[animationIndex];\r\n const internalClass = GetClass(\"BABYLON.Animation\");\r\n if (internalClass) {\r\n texture.animations.push(internalClass.Parse(parsedAnimation));\r\n }\r\n }\r\n }\r\n\r\n if (texture && texture._texture) {\r\n if (hasInternalTextureUniqueId && !internalTexture) {\r\n texture._texture._setUniqueId(parsedTexture.internalTextureUniqueId);\r\n }\r\n\r\n texture._texture.label = parsedTexture.internalTextureLabel;\r\n }\r\n };\r\n\r\n const texture = SerializationHelper.Parse(\r\n () => {\r\n let generateMipMaps: boolean = true;\r\n if (parsedTexture.noMipmap) {\r\n generateMipMaps = false;\r\n }\r\n if (parsedTexture.mirrorPlane) {\r\n const mirrorTexture = Texture._CreateMirror(parsedTexture.name, parsedTexture.renderTargetSize, scene, generateMipMaps);\r\n mirrorTexture._waitingRenderList = parsedTexture.renderList;\r\n mirrorTexture.mirrorPlane = Plane.FromArray(parsedTexture.mirrorPlane);\r\n onLoaded(mirrorTexture);\r\n return mirrorTexture;\r\n } else if (parsedTexture.isRenderTarget) {\r\n let renderTargetTexture: Nullable = null;\r\n if (parsedTexture.isCube) {\r\n // Search for an existing reflection probe (which contains a cube render target texture)\r\n if (scene.reflectionProbes) {\r\n for (let index = 0; index < scene.reflectionProbes.length; index++) {\r\n const probe = scene.reflectionProbes[index];\r\n if (probe.name === parsedTexture.name) {\r\n return probe.cubeTexture;\r\n }\r\n }\r\n }\r\n } else {\r\n renderTargetTexture = Texture._CreateRenderTargetTexture(\r\n parsedTexture.name,\r\n parsedTexture.renderTargetSize,\r\n scene,\r\n generateMipMaps,\r\n parsedTexture._creationFlags ?? 0\r\n );\r\n renderTargetTexture._waitingRenderList = parsedTexture.renderList;\r\n }\r\n onLoaded(renderTargetTexture);\r\n return renderTargetTexture;\r\n } else if (parsedTexture.isVideo) {\r\n const texture = Texture._CreateVideoTexture(\r\n rootUrl + (parsedTexture.url || parsedTexture.name),\r\n rootUrl + (parsedTexture.src || parsedTexture.url),\r\n scene,\r\n generateMipMaps,\r\n parsedTexture.invertY,\r\n parsedTexture.samplingMode,\r\n parsedTexture.settings || {}\r\n );\r\n onLoaded(texture);\r\n return texture;\r\n } else {\r\n let texture: Texture;\r\n\r\n if (parsedTexture.base64String && !internalTexture) {\r\n // name and url are the same to ensure caching happens from the actual base64 string\r\n texture = Texture.CreateFromBase64String(\r\n parsedTexture.base64String,\r\n parsedTexture.base64String,\r\n scene,\r\n !generateMipMaps,\r\n parsedTexture.invertY,\r\n parsedTexture.samplingMode,\r\n () => {\r\n onLoaded(texture);\r\n },\r\n parsedTexture._creationFlags ?? 0,\r\n parsedTexture._useSRGBBuffer ?? false\r\n );\r\n\r\n // prettier name to fit with the loaded data\r\n texture.name = parsedTexture.name;\r\n } else {\r\n let url: string;\r\n if (parsedTexture.name && (parsedTexture.name.indexOf(\"://\") > 0 || parsedTexture.name.startsWith(\"data:\"))) {\r\n url = parsedTexture.name;\r\n } else {\r\n url = rootUrl + parsedTexture.name;\r\n }\r\n\r\n if (parsedTexture.url && (parsedTexture.url.startsWith(\"data:\") || Texture.UseSerializedUrlIfAny)) {\r\n url = parsedTexture.url;\r\n }\r\n\r\n const options: ITextureCreationOptions = {\r\n noMipmap: !generateMipMaps,\r\n invertY: parsedTexture.invertY,\r\n samplingMode: parsedTexture.samplingMode,\r\n onLoad: () => {\r\n onLoaded(texture);\r\n },\r\n internalTexture,\r\n };\r\n\r\n texture = new Texture(url, scene, options);\r\n }\r\n\r\n return texture;\r\n }\r\n },\r\n parsedTexture,\r\n scene\r\n );\r\n\r\n return texture;\r\n }\r\n\r\n /**\r\n * Creates a texture from its base 64 representation.\r\n * @param data Define the base64 payload without the data: prefix\r\n * @param name Define the name of the texture in the scene useful fo caching purpose for instance\r\n * @param scene Define the scene the texture should belong to\r\n * @param noMipmapOrOptions defines if the texture will require mip maps or not or set of all options to create the texture\r\n * @param invertY define if the texture needs to be inverted on the y axis during loading\r\n * @param samplingMode define the sampling mode we want for the texture while fetching from it (Texture.NEAREST_SAMPLINGMODE...)\r\n * @param onLoad define a callback triggered when the texture has been loaded\r\n * @param onError define a callback triggered when an error occurred during the loading session\r\n * @param format define the format of the texture we are trying to load (Engine.TEXTUREFORMAT_RGBA...)\r\n * @param creationFlags specific flags to use when creating the texture (Constants.TEXTURE_CREATIONFLAG_STORAGE for storage textures, for eg)\r\n * @param forcedExtension defines the extension to use to pick the right loader\r\n * @returns the created texture\r\n */\r\n public static CreateFromBase64String(\r\n data: string,\r\n name: string,\r\n scene: Scene,\r\n noMipmapOrOptions?: boolean | ITextureCreationOptions,\r\n invertY?: boolean,\r\n samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE,\r\n onLoad: Nullable<() => void> = null,\r\n onError: Nullable<() => void> = null,\r\n format: number = Constants.TEXTUREFORMAT_RGBA,\r\n creationFlags?: number,\r\n forcedExtension?: string\r\n ): Texture {\r\n return new Texture(\r\n \"data:\" + name,\r\n scene,\r\n noMipmapOrOptions,\r\n invertY,\r\n samplingMode,\r\n onLoad,\r\n onError,\r\n data,\r\n false,\r\n format,\r\n undefined,\r\n undefined,\r\n creationFlags,\r\n forcedExtension\r\n );\r\n }\r\n\r\n /**\r\n * Creates a texture from its data: representation. (data: will be added in case only the payload has been passed in)\r\n * @param name Define the name of the texture in the scene useful fo caching purpose for instance\r\n * @param buffer define the buffer to load the texture from in case the texture is loaded from a buffer representation\r\n * @param scene Define the scene the texture should belong to\r\n * @param deleteBuffer define if the buffer we are loading the texture from should be deleted after load\r\n * @param noMipmapOrOptions defines if the texture will require mip maps or not or set of all options to create the texture\r\n * @param invertY define if the texture needs to be inverted on the y axis during loading\r\n * @param samplingMode define the sampling mode we want for the texture while fetching from it (Texture.NEAREST_SAMPLINGMODE...)\r\n * @param onLoad define a callback triggered when the texture has been loaded\r\n * @param onError define a callback triggered when an error occurred during the loading session\r\n * @param format define the format of the texture we are trying to load (Engine.TEXTUREFORMAT_RGBA...)\r\n * @param creationFlags specific flags to use when creating the texture (Constants.TEXTURE_CREATIONFLAG_STORAGE for storage textures, for eg)\r\n * @param forcedExtension defines the extension to use to pick the right loader\r\n * @returns the created texture\r\n */\r\n public static LoadFromDataString(\r\n name: string,\r\n buffer: any,\r\n scene: Scene,\r\n deleteBuffer: boolean = false,\r\n noMipmapOrOptions?: boolean | ITextureCreationOptions,\r\n invertY: boolean = true,\r\n samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE,\r\n onLoad: Nullable<() => void> = null,\r\n onError: Nullable<(message?: string, exception?: any) => void> = null,\r\n format: number = Constants.TEXTUREFORMAT_RGBA,\r\n creationFlags?: number,\r\n forcedExtension?: string\r\n ): Texture {\r\n if (name.substring(0, 5) !== \"data:\") {\r\n name = \"data:\" + name;\r\n }\r\n\r\n return new Texture(\r\n name,\r\n scene,\r\n noMipmapOrOptions,\r\n invertY,\r\n samplingMode,\r\n onLoad,\r\n onError,\r\n buffer,\r\n deleteBuffer,\r\n format,\r\n undefined,\r\n undefined,\r\n creationFlags,\r\n forcedExtension\r\n );\r\n }\r\n}\r\n\r\n// References the dependencies.\r\nRegisterClass(\"BABYLON.Texture\", Texture);\r\nSerializationHelper._TextureParser = Texture.Parse;\r\n","import { Logger } from \"../Misc/logger\";\r\nimport type { Nullable, FloatArray } from \"../types\";\r\nimport type { IMatrixLike, IVector3Like, IVector4Like, IColor3Like, IColor4Like } from \"../Maths/math.like\";\r\nimport type { Effect } from \"./effect\";\r\nimport type { ThinTexture } from \"../Materials/Textures/thinTexture\";\r\nimport type { DataBuffer } from \"../Buffers/dataBuffer\";\r\nimport type { InternalTexture } from \"./Textures/internalTexture\";\r\nimport { Tools } from \"../Misc/tools\";\r\nimport type { AbstractEngine } from \"core/Engines/abstractEngine\";\r\n\r\n/**\r\n * Uniform buffer objects.\r\n *\r\n * Handles blocks of uniform on the GPU.\r\n *\r\n * If WebGL 2 is not available, this class falls back on traditional setUniformXXX calls.\r\n *\r\n * For more information, please refer to :\r\n * https://www.khronos.org/opengl/wiki/Uniform_Buffer_Object\r\n */\r\nexport class UniformBuffer {\r\n /** @internal */\r\n public static _UpdatedUbosInFrame: { [name: string]: number } = {};\r\n\r\n private _engine: AbstractEngine;\r\n private _buffer: Nullable;\r\n private _buffers: Array<[DataBuffer, Float32Array | undefined]>;\r\n private _bufferIndex: number;\r\n private _createBufferOnWrite: boolean;\r\n private _data: number[];\r\n private _bufferData: Float32Array;\r\n private _dynamic?: boolean;\r\n private _uniformLocations: { [key: string]: number };\r\n private _uniformSizes: { [key: string]: number };\r\n private _uniformArraySizes: { [key: string]: { strideSize: number; arraySize: number } };\r\n private _uniformLocationPointer: number;\r\n private _needSync: boolean;\r\n private _noUBO: boolean;\r\n private _currentEffect: Effect;\r\n private _currentEffectName: string;\r\n private _name: string;\r\n private _currentFrameId: number;\r\n\r\n // Pool for avoiding memory leaks\r\n private static _MAX_UNIFORM_SIZE = 256;\r\n private static _TempBuffer = new Float32Array(UniformBuffer._MAX_UNIFORM_SIZE);\r\n private static _TempBufferInt32View = new Int32Array(UniformBuffer._TempBuffer.buffer);\r\n private static _TempBufferUInt32View = new Uint32Array(UniformBuffer._TempBuffer.buffer);\r\n\r\n /**\r\n * Lambda to Update a 3x3 Matrix in a uniform buffer.\r\n * This is dynamic to allow compat with webgl 1 and 2.\r\n * You will need to pass the name of the uniform as well as the value.\r\n */\r\n public updateMatrix3x3: (name: string, matrix: Float32Array) => void;\r\n\r\n /**\r\n * Lambda to Update a 2x2 Matrix in a uniform buffer.\r\n * This is dynamic to allow compat with webgl 1 and 2.\r\n * You will need to pass the name of the uniform as well as the value.\r\n */\r\n public updateMatrix2x2: (name: string, matrix: Float32Array) => void;\r\n\r\n /**\r\n * Lambda to Update a single float in a uniform buffer.\r\n * This is dynamic to allow compat with webgl 1 and 2.\r\n * You will need to pass the name of the uniform as well as the value.\r\n */\r\n public updateFloat: (name: string, x: number) => void;\r\n\r\n /**\r\n * Lambda to Update a vec2 of float in a uniform buffer.\r\n * This is dynamic to allow compat with webgl 1 and 2.\r\n * You will need to pass the name of the uniform as well as the value.\r\n */\r\n public updateFloat2: (name: string, x: number, y: number, suffix?: string) => void;\r\n\r\n /**\r\n * Lambda to Update a vec3 of float in a uniform buffer.\r\n * This is dynamic to allow compat with webgl 1 and 2.\r\n * You will need to pass the name of the uniform as well as the value.\r\n */\r\n public updateFloat3: (name: string, x: number, y: number, z: number, suffix?: string) => void;\r\n\r\n /**\r\n * Lambda to Update a vec4 of float in a uniform buffer.\r\n * This is dynamic to allow compat with webgl 1 and 2.\r\n * You will need to pass the name of the uniform as well as the value.\r\n */\r\n public updateFloat4: (name: string, x: number, y: number, z: number, w: number, suffix?: string) => void;\r\n\r\n /**\r\n * Lambda to Update an array of float in a uniform buffer.\r\n * This is dynamic to allow compat with webgl 1 and 2.\r\n * You will need to pass the name of the uniform as well as the value.\r\n */\r\n public updateFloatArray: (name: string, array: Float32Array) => void;\r\n\r\n /**\r\n * Lambda to Update an array of number in a uniform buffer.\r\n * This is dynamic to allow compat with webgl 1 and 2.\r\n * You will need to pass the name of the uniform as well as the value.\r\n */\r\n public updateArray: (name: string, array: number[]) => void;\r\n\r\n /**\r\n * Lambda to Update an array of number in a uniform buffer.\r\n * This is dynamic to allow compat with webgl 1 and 2.\r\n * You will need to pass the name of the uniform as well as the value.\r\n */\r\n public updateIntArray: (name: string, array: Int32Array) => void;\r\n\r\n /**\r\n * Lambda to Update an array of number in a uniform buffer.\r\n * This is dynamic to allow compat with webgl 1 and 2.\r\n * You will need to pass the name of the uniform as well as the value.\r\n */\r\n public updateUIntArray: (name: string, array: Uint32Array) => void;\r\n\r\n /**\r\n * Lambda to Update a 4x4 Matrix in a uniform buffer.\r\n * This is dynamic to allow compat with webgl 1 and 2.\r\n * You will need to pass the name of the uniform as well as the value.\r\n */\r\n public updateMatrix: (name: string, mat: IMatrixLike) => void;\r\n\r\n /**\r\n * Lambda to Update an array of 4x4 Matrix in a uniform buffer.\r\n * This is dynamic to allow compat with webgl 1 and 2.\r\n * You will need to pass the name of the uniform as well as the value.\r\n */\r\n public updateMatrices: (name: string, mat: Float32Array) => void;\r\n\r\n /**\r\n * Lambda to Update vec3 of float from a Vector in a uniform buffer.\r\n * This is dynamic to allow compat with webgl 1 and 2.\r\n * You will need to pass the name of the uniform as well as the value.\r\n */\r\n public updateVector3: (name: string, vector: IVector3Like) => void;\r\n\r\n /**\r\n * Lambda to Update vec4 of float from a Vector in a uniform buffer.\r\n * This is dynamic to allow compat with webgl 1 and 2.\r\n * You will need to pass the name of the uniform as well as the value.\r\n */\r\n public updateVector4: (name: string, vector: IVector4Like) => void;\r\n\r\n /**\r\n * Lambda to Update vec3 of float from a Color in a uniform buffer.\r\n * This is dynamic to allow compat with webgl 1 and 2.\r\n * You will need to pass the name of the uniform as well as the value.\r\n */\r\n public updateColor3: (name: string, color: IColor3Like, suffix?: string) => void;\r\n\r\n /**\r\n * Lambda to Update vec4 of float from a Color in a uniform buffer.\r\n * This is dynamic to allow compat with webgl 1 and 2.\r\n * You will need to pass the name of the uniform as well as the value.\r\n */\r\n public updateColor4: (name: string, color: IColor3Like, alpha: number, suffix?: string) => void;\r\n\r\n /**\r\n * Lambda to Update vec4 of float from a Color in a uniform buffer.\r\n * This is dynamic to allow compat with webgl 1 and 2.\r\n * You will need to pass the name of the uniform as well as the value.\r\n */\r\n public updateDirectColor4: (name: string, color: IColor4Like, suffix?: string) => void;\r\n\r\n /**\r\n * Lambda to Update a int a uniform buffer.\r\n * This is dynamic to allow compat with webgl 1 and 2.\r\n * You will need to pass the name of the uniform as well as the value.\r\n */\r\n public updateInt: (name: string, x: number, suffix?: string) => void;\r\n\r\n /**\r\n * Lambda to Update a vec2 of int in a uniform buffer.\r\n * This is dynamic to allow compat with webgl 1 and 2.\r\n * You will need to pass the name of the uniform as well as the value.\r\n */\r\n public updateInt2: (name: string, x: number, y: number, suffix?: string) => void;\r\n\r\n /**\r\n * Lambda to Update a vec3 of int in a uniform buffer.\r\n * This is dynamic to allow compat with webgl 1 and 2.\r\n * You will need to pass the name of the uniform as well as the value.\r\n */\r\n public updateInt3: (name: string, x: number, y: number, z: number, suffix?: string) => void;\r\n\r\n /**\r\n * Lambda to Update a vec4 of int in a uniform buffer.\r\n * This is dynamic to allow compat with webgl 1 and 2.\r\n * You will need to pass the name of the uniform as well as the value.\r\n */\r\n public updateInt4: (name: string, x: number, y: number, z: number, w: number, suffix?: string) => void;\r\n\r\n /**\r\n * Lambda to Update a unsigned int a uniform buffer.\r\n * This is dynamic to allow compat with webgl 1 and 2.\r\n * You will need to pass the name of the uniform as well as the value.\r\n */\r\n public updateUInt: (name: string, x: number, suffix?: string) => void;\r\n\r\n /**\r\n * Lambda to Update a vec2 of unsigned int in a uniform buffer.\r\n * This is dynamic to allow compat with webgl 1 and 2.\r\n * You will need to pass the name of the uniform as well as the value.\r\n */\r\n public updateUInt2: (name: string, x: number, y: number, suffix?: string) => void;\r\n\r\n /**\r\n * Lambda to Update a vec3 of unsigned int in a uniform buffer.\r\n * This is dynamic to allow compat with webgl 1 and 2.\r\n * You will need to pass the name of the uniform as well as the value.\r\n */\r\n public updateUInt3: (name: string, x: number, y: number, z: number, suffix?: string) => void;\r\n\r\n /**\r\n * Lambda to Update a vec4 of unsigned int in a uniform buffer.\r\n * This is dynamic to allow compat with webgl 1 and 2.\r\n * You will need to pass the name of the uniform as well as the value.\r\n */\r\n public updateUInt4: (name: string, x: number, y: number, z: number, w: number, suffix?: string) => void;\r\n\r\n /**\r\n * Instantiates a new Uniform buffer objects.\r\n *\r\n * Handles blocks of uniform on the GPU.\r\n *\r\n * If WebGL 2 is not available, this class falls back on traditional setUniformXXX calls.\r\n *\r\n * For more information, please refer to :\r\n * @see https://www.khronos.org/opengl/wiki/Uniform_Buffer_Object\r\n * @param engine Define the engine the buffer is associated with\r\n * @param data Define the data contained in the buffer\r\n * @param dynamic Define if the buffer is updatable\r\n * @param name to assign to the buffer (debugging purpose)\r\n * @param forceNoUniformBuffer define that this object must not rely on UBO objects\r\n */\r\n constructor(engine: AbstractEngine, data?: number[], dynamic?: boolean, name?: string, forceNoUniformBuffer = false) {\r\n this._engine = engine;\r\n this._noUBO = !engine.supportsUniformBuffers || forceNoUniformBuffer;\r\n this._dynamic = dynamic;\r\n this._name = name ?? \"no-name\";\r\n\r\n this._data = data || [];\r\n\r\n this._uniformLocations = {};\r\n this._uniformSizes = {};\r\n this._uniformArraySizes = {};\r\n this._uniformLocationPointer = 0;\r\n this._needSync = false;\r\n\r\n if (this._engine._features.trackUbosInFrame) {\r\n this._buffers = [];\r\n this._bufferIndex = -1;\r\n this._createBufferOnWrite = false;\r\n this._currentFrameId = 0;\r\n }\r\n\r\n if (this._noUBO) {\r\n this.updateMatrix3x3 = this._updateMatrix3x3ForEffect;\r\n this.updateMatrix2x2 = this._updateMatrix2x2ForEffect;\r\n this.updateFloat = this._updateFloatForEffect;\r\n this.updateFloat2 = this._updateFloat2ForEffect;\r\n this.updateFloat3 = this._updateFloat3ForEffect;\r\n this.updateFloat4 = this._updateFloat4ForEffect;\r\n this.updateFloatArray = this._updateFloatArrayForEffect;\r\n this.updateArray = this._updateArrayForEffect;\r\n this.updateIntArray = this._updateIntArrayForEffect;\r\n this.updateUIntArray = this._updateUIntArrayForEffect;\r\n this.updateMatrix = this._updateMatrixForEffect;\r\n this.updateMatrices = this._updateMatricesForEffect;\r\n this.updateVector3 = this._updateVector3ForEffect;\r\n this.updateVector4 = this._updateVector4ForEffect;\r\n this.updateColor3 = this._updateColor3ForEffect;\r\n this.updateColor4 = this._updateColor4ForEffect;\r\n this.updateDirectColor4 = this._updateDirectColor4ForEffect;\r\n this.updateInt = this._updateIntForEffect;\r\n this.updateInt2 = this._updateInt2ForEffect;\r\n this.updateInt3 = this._updateInt3ForEffect;\r\n this.updateInt4 = this._updateInt4ForEffect;\r\n this.updateUInt = this._updateUIntForEffect;\r\n this.updateUInt2 = this._updateUInt2ForEffect;\r\n this.updateUInt3 = this._updateUInt3ForEffect;\r\n this.updateUInt4 = this._updateUInt4ForEffect;\r\n } else {\r\n this._engine._uniformBuffers.push(this);\r\n\r\n this.updateMatrix3x3 = this._updateMatrix3x3ForUniform;\r\n this.updateMatrix2x2 = this._updateMatrix2x2ForUniform;\r\n this.updateFloat = this._updateFloatForUniform;\r\n this.updateFloat2 = this._updateFloat2ForUniform;\r\n this.updateFloat3 = this._updateFloat3ForUniform;\r\n this.updateFloat4 = this._updateFloat4ForUniform;\r\n this.updateFloatArray = this._updateFloatArrayForUniform;\r\n this.updateArray = this._updateArrayForUniform;\r\n this.updateIntArray = this._updateIntArrayForUniform;\r\n this.updateUIntArray = this._updateUIntArrayForUniform;\r\n this.updateMatrix = this._updateMatrixForUniform;\r\n this.updateMatrices = this._updateMatricesForUniform;\r\n this.updateVector3 = this._updateVector3ForUniform;\r\n this.updateVector4 = this._updateVector4ForUniform;\r\n this.updateColor3 = this._updateColor3ForUniform;\r\n this.updateColor4 = this._updateColor4ForUniform;\r\n this.updateDirectColor4 = this._updateDirectColor4ForUniform;\r\n this.updateInt = this._updateIntForUniform;\r\n this.updateInt2 = this._updateInt2ForUniform;\r\n this.updateInt3 = this._updateInt3ForUniform;\r\n this.updateInt4 = this._updateInt4ForUniform;\r\n this.updateUInt = this._updateUIntForUniform;\r\n this.updateUInt2 = this._updateUInt2ForUniform;\r\n this.updateUInt3 = this._updateUInt3ForUniform;\r\n this.updateUInt4 = this._updateUInt4ForUniform;\r\n }\r\n }\r\n\r\n /**\r\n * Indicates if the buffer is using the WebGL2 UBO implementation,\r\n * or just falling back on setUniformXXX calls.\r\n */\r\n public get useUbo(): boolean {\r\n return !this._noUBO;\r\n }\r\n\r\n /**\r\n * Indicates if the WebGL underlying uniform buffer is in sync\r\n * with the javascript cache data.\r\n */\r\n public get isSync(): boolean {\r\n return !this._needSync;\r\n }\r\n\r\n /**\r\n * Indicates if the WebGL underlying uniform buffer is dynamic.\r\n * Also, a dynamic UniformBuffer will disable cache verification and always\r\n * update the underlying WebGL uniform buffer to the GPU.\r\n * @returns if Dynamic, otherwise false\r\n */\r\n public isDynamic(): boolean {\r\n return this._dynamic !== undefined;\r\n }\r\n\r\n /**\r\n * The data cache on JS side.\r\n * @returns the underlying data as a float array\r\n */\r\n public getData(): Float32Array {\r\n return this._bufferData;\r\n }\r\n\r\n /**\r\n * The underlying WebGL Uniform buffer.\r\n * @returns the webgl buffer\r\n */\r\n public getBuffer(): Nullable {\r\n return this._buffer;\r\n }\r\n\r\n /**\r\n * std140 layout specifies how to align data within an UBO structure.\r\n * See https://khronos.org/registry/OpenGL/specs/gl/glspec45.core.pdf#page=159\r\n * for specs.\r\n * @param size\r\n */\r\n private _fillAlignment(size: number) {\r\n // This code has been simplified because we only use floats, vectors of 1, 2, 3, 4 components\r\n // and 4x4 matrices\r\n // TODO : change if other types are used\r\n\r\n let alignment;\r\n if (size <= 2) {\r\n alignment = size;\r\n } else {\r\n alignment = 4;\r\n }\r\n\r\n if (this._uniformLocationPointer % alignment !== 0) {\r\n const oldPointer = this._uniformLocationPointer;\r\n this._uniformLocationPointer += alignment - (this._uniformLocationPointer % alignment);\r\n const diff = this._uniformLocationPointer - oldPointer;\r\n\r\n for (let i = 0; i < diff; i++) {\r\n this._data.push(0);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Adds an uniform in the buffer.\r\n * Warning : the subsequents calls of this function must be in the same order as declared in the shader\r\n * for the layout to be correct ! The addUniform function only handles types like float, vec2, vec3, vec4, mat4,\r\n * meaning size=1,2,3,4 or 16. It does not handle struct types.\r\n * @param name Name of the uniform, as used in the uniform block in the shader.\r\n * @param size Data size, or data directly.\r\n * @param arraySize The number of elements in the array, 0 if not an array.\r\n */\r\n public addUniform(name: string, size: number | number[], arraySize = 0) {\r\n if (this._noUBO) {\r\n return;\r\n }\r\n\r\n if (this._uniformLocations[name] !== undefined) {\r\n // Already existing uniform\r\n return;\r\n }\r\n // This function must be called in the order of the shader layout !\r\n // size can be the size of the uniform, or data directly\r\n let data;\r\n\r\n // std140 FTW...\r\n if (arraySize > 0) {\r\n if (size instanceof Array) {\r\n // eslint-disable-next-line no-throw-literal\r\n throw \"addUniform should not be use with Array in UBO: \" + name;\r\n }\r\n\r\n this._fillAlignment(4);\r\n\r\n this._uniformArraySizes[name] = { strideSize: size, arraySize };\r\n if (size == 16) {\r\n size = size * arraySize;\r\n } else {\r\n const perElementPadding = 4 - size;\r\n const totalPadding = perElementPadding * arraySize;\r\n size = size * arraySize + totalPadding;\r\n }\r\n\r\n data = [];\r\n // Fill with zeros\r\n for (let i = 0; i < size; i++) {\r\n data.push(0);\r\n }\r\n } else {\r\n if (size instanceof Array) {\r\n data = size;\r\n size = data.length;\r\n } else {\r\n size = size;\r\n data = [];\r\n\r\n // Fill with zeros\r\n for (let i = 0; i < size; i++) {\r\n data.push(0);\r\n }\r\n }\r\n this._fillAlignment(size);\r\n }\r\n\r\n this._uniformSizes[name] = size;\r\n this._uniformLocations[name] = this._uniformLocationPointer;\r\n this._uniformLocationPointer += size;\r\n\r\n for (let i = 0; i < size; i++) {\r\n this._data.push(data[i]);\r\n }\r\n\r\n this._needSync = true;\r\n }\r\n\r\n /**\r\n * Adds a Matrix 4x4 to the uniform buffer.\r\n * @param name Name of the uniform, as used in the uniform block in the shader.\r\n * @param mat A 4x4 matrix.\r\n */\r\n public addMatrix(name: string, mat: IMatrixLike) {\r\n this.addUniform(name, Array.prototype.slice.call(mat.asArray()));\r\n }\r\n\r\n /**\r\n * Adds a vec2 to the uniform buffer.\r\n * @param name Name of the uniform, as used in the uniform block in the shader.\r\n * @param x Define the x component value of the vec2\r\n * @param y Define the y component value of the vec2\r\n */\r\n public addFloat2(name: string, x: number, y: number) {\r\n const temp = [x, y];\r\n this.addUniform(name, temp);\r\n }\r\n\r\n /**\r\n * Adds a vec3 to the uniform buffer.\r\n * @param name Name of the uniform, as used in the uniform block in the shader.\r\n * @param x Define the x component value of the vec3\r\n * @param y Define the y component value of the vec3\r\n * @param z Define the z component value of the vec3\r\n */\r\n public addFloat3(name: string, x: number, y: number, z: number) {\r\n const temp = [x, y, z];\r\n this.addUniform(name, temp);\r\n }\r\n\r\n /**\r\n * Adds a vec3 to the uniform buffer.\r\n * @param name Name of the uniform, as used in the uniform block in the shader.\r\n * @param color Define the vec3 from a Color\r\n */\r\n public addColor3(name: string, color: IColor3Like) {\r\n const temp = [color.r, color.g, color.b];\r\n this.addUniform(name, temp);\r\n }\r\n\r\n /**\r\n * Adds a vec4 to the uniform buffer.\r\n * @param name Name of the uniform, as used in the uniform block in the shader.\r\n * @param color Define the rgb components from a Color\r\n * @param alpha Define the a component of the vec4\r\n */\r\n public addColor4(name: string, color: IColor3Like, alpha: number) {\r\n const temp = [color.r, color.g, color.b, alpha];\r\n this.addUniform(name, temp);\r\n }\r\n\r\n /**\r\n * Adds a vec3 to the uniform buffer.\r\n * @param name Name of the uniform, as used in the uniform block in the shader.\r\n * @param vector Define the vec3 components from a Vector\r\n */\r\n public addVector3(name: string, vector: IVector3Like) {\r\n const temp = [vector.x, vector.y, vector.z];\r\n this.addUniform(name, temp);\r\n }\r\n\r\n /**\r\n * Adds a Matrix 3x3 to the uniform buffer.\r\n * @param name Name of the uniform, as used in the uniform block in the shader.\r\n */\r\n public addMatrix3x3(name: string) {\r\n this.addUniform(name, 12);\r\n }\r\n\r\n /**\r\n * Adds a Matrix 2x2 to the uniform buffer.\r\n * @param name Name of the uniform, as used in the uniform block in the shader.\r\n */\r\n public addMatrix2x2(name: string) {\r\n this.addUniform(name, 8);\r\n }\r\n\r\n /**\r\n * Effectively creates the WebGL Uniform Buffer, once layout is completed with `addUniform`.\r\n */\r\n public create(): void {\r\n if (this._noUBO) {\r\n return;\r\n }\r\n if (this._buffer) {\r\n return; // nothing to do\r\n }\r\n\r\n // See spec, alignment must be filled as a vec4\r\n this._fillAlignment(4);\r\n this._bufferData = new Float32Array(this._data);\r\n\r\n this._rebuild();\r\n\r\n this._needSync = true;\r\n }\r\n\r\n // The result of this method is used for debugging purpose, as part of the buffer name\r\n // It is meant to more easily know what this buffer is about when debugging\r\n // Some buffers can have a lot of uniforms (several dozens), so the method only returns the first 10 of them\r\n // (should be enough to understand what the buffer is for)\r\n private _getNames() {\r\n const names = [];\r\n let i = 0;\r\n for (const name in this._uniformLocations) {\r\n names.push(name);\r\n if (++i === 10) {\r\n break;\r\n }\r\n }\r\n return names.join(\",\");\r\n }\r\n\r\n /** @internal */\r\n public _rebuild(): void {\r\n if (this._noUBO || !this._bufferData) {\r\n return;\r\n }\r\n\r\n if (this._dynamic) {\r\n this._buffer = this._engine.createDynamicUniformBuffer(this._bufferData, this._name + \"_UniformList:\" + this._getNames());\r\n } else {\r\n this._buffer = this._engine.createUniformBuffer(this._bufferData, this._name + \"_UniformList:\" + this._getNames());\r\n }\r\n\r\n if (this._engine._features.trackUbosInFrame) {\r\n this._buffers.push([this._buffer, this._engine._features.checkUbosContentBeforeUpload ? this._bufferData.slice() : undefined]);\r\n this._bufferIndex = this._buffers.length - 1;\r\n this._createBufferOnWrite = false;\r\n }\r\n }\r\n\r\n /** @internal */\r\n public _rebuildAfterContextLost(): void {\r\n if (this._engine._features.trackUbosInFrame) {\r\n this._buffers = [];\r\n this._currentFrameId = 0;\r\n }\r\n this._rebuild();\r\n }\r\n\r\n /** @internal */\r\n public get _numBuffers(): number {\r\n return this._buffers.length;\r\n }\r\n\r\n /** @internal */\r\n public get _indexBuffer(): number {\r\n return this._bufferIndex;\r\n }\r\n\r\n /** Gets the name of this buffer */\r\n public get name(): string {\r\n return this._name;\r\n }\r\n\r\n /** Gets the current effect */\r\n public get currentEffect(): Nullable {\r\n return this._currentEffect;\r\n }\r\n\r\n private _buffersEqual(buf1: Float32Array, buf2: Float32Array): boolean {\r\n for (let i = 0; i < buf1.length; ++i) {\r\n if (buf1[i] !== buf2[i]) {\r\n return false;\r\n }\r\n }\r\n return true;\r\n }\r\n\r\n private _copyBuffer(src: Float32Array, dst: Float32Array): void {\r\n for (let i = 0; i < src.length; ++i) {\r\n dst[i] = src[i];\r\n }\r\n }\r\n\r\n /**\r\n * Updates the WebGL Uniform Buffer on the GPU.\r\n * If the `dynamic` flag is set to true, no cache comparison is done.\r\n * Otherwise, the buffer will be updated only if the cache differs.\r\n */\r\n public update(): void {\r\n if (this._noUBO) {\r\n return;\r\n }\r\n\r\n this.bindUniformBuffer();\r\n\r\n if (!this._buffer) {\r\n this.create();\r\n return;\r\n }\r\n\r\n if (!this._dynamic && !this._needSync) {\r\n this._createBufferOnWrite = this._engine._features.trackUbosInFrame;\r\n return;\r\n }\r\n\r\n if (this._buffers && this._buffers.length > 1 && this._buffers[this._bufferIndex][1]) {\r\n if (this._buffersEqual(this._bufferData, this._buffers[this._bufferIndex][1]!)) {\r\n this._needSync = false;\r\n this._createBufferOnWrite = this._engine._features.trackUbosInFrame;\r\n return;\r\n } else {\r\n this._copyBuffer(this._bufferData, this._buffers[this._bufferIndex][1]!);\r\n }\r\n }\r\n\r\n this._engine.updateUniformBuffer(this._buffer, this._bufferData);\r\n\r\n if (this._engine._features._collectUbosUpdatedInFrame) {\r\n if (!UniformBuffer._UpdatedUbosInFrame[this._name]) {\r\n UniformBuffer._UpdatedUbosInFrame[this._name] = 0;\r\n }\r\n UniformBuffer._UpdatedUbosInFrame[this._name]++;\r\n }\r\n\r\n this._needSync = false;\r\n this._createBufferOnWrite = this._engine._features.trackUbosInFrame;\r\n }\r\n\r\n private _createNewBuffer() {\r\n if (this._bufferIndex + 1 < this._buffers.length) {\r\n this._bufferIndex++;\r\n this._buffer = this._buffers[this._bufferIndex][0];\r\n this._createBufferOnWrite = false;\r\n this._needSync = true;\r\n } else {\r\n this._rebuild();\r\n }\r\n }\r\n\r\n private _checkNewFrame(): void {\r\n if (this._engine._features.trackUbosInFrame && this._currentFrameId !== this._engine.frameId) {\r\n this._currentFrameId = this._engine.frameId;\r\n this._createBufferOnWrite = false;\r\n if (this._buffers && this._buffers.length > 0) {\r\n this._needSync = this._bufferIndex !== 0;\r\n this._bufferIndex = 0;\r\n this._buffer = this._buffers[this._bufferIndex][0];\r\n } else {\r\n this._bufferIndex = -1;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Updates the value of an uniform. The `update` method must be called afterwards to make it effective in the GPU.\r\n * @param uniformName Define the name of the uniform, as used in the uniform block in the shader.\r\n * @param data Define the flattened data\r\n * @param size Define the size of the data.\r\n */\r\n public updateUniform(uniformName: string, data: FloatArray, size: number) {\r\n this._checkNewFrame();\r\n\r\n let location = this._uniformLocations[uniformName];\r\n if (location === undefined) {\r\n if (this._buffer) {\r\n // Cannot add an uniform if the buffer is already created\r\n Logger.Error(\"Cannot add an uniform after UBO has been created. uniformName=\" + uniformName);\r\n return;\r\n }\r\n this.addUniform(uniformName, size);\r\n location = this._uniformLocations[uniformName];\r\n }\r\n\r\n if (!this._buffer) {\r\n this.create();\r\n }\r\n\r\n if (!this._dynamic) {\r\n // Cache for static uniform buffers\r\n let changed = false;\r\n\r\n for (let i = 0; i < size; i++) {\r\n // We are checking the matrix cache before calling updateUniform so we do not need to check it here\r\n // Hence the test for size === 16 to simply commit the matrix values\r\n if ((size === 16 && !this._engine._features.uniformBufferHardCheckMatrix) || this._bufferData[location + i] !== Math.fround(data[i])) {\r\n changed = true;\r\n if (this._createBufferOnWrite) {\r\n this._createNewBuffer();\r\n }\r\n this._bufferData[location + i] = data[i];\r\n }\r\n }\r\n\r\n this._needSync = this._needSync || changed;\r\n } else {\r\n // No cache for dynamic\r\n for (let i = 0; i < size; i++) {\r\n this._bufferData[location + i] = data[i];\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Updates the value of an uniform. The `update` method must be called afterwards to make it effective in the GPU.\r\n * @param uniformName Define the name of the uniform, as used in the uniform block in the shader.\r\n * @param data Define the flattened data\r\n * @param size Define the size of the data.\r\n */\r\n public updateUniformArray(uniformName: string, data: FloatArray, size: number) {\r\n this._checkNewFrame();\r\n\r\n const location = this._uniformLocations[uniformName];\r\n if (location === undefined) {\r\n Logger.Error(\"Cannot add an uniform Array dynamically. Please, add it using addUniform and make sure that uniform buffers are supported by the current engine.\");\r\n return;\r\n }\r\n\r\n if (!this._buffer) {\r\n this.create();\r\n }\r\n\r\n const arraySizes = this._uniformArraySizes[uniformName];\r\n\r\n if (!this._dynamic) {\r\n // Cache for static uniform buffers\r\n let changed = false;\r\n let countToFour = 0;\r\n let baseStride = 0;\r\n for (let i = 0; i < size; i++) {\r\n if (this._bufferData[location + baseStride * 4 + countToFour] !== Tools.FloatRound(data[i])) {\r\n changed = true;\r\n if (this._createBufferOnWrite) {\r\n this._createNewBuffer();\r\n }\r\n this._bufferData[location + baseStride * 4 + countToFour] = data[i];\r\n }\r\n countToFour++;\r\n if (countToFour === arraySizes.strideSize) {\r\n for (; countToFour < 4; countToFour++) {\r\n this._bufferData[location + baseStride * 4 + countToFour] = 0;\r\n }\r\n countToFour = 0;\r\n baseStride++;\r\n }\r\n }\r\n\r\n this._needSync = this._needSync || changed;\r\n } else {\r\n // No cache for dynamic\r\n for (let i = 0; i < size; i++) {\r\n this._bufferData[location + i] = data[i];\r\n }\r\n }\r\n }\r\n\r\n // Matrix cache\r\n private _valueCache: { [key: string]: number } = {};\r\n private _cacheMatrix(name: string, matrix: IMatrixLike): boolean {\r\n this._checkNewFrame();\r\n\r\n const cache = this._valueCache[name];\r\n const flag = matrix.updateFlag;\r\n if (cache !== undefined && cache === flag) {\r\n return false;\r\n }\r\n\r\n this._valueCache[name] = flag;\r\n return true;\r\n }\r\n\r\n // Update methods\r\n\r\n private _updateMatrix3x3ForUniform(name: string, matrix: Float32Array): void {\r\n // To match std140, matrix must be realigned\r\n for (let i = 0; i < 3; i++) {\r\n UniformBuffer._TempBuffer[i * 4] = matrix[i * 3];\r\n UniformBuffer._TempBuffer[i * 4 + 1] = matrix[i * 3 + 1];\r\n UniformBuffer._TempBuffer[i * 4 + 2] = matrix[i * 3 + 2];\r\n UniformBuffer._TempBuffer[i * 4 + 3] = 0.0;\r\n }\r\n\r\n this.updateUniform(name, UniformBuffer._TempBuffer, 12);\r\n }\r\n\r\n private _updateMatrix3x3ForEffect(name: string, matrix: Float32Array): void {\r\n this._currentEffect.setMatrix3x3(name, matrix);\r\n }\r\n\r\n private _updateMatrix2x2ForEffect(name: string, matrix: Float32Array): void {\r\n this._currentEffect.setMatrix2x2(name, matrix);\r\n }\r\n\r\n private _updateMatrix2x2ForUniform(name: string, matrix: Float32Array): void {\r\n // To match std140, matrix must be realigned\r\n for (let i = 0; i < 2; i++) {\r\n UniformBuffer._TempBuffer[i * 4] = matrix[i * 2];\r\n UniformBuffer._TempBuffer[i * 4 + 1] = matrix[i * 2 + 1];\r\n UniformBuffer._TempBuffer[i * 4 + 2] = 0.0;\r\n UniformBuffer._TempBuffer[i * 4 + 3] = 0.0;\r\n }\r\n\r\n this.updateUniform(name, UniformBuffer._TempBuffer, 8);\r\n }\r\n\r\n private _updateFloatForEffect(name: string, x: number) {\r\n this._currentEffect.setFloat(name, x);\r\n }\r\n\r\n private _updateFloatForUniform(name: string, x: number) {\r\n UniformBuffer._TempBuffer[0] = x;\r\n this.updateUniform(name, UniformBuffer._TempBuffer, 1);\r\n }\r\n\r\n private _updateFloat2ForEffect(name: string, x: number, y: number, suffix = \"\") {\r\n this._currentEffect.setFloat2(name + suffix, x, y);\r\n }\r\n\r\n private _updateFloat2ForUniform(name: string, x: number, y: number) {\r\n UniformBuffer._TempBuffer[0] = x;\r\n UniformBuffer._TempBuffer[1] = y;\r\n this.updateUniform(name, UniformBuffer._TempBuffer, 2);\r\n }\r\n\r\n private _updateFloat3ForEffect(name: string, x: number, y: number, z: number, suffix = \"\") {\r\n this._currentEffect.setFloat3(name + suffix, x, y, z);\r\n }\r\n\r\n private _updateFloat3ForUniform(name: string, x: number, y: number, z: number) {\r\n UniformBuffer._TempBuffer[0] = x;\r\n UniformBuffer._TempBuffer[1] = y;\r\n UniformBuffer._TempBuffer[2] = z;\r\n this.updateUniform(name, UniformBuffer._TempBuffer, 3);\r\n }\r\n\r\n private _updateFloat4ForEffect(name: string, x: number, y: number, z: number, w: number, suffix = \"\") {\r\n this._currentEffect.setFloat4(name + suffix, x, y, z, w);\r\n }\r\n\r\n private _updateFloat4ForUniform(name: string, x: number, y: number, z: number, w: number) {\r\n UniformBuffer._TempBuffer[0] = x;\r\n UniformBuffer._TempBuffer[1] = y;\r\n UniformBuffer._TempBuffer[2] = z;\r\n UniformBuffer._TempBuffer[3] = w;\r\n this.updateUniform(name, UniformBuffer._TempBuffer, 4);\r\n }\r\n\r\n private _updateFloatArrayForEffect(name: string, array: Float32Array) {\r\n this._currentEffect.setFloatArray(name, array);\r\n }\r\n\r\n private _updateFloatArrayForUniform(name: string, array: Float32Array) {\r\n this.updateUniformArray(name, array, array.length);\r\n }\r\n\r\n private _updateArrayForEffect(name: string, array: number[]) {\r\n this._currentEffect.setArray(name, array);\r\n }\r\n\r\n private _updateArrayForUniform(name: string, array: number[]) {\r\n this.updateUniformArray(name, array, array.length);\r\n }\r\n\r\n private _updateIntArrayForEffect(name: string, array: Int32Array) {\r\n this._currentEffect.setIntArray(name, array);\r\n }\r\n\r\n private _updateIntArrayForUniform(name: string, array: Int32Array) {\r\n UniformBuffer._TempBufferInt32View.set(array);\r\n this.updateUniformArray(name, UniformBuffer._TempBuffer, array.length);\r\n }\r\n\r\n private _updateUIntArrayForEffect(name: string, array: Uint32Array) {\r\n this._currentEffect.setUIntArray(name, array);\r\n }\r\n\r\n private _updateUIntArrayForUniform(name: string, array: Uint32Array) {\r\n UniformBuffer._TempBufferUInt32View.set(array);\r\n this.updateUniformArray(name, UniformBuffer._TempBuffer, array.length);\r\n }\r\n\r\n private _updateMatrixForEffect(name: string, mat: IMatrixLike) {\r\n this._currentEffect.setMatrix(name, mat);\r\n }\r\n\r\n private _updateMatrixForUniform(name: string, mat: IMatrixLike) {\r\n if (this._cacheMatrix(name, mat)) {\r\n this.updateUniform(name, mat.asArray(), 16);\r\n }\r\n }\r\n\r\n private _updateMatricesForEffect(name: string, mat: Float32Array) {\r\n this._currentEffect.setMatrices(name, mat);\r\n }\r\n\r\n private _updateMatricesForUniform(name: string, mat: Float32Array) {\r\n this.updateUniform(name, mat, mat.length);\r\n }\r\n\r\n private _updateVector3ForEffect(name: string, vector: IVector3Like) {\r\n this._currentEffect.setVector3(name, vector);\r\n }\r\n\r\n private _updateVector3ForUniform(name: string, vector: IVector3Like) {\r\n UniformBuffer._TempBuffer[0] = vector.x;\r\n UniformBuffer._TempBuffer[1] = vector.y;\r\n UniformBuffer._TempBuffer[2] = vector.z;\r\n this.updateUniform(name, UniformBuffer._TempBuffer, 3);\r\n }\r\n\r\n private _updateVector4ForEffect(name: string, vector: IVector4Like) {\r\n this._currentEffect.setVector4(name, vector);\r\n }\r\n\r\n private _updateVector4ForUniform(name: string, vector: IVector4Like) {\r\n UniformBuffer._TempBuffer[0] = vector.x;\r\n UniformBuffer._TempBuffer[1] = vector.y;\r\n UniformBuffer._TempBuffer[2] = vector.z;\r\n UniformBuffer._TempBuffer[3] = vector.w;\r\n this.updateUniform(name, UniformBuffer._TempBuffer, 4);\r\n }\r\n\r\n private _updateColor3ForEffect(name: string, color: IColor3Like, suffix = \"\") {\r\n this._currentEffect.setColor3(name + suffix, color);\r\n }\r\n\r\n private _updateColor3ForUniform(name: string, color: IColor3Like) {\r\n UniformBuffer._TempBuffer[0] = color.r;\r\n UniformBuffer._TempBuffer[1] = color.g;\r\n UniformBuffer._TempBuffer[2] = color.b;\r\n this.updateUniform(name, UniformBuffer._TempBuffer, 3);\r\n }\r\n\r\n private _updateColor4ForEffect(name: string, color: IColor3Like, alpha: number, suffix = \"\") {\r\n this._currentEffect.setColor4(name + suffix, color, alpha);\r\n }\r\n\r\n private _updateDirectColor4ForEffect(name: string, color: IColor4Like, suffix = \"\") {\r\n this._currentEffect.setDirectColor4(name + suffix, color);\r\n }\r\n\r\n private _updateColor4ForUniform(name: string, color: IColor3Like, alpha: number) {\r\n UniformBuffer._TempBuffer[0] = color.r;\r\n UniformBuffer._TempBuffer[1] = color.g;\r\n UniformBuffer._TempBuffer[2] = color.b;\r\n UniformBuffer._TempBuffer[3] = alpha;\r\n this.updateUniform(name, UniformBuffer._TempBuffer, 4);\r\n }\r\n\r\n private _updateDirectColor4ForUniform(name: string, color: IColor4Like) {\r\n UniformBuffer._TempBuffer[0] = color.r;\r\n UniformBuffer._TempBuffer[1] = color.g;\r\n UniformBuffer._TempBuffer[2] = color.b;\r\n UniformBuffer._TempBuffer[3] = color.a;\r\n this.updateUniform(name, UniformBuffer._TempBuffer, 4);\r\n }\r\n\r\n private _updateIntForEffect(name: string, x: number, suffix = \"\") {\r\n this._currentEffect.setInt(name + suffix, x);\r\n }\r\n\r\n private _updateIntForUniform(name: string, x: number) {\r\n UniformBuffer._TempBufferInt32View[0] = x;\r\n this.updateUniform(name, UniformBuffer._TempBuffer, 1);\r\n }\r\n\r\n private _updateInt2ForEffect(name: string, x: number, y: number, suffix = \"\") {\r\n this._currentEffect.setInt2(name + suffix, x, y);\r\n }\r\n\r\n private _updateInt2ForUniform(name: string, x: number, y: number) {\r\n UniformBuffer._TempBufferInt32View[0] = x;\r\n UniformBuffer._TempBufferInt32View[1] = y;\r\n this.updateUniform(name, UniformBuffer._TempBuffer, 2);\r\n }\r\n\r\n private _updateInt3ForEffect(name: string, x: number, y: number, z: number, suffix = \"\") {\r\n this._currentEffect.setInt3(name + suffix, x, y, z);\r\n }\r\n\r\n private _updateInt3ForUniform(name: string, x: number, y: number, z: number) {\r\n UniformBuffer._TempBufferInt32View[0] = x;\r\n UniformBuffer._TempBufferInt32View[1] = y;\r\n UniformBuffer._TempBufferInt32View[2] = z;\r\n this.updateUniform(name, UniformBuffer._TempBuffer, 3);\r\n }\r\n\r\n private _updateInt4ForEffect(name: string, x: number, y: number, z: number, w: number, suffix = \"\") {\r\n this._currentEffect.setInt4(name + suffix, x, y, z, w);\r\n }\r\n\r\n private _updateInt4ForUniform(name: string, x: number, y: number, z: number, w: number) {\r\n UniformBuffer._TempBufferInt32View[0] = x;\r\n UniformBuffer._TempBufferInt32View[1] = y;\r\n UniformBuffer._TempBufferInt32View[2] = z;\r\n UniformBuffer._TempBufferInt32View[3] = w;\r\n this.updateUniform(name, UniformBuffer._TempBuffer, 4);\r\n }\r\n\r\n private _updateUIntForEffect(name: string, x: number, suffix = \"\") {\r\n this._currentEffect.setUInt(name + suffix, x);\r\n }\r\n\r\n private _updateUIntForUniform(name: string, x: number) {\r\n UniformBuffer._TempBufferUInt32View[0] = x;\r\n this.updateUniform(name, UniformBuffer._TempBuffer, 1);\r\n }\r\n\r\n private _updateUInt2ForEffect(name: string, x: number, y: number, suffix = \"\") {\r\n this._currentEffect.setUInt2(name + suffix, x, y);\r\n }\r\n\r\n private _updateUInt2ForUniform(name: string, x: number, y: number) {\r\n UniformBuffer._TempBufferUInt32View[0] = x;\r\n UniformBuffer._TempBufferUInt32View[1] = y;\r\n this.updateUniform(name, UniformBuffer._TempBuffer, 2);\r\n }\r\n\r\n private _updateUInt3ForEffect(name: string, x: number, y: number, z: number, suffix = \"\") {\r\n this._currentEffect.setUInt3(name + suffix, x, y, z);\r\n }\r\n\r\n private _updateUInt3ForUniform(name: string, x: number, y: number, z: number) {\r\n UniformBuffer._TempBufferUInt32View[0] = x;\r\n UniformBuffer._TempBufferUInt32View[1] = y;\r\n UniformBuffer._TempBufferUInt32View[2] = z;\r\n this.updateUniform(name, UniformBuffer._TempBuffer, 3);\r\n }\r\n\r\n private _updateUInt4ForEffect(name: string, x: number, y: number, z: number, w: number, suffix = \"\") {\r\n this._currentEffect.setUInt4(name + suffix, x, y, z, w);\r\n }\r\n\r\n private _updateUInt4ForUniform(name: string, x: number, y: number, z: number, w: number) {\r\n UniformBuffer._TempBufferUInt32View[0] = x;\r\n UniformBuffer._TempBufferUInt32View[1] = y;\r\n UniformBuffer._TempBufferUInt32View[2] = z;\r\n UniformBuffer._TempBufferUInt32View[3] = w;\r\n this.updateUniform(name, UniformBuffer._TempBuffer, 4);\r\n }\r\n\r\n /**\r\n * Sets a sampler uniform on the effect.\r\n * @param name Define the name of the sampler.\r\n * @param texture Define the texture to set in the sampler\r\n */\r\n public setTexture(name: string, texture: Nullable) {\r\n this._currentEffect.setTexture(name, texture);\r\n }\r\n\r\n /**\r\n * Sets an array of sampler uniforms on the effect.\r\n * @param name Define the name of uniform.\r\n * @param textures Define the textures to set in the array of samplers\r\n */\r\n public setTextureArray(name: string, textures: ThinTexture[]) {\r\n this._currentEffect.setTextureArray(name, textures);\r\n }\r\n /**\r\n * Sets a sampler uniform on the effect.\r\n * @param name Define the name of the sampler.\r\n * @param texture Define the (internal) texture to set in the sampler\r\n */\r\n public bindTexture(name: string, texture: Nullable) {\r\n this._currentEffect._bindTexture(name, texture);\r\n }\r\n\r\n /**\r\n * Directly updates the value of the uniform in the cache AND on the GPU.\r\n * @param uniformName Define the name of the uniform, as used in the uniform block in the shader.\r\n * @param data Define the flattened data\r\n */\r\n public updateUniformDirectly(uniformName: string, data: FloatArray) {\r\n this.updateUniform(uniformName, data, data.length);\r\n\r\n this.update();\r\n }\r\n\r\n /**\r\n * Associates an effect to this uniform buffer\r\n * @param effect Define the effect to associate the buffer to\r\n * @param name Name of the uniform block in the shader.\r\n */\r\n public bindToEffect(effect: Effect, name: string): void {\r\n this._currentEffect = effect;\r\n this._currentEffectName = name;\r\n }\r\n\r\n /**\r\n * Binds the current (GPU) buffer to the effect\r\n */\r\n public bindUniformBuffer(): void {\r\n if (!this._noUBO && this._buffer && this._currentEffect) {\r\n this._currentEffect.bindUniformBuffer(this._buffer, this._currentEffectName);\r\n }\r\n }\r\n\r\n /**\r\n * Dissociates the current effect from this uniform buffer\r\n */\r\n public unbindEffect(): void {\r\n this._currentEffect = undefined as any;\r\n this._currentEffectName = undefined as any;\r\n }\r\n\r\n /**\r\n * Sets the current state of the class (_bufferIndex, _buffer) to point to the data buffer passed in parameter if this buffer is one of the buffers handled by the class (meaning if it can be found in the _buffers array)\r\n * This method is meant to be able to update a buffer at any time: just call setDataBuffer to set the class in the right state, call some updateXXX methods and then call udpate() => that will update the GPU buffer on the graphic card\r\n * @param dataBuffer buffer to look for\r\n * @returns true if the buffer has been found and the class internal state points to it, else false\r\n */\r\n public setDataBuffer(dataBuffer: DataBuffer): boolean {\r\n if (!this._buffers) {\r\n return this._buffer === dataBuffer;\r\n }\r\n\r\n for (let b = 0; b < this._buffers.length; ++b) {\r\n const buffer = this._buffers[b];\r\n if (buffer[0] === dataBuffer) {\r\n this._bufferIndex = b;\r\n this._buffer = dataBuffer;\r\n this._createBufferOnWrite = false;\r\n this._currentEffect = undefined as any;\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n }\r\n\r\n /**\r\n * Disposes the uniform buffer.\r\n */\r\n public dispose(): void {\r\n if (this._noUBO) {\r\n return;\r\n }\r\n\r\n const uniformBuffers = this._engine._uniformBuffers;\r\n const index = uniformBuffers.indexOf(this);\r\n\r\n if (index !== -1) {\r\n uniformBuffers[index] = uniformBuffers[uniformBuffers.length - 1];\r\n uniformBuffers.pop();\r\n }\r\n\r\n if (this._engine._features.trackUbosInFrame && this._buffers) {\r\n for (let i = 0; i < this._buffers.length; ++i) {\r\n const buffer = this._buffers[i][0];\r\n this._engine._releaseBuffer(buffer!);\r\n }\r\n } else if (this._buffer && this._engine._releaseBuffer(this._buffer)) {\r\n this._buffer = null;\r\n }\r\n }\r\n}\r\n","import { Vector3 } from \"./math.vector\";\r\n\r\n/** Defines supported spaces */\r\nexport const enum Space {\r\n /** Local (object) space */\r\n LOCAL = 0,\r\n /** World space */\r\n WORLD = 1,\r\n /** Bone space */\r\n BONE = 2,\r\n}\r\n\r\n/** Defines the 3 main axes */\r\nexport class Axis {\r\n /** X axis */\r\n public static X: Vector3 = new Vector3(1.0, 0.0, 0.0);\r\n /** Y axis */\r\n public static Y: Vector3 = new Vector3(0.0, 1.0, 0.0);\r\n /** Z axis */\r\n public static Z: Vector3 = new Vector3(0.0, 0.0, 1.0);\r\n}\r\n\r\n/**\r\n * Defines cartesian components.\r\n */\r\nexport const enum Coordinate {\r\n /** X axis */\r\n X,\r\n /** Y axis */\r\n Y,\r\n /** Z axis */\r\n Z,\r\n}\r\n","import { BuildArray } from \"../Misc/arrayTools\";\r\nimport { RegisterClass } from \"../Misc/typeStore\";\r\nimport type { DeepImmutable, FloatArray, Tuple } from \"../types\";\r\nimport { Epsilon, ToGammaSpace, ToLinearSpace } from \"./math.constants\";\r\nimport type { IColor3Like, IColor4Like } from \"./math.like\";\r\nimport { Clamp, ToHex, WithinEpsilon } from \"./math.scalar.functions\";\r\nimport type { Tensor } from \"./tensor\";\r\n\r\nfunction colorChannelToLinearSpace(color: number): number {\r\n return Math.pow(color, ToLinearSpace);\r\n}\r\n\r\nfunction colorChannelToLinearSpaceExact(color: number): number {\r\n if (color <= 0.04045) {\r\n return 0.0773993808 * color;\r\n }\r\n return Math.pow(0.947867299 * (color + 0.055), 2.4);\r\n}\r\n\r\nfunction colorChannelToGammaSpace(color: number): number {\r\n return Math.pow(color, ToGammaSpace);\r\n}\r\n\r\nfunction colorChannelToGammaSpaceExact(color: number): number {\r\n if (color <= 0.0031308) {\r\n return 12.92 * color;\r\n }\r\n return 1.055 * Math.pow(color, 0.41666) - 0.055;\r\n}\r\n\r\n/**\r\n * Class used to hold a RGB color\r\n */\r\nexport class Color3 implements Tensor, IColor3Like>, IColor3Like {\r\n /**\r\n * If the first color is flagged with integers (as everything is 0,0,0), V8 stores all of the properties as integers internally because it doesn't know any better yet.\r\n * If subsequent colors are created with non-integer values, V8 determines that it would be best to represent these properties as doubles instead of integers,\r\n * and henceforth it will use floating-point representation for all color instances that it creates.\r\n * But the original color instances are unchanged and has a \"deprecated map\".\r\n * If we keep using the color instances from step 1, it will now be a poison pill which will mess up optimizations in any code it touches.\r\n */\r\n static _V8PerformanceHack = new Color3(0.5, 0.5, 0.5) as DeepImmutable;\r\n /**\r\n * @see Tensor.dimension\r\n */\r\n declare public readonly dimension: [3];\r\n\r\n /**\r\n * @see Tensor.rank\r\n */\r\n declare public readonly rank: 1;\r\n\r\n /**\r\n * Creates a new Color3 object from red, green, blue values, all between 0 and 1\r\n * @param r defines the red component (between 0 and 1, default is 0)\r\n * @param g defines the green component (between 0 and 1, default is 0)\r\n * @param b defines the blue component (between 0 and 1, default is 0)\r\n */\r\n constructor(\r\n /**\r\n * [0] Defines the red component (between 0 and 1, default is 0)\r\n */\r\n public r: number = 0,\r\n /**\r\n * [0] Defines the green component (between 0 and 1, default is 0)\r\n */\r\n public g: number = 0,\r\n /**\r\n * [0] Defines the blue component (between 0 and 1, default is 0)\r\n */\r\n public b: number = 0\r\n ) {}\r\n\r\n /**\r\n * Creates a string with the Color3 current values\r\n * @returns the string representation of the Color3 object\r\n */\r\n public toString(): string {\r\n return \"{R: \" + this.r + \" G:\" + this.g + \" B:\" + this.b + \"}\";\r\n }\r\n\r\n /**\r\n * Returns the string \"Color3\"\r\n * @returns \"Color3\"\r\n */\r\n public getClassName(): string {\r\n return \"Color3\";\r\n }\r\n\r\n /**\r\n * Compute the Color3 hash code\r\n * @returns an unique number that can be used to hash Color3 objects\r\n */\r\n public getHashCode(): number {\r\n let hash = (this.r * 255) | 0;\r\n hash = (hash * 397) ^ ((this.g * 255) | 0);\r\n hash = (hash * 397) ^ ((this.b * 255) | 0);\r\n return hash;\r\n }\r\n\r\n // Operators\r\n\r\n /**\r\n * Stores in the given array from the given starting index the red, green, blue values as successive elements\r\n * @param array defines the array where to store the r,g,b components\r\n * @param index defines an optional index in the target array to define where to start storing values\r\n * @returns the current Color3 object\r\n */\r\n public toArray(array: FloatArray, index: number = 0): this {\r\n array[index] = this.r;\r\n array[index + 1] = this.g;\r\n array[index + 2] = this.b;\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Update the current color with values stored in an array from the starting index of the given array\r\n * @param array defines the source array\r\n * @param offset defines an offset in the source array\r\n * @returns the current Color3 object\r\n */\r\n public fromArray(array: DeepImmutable>, offset: number = 0): this {\r\n Color3.FromArrayToRef(array, offset, this);\r\n return this;\r\n }\r\n\r\n /**\r\n * Returns a new Color4 object from the current Color3 and the given alpha\r\n * @param alpha defines the alpha component on the new Color4 object (default is 1)\r\n * @returns a new Color4 object\r\n */\r\n public toColor4(alpha: number = 1): Color4 {\r\n return new Color4(this.r, this.g, this.b, alpha);\r\n }\r\n\r\n /**\r\n * Returns a new array populated with 3 numeric elements : red, green and blue values\r\n * @returns the new array\r\n */\r\n public asArray(): Tuple {\r\n return [this.r, this.g, this.b];\r\n }\r\n\r\n /**\r\n * Returns the luminance value\r\n * @returns a float value\r\n */\r\n public toLuminance(): number {\r\n return this.r * 0.3 + this.g * 0.59 + this.b * 0.11;\r\n }\r\n\r\n /**\r\n * Multiply each Color3 rgb values by the given Color3 rgb values in a new Color3 object\r\n * @param otherColor defines the second operand\r\n * @returns the new Color3 object\r\n */\r\n public multiply(otherColor: DeepImmutable): Color3 {\r\n return new Color3(this.r * otherColor.r, this.g * otherColor.g, this.b * otherColor.b);\r\n }\r\n\r\n /**\r\n * Multiply the rgb values of the Color3 and the given Color3 and stores the result in the object \"result\"\r\n * @param otherColor defines the second operand\r\n * @param result defines the Color3 object where to store the result\r\n * @returns the result Color3\r\n */\r\n public multiplyToRef(otherColor: DeepImmutable, result: T): T {\r\n result.r = this.r * otherColor.r;\r\n result.g = this.g * otherColor.g;\r\n result.b = this.b * otherColor.b;\r\n return result;\r\n }\r\n\r\n /**\r\n * Multiplies the current Color3 coordinates by the given ones\r\n * @param otherColor defines the second operand\r\n * @returns the current updated Color3\r\n */\r\n public multiplyInPlace(otherColor: DeepImmutable): this {\r\n this.r *= otherColor.r;\r\n this.g *= otherColor.g;\r\n this.b *= otherColor.b;\r\n return this;\r\n }\r\n\r\n /**\r\n * Returns a new Color3 set with the result of the multiplication of the current Color3 coordinates by the given floats\r\n * @param r defines the r coordinate of the operand\r\n * @param g defines the g coordinate of the operand\r\n * @param b defines the b coordinate of the operand\r\n * @returns the new Color3\r\n */\r\n public multiplyByFloats(r: number, g: number, b: number): Color3 {\r\n return new Color3(this.r * r, this.g * g, this.b * b);\r\n }\r\n\r\n /**\r\n * @internal\r\n * Do not use\r\n */\r\n public divide(_other: DeepImmutable): never {\r\n throw new ReferenceError(\"Can not divide a color\");\r\n }\r\n\r\n /**\r\n * @internal\r\n * Do not use\r\n */\r\n public divideToRef(_other: DeepImmutable, _result: IColor3Like): never {\r\n throw new ReferenceError(\"Can not divide a color\");\r\n }\r\n\r\n /**\r\n * @internal\r\n * Do not use\r\n */\r\n public divideInPlace(_other: DeepImmutable): never {\r\n throw new ReferenceError(\"Can not divide a color\");\r\n }\r\n\r\n /**\r\n * Updates the current Color3 with the minimal coordinate values between its and the given color ones\r\n * @param other defines the second operand\r\n * @returns the current updated Color3\r\n */\r\n public minimizeInPlace(other: DeepImmutable): this {\r\n return this.minimizeInPlaceFromFloats(other.r, other.g, other.b);\r\n }\r\n\r\n /**\r\n * Updates the current Color3 with the maximal coordinate values between its and the given color ones.\r\n * @param other defines the second operand\r\n * @returns the current updated Color3\r\n */\r\n public maximizeInPlace(other: DeepImmutable): this {\r\n return this.maximizeInPlaceFromFloats(other.r, other.g, other.b);\r\n }\r\n\r\n /**\r\n * Updates the current Color3 with the minimal coordinate values between its and the given coordinates\r\n * @param r defines the r coordinate of the operand\r\n * @param g defines the g coordinate of the operand\r\n * @param b defines the b coordinate of the operand\r\n * @returns the current updated Color3\r\n */\r\n public minimizeInPlaceFromFloats(r: number, g: number, b: number): this {\r\n this.r = Math.min(r, this.r);\r\n this.g = Math.min(g, this.g);\r\n this.b = Math.min(b, this.b);\r\n return this;\r\n }\r\n\r\n /**\r\n * Updates the current Color3 with the maximal coordinate values between its and the given coordinates.\r\n * @param r defines the r coordinate of the operand\r\n * @param g defines the g coordinate of the operand\r\n * @param b defines the b coordinate of the operand\r\n * @returns the current updated Color3\r\n */\r\n public maximizeInPlaceFromFloats(r: number, g: number, b: number): this {\r\n this.r = Math.max(r, this.r);\r\n this.g = Math.max(g, this.g);\r\n this.b = Math.max(b, this.b);\r\n return this;\r\n }\r\n\r\n /**\r\n * @internal\r\n * Do not use\r\n */\r\n public floorToRef(_result: IColor3Like): never {\r\n throw new ReferenceError(\"Can not floor a color\");\r\n }\r\n\r\n /**\r\n * @internal\r\n * Do not use\r\n */\r\n public floor(): never {\r\n throw new ReferenceError(\"Can not floor a color\");\r\n }\r\n\r\n /**\r\n * @internal\r\n * Do not use\r\n */\r\n public fractToRef(_result: IColor3Like): never {\r\n throw new ReferenceError(\"Can not fract a color\");\r\n }\r\n\r\n /**\r\n * @internal\r\n * Do not use\r\n */\r\n public fract(): never {\r\n throw new ReferenceError(\"Can not fract a color\");\r\n }\r\n\r\n /**\r\n * Determines equality between Color3 objects\r\n * @param otherColor defines the second operand\r\n * @returns true if the rgb values are equal to the given ones\r\n */\r\n public equals(otherColor: DeepImmutable): boolean {\r\n return otherColor && this.r === otherColor.r && this.g === otherColor.g && this.b === otherColor.b;\r\n }\r\n\r\n /**\r\n * Alias for equalsToFloats\r\n * @param r red color component\r\n * @param g green color component\r\n * @param b blue color component\r\n * @returns boolean\r\n */\r\n public equalsFloats(r: number, g: number, b: number): boolean {\r\n return this.equalsToFloats(r, g, b);\r\n }\r\n\r\n /**\r\n * Determines equality between the current Color3 object and a set of r,b,g values\r\n * @param r defines the red component to check\r\n * @param g defines the green component to check\r\n * @param b defines the blue component to check\r\n * @returns true if the rgb values are equal to the given ones\r\n */\r\n public equalsToFloats(r: number, g: number, b: number): boolean {\r\n return this.r === r && this.g === g && this.b === b;\r\n }\r\n\r\n /**\r\n * Returns true if the current Color3 and the given color coordinates are distant less than epsilon\r\n * @param otherColor defines the second operand\r\n * @param epsilon defines the minimal distance to define values as equals\r\n * @returns true if both colors are distant less than epsilon\r\n */\r\n public equalsWithEpsilon(otherColor: DeepImmutable, epsilon: number = Epsilon): boolean {\r\n return WithinEpsilon(this.r, otherColor.r, epsilon) && WithinEpsilon(this.g, otherColor.g, epsilon) && WithinEpsilon(this.b, otherColor.b, epsilon);\r\n }\r\n\r\n /**\r\n * @internal\r\n * Do not use\r\n */\r\n public negate(): never {\r\n throw new ReferenceError(\"Can not negate a color\");\r\n }\r\n\r\n /**\r\n * @internal\r\n * Do not use\r\n */\r\n public negateInPlace(): never {\r\n throw new ReferenceError(\"Can not negate a color\");\r\n }\r\n\r\n /**\r\n * @internal\r\n * Do not use\r\n */\r\n public negateToRef(_result: IColor3Like): never {\r\n throw new ReferenceError(\"Can not negate a color\");\r\n }\r\n\r\n /**\r\n * Creates a new Color3 with the current Color3 values multiplied by scale\r\n * @param scale defines the scaling factor to apply\r\n * @returns a new Color3 object\r\n */\r\n public scale(scale: number): Color3 {\r\n return new Color3(this.r * scale, this.g * scale, this.b * scale);\r\n }\r\n\r\n /**\r\n * Multiplies the Color3 values by the float \"scale\"\r\n * @param scale defines the scaling factor to apply\r\n * @returns the current updated Color3\r\n */\r\n public scaleInPlace(scale: number): this {\r\n this.r *= scale;\r\n this.g *= scale;\r\n this.b *= scale;\r\n return this;\r\n }\r\n\r\n /**\r\n * Multiplies the rgb values by scale and stores the result into \"result\"\r\n * @param scale defines the scaling factor\r\n * @param result defines the Color3 object where to store the result\r\n * @returns the result Color3\r\n */\r\n public scaleToRef(scale: number, result: T): T {\r\n result.r = this.r * scale;\r\n result.g = this.g * scale;\r\n result.b = this.b * scale;\r\n return result;\r\n }\r\n\r\n /**\r\n * Scale the current Color3 values by a factor and add the result to a given Color3\r\n * @param scale defines the scale factor\r\n * @param result defines color to store the result into\r\n * @returns the result Color3\r\n */\r\n public scaleAndAddToRef(scale: number, result: T): T {\r\n result.r += this.r * scale;\r\n result.g += this.g * scale;\r\n result.b += this.b * scale;\r\n return result;\r\n }\r\n\r\n /**\r\n * Clamps the rgb values by the min and max values and stores the result into \"result\"\r\n * @param min defines minimum clamping value (default is 0)\r\n * @param max defines maximum clamping value (default is 1)\r\n * @param result defines color to store the result into\r\n * @returns the result Color3\r\n */\r\n public clampToRef(min: number = 0, max: number = 1, result: T): T {\r\n result.r = Clamp(this.r, min, max);\r\n result.g = Clamp(this.g, min, max);\r\n result.b = Clamp(this.b, min, max);\r\n return result;\r\n }\r\n\r\n /**\r\n * Creates a new Color3 set with the added values of the current Color3 and of the given one\r\n * @param otherColor defines the second operand\r\n * @returns the new Color3\r\n */\r\n public add(otherColor: DeepImmutable): Color3 {\r\n return new Color3(this.r + otherColor.r, this.g + otherColor.g, this.b + otherColor.b);\r\n }\r\n\r\n /**\r\n * Adds the given color to the current Color3\r\n * @param otherColor defines the second operand\r\n * @returns the current updated Color3\r\n */\r\n public addInPlace(otherColor: DeepImmutable): this {\r\n this.r += otherColor.r;\r\n this.g += otherColor.g;\r\n this.b += otherColor.b;\r\n return this;\r\n }\r\n\r\n /**\r\n * Adds the given coordinates to the current Color3\r\n * @param r defines the r coordinate of the operand\r\n * @param g defines the g coordinate of the operand\r\n * @param b defines the b coordinate of the operand\r\n * @returns the current updated Color3\r\n */\r\n public addInPlaceFromFloats(r: number, g: number, b: number): this {\r\n this.r += r;\r\n this.g += g;\r\n this.b += b;\r\n return this;\r\n }\r\n\r\n /**\r\n * Stores the result of the addition of the current Color3 and given one rgb values into \"result\"\r\n * @param otherColor defines the second operand\r\n * @param result defines Color3 object to store the result into\r\n * @returns the unmodified current Color3\r\n */\r\n public addToRef(otherColor: DeepImmutable, result: T): T {\r\n result.r = this.r + otherColor.r;\r\n result.g = this.g + otherColor.g;\r\n result.b = this.b + otherColor.b;\r\n return result;\r\n }\r\n\r\n /**\r\n * Returns a new Color3 set with the subtracted values of the given one from the current Color3\r\n * @param otherColor defines the second operand\r\n * @returns the new Color3\r\n */\r\n public subtract(otherColor: DeepImmutable): Color3 {\r\n return new Color3(this.r - otherColor.r, this.g - otherColor.g, this.b - otherColor.b);\r\n }\r\n\r\n /**\r\n * Stores the result of the subtraction of given one from the current Color3 rgb values into \"result\"\r\n * @param otherColor defines the second operand\r\n * @param result defines Color3 object to store the result into\r\n * @returns the unmodified current Color3\r\n */\r\n public subtractToRef(otherColor: DeepImmutable, result: T): T {\r\n result.r = this.r - otherColor.r;\r\n result.g = this.g - otherColor.g;\r\n result.b = this.b - otherColor.b;\r\n return result;\r\n }\r\n\r\n /**\r\n * Subtract the given color from the current Color3\r\n * @param otherColor defines the second operand\r\n * @returns the current updated Color3\r\n */\r\n public subtractInPlace(otherColor: DeepImmutable): this {\r\n this.r -= otherColor.r;\r\n this.g -= otherColor.g;\r\n this.b -= otherColor.b;\r\n return this;\r\n }\r\n\r\n /**\r\n * Returns a new Color3 set with the subtraction of the given floats from the current Color3 coordinates\r\n * @param r defines the r coordinate of the operand\r\n * @param g defines the g coordinate of the operand\r\n * @param b defines the b coordinate of the operand\r\n * @returns the resulting Color3\r\n */\r\n public subtractFromFloats(r: number, g: number, b: number): Color3 {\r\n return new Color3(this.r - r, this.g - g, this.b - b);\r\n }\r\n\r\n /**\r\n * Subtracts the given floats from the current Color3 coordinates and set the given color \"result\" with this result\r\n * @param r defines the r coordinate of the operand\r\n * @param g defines the g coordinate of the operand\r\n * @param b defines the b coordinate of the operand\r\n * @param result defines the Color3 object where to store the result\r\n * @returns the result\r\n */\r\n public subtractFromFloatsToRef(r: number, g: number, b: number, result: T): T {\r\n result.r = this.r - r;\r\n result.g = this.g - g;\r\n result.b = this.b - b;\r\n return result;\r\n }\r\n\r\n /**\r\n * Copy the current object\r\n * @returns a new Color3 copied the current one\r\n */\r\n public clone(): Color3 {\r\n return new Color3(this.r, this.g, this.b);\r\n }\r\n\r\n /**\r\n * Copies the rgb values from the source in the current Color3\r\n * @param source defines the source Color3 object\r\n * @returns the updated Color3 object\r\n */\r\n public copyFrom(source: DeepImmutable): this {\r\n this.r = source.r;\r\n this.g = source.g;\r\n this.b = source.b;\r\n return this;\r\n }\r\n\r\n /**\r\n * Updates the Color3 rgb values from the given floats\r\n * @param r defines the red component to read from\r\n * @param g defines the green component to read from\r\n * @param b defines the blue component to read from\r\n * @returns the current Color3 object\r\n */\r\n public copyFromFloats(r: number, g: number, b: number): this {\r\n this.r = r;\r\n this.g = g;\r\n this.b = b;\r\n return this;\r\n }\r\n\r\n /**\r\n * Updates the Color3 rgb values from the given floats\r\n * @param r defines the red component to read from\r\n * @param g defines the green component to read from\r\n * @param b defines the blue component to read from\r\n * @returns the current Color3 object\r\n */\r\n public set(r: number, g: number, b: number): this {\r\n return this.copyFromFloats(r, g, b);\r\n }\r\n\r\n /**\r\n * Copies the given float to the current Color3 coordinates\r\n * @param v defines the r, g and b coordinates of the operand\r\n * @returns the current updated Color3\r\n */\r\n public setAll(v: number): this {\r\n this.r = this.g = this.b = v;\r\n return this;\r\n }\r\n\r\n /**\r\n * Compute the Color3 hexadecimal code as a string\r\n * @returns a string containing the hexadecimal representation of the Color3 object\r\n */\r\n public toHexString(): string {\r\n const intR = Math.round(this.r * 255);\r\n const intG = Math.round(this.g * 255);\r\n const intB = Math.round(this.b * 255);\r\n return \"#\" + ToHex(intR) + ToHex(intG) + ToHex(intB);\r\n }\r\n\r\n /**\r\n * Updates the Color3 rgb values from the string containing valid hexadecimal values\r\n * @param hex defines a string containing valid hexadecimal values\r\n * @returns the current Color3 object\r\n */\r\n public fromHexString(hex: string): this {\r\n if (hex.substring(0, 1) !== \"#\" || hex.length !== 7) {\r\n return this;\r\n }\r\n\r\n this.r = parseInt(hex.substring(1, 3), 16) / 255;\r\n this.g = parseInt(hex.substring(3, 5), 16) / 255;\r\n this.b = parseInt(hex.substring(5, 7), 16) / 255;\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Converts current color in rgb space to HSV values\r\n * @returns a new color3 representing the HSV values\r\n */\r\n public toHSV(): Color3 {\r\n return this.toHSVToRef(new Color3());\r\n }\r\n\r\n /**\r\n * Converts current color in rgb space to HSV values\r\n * @param result defines the Color3 where to store the HSV values\r\n * @returns the updated result\r\n */\r\n public toHSVToRef(result: T): T {\r\n const r = this.r;\r\n const g = this.g;\r\n const b = this.b;\r\n\r\n const max = Math.max(r, g, b);\r\n const min = Math.min(r, g, b);\r\n let h = 0;\r\n let s = 0;\r\n const v = max;\r\n\r\n const dm = max - min;\r\n\r\n if (max !== 0) {\r\n s = dm / max;\r\n }\r\n\r\n if (max != min) {\r\n if (max == r) {\r\n h = (g - b) / dm;\r\n if (g < b) {\r\n h += 6;\r\n }\r\n } else if (max == g) {\r\n h = (b - r) / dm + 2;\r\n } else if (max == b) {\r\n h = (r - g) / dm + 4;\r\n }\r\n h *= 60;\r\n }\r\n\r\n result.r = h;\r\n result.g = s;\r\n result.b = v;\r\n return result;\r\n }\r\n\r\n /**\r\n * Computes a new Color3 converted from the current one to linear space\r\n * @param exact defines if the conversion will be done in an exact way which is slower but more accurate (default is false)\r\n * @returns a new Color3 object\r\n */\r\n public toLinearSpace(exact = false): Color3 {\r\n const convertedColor = new Color3();\r\n this.toLinearSpaceToRef(convertedColor, exact);\r\n return convertedColor;\r\n }\r\n\r\n /**\r\n * Converts the Color3 values to linear space and stores the result in \"convertedColor\"\r\n * @param convertedColor defines the Color3 object where to store the linear space version\r\n * @param exact defines if the conversion will be done in an exact way which is slower but more accurate (default is false)\r\n * @returns the unmodified Color3\r\n */\r\n public toLinearSpaceToRef(convertedColor: IColor3Like, exact = false): this {\r\n if (exact) {\r\n convertedColor.r = colorChannelToLinearSpaceExact(this.r);\r\n convertedColor.g = colorChannelToLinearSpaceExact(this.g);\r\n convertedColor.b = colorChannelToLinearSpaceExact(this.b);\r\n } else {\r\n convertedColor.r = colorChannelToLinearSpace(this.r);\r\n convertedColor.g = colorChannelToLinearSpace(this.g);\r\n convertedColor.b = colorChannelToLinearSpace(this.b);\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Computes a new Color3 converted from the current one to gamma space\r\n * @param exact defines if the conversion will be done in an exact way which is slower but more accurate (default is false)\r\n * @returns a new Color3 object\r\n */\r\n public toGammaSpace(exact = false): Color3 {\r\n const convertedColor = new Color3();\r\n this.toGammaSpaceToRef(convertedColor, exact);\r\n return convertedColor;\r\n }\r\n\r\n /**\r\n * Converts the Color3 values to gamma space and stores the result in \"convertedColor\"\r\n * @param convertedColor defines the Color3 object where to store the gamma space version\r\n * @param exact defines if the conversion will be done in an exact way which is slower but more accurate (default is false)\r\n * @returns the unmodified Color3\r\n */\r\n public toGammaSpaceToRef(convertedColor: IColor3Like, exact = false): this {\r\n if (exact) {\r\n convertedColor.r = colorChannelToGammaSpaceExact(this.r);\r\n convertedColor.g = colorChannelToGammaSpaceExact(this.g);\r\n convertedColor.b = colorChannelToGammaSpaceExact(this.b);\r\n } else {\r\n convertedColor.r = colorChannelToGammaSpace(this.r);\r\n convertedColor.g = colorChannelToGammaSpace(this.g);\r\n convertedColor.b = colorChannelToGammaSpace(this.b);\r\n }\r\n return this;\r\n }\r\n\r\n // Statics\r\n\r\n private static _BlackReadOnly = Color3.Black() as DeepImmutable;\r\n\r\n /**\r\n * Converts Hue, saturation and value to a Color3 (RGB)\r\n * @param hue defines the hue (value between 0 and 360)\r\n * @param saturation defines the saturation (value between 0 and 1)\r\n * @param value defines the value (value between 0 and 1)\r\n * @param result defines the Color3 where to store the RGB values\r\n * @returns the updated result\r\n */\r\n public static HSVtoRGBToRef(hue: number, saturation: number, value: number, result: T): T {\r\n const chroma = value * saturation;\r\n const h = hue / 60;\r\n const x = chroma * (1 - Math.abs((h % 2) - 1));\r\n let r = 0;\r\n let g = 0;\r\n let b = 0;\r\n\r\n if (h >= 0 && h <= 1) {\r\n r = chroma;\r\n g = x;\r\n } else if (h >= 1 && h <= 2) {\r\n r = x;\r\n g = chroma;\r\n } else if (h >= 2 && h <= 3) {\r\n g = chroma;\r\n b = x;\r\n } else if (h >= 3 && h <= 4) {\r\n g = x;\r\n b = chroma;\r\n } else if (h >= 4 && h <= 5) {\r\n r = x;\r\n b = chroma;\r\n } else if (h >= 5 && h <= 6) {\r\n r = chroma;\r\n b = x;\r\n }\r\n\r\n const m = value - chroma;\r\n result.r = r + m;\r\n result.g = g + m;\r\n result.b = b + m;\r\n return result;\r\n }\r\n\r\n /**\r\n * Converts Hue, saturation and value to a new Color3 (RGB)\r\n * @param hue defines the hue (value between 0 and 360)\r\n * @param saturation defines the saturation (value between 0 and 1)\r\n * @param value defines the value (value between 0 and 1)\r\n * @returns a new Color3 object\r\n */\r\n public static FromHSV(hue: number, saturation: number, value: number): Color3 {\r\n const result = new Color3(0, 0, 0);\r\n Color3.HSVtoRGBToRef(hue, saturation, value, result);\r\n return result;\r\n }\r\n\r\n /**\r\n * Creates a new Color3 from the string containing valid hexadecimal values\r\n * @param hex defines a string containing valid hexadecimal values\r\n * @returns a new Color3 object\r\n */\r\n public static FromHexString(hex: string): Color3 {\r\n return new Color3(0, 0, 0).fromHexString(hex);\r\n }\r\n\r\n /**\r\n * Creates a new Color3 from the starting index of the given array\r\n * @param array defines the source array\r\n * @param offset defines an offset in the source array\r\n * @returns a new Color3 object\r\n */\r\n public static FromArray(array: DeepImmutable>, offset: number = 0): Color3 {\r\n return new Color3(array[offset], array[offset + 1], array[offset + 2]);\r\n }\r\n\r\n /**\r\n * Creates a new Color3 from the starting index element of the given array\r\n * @param array defines the source array to read from\r\n * @param offset defines the offset in the source array\r\n * @param result defines the target Color3 object\r\n */\r\n public static FromArrayToRef(array: DeepImmutable>, offset: number = 0, result: Color3) {\r\n result.r = array[offset];\r\n result.g = array[offset + 1];\r\n result.b = array[offset + 2];\r\n }\r\n\r\n /**\r\n * Creates a new Color3 from integer values (\\< 256)\r\n * @param r defines the red component to read from (value between 0 and 255)\r\n * @param g defines the green component to read from (value between 0 and 255)\r\n * @param b defines the blue component to read from (value between 0 and 255)\r\n * @returns a new Color3 object\r\n */\r\n public static FromInts(r: number, g: number, b: number): Color3 {\r\n return new Color3(r / 255.0, g / 255.0, b / 255.0);\r\n }\r\n\r\n /**\r\n * Creates a new Color3 with values linearly interpolated of \"amount\" between the start Color3 and the end Color3\r\n * @param start defines the start Color3 value\r\n * @param end defines the end Color3 value\r\n * @param amount defines the gradient value between start and end\r\n * @returns a new Color3 object\r\n */\r\n public static Lerp(start: DeepImmutable, end: DeepImmutable, amount: number): Color3 {\r\n const result = new Color3(0.0, 0.0, 0.0);\r\n Color3.LerpToRef(start, end, amount, result);\r\n return result;\r\n }\r\n\r\n /**\r\n * Creates a new Color3 with values linearly interpolated of \"amount\" between the start Color3 and the end Color3\r\n * @param left defines the start value\r\n * @param right defines the end value\r\n * @param amount defines the gradient factor\r\n * @param result defines the Color3 object where to store the result\r\n */\r\n public static LerpToRef(left: DeepImmutable, right: DeepImmutable, amount: number, result: Color3): void {\r\n result.r = left.r + (right.r - left.r) * amount;\r\n result.g = left.g + (right.g - left.g) * amount;\r\n result.b = left.b + (right.b - left.b) * amount;\r\n }\r\n\r\n /**\r\n * Returns a new Color3 located for \"amount\" (float) on the Hermite interpolation spline defined by the vectors \"value1\", \"tangent1\", \"value2\", \"tangent2\"\r\n * @param value1 defines the first control point\r\n * @param tangent1 defines the first tangent Color3\r\n * @param value2 defines the second control point\r\n * @param tangent2 defines the second tangent Color3\r\n * @param amount defines the amount on the interpolation spline (between 0 and 1)\r\n * @returns the new Color3\r\n */\r\n public static Hermite(value1: DeepImmutable, tangent1: DeepImmutable, value2: DeepImmutable, tangent2: DeepImmutable, amount: number): Color3 {\r\n const squared = amount * amount;\r\n const cubed = amount * squared;\r\n const part1 = 2.0 * cubed - 3.0 * squared + 1.0;\r\n const part2 = -2.0 * cubed + 3.0 * squared;\r\n const part3 = cubed - 2.0 * squared + amount;\r\n const part4 = cubed - squared;\r\n\r\n const r = value1.r * part1 + value2.r * part2 + tangent1.r * part3 + tangent2.r * part4;\r\n const g = value1.g * part1 + value2.g * part2 + tangent1.g * part3 + tangent2.g * part4;\r\n const b = value1.b * part1 + value2.b * part2 + tangent1.b * part3 + tangent2.b * part4;\r\n return new Color3(r, g, b);\r\n }\r\n\r\n /**\r\n * Returns a new Color3 which is the 1st derivative of the Hermite spline defined by the colors \"value1\", \"value2\", \"tangent1\", \"tangent2\".\r\n * @param value1 defines the first control point\r\n * @param tangent1 defines the first tangent\r\n * @param value2 defines the second control point\r\n * @param tangent2 defines the second tangent\r\n * @param time define where the derivative must be done\r\n * @returns 1st derivative\r\n */\r\n public static Hermite1stDerivative(\r\n value1: DeepImmutable,\r\n tangent1: DeepImmutable,\r\n value2: DeepImmutable,\r\n tangent2: DeepImmutable,\r\n time: number\r\n ): Color3 {\r\n const result = Color3.Black();\r\n\r\n this.Hermite1stDerivativeToRef(value1, tangent1, value2, tangent2, time, result);\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Returns a new Color3 which is the 1st derivative of the Hermite spline defined by the colors \"value1\", \"value2\", \"tangent1\", \"tangent2\".\r\n * @param value1 defines the first control point\r\n * @param tangent1 defines the first tangent\r\n * @param value2 defines the second control point\r\n * @param tangent2 defines the second tangent\r\n * @param time define where the derivative must be done\r\n * @param result define where to store the derivative\r\n */\r\n public static Hermite1stDerivativeToRef(\r\n value1: DeepImmutable,\r\n tangent1: DeepImmutable,\r\n value2: DeepImmutable,\r\n tangent2: DeepImmutable,\r\n time: number,\r\n result: Color3\r\n ) {\r\n const t2 = time * time;\r\n\r\n result.r = (t2 - time) * 6 * value1.r + (3 * t2 - 4 * time + 1) * tangent1.r + (-t2 + time) * 6 * value2.r + (3 * t2 - 2 * time) * tangent2.r;\r\n result.g = (t2 - time) * 6 * value1.g + (3 * t2 - 4 * time + 1) * tangent1.g + (-t2 + time) * 6 * value2.g + (3 * t2 - 2 * time) * tangent2.g;\r\n result.b = (t2 - time) * 6 * value1.b + (3 * t2 - 4 * time + 1) * tangent1.b + (-t2 + time) * 6 * value2.b + (3 * t2 - 2 * time) * tangent2.b;\r\n }\r\n\r\n /**\r\n * Returns a Color3 value containing a red color\r\n * @returns a new Color3 object\r\n */\r\n public static Red(): Color3 {\r\n return new Color3(1, 0, 0);\r\n }\r\n /**\r\n * Returns a Color3 value containing a green color\r\n * @returns a new Color3 object\r\n */\r\n public static Green(): Color3 {\r\n return new Color3(0, 1, 0);\r\n }\r\n /**\r\n * Returns a Color3 value containing a blue color\r\n * @returns a new Color3 object\r\n */\r\n public static Blue(): Color3 {\r\n return new Color3(0, 0, 1);\r\n }\r\n /**\r\n * Returns a Color3 value containing a black color\r\n * @returns a new Color3 object\r\n */\r\n public static Black(): Color3 {\r\n return new Color3(0, 0, 0);\r\n }\r\n\r\n /**\r\n * Gets a Color3 value containing a black color that must not be updated\r\n */\r\n public static get BlackReadOnly(): DeepImmutable {\r\n return Color3._BlackReadOnly;\r\n }\r\n\r\n /**\r\n * Returns a Color3 value containing a white color\r\n * @returns a new Color3 object\r\n */\r\n public static White(): Color3 {\r\n return new Color3(1, 1, 1);\r\n }\r\n /**\r\n * Returns a Color3 value containing a purple color\r\n * @returns a new Color3 object\r\n */\r\n public static Purple(): Color3 {\r\n return new Color3(0.5, 0, 0.5);\r\n }\r\n /**\r\n * Returns a Color3 value containing a magenta color\r\n * @returns a new Color3 object\r\n */\r\n public static Magenta(): Color3 {\r\n return new Color3(1, 0, 1);\r\n }\r\n /**\r\n * Returns a Color3 value containing a yellow color\r\n * @returns a new Color3 object\r\n */\r\n public static Yellow(): Color3 {\r\n return new Color3(1, 1, 0);\r\n }\r\n /**\r\n * Returns a Color3 value containing a gray color\r\n * @returns a new Color3 object\r\n */\r\n public static Gray(): Color3 {\r\n return new Color3(0.5, 0.5, 0.5);\r\n }\r\n /**\r\n * Returns a Color3 value containing a teal color\r\n * @returns a new Color3 object\r\n */\r\n public static Teal(): Color3 {\r\n return new Color3(0, 1.0, 1.0);\r\n }\r\n /**\r\n * Returns a Color3 value containing a random color\r\n * @returns a new Color3 object\r\n */\r\n public static Random(): Color3 {\r\n return new Color3(Math.random(), Math.random(), Math.random());\r\n }\r\n}\r\nObject.defineProperties(Color3.prototype, {\r\n dimension: { value: [3] },\r\n rank: { value: 1 },\r\n});\r\n\r\n/**\r\n * Class used to hold a RBGA color\r\n */\r\nexport class Color4 implements Tensor, IColor4Like>, IColor4Like {\r\n /**\r\n * If the first color is flagged with integers (as everything is 0,0,0,0), V8 stores all of the properties as integers internally because it doesn't know any better yet.\r\n * If subsequent colors are created with non-integer values, V8 determines that it would be best to represent these properties as doubles instead of integers,\r\n * and henceforth it will use floating-point representation for all color instances that it creates.\r\n * But the original color instances are unchanged and has a \"deprecated map\".\r\n * If we keep using the color instances from step 1, it will now be a poison pill which will mess up optimizations in any code it touches.\r\n */\r\n static _V8PerformanceHack = new Color4(0.5, 0.5, 0.5, 0.5) as DeepImmutable;\r\n /**\r\n * @see Tensor.dimension\r\n */\r\n declare public readonly dimension: [4];\r\n\r\n /**\r\n * @see Tensor.rank\r\n */\r\n declare public readonly rank: 1;\r\n\r\n /**\r\n * Creates a new Color4 object from red, green, blue values, all between 0 and 1\r\n * @param r defines the red component (between 0 and 1, default is 0)\r\n * @param g defines the green component (between 0 and 1, default is 0)\r\n * @param b defines the blue component (between 0 and 1, default is 0)\r\n * @param a defines the alpha component (between 0 and 1, default is 1)\r\n */\r\n constructor(\r\n /**\r\n * [0] Defines the red component (between 0 and 1, default is 0)\r\n */\r\n public r: number = 0,\r\n /**\r\n * [0] Defines the green component (between 0 and 1, default is 0)\r\n */\r\n public g: number = 0,\r\n /**\r\n * [0] Defines the blue component (between 0 and 1, default is 0)\r\n */\r\n public b: number = 0,\r\n /**\r\n * [1] Defines the alpha component (between 0 and 1, default is 1)\r\n */\r\n public a: number = 1\r\n ) {}\r\n\r\n // Operators\r\n\r\n /**\r\n * Creates a new array populated with 4 numeric elements : red, green, blue, alpha values\r\n * @returns the new array\r\n */\r\n public asArray(): Tuple {\r\n return [this.r, this.g, this.b, this.a];\r\n }\r\n\r\n /**\r\n * Stores from the starting index in the given array the Color4 successive values\r\n * @param array defines the array where to store the r,g,b components\r\n * @param index defines an optional index in the target array to define where to start storing values\r\n * @returns the current Color4 object\r\n */\r\n public toArray(array: FloatArray, index: number = 0): this {\r\n array[index] = this.r;\r\n array[index + 1] = this.g;\r\n array[index + 2] = this.b;\r\n array[index + 3] = this.a;\r\n return this;\r\n }\r\n\r\n /**\r\n * Update the current color with values stored in an array from the starting index of the given array\r\n * @param array defines the source array\r\n * @param offset defines an offset in the source array\r\n * @returns the current Color4 object\r\n */\r\n public fromArray(array: DeepImmutable>, offset: number = 0): this {\r\n this.r = array[offset];\r\n this.g = array[offset + 1];\r\n this.b = array[offset + 2];\r\n this.a = array[offset + 3];\r\n return this;\r\n }\r\n\r\n /**\r\n * Determines equality between Color4 objects\r\n * @param otherColor defines the second operand\r\n * @returns true if the rgba values are equal to the given ones\r\n */\r\n public equals(otherColor: DeepImmutable): boolean {\r\n return otherColor && this.r === otherColor.r && this.g === otherColor.g && this.b === otherColor.b && this.a === otherColor.a;\r\n }\r\n\r\n /**\r\n * Creates a new Color4 set with the added values of the current Color4 and of the given one\r\n * @param otherColor defines the second operand\r\n * @returns a new Color4 object\r\n */\r\n public add(otherColor: DeepImmutable): Color4 {\r\n return new Color4(this.r + otherColor.r, this.g + otherColor.g, this.b + otherColor.b, this.a + otherColor.a);\r\n }\r\n\r\n /**\r\n * Updates the given color \"result\" with the result of the addition of the current Color4 and the given one.\r\n * @param otherColor the color to add\r\n * @param result the color to store the result\r\n * @returns result input\r\n */\r\n public addToRef(otherColor: DeepImmutable, result: T): T {\r\n result.r = this.r + otherColor.r;\r\n result.g = this.g + otherColor.g;\r\n result.b = this.b + otherColor.b;\r\n result.a = this.a + otherColor.a;\r\n return result;\r\n }\r\n\r\n /**\r\n * Adds in place the given Color4 values to the current Color4 object\r\n * @param otherColor defines the second operand\r\n * @returns the current updated Color4 object\r\n */\r\n public addInPlace(otherColor: DeepImmutable): this {\r\n this.r += otherColor.r;\r\n this.g += otherColor.g;\r\n this.b += otherColor.b;\r\n this.a += otherColor.a;\r\n return this;\r\n }\r\n\r\n /**\r\n * Adds the given coordinates to the current Color4\r\n * @param r defines the r coordinate of the operand\r\n * @param g defines the g coordinate of the operand\r\n * @param b defines the b coordinate of the operand\r\n * @param a defines the a coordinate of the operand\r\n * @returns the current updated Color4\r\n */\r\n public addInPlaceFromFloats(r: number, g: number, b: number, a: number): this {\r\n this.r += r;\r\n this.g += g;\r\n this.b += b;\r\n this.a += a;\r\n return this;\r\n }\r\n\r\n /**\r\n * Creates a new Color4 set with the subtracted values of the given one from the current Color4\r\n * @param otherColor defines the second operand\r\n * @returns a new Color4 object\r\n */\r\n public subtract(otherColor: DeepImmutable): Color4 {\r\n return new Color4(this.r - otherColor.r, this.g - otherColor.g, this.b - otherColor.b, this.a - otherColor.a);\r\n }\r\n\r\n /**\r\n * Subtracts the given ones from the current Color4 values and stores the results in \"result\"\r\n * @param otherColor defines the second operand\r\n * @param result defines the Color4 object where to store the result\r\n * @returns the result Color4 object\r\n */\r\n public subtractToRef(otherColor: DeepImmutable, result: T): T {\r\n result.r = this.r - otherColor.r;\r\n result.g = this.g - otherColor.g;\r\n result.b = this.b - otherColor.b;\r\n result.a = this.a - otherColor.a;\r\n return result;\r\n }\r\n\r\n /**\r\n * Subtract in place the given color from the current Color4.\r\n * @param otherColor the color to subtract\r\n * @returns the updated Color4.\r\n */\r\n public subtractInPlace(otherColor: DeepImmutable): this {\r\n this.r -= otherColor.r;\r\n this.g -= otherColor.g;\r\n this.b -= otherColor.b;\r\n this.a -= otherColor.a;\r\n return this;\r\n }\r\n\r\n /**\r\n * Returns a new Color4 set with the result of the subtraction of the given floats from the current Color4 coordinates.\r\n * @param r value to subtract\r\n * @param g value to subtract\r\n * @param b value to subtract\r\n * @param a value to subtract\r\n * @returns new color containing the result\r\n */\r\n public subtractFromFloats(r: number, g: number, b: number, a: number): Color4 {\r\n return new Color4(this.r - r, this.g - g, this.b - b, this.a - a);\r\n }\r\n\r\n /**\r\n * Sets the given color \"result\" set with the result of the subtraction of the given floats from the current Color4 coordinates.\r\n * @param r value to subtract\r\n * @param g value to subtract\r\n * @param b value to subtract\r\n * @param a value to subtract\r\n * @param result the color to store the result in\r\n * @returns result input\r\n */\r\n public subtractFromFloatsToRef(r: number, g: number, b: number, a: number, result: T): T {\r\n result.r = this.r - r;\r\n result.g = this.g - g;\r\n result.b = this.b - b;\r\n result.a = this.a - a;\r\n return result;\r\n }\r\n\r\n /**\r\n * Creates a new Color4 with the current Color4 values multiplied by scale\r\n * @param scale defines the scaling factor to apply\r\n * @returns a new Color4 object\r\n */\r\n public scale(scale: number): Color4 {\r\n return new Color4(this.r * scale, this.g * scale, this.b * scale, this.a * scale);\r\n }\r\n\r\n /**\r\n * Multiplies the Color4 values by the float \"scale\"\r\n * @param scale defines the scaling factor to apply\r\n * @returns the current updated Color4\r\n */\r\n public scaleInPlace(scale: number): this {\r\n this.r *= scale;\r\n this.g *= scale;\r\n this.b *= scale;\r\n this.a *= scale;\r\n return this;\r\n }\r\n\r\n /**\r\n * Multiplies the current Color4 values by scale and stores the result in \"result\"\r\n * @param scale defines the scaling factor to apply\r\n * @param result defines the Color4 object where to store the result\r\n * @returns the result Color4\r\n */\r\n public scaleToRef(scale: number, result: T): T {\r\n result.r = this.r * scale;\r\n result.g = this.g * scale;\r\n result.b = this.b * scale;\r\n result.a = this.a * scale;\r\n return result;\r\n }\r\n\r\n /**\r\n * Scale the current Color4 values by a factor and add the result to a given Color4\r\n * @param scale defines the scale factor\r\n * @param result defines the Color4 object where to store the result\r\n * @returns the result Color4\r\n */\r\n public scaleAndAddToRef(scale: number, result: T): T {\r\n result.r += this.r * scale;\r\n result.g += this.g * scale;\r\n result.b += this.b * scale;\r\n result.a += this.a * scale;\r\n return result;\r\n }\r\n\r\n /**\r\n * Clamps the rgb values by the min and max values and stores the result into \"result\"\r\n * @param min defines minimum clamping value (default is 0)\r\n * @param max defines maximum clamping value (default is 1)\r\n * @param result defines color to store the result into.\r\n * @returns the result Color4\r\n */\r\n public clampToRef(min: number = 0, max: number = 1, result: T): T {\r\n result.r = Clamp(this.r, min, max);\r\n result.g = Clamp(this.g, min, max);\r\n result.b = Clamp(this.b, min, max);\r\n result.a = Clamp(this.a, min, max);\r\n return result;\r\n }\r\n\r\n /**\r\n * Multiply an Color4 value by another and return a new Color4 object\r\n * @param color defines the Color4 value to multiply by\r\n * @returns a new Color4 object\r\n */\r\n public multiply(color: DeepImmutable): Color4 {\r\n return new Color4(this.r * color.r, this.g * color.g, this.b * color.b, this.a * color.a);\r\n }\r\n\r\n /**\r\n * Multiply a Color4 value by another and push the result in a reference value\r\n * @param color defines the Color4 value to multiply by\r\n * @param result defines the Color4 to fill the result in\r\n * @returns the result Color4\r\n */\r\n public multiplyToRef(color: DeepImmutable, result: T): T {\r\n result.r = this.r * color.r;\r\n result.g = this.g * color.g;\r\n result.b = this.b * color.b;\r\n result.a = this.a * color.a;\r\n return result;\r\n }\r\n\r\n /**\r\n * Multiplies in place the current Color4 by the given one.\r\n * @param otherColor color to multiple with\r\n * @returns the updated Color4.\r\n */\r\n public multiplyInPlace(otherColor: DeepImmutable): this {\r\n this.r *= otherColor.r;\r\n this.g *= otherColor.g;\r\n this.b *= otherColor.b;\r\n this.a *= otherColor.a;\r\n return this;\r\n }\r\n\r\n /**\r\n * Returns a new Color4 set with the multiplication result of the given floats and the current Color4 coordinates.\r\n * @param r value multiply with\r\n * @param g value multiply with\r\n * @param b value multiply with\r\n * @param a value multiply with\r\n * @returns resulting new color\r\n */\r\n public multiplyByFloats(r: number, g: number, b: number, a: number): Color4 {\r\n return new Color4(this.r * r, this.g * g, this.b * b, this.a * a);\r\n }\r\n\r\n /**\r\n * @internal\r\n * Do not use\r\n */\r\n public divide(_other: DeepImmutable): never {\r\n throw new ReferenceError(\"Can not divide a color\");\r\n }\r\n\r\n /**\r\n * @internal\r\n * Do not use\r\n */\r\n public divideToRef(_other: DeepImmutable, _result: IColor4Like): never {\r\n throw new ReferenceError(\"Can not divide a color\");\r\n }\r\n\r\n /**\r\n * @internal\r\n * Do not use\r\n */\r\n public divideInPlace(_other: DeepImmutable): never {\r\n throw new ReferenceError(\"Can not divide a color\");\r\n }\r\n\r\n /**\r\n * Updates the Color4 coordinates with the minimum values between its own and the given color ones\r\n * @param other defines the second operand\r\n * @returns the current updated Color4\r\n */\r\n public minimizeInPlace(other: DeepImmutable): this {\r\n this.r = Math.min(this.r, other.r);\r\n this.g = Math.min(this.g, other.g);\r\n this.b = Math.min(this.b, other.b);\r\n this.a = Math.min(this.a, other.a);\r\n return this;\r\n }\r\n /**\r\n * Updates the Color4 coordinates with the maximum values between its own and the given color ones\r\n * @param other defines the second operand\r\n * @returns the current updated Color4\r\n */\r\n public maximizeInPlace(other: DeepImmutable): this {\r\n this.r = Math.max(this.r, other.r);\r\n this.g = Math.max(this.g, other.g);\r\n this.b = Math.max(this.b, other.b);\r\n this.a = Math.max(this.a, other.a);\r\n return this;\r\n }\r\n\r\n /**\r\n * Updates the current Color4 with the minimal coordinate values between its and the given coordinates\r\n * @param r defines the r coordinate of the operand\r\n * @param g defines the g coordinate of the operand\r\n * @param b defines the b coordinate of the operand\r\n * @param a defines the a coordinate of the operand\r\n * @returns the current updated Color4\r\n */\r\n public minimizeInPlaceFromFloats(r: number, g: number, b: number, a: number): this {\r\n this.r = Math.min(r, this.r);\r\n this.g = Math.min(g, this.g);\r\n this.b = Math.min(b, this.b);\r\n this.a = Math.min(a, this.a);\r\n return this;\r\n }\r\n\r\n /**\r\n * Updates the current Color4 with the maximal coordinate values between its and the given coordinates.\r\n * @param r defines the r coordinate of the operand\r\n * @param g defines the g coordinate of the operand\r\n * @param b defines the b coordinate of the operand\r\n * @param a defines the a coordinate of the operand\r\n * @returns the current updated Color4\r\n */\r\n public maximizeInPlaceFromFloats(r: number, g: number, b: number, a: number): this {\r\n this.r = Math.max(r, this.r);\r\n this.g = Math.max(g, this.g);\r\n this.b = Math.max(b, this.b);\r\n this.a = Math.max(a, this.a);\r\n return this;\r\n }\r\n\r\n /**\r\n * @internal\r\n * Do not use\r\n */\r\n public floorToRef(_result: IColor4Like): never {\r\n throw new ReferenceError(\"Can not floor a color\");\r\n }\r\n\r\n /**\r\n * @internal\r\n * Do not use\r\n */\r\n public floor(): never {\r\n throw new ReferenceError(\"Can not floor a color\");\r\n }\r\n\r\n /**\r\n * @internal\r\n * Do not use\r\n */\r\n public fractToRef(_result: IColor4Like): never {\r\n throw new ReferenceError(\"Can not fract a color\");\r\n }\r\n\r\n /**\r\n * @internal\r\n * Do not use\r\n */\r\n public fract(): never {\r\n throw new ReferenceError(\"Can not fract a color\");\r\n }\r\n\r\n /**\r\n * @internal\r\n * Do not use\r\n */\r\n public negate(): never {\r\n throw new ReferenceError(\"Can not negate a color\");\r\n }\r\n\r\n /**\r\n * @internal\r\n * Do not use\r\n */\r\n public negateInPlace(): never {\r\n throw new ReferenceError(\"Can not negate a color\");\r\n }\r\n\r\n /**\r\n * @internal\r\n * Do not use\r\n */\r\n public negateToRef(_result: IColor4Like): never {\r\n throw new ReferenceError(\"Can not negate a color\");\r\n }\r\n\r\n /**\r\n * Boolean : True if the current Color4 coordinates are each beneath the distance \"epsilon\" from the given color ones.\r\n * @param otherColor color to compare against\r\n * @param epsilon (Default: very small number)\r\n * @returns true if they are equal\r\n */\r\n public equalsWithEpsilon(otherColor: DeepImmutable, epsilon: number = Epsilon): boolean {\r\n return (\r\n WithinEpsilon(this.r, otherColor.r, epsilon) &&\r\n WithinEpsilon(this.g, otherColor.g, epsilon) &&\r\n WithinEpsilon(this.b, otherColor.b, epsilon) &&\r\n WithinEpsilon(this.a, otherColor.a, epsilon)\r\n );\r\n }\r\n\r\n /**\r\n * Boolean : True if the given floats are strictly equal to the current Color4 coordinates.\r\n * @param x x value to compare against\r\n * @param y y value to compare against\r\n * @param z z value to compare against\r\n * @param w w value to compare against\r\n * @returns true if equal\r\n */\r\n public equalsToFloats(x: number, y: number, z: number, w: number): boolean {\r\n return this.r === x && this.g === y && this.b === z && this.a === w;\r\n }\r\n\r\n /**\r\n * Creates a string with the Color4 current values\r\n * @returns the string representation of the Color4 object\r\n */\r\n public toString(): string {\r\n return \"{R: \" + this.r + \" G:\" + this.g + \" B:\" + this.b + \" A:\" + this.a + \"}\";\r\n }\r\n\r\n /**\r\n * Returns the string \"Color4\"\r\n * @returns \"Color4\"\r\n */\r\n public getClassName(): string {\r\n return \"Color4\";\r\n }\r\n\r\n /**\r\n * Compute the Color4 hash code\r\n * @returns an unique number that can be used to hash Color4 objects\r\n */\r\n public getHashCode(): number {\r\n let hash = (this.r * 255) | 0;\r\n hash = (hash * 397) ^ ((this.g * 255) | 0);\r\n hash = (hash * 397) ^ ((this.b * 255) | 0);\r\n hash = (hash * 397) ^ ((this.a * 255) | 0);\r\n return hash;\r\n }\r\n\r\n /**\r\n * Creates a new Color4 copied from the current one\r\n * @returns a new Color4 object\r\n */\r\n public clone(): Color4 {\r\n const result = new Color4();\r\n return result.copyFrom(this);\r\n }\r\n\r\n /**\r\n * Copies the given Color4 values into the current one\r\n * @param source defines the source Color4 object\r\n * @returns the current updated Color4 object\r\n */\r\n public copyFrom(source: DeepImmutable): this {\r\n this.r = source.r;\r\n this.g = source.g;\r\n this.b = source.b;\r\n this.a = source.a;\r\n return this;\r\n }\r\n\r\n /**\r\n * Copies the given float values into the current one\r\n * @param r defines the red component to read from\r\n * @param g defines the green component to read from\r\n * @param b defines the blue component to read from\r\n * @param a defines the alpha component to read from\r\n * @returns the current updated Color4 object\r\n */\r\n public copyFromFloats(r: number, g: number, b: number, a: number): this {\r\n this.r = r;\r\n this.g = g;\r\n this.b = b;\r\n this.a = a;\r\n return this;\r\n }\r\n\r\n /**\r\n * Copies the given float values into the current one\r\n * @param r defines the red component to read from\r\n * @param g defines the green component to read from\r\n * @param b defines the blue component to read from\r\n * @param a defines the alpha component to read from\r\n * @returns the current updated Color4 object\r\n */\r\n public set(r: number, g: number, b: number, a: number): this {\r\n return this.copyFromFloats(r, g, b, a);\r\n }\r\n\r\n /**\r\n * Copies the given float to the current Vector4 coordinates\r\n * @param v defines the r, g, b, and a coordinates of the operand\r\n * @returns the current updated Vector4\r\n */\r\n public setAll(v: number): this {\r\n this.r = this.g = this.b = this.a = v;\r\n return this;\r\n }\r\n\r\n /**\r\n * Compute the Color4 hexadecimal code as a string\r\n * @param returnAsColor3 defines if the string should only contains RGB values (off by default)\r\n * @returns a string containing the hexadecimal representation of the Color4 object\r\n */\r\n public toHexString(returnAsColor3 = false): string {\r\n const intR = Math.round(this.r * 255);\r\n const intG = Math.round(this.g * 255);\r\n const intB = Math.round(this.b * 255);\r\n\r\n if (returnAsColor3) {\r\n return \"#\" + ToHex(intR) + ToHex(intG) + ToHex(intB);\r\n }\r\n\r\n const intA = Math.round(this.a * 255);\r\n return \"#\" + ToHex(intR) + ToHex(intG) + ToHex(intB) + ToHex(intA);\r\n }\r\n\r\n /**\r\n * Updates the Color4 rgba values from the string containing valid hexadecimal values.\r\n *\r\n * A valid hex string is either in the format #RRGGBB or #RRGGBBAA.\r\n *\r\n * When a hex string without alpha is passed, the resulting Color4 keeps\r\n * its previous alpha value.\r\n *\r\n * An invalid string does not modify this object\r\n *\r\n * @param hex defines a string containing valid hexadecimal values\r\n * @returns the current updated Color4 object\r\n */\r\n public fromHexString(hex: string): this {\r\n if (hex.substring(0, 1) !== \"#\" || (hex.length !== 9 && hex.length !== 7)) {\r\n return this;\r\n }\r\n\r\n this.r = parseInt(hex.substring(1, 3), 16) / 255;\r\n this.g = parseInt(hex.substring(3, 5), 16) / 255;\r\n this.b = parseInt(hex.substring(5, 7), 16) / 255;\r\n if (hex.length === 9) {\r\n this.a = parseInt(hex.substring(7, 9), 16) / 255;\r\n }\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Computes a new Color4 converted from the current one to linear space\r\n * @param exact defines if the conversion will be done in an exact way which is slower but more accurate (default is false)\r\n * @returns a new Color4 object\r\n */\r\n public toLinearSpace(exact = false): Color4 {\r\n const convertedColor = new Color4();\r\n this.toLinearSpaceToRef(convertedColor, exact);\r\n return convertedColor;\r\n }\r\n\r\n /**\r\n * Converts the Color4 values to linear space and stores the result in \"convertedColor\"\r\n * @param convertedColor defines the Color4 object where to store the linear space version\r\n * @param exact defines if the conversion will be done in an exact way which is slower but more accurate (default is false)\r\n * @returns the unmodified Color4\r\n */\r\n public toLinearSpaceToRef(convertedColor: IColor4Like, exact = false): this {\r\n if (exact) {\r\n convertedColor.r = colorChannelToLinearSpaceExact(this.r);\r\n convertedColor.g = colorChannelToLinearSpaceExact(this.g);\r\n convertedColor.b = colorChannelToLinearSpaceExact(this.b);\r\n } else {\r\n convertedColor.r = colorChannelToLinearSpace(this.r);\r\n convertedColor.g = colorChannelToLinearSpace(this.g);\r\n convertedColor.b = colorChannelToLinearSpace(this.b);\r\n }\r\n convertedColor.a = this.a;\r\n return this;\r\n }\r\n\r\n /**\r\n * Computes a new Color4 converted from the current one to gamma space\r\n * @param exact defines if the conversion will be done in an exact way which is slower but more accurate (default is false)\r\n * @returns a new Color4 object\r\n */\r\n public toGammaSpace(exact = false): Color4 {\r\n const convertedColor = new Color4();\r\n this.toGammaSpaceToRef(convertedColor, exact);\r\n return convertedColor;\r\n }\r\n\r\n /**\r\n * Converts the Color4 values to gamma space and stores the result in \"convertedColor\"\r\n * @param convertedColor defines the Color4 object where to store the gamma space version\r\n * @param exact defines if the conversion will be done in an exact way which is slower but more accurate (default is false)\r\n * @returns the unmodified Color4\r\n */\r\n public toGammaSpaceToRef(convertedColor: IColor4Like, exact = false): this {\r\n if (exact) {\r\n convertedColor.r = colorChannelToGammaSpaceExact(this.r);\r\n convertedColor.g = colorChannelToGammaSpaceExact(this.g);\r\n convertedColor.b = colorChannelToGammaSpaceExact(this.b);\r\n } else {\r\n convertedColor.r = colorChannelToGammaSpace(this.r);\r\n convertedColor.g = colorChannelToGammaSpace(this.g);\r\n convertedColor.b = colorChannelToGammaSpace(this.b);\r\n }\r\n convertedColor.a = this.a;\r\n return this;\r\n }\r\n\r\n // Statics\r\n\r\n /**\r\n * Creates a new Color4 from the string containing valid hexadecimal values.\r\n *\r\n * A valid hex string is either in the format #RRGGBB or #RRGGBBAA.\r\n *\r\n * When a hex string without alpha is passed, the resulting Color4 has\r\n * its alpha value set to 1.0.\r\n *\r\n * An invalid string results in a Color with all its channels set to 0.0,\r\n * i.e. \"transparent black\".\r\n *\r\n * @param hex defines a string containing valid hexadecimal values\r\n * @returns a new Color4 object\r\n */\r\n public static FromHexString(hex: string): Color4 {\r\n if (hex.substring(0, 1) !== \"#\" || (hex.length !== 9 && hex.length !== 7)) {\r\n return new Color4(0.0, 0.0, 0.0, 0.0);\r\n }\r\n\r\n return new Color4(0.0, 0.0, 0.0, 1.0).fromHexString(hex);\r\n }\r\n\r\n /**\r\n * Creates a new Color4 object set with the linearly interpolated values of \"amount\" between the left Color4 object and the right Color4 object\r\n * @param left defines the start value\r\n * @param right defines the end value\r\n * @param amount defines the gradient factor\r\n * @returns a new Color4 object\r\n */\r\n public static Lerp(left: DeepImmutable, right: DeepImmutable, amount: number): Color4 {\r\n return Color4.LerpToRef(left, right, amount, new Color4());\r\n }\r\n\r\n /**\r\n * Set the given \"result\" with the linearly interpolated values of \"amount\" between the left Color4 object and the right Color4 object\r\n * @param left defines the start value\r\n * @param right defines the end value\r\n * @param amount defines the gradient factor\r\n * @param result defines the Color4 object where to store data\r\n * @returns the updated result\r\n */\r\n public static LerpToRef(left: DeepImmutable, right: DeepImmutable, amount: number, result: T): T {\r\n result.r = left.r + (right.r - left.r) * amount;\r\n result.g = left.g + (right.g - left.g) * amount;\r\n result.b = left.b + (right.b - left.b) * amount;\r\n result.a = left.a + (right.a - left.a) * amount;\r\n return result;\r\n }\r\n\r\n /**\r\n * Interpolate between two Color4 using Hermite interpolation\r\n * @param value1 defines first Color4\r\n * @param tangent1 defines the incoming tangent\r\n * @param value2 defines second Color4\r\n * @param tangent2 defines the outgoing tangent\r\n * @param amount defines the target Color4\r\n * @returns the new interpolated Color4\r\n */\r\n public static Hermite(\r\n value1: DeepImmutable,\r\n tangent1: DeepImmutable,\r\n value2: DeepImmutable,\r\n tangent2: DeepImmutable,\r\n amount: number\r\n ): Color4 {\r\n const squared = amount * amount;\r\n const cubed = amount * squared;\r\n const part1 = 2.0 * cubed - 3.0 * squared + 1.0;\r\n const part2 = -2.0 * cubed + 3.0 * squared;\r\n const part3 = cubed - 2.0 * squared + amount;\r\n const part4 = cubed - squared;\r\n\r\n const r = value1.r * part1 + value2.r * part2 + tangent1.r * part3 + tangent2.r * part4;\r\n const g = value1.g * part1 + value2.g * part2 + tangent1.g * part3 + tangent2.g * part4;\r\n const b = value1.b * part1 + value2.b * part2 + tangent1.b * part3 + tangent2.b * part4;\r\n const a = value1.a * part1 + value2.a * part2 + tangent1.a * part3 + tangent2.a * part4;\r\n return new Color4(r, g, b, a);\r\n }\r\n\r\n /**\r\n * Returns a new Color4 which is the 1st derivative of the Hermite spline defined by the colors \"value1\", \"value2\", \"tangent1\", \"tangent2\".\r\n * @param value1 defines the first control point\r\n * @param tangent1 defines the first tangent\r\n * @param value2 defines the second control point\r\n * @param tangent2 defines the second tangent\r\n * @param time define where the derivative must be done\r\n * @returns 1st derivative\r\n */\r\n public static Hermite1stDerivative(\r\n value1: DeepImmutable,\r\n tangent1: DeepImmutable,\r\n value2: DeepImmutable,\r\n tangent2: DeepImmutable,\r\n time: number\r\n ): Color4 {\r\n const result = new Color4();\r\n\r\n this.Hermite1stDerivativeToRef(value1, tangent1, value2, tangent2, time, result);\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Update a Color4 with the 1st derivative of the Hermite spline defined by the colors \"value1\", \"value2\", \"tangent1\", \"tangent2\".\r\n * @param value1 defines the first control point\r\n * @param tangent1 defines the first tangent\r\n * @param value2 defines the second control point\r\n * @param tangent2 defines the second tangent\r\n * @param time define where the derivative must be done\r\n * @param result define where to store the derivative\r\n */\r\n public static Hermite1stDerivativeToRef(\r\n value1: DeepImmutable,\r\n tangent1: DeepImmutable,\r\n value2: DeepImmutable,\r\n tangent2: DeepImmutable,\r\n time: number,\r\n result: IColor4Like\r\n ) {\r\n const t2 = time * time;\r\n\r\n result.r = (t2 - time) * 6 * value1.r + (3 * t2 - 4 * time + 1) * tangent1.r + (-t2 + time) * 6 * value2.r + (3 * t2 - 2 * time) * tangent2.r;\r\n result.g = (t2 - time) * 6 * value1.g + (3 * t2 - 4 * time + 1) * tangent1.g + (-t2 + time) * 6 * value2.g + (3 * t2 - 2 * time) * tangent2.g;\r\n result.b = (t2 - time) * 6 * value1.b + (3 * t2 - 4 * time + 1) * tangent1.b + (-t2 + time) * 6 * value2.b + (3 * t2 - 2 * time) * tangent2.b;\r\n result.a = (t2 - time) * 6 * value1.a + (3 * t2 - 4 * time + 1) * tangent1.a + (-t2 + time) * 6 * value2.a + (3 * t2 - 2 * time) * tangent2.a;\r\n }\r\n\r\n /**\r\n * Creates a new Color4 from a Color3 and an alpha value\r\n * @param color3 defines the source Color3 to read from\r\n * @param alpha defines the alpha component (1.0 by default)\r\n * @returns a new Color4 object\r\n */\r\n public static FromColor3(color3: DeepImmutable, alpha: number = 1.0): Color4 {\r\n return new Color4(color3.r, color3.g, color3.b, alpha);\r\n }\r\n\r\n /**\r\n * Creates a new Color4 from the starting index element of the given array\r\n * @param array defines the source array to read from\r\n * @param offset defines the offset in the source array\r\n * @returns a new Color4 object\r\n */\r\n public static FromArray(array: DeepImmutable>, offset: number = 0): Color4 {\r\n return new Color4(array[offset], array[offset + 1], array[offset + 2], array[offset + 3]);\r\n }\r\n\r\n /**\r\n * Creates a new Color4 from the starting index element of the given array\r\n * @param array defines the source array to read from\r\n * @param offset defines the offset in the source array\r\n * @param result defines the target Color4 object\r\n */\r\n public static FromArrayToRef(array: DeepImmutable>, offset: number = 0, result: Color4) {\r\n result.r = array[offset];\r\n result.g = array[offset + 1];\r\n result.b = array[offset + 2];\r\n result.a = array[offset + 3];\r\n }\r\n\r\n /**\r\n * Creates a new Color3 from integer values (less than 256)\r\n * @param r defines the red component to read from (value between 0 and 255)\r\n * @param g defines the green component to read from (value between 0 and 255)\r\n * @param b defines the blue component to read from (value between 0 and 255)\r\n * @param a defines the alpha component to read from (value between 0 and 255)\r\n * @returns a new Color3 object\r\n */\r\n public static FromInts(r: number, g: number, b: number, a: number): Color4 {\r\n return new Color4(r / 255.0, g / 255.0, b / 255.0, a / 255.0);\r\n }\r\n\r\n /**\r\n * Check the content of a given array and convert it to an array containing RGBA data\r\n * If the original array was already containing count * 4 values then it is returned directly\r\n * @param colors defines the array to check\r\n * @param count defines the number of RGBA data to expect\r\n * @returns an array containing count * 4 values (RGBA)\r\n */\r\n public static CheckColors4(colors: number[], count: number): number[] {\r\n // Check if color3 was used\r\n if (colors.length === count * 3) {\r\n const colors4 = [];\r\n for (let index = 0; index < colors.length; index += 3) {\r\n const newIndex = (index / 3) * 4;\r\n colors4[newIndex] = colors[index];\r\n colors4[newIndex + 1] = colors[index + 1];\r\n colors4[newIndex + 2] = colors[index + 2];\r\n colors4[newIndex + 3] = 1.0;\r\n }\r\n\r\n return colors4;\r\n }\r\n\r\n return colors;\r\n }\r\n}\r\nObject.defineProperties(Color4.prototype, {\r\n dimension: { value: [4] },\r\n rank: { value: 1 },\r\n});\r\n\r\n/**\r\n * @internal\r\n */\r\nexport class TmpColors {\r\n public static Color3: Color3[] = BuildArray(3, Color3.Black);\r\n public static Color4: Color4[] = BuildArray(3, () => new Color4(0, 0, 0, 0));\r\n}\r\n\r\nRegisterClass(\"BABYLON.Color3\", Color3);\r\nRegisterClass(\"BABYLON.Color4\", Color4);\r\n","/**\r\n * Constant used to convert a value to gamma space\r\n * @ignorenaming\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport const ToGammaSpace = 1 / 2.2;\r\n\r\n/**\r\n * Constant used to convert a value to linear space\r\n * @ignorenaming\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport const ToLinearSpace = 2.2;\r\n\r\n/**\r\n * Constant Golden Ratio value in Babylon.js\r\n * @ignorenaming\r\n */\r\nexport const PHI = (1 + Math.sqrt(5)) / 2;\r\n\r\n/**\r\n * Constant used to define the minimal number value in Babylon.js\r\n * @ignorenaming\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport const Epsilon = 0.001;\r\n","import type { Matrix, Vector3 } from \"./math.vector\";\r\nimport type { DeepImmutable } from \"../types\";\r\nimport { Plane } from \"./math.plane\";\r\n\r\n/**\r\n * Represents a camera frustum\r\n */\r\nexport class Frustum {\r\n /**\r\n * Gets the planes representing the frustum\r\n * @param transform matrix to be applied to the returned planes\r\n * @returns a new array of 6 Frustum planes computed by the given transformation matrix.\r\n */\r\n public static GetPlanes(transform: DeepImmutable): Plane[] {\r\n const frustumPlanes = [];\r\n for (let index = 0; index < 6; index++) {\r\n frustumPlanes.push(new Plane(0.0, 0.0, 0.0, 0.0));\r\n }\r\n Frustum.GetPlanesToRef(transform, frustumPlanes);\r\n return frustumPlanes;\r\n }\r\n\r\n /**\r\n * Gets the near frustum plane transformed by the transform matrix\r\n * @param transform transformation matrix to be applied to the resulting frustum plane\r\n * @param frustumPlane the resulting frustum plane\r\n */\r\n public static GetNearPlaneToRef(transform: DeepImmutable, frustumPlane: Plane): void {\r\n const m = transform.m;\r\n frustumPlane.normal.x = m[3] + m[2];\r\n frustumPlane.normal.y = m[7] + m[6];\r\n frustumPlane.normal.z = m[11] + m[10];\r\n frustumPlane.d = m[15] + m[14];\r\n frustumPlane.normalize();\r\n }\r\n\r\n /**\r\n * Gets the far frustum plane transformed by the transform matrix\r\n * @param transform transformation matrix to be applied to the resulting frustum plane\r\n * @param frustumPlane the resulting frustum plane\r\n */\r\n public static GetFarPlaneToRef(transform: DeepImmutable, frustumPlane: Plane): void {\r\n const m = transform.m;\r\n frustumPlane.normal.x = m[3] - m[2];\r\n frustumPlane.normal.y = m[7] - m[6];\r\n frustumPlane.normal.z = m[11] - m[10];\r\n frustumPlane.d = m[15] - m[14];\r\n frustumPlane.normalize();\r\n }\r\n\r\n /**\r\n * Gets the left frustum plane transformed by the transform matrix\r\n * @param transform transformation matrix to be applied to the resulting frustum plane\r\n * @param frustumPlane the resulting frustum plane\r\n */\r\n public static GetLeftPlaneToRef(transform: DeepImmutable, frustumPlane: Plane): void {\r\n const m = transform.m;\r\n frustumPlane.normal.x = m[3] + m[0];\r\n frustumPlane.normal.y = m[7] + m[4];\r\n frustumPlane.normal.z = m[11] + m[8];\r\n frustumPlane.d = m[15] + m[12];\r\n frustumPlane.normalize();\r\n }\r\n\r\n /**\r\n * Gets the right frustum plane transformed by the transform matrix\r\n * @param transform transformation matrix to be applied to the resulting frustum plane\r\n * @param frustumPlane the resulting frustum plane\r\n */\r\n public static GetRightPlaneToRef(transform: DeepImmutable, frustumPlane: Plane): void {\r\n const m = transform.m;\r\n frustumPlane.normal.x = m[3] - m[0];\r\n frustumPlane.normal.y = m[7] - m[4];\r\n frustumPlane.normal.z = m[11] - m[8];\r\n frustumPlane.d = m[15] - m[12];\r\n frustumPlane.normalize();\r\n }\r\n\r\n /**\r\n * Gets the top frustum plane transformed by the transform matrix\r\n * @param transform transformation matrix to be applied to the resulting frustum plane\r\n * @param frustumPlane the resulting frustum plane\r\n */\r\n public static GetTopPlaneToRef(transform: DeepImmutable, frustumPlane: Plane): void {\r\n const m = transform.m;\r\n frustumPlane.normal.x = m[3] - m[1];\r\n frustumPlane.normal.y = m[7] - m[5];\r\n frustumPlane.normal.z = m[11] - m[9];\r\n frustumPlane.d = m[15] - m[13];\r\n frustumPlane.normalize();\r\n }\r\n\r\n /**\r\n * Gets the bottom frustum plane transformed by the transform matrix\r\n * @param transform transformation matrix to be applied to the resulting frustum plane\r\n * @param frustumPlane the resulting frustum plane\r\n */\r\n public static GetBottomPlaneToRef(transform: DeepImmutable, frustumPlane: Plane): void {\r\n const m = transform.m;\r\n frustumPlane.normal.x = m[3] + m[1];\r\n frustumPlane.normal.y = m[7] + m[5];\r\n frustumPlane.normal.z = m[11] + m[9];\r\n frustumPlane.d = m[15] + m[13];\r\n frustumPlane.normalize();\r\n }\r\n\r\n /**\r\n * Sets the given array \"frustumPlanes\" with the 6 Frustum planes computed by the given transformation matrix.\r\n * @param transform transformation matrix to be applied to the resulting frustum planes\r\n * @param frustumPlanes the resulting frustum planes\r\n */\r\n public static GetPlanesToRef(transform: DeepImmutable, frustumPlanes: Plane[]): void {\r\n // Near\r\n Frustum.GetNearPlaneToRef(transform, frustumPlanes[0]);\r\n\r\n // Far\r\n Frustum.GetFarPlaneToRef(transform, frustumPlanes[1]);\r\n\r\n // Left\r\n Frustum.GetLeftPlaneToRef(transform, frustumPlanes[2]);\r\n\r\n // Right\r\n Frustum.GetRightPlaneToRef(transform, frustumPlanes[3]);\r\n\r\n // Top\r\n Frustum.GetTopPlaneToRef(transform, frustumPlanes[4]);\r\n\r\n // Bottom\r\n Frustum.GetBottomPlaneToRef(transform, frustumPlanes[5]);\r\n }\r\n\r\n /**\r\n * Tests if a point is located between the frustum planes.\r\n * @param point defines the point to test\r\n * @param frustumPlanes defines the frustum planes to test\r\n * @returns true if the point is located between the frustum planes\r\n */\r\n public static IsPointInFrustum(point: Vector3, frustumPlanes: Array>): boolean {\r\n for (let i = 0; i < 6; i++) {\r\n if (frustumPlanes[i].dotCoordinate(point) < 0) {\r\n return false;\r\n }\r\n }\r\n return true;\r\n }\r\n}\r\n","import type { DeepImmutable } from \"../types\";\r\nimport { Vector3, Matrix } from \"./math.vector\";\r\nimport type { IPlaneLike } from \"./math.like\";\r\n\r\n/**\r\n * Represents a plane by the equation ax + by + cz + d = 0\r\n */\r\nexport class Plane implements IPlaneLike {\r\n private static _TmpMatrix = Matrix.Identity();\r\n\r\n /**\r\n * Normal of the plane (a,b,c)\r\n */\r\n public normal: Vector3;\r\n /**\r\n * d component of the plane\r\n */\r\n public d: number;\r\n /**\r\n * Creates a Plane object according to the given floats a, b, c, d and the plane equation : ax + by + cz + d = 0\r\n * @param a a component of the plane\r\n * @param b b component of the plane\r\n * @param c c component of the plane\r\n * @param d d component of the plane\r\n */\r\n constructor(a: number, b: number, c: number, d: number) {\r\n this.normal = new Vector3(a, b, c);\r\n this.d = d;\r\n }\r\n\r\n /**\r\n * @returns the plane coordinates as a new array of 4 elements [a, b, c, d].\r\n */\r\n public asArray(): number[] {\r\n return [this.normal.x, this.normal.y, this.normal.z, this.d];\r\n }\r\n\r\n // Methods\r\n /**\r\n * @returns a new plane copied from the current Plane.\r\n */\r\n public clone(): Plane {\r\n return new Plane(this.normal.x, this.normal.y, this.normal.z, this.d);\r\n }\r\n /**\r\n * @returns the string \"Plane\".\r\n */\r\n public getClassName(): string {\r\n return \"Plane\";\r\n }\r\n /**\r\n * @returns the Plane hash code.\r\n */\r\n public getHashCode(): number {\r\n let hash = this.normal.getHashCode();\r\n hash = (hash * 397) ^ (this.d | 0);\r\n return hash;\r\n }\r\n /**\r\n * Normalize the current Plane in place.\r\n * @returns the updated Plane.\r\n */\r\n public normalize(): Plane {\r\n const norm = Math.sqrt(this.normal.x * this.normal.x + this.normal.y * this.normal.y + this.normal.z * this.normal.z);\r\n let magnitude = 0.0;\r\n\r\n if (norm !== 0) {\r\n magnitude = 1.0 / norm;\r\n }\r\n this.normal.x *= magnitude;\r\n this.normal.y *= magnitude;\r\n this.normal.z *= magnitude;\r\n this.d *= magnitude;\r\n return this;\r\n }\r\n /**\r\n * Applies a transformation the plane and returns the result\r\n * @param transformation the transformation matrix to be applied to the plane\r\n * @returns a new Plane as the result of the transformation of the current Plane by the given matrix.\r\n */\r\n public transform(transformation: DeepImmutable): Plane {\r\n const invertedMatrix = Plane._TmpMatrix;\r\n transformation.invertToRef(invertedMatrix);\r\n const m = invertedMatrix.m;\r\n const x = this.normal.x;\r\n const y = this.normal.y;\r\n const z = this.normal.z;\r\n const d = this.d;\r\n\r\n const normalX = x * m[0] + y * m[1] + z * m[2] + d * m[3];\r\n const normalY = x * m[4] + y * m[5] + z * m[6] + d * m[7];\r\n const normalZ = x * m[8] + y * m[9] + z * m[10] + d * m[11];\r\n const finalD = x * m[12] + y * m[13] + z * m[14] + d * m[15];\r\n\r\n return new Plane(normalX, normalY, normalZ, finalD);\r\n }\r\n\r\n /**\r\n * Compute the dot product between the point and the plane normal\r\n * @param point point to calculate the dot product with\r\n * @returns the dot product (float) of the point coordinates and the plane normal.\r\n */\r\n public dotCoordinate(point: DeepImmutable): number {\r\n return this.normal.x * point.x + this.normal.y * point.y + this.normal.z * point.z + this.d;\r\n }\r\n\r\n /**\r\n * Updates the current Plane from the plane defined by the three given points.\r\n * @param point1 one of the points used to construct the plane\r\n * @param point2 one of the points used to construct the plane\r\n * @param point3 one of the points used to construct the plane\r\n * @returns the updated Plane.\r\n */\r\n public copyFromPoints(point1: DeepImmutable, point2: DeepImmutable, point3: DeepImmutable): Plane {\r\n const x1 = point2.x - point1.x;\r\n const y1 = point2.y - point1.y;\r\n const z1 = point2.z - point1.z;\r\n const x2 = point3.x - point1.x;\r\n const y2 = point3.y - point1.y;\r\n const z2 = point3.z - point1.z;\r\n const yz = y1 * z2 - z1 * y2;\r\n const xz = z1 * x2 - x1 * z2;\r\n const xy = x1 * y2 - y1 * x2;\r\n const pyth = Math.sqrt(yz * yz + xz * xz + xy * xy);\r\n let invPyth;\r\n\r\n if (pyth !== 0) {\r\n invPyth = 1.0 / pyth;\r\n } else {\r\n invPyth = 0.0;\r\n }\r\n\r\n this.normal.x = yz * invPyth;\r\n this.normal.y = xz * invPyth;\r\n this.normal.z = xy * invPyth;\r\n this.d = -(this.normal.x * point1.x + this.normal.y * point1.y + this.normal.z * point1.z);\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Checks if the plane is facing a given direction (meaning if the plane's normal is pointing in the opposite direction of the given vector).\r\n * Note that for this function to work as expected you should make sure that:\r\n * - direction and the plane normal are normalized\r\n * - epsilon is a number just bigger than -1, something like -0.99 for eg\r\n * @param direction the direction to check if the plane is facing\r\n * @param epsilon value the dot product is compared against (returns true if dot <= epsilon)\r\n * @returns True if the plane is facing the given direction\r\n */\r\n public isFrontFacingTo(direction: DeepImmutable, epsilon: number): boolean {\r\n const dot = Vector3.Dot(this.normal, direction);\r\n return dot <= epsilon;\r\n }\r\n\r\n /**\r\n * Calculates the distance to a point\r\n * @param point point to calculate distance to\r\n * @returns the signed distance (float) from the given point to the Plane.\r\n */\r\n public signedDistanceTo(point: DeepImmutable): number {\r\n return Vector3.Dot(point, this.normal) + this.d;\r\n }\r\n\r\n // Statics\r\n /**\r\n * Creates a plane from an array\r\n * @param array the array to create a plane from\r\n * @returns a new Plane from the given array.\r\n */\r\n static FromArray(array: DeepImmutable>): Plane {\r\n return new Plane(array[0], array[1], array[2], array[3]);\r\n }\r\n /**\r\n * Creates a plane from three points\r\n * @param point1 point used to create the plane\r\n * @param point2 point used to create the plane\r\n * @param point3 point used to create the plane\r\n * @returns a new Plane defined by the three given points.\r\n */\r\n static FromPoints(point1: DeepImmutable, point2: DeepImmutable, point3: DeepImmutable): Plane {\r\n const result = new Plane(0.0, 0.0, 0.0, 0.0);\r\n result.copyFromPoints(point1, point2, point3);\r\n return result;\r\n }\r\n /**\r\n * Creates a plane from an origin point and a normal\r\n * @param origin origin of the plane to be constructed\r\n * @param normal normal of the plane to be constructed\r\n * @returns a new Plane the normal vector to this plane at the given origin point.\r\n */\r\n static FromPositionAndNormal(origin: DeepImmutable, normal: Vector3): Plane {\r\n const plane = new Plane(0.0, 0.0, 0.0, 0.0);\r\n return this.FromPositionAndNormalToRef(origin, normal, plane);\r\n }\r\n\r\n /**\r\n * Updates the given Plane \"result\" from an origin point and a normal.\r\n * @param origin origin of the plane to be constructed\r\n * @param normal the normalized normals of the plane to be constructed\r\n * @param result defines the Plane where to store the result\r\n * @returns result input\r\n */\r\n static FromPositionAndNormalToRef(origin: DeepImmutable, normal: DeepImmutable, result: T): T {\r\n result.normal.copyFrom(normal);\r\n result.normal.normalize();\r\n result.d = -origin.dot(result.normal);\r\n return result;\r\n }\r\n\r\n /**\r\n * Calculates the distance from a plane and a point\r\n * @param origin origin of the plane to be constructed\r\n * @param normal normal of the plane to be constructed\r\n * @param point point to calculate distance to\r\n * @returns the signed distance between the plane defined by the normal vector at the \"origin\"\" point and the given other point.\r\n */\r\n static SignedDistanceToPlaneFromPositionAndNormal(origin: DeepImmutable, normal: DeepImmutable, point: DeepImmutable): number {\r\n const d = -(normal.x * origin.x + normal.y * origin.y + normal.z * origin.z);\r\n return Vector3.Dot(point, normal) + d;\r\n }\r\n}\r\n","/**\r\n * Extract int value\r\n * @param value number value\r\n * @returns int value\r\n */\r\nexport function ExtractAsInt(value: number) {\r\n return parseInt(value.toString().replace(/\\W/g, \"\"));\r\n}\r\n\r\n/**\r\n * Boolean : true if the absolute difference between a and b is lower than epsilon (default = 1.401298E-45)\r\n * @param a number\r\n * @param b number\r\n * @param epsilon (default = 1.401298E-45)\r\n * @returns true if the absolute difference between a and b is lower than epsilon (default = 1.401298E-45)\r\n */\r\nexport function WithinEpsilon(a: number, b: number, epsilon: number = 1.401298e-45): boolean {\r\n return Math.abs(a - b) <= epsilon;\r\n}\r\n\r\n/**\r\n * Returns a random float number between and min and max values\r\n * @param min min value of random\r\n * @param max max value of random\r\n * @returns random value\r\n */\r\nexport function RandomRange(min: number, max: number): number {\r\n if (min === max) {\r\n return min;\r\n }\r\n return Math.random() * (max - min) + min;\r\n}\r\n\r\n/**\r\n * Creates a new scalar with values linearly interpolated of \"amount\" between the start scalar and the end scalar.\r\n * @param start start value\r\n * @param end target value\r\n * @param amount amount to lerp between\r\n * @returns the lerped value\r\n */\r\nexport function Lerp(start: number, end: number, amount: number): number {\r\n return start + (end - start) * amount;\r\n}\r\n\r\n/**\r\n * Same as Lerp but makes sure the values interpolate correctly when they wrap around 360 degrees.\r\n * The parameter t is clamped to the range [0, 1]. Variables a and b are assumed to be in degrees.\r\n * @param start start value\r\n * @param end target value\r\n * @param amount amount to lerp between\r\n * @returns the lerped value\r\n */\r\nexport function LerpAngle(start: number, end: number, amount: number): number {\r\n let num: number = Repeat(end - start, 360.0);\r\n if (num > 180.0) {\r\n num -= 360.0;\r\n }\r\n return start + num * Clamp(amount);\r\n}\r\n\r\n/**\r\n * Calculates the linear parameter t that produces the interpolant value within the range [a, b].\r\n * @param a start value\r\n * @param b target value\r\n * @param value value between a and b\r\n * @returns the inverseLerp value\r\n */\r\nexport function InverseLerp(a: number, b: number, value: number): number {\r\n let result: number = 0;\r\n if (a != b) {\r\n result = Clamp((value - a) / (b - a));\r\n } else {\r\n result = 0.0;\r\n }\r\n return result;\r\n}\r\n\r\n/**\r\n * Returns a new scalar located for \"amount\" (float) on the Hermite spline defined by the scalars \"value1\", \"value3\", \"tangent1\", \"tangent2\".\r\n * @see http://mathworld.wolfram.com/HermitePolynomial.html\r\n * @param value1 defines the first control point\r\n * @param tangent1 defines the first tangent\r\n * @param value2 defines the second control point\r\n * @param tangent2 defines the second tangent\r\n * @param amount defines the amount on the interpolation spline (between 0 and 1)\r\n * @returns hermite result\r\n */\r\nexport function Hermite(value1: number, tangent1: number, value2: number, tangent2: number, amount: number): number {\r\n const squared = amount * amount;\r\n const cubed = amount * squared;\r\n const part1 = 2.0 * cubed - 3.0 * squared + 1.0;\r\n const part2 = -2.0 * cubed + 3.0 * squared;\r\n const part3 = cubed - 2.0 * squared + amount;\r\n const part4 = cubed - squared;\r\n\r\n return value1 * part1 + value2 * part2 + tangent1 * part3 + tangent2 * part4;\r\n}\r\n\r\n/**\r\n * Returns a new scalar which is the 1st derivative of the Hermite spline defined by the scalars \"value1\", \"value2\", \"tangent1\", \"tangent2\".\r\n * @param value1 defines the first control point\r\n * @param tangent1 defines the first tangent\r\n * @param value2 defines the second control point\r\n * @param tangent2 defines the second tangent\r\n * @param time define where the derivative must be done\r\n * @returns 1st derivative\r\n */\r\nexport function Hermite1stDerivative(value1: number, tangent1: number, value2: number, tangent2: number, time: number): number {\r\n const t2 = time * time;\r\n return (t2 - time) * 6 * value1 + (3 * t2 - 4 * time + 1) * tangent1 + (-t2 + time) * 6 * value2 + (3 * t2 - 2 * time) * tangent2;\r\n}\r\n\r\n/**\r\n * Returns the value itself if it's between min and max.\r\n * Returns min if the value is lower than min.\r\n * Returns max if the value is greater than max.\r\n * @param value the value to clmap\r\n * @param min the min value to clamp to (default: 0)\r\n * @param max the max value to clamp to (default: 1)\r\n * @returns the clamped value\r\n */\r\nexport function Clamp(value: number, min = 0, max = 1): number {\r\n return Math.min(max, Math.max(min, value));\r\n}\r\n\r\n/**\r\n * Returns the angle converted to equivalent value between -Math.PI and Math.PI radians.\r\n * @param angle The angle to normalize in radian.\r\n * @returns The converted angle.\r\n */\r\nexport function NormalizeRadians(angle: number): number {\r\n // More precise but slower version kept for reference.\r\n // angle = angle % Tools.TwoPi;\r\n // angle = (angle + Tools.TwoPi) % Tools.TwoPi;\r\n\r\n //if (angle > Math.PI) {\r\n //\tangle -= Tools.TwoPi;\r\n //}\r\n\r\n angle -= Math.PI * 2 * Math.floor((angle + Math.PI) / (Math.PI * 2));\r\n\r\n return angle;\r\n}\r\n\r\n/**\r\n * Returns a string : the upper case translation of the number i to hexadecimal.\r\n * @param i number\r\n * @returns the upper case translation of the number i to hexadecimal.\r\n */\r\nexport function ToHex(i: number): string {\r\n const str = i.toString(16);\r\n\r\n if (i <= 15) {\r\n return (\"0\" + str).toUpperCase();\r\n }\r\n\r\n return str.toUpperCase();\r\n}\r\n\r\n/**\r\n * the floor part of a log2 value.\r\n * @param value the value to compute log2 of\r\n * @returns the log2 of value.\r\n */\r\nexport function ILog2(value: number): number {\r\n if (Math.log2) {\r\n return Math.floor(Math.log2(value));\r\n }\r\n\r\n if (value < 0) {\r\n return NaN;\r\n } else if (value === 0) {\r\n return -Infinity;\r\n }\r\n\r\n let n = 0;\r\n if (value < 1) {\r\n while (value < 1) {\r\n n++;\r\n value = value * 2;\r\n }\r\n n = -n;\r\n } else if (value > 1) {\r\n while (value > 1) {\r\n n++;\r\n value = Math.floor(value / 2);\r\n }\r\n }\r\n\r\n return n;\r\n}\r\n\r\n/**\r\n * Loops the value, so that it is never larger than length and never smaller than 0.\r\n *\r\n * This is similar to the modulo operator but it works with floating point numbers.\r\n * For example, using 3.0 for t and 2.5 for length, the result would be 0.5.\r\n * With t = 5 and length = 2.5, the result would be 0.0.\r\n * Note, however, that the behaviour is not defined for negative numbers as it is for the modulo operator\r\n * @param value the value\r\n * @param length the length\r\n * @returns the looped value\r\n */\r\nexport function Repeat(value: number, length: number): number {\r\n return value - Math.floor(value / length) * length;\r\n}\r\n\r\n/**\r\n * Normalize the value between 0.0 and 1.0 using min and max values\r\n * @param value value to normalize\r\n * @param min max to normalize between\r\n * @param max min to normalize between\r\n * @returns the normalized value\r\n */\r\nexport function Normalize(value: number, min: number, max: number): number {\r\n return (value - min) / (max - min);\r\n}\r\n\r\n/**\r\n * Denormalize the value from 0.0 and 1.0 using min and max values\r\n * @param normalized value to denormalize\r\n * @param min max to denormalize between\r\n * @param max min to denormalize between\r\n * @returns the denormalized value\r\n */\r\nexport function Denormalize(normalized: number, min: number, max: number): number {\r\n return normalized * (max - min) + min;\r\n}\r\n\r\n/**\r\n * Calculates the shortest difference between two given angles given in degrees.\r\n * @param current current angle in degrees\r\n * @param target target angle in degrees\r\n * @returns the delta\r\n */\r\nexport function DeltaAngle(current: number, target: number): number {\r\n let num: number = Repeat(target - current, 360.0);\r\n if (num > 180.0) {\r\n num -= 360.0;\r\n }\r\n return num;\r\n}\r\n\r\n/**\r\n * PingPongs the value t, so that it is never larger than length and never smaller than 0.\r\n * @param tx value\r\n * @param length length\r\n * @returns The returned value will move back and forth between 0 and length\r\n */\r\nexport function PingPong(tx: number, length: number): number {\r\n const t: number = Repeat(tx, length * 2.0);\r\n return length - Math.abs(t - length);\r\n}\r\n\r\n/**\r\n * Interpolates between min and max with smoothing at the limits.\r\n *\r\n * This function interpolates between min and max in a similar way to Lerp. However, the interpolation will gradually speed up\r\n * from the start and slow down toward the end. This is useful for creating natural-looking animation, fading and other transitions.\r\n * @param from from\r\n * @param to to\r\n * @param tx value\r\n * @returns the smooth stepped value\r\n */\r\nexport function SmoothStep(from: number, to: number, tx: number): number {\r\n let t: number = Clamp(tx);\r\n t = -2.0 * t * t * t + 3.0 * t * t;\r\n return to * t + from * (1.0 - t);\r\n}\r\n\r\n/**\r\n * Moves a value current towards target.\r\n *\r\n * This is essentially the same as Mathf.Lerp but instead the function will ensure that the speed never exceeds maxDelta.\r\n * Negative values of maxDelta pushes the value away from target.\r\n * @param current current value\r\n * @param target target value\r\n * @param maxDelta max distance to move\r\n * @returns resulting value\r\n */\r\nexport function MoveTowards(current: number, target: number, maxDelta: number): number {\r\n let result: number = 0;\r\n if (Math.abs(target - current) <= maxDelta) {\r\n result = target;\r\n } else {\r\n result = current + Math.sign(target - current) * maxDelta;\r\n }\r\n return result;\r\n}\r\n\r\n/**\r\n * Same as MoveTowards but makes sure the values interpolate correctly when they wrap around 360 degrees.\r\n *\r\n * Variables current and target are assumed to be in degrees. For optimization reasons, negative values of maxDelta\r\n * are not supported and may cause oscillation. To push current away from a target angle, add 180 to that angle instead.\r\n * @param current current value\r\n * @param target target value\r\n * @param maxDelta max distance to move\r\n * @returns resulting angle\r\n */\r\nexport function MoveTowardsAngle(current: number, target: number, maxDelta: number): number {\r\n const num: number = DeltaAngle(current, target);\r\n let result: number = 0;\r\n if (-maxDelta < num && num < maxDelta) {\r\n result = target;\r\n } else {\r\n target = current + num;\r\n result = MoveTowards(current, target, maxDelta);\r\n }\r\n return result;\r\n}\r\n\r\n/**\r\n * This function returns percentage of a number in a given range.\r\n *\r\n * RangeToPercent(40,20,60) will return 0.5 (50%)\r\n * RangeToPercent(34,0,100) will return 0.34 (34%)\r\n * @param number to convert to percentage\r\n * @param min min range\r\n * @param max max range\r\n * @returns the percentage\r\n */\r\nexport function RangeToPercent(number: number, min: number, max: number): number {\r\n return (number - min) / (max - min);\r\n}\r\n\r\n/**\r\n * This function returns number that corresponds to the percentage in a given range.\r\n *\r\n * PercentToRange(0.34,0,100) will return 34.\r\n * @param percent to convert to number\r\n * @param min min range\r\n * @param max max range\r\n * @returns the number\r\n */\r\nexport function PercentToRange(percent: number, min: number, max: number): number {\r\n return (max - min) * percent + min;\r\n}\r\n\r\n/**\r\n * Returns the highest common factor of two integers.\r\n * @param a first parameter\r\n * @param b second parameter\r\n * @returns HCF of a and b\r\n */\r\nexport function HighestCommonFactor(a: number, b: number): number {\r\n const r: number = a % b;\r\n if (r === 0) {\r\n return b;\r\n }\r\n return HighestCommonFactor(b, r);\r\n}\r\n","/* eslint-disable @typescript-eslint/naming-convention */\r\nimport { Epsilon } from \"./math.constants\";\r\nimport type { Viewport } from \"./math.viewport\";\r\nimport type { DeepImmutable, Nullable, FloatArray, float, Tuple } from \"../types\";\r\nimport { BuildTuple } from \"../Misc/arrayTools\";\r\nimport { RegisterClass } from \"../Misc/typeStore\";\r\nimport type { Plane } from \"./math.plane\";\r\nimport { PerformanceConfigurator } from \"../Engines/performanceConfigurator\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\nimport type { TransformNode } from \"../Meshes/transformNode\";\r\nimport type { Dimension, Tensor, TensorLike, TensorStatic } from \"./tensor\";\r\nimport type { IVector2Like, IVector3Like, IVector4Like, IQuaternionLike, IMatrixLike, IPlaneLike, Vector3LikeInternal } from \"./math.like\";\r\nimport { Clamp, Lerp, NormalizeRadians, RandomRange, WithinEpsilon } from \"./math.scalar.functions\";\r\n\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nconst _ExtractAsInt = (value: number) => {\r\n return parseInt(value.toString().replace(/\\W/g, \"\"));\r\n};\r\n\r\n/**\r\n * Represents a vector of any dimension\r\n */\r\nexport interface Vector extends Tensor {\r\n /**\r\n * @see Tensor.dimension\r\n */\r\n readonly dimension: Readonly>;\r\n\r\n /**\r\n * @see Tensor.rank\r\n */\r\n readonly rank: 1;\r\n\r\n /**\r\n * Gets the length of the vector\r\n * @returns the vector length (float)\r\n */\r\n length(): number;\r\n\r\n /**\r\n * Gets the vector squared length\r\n * @returns the vector squared length (float)\r\n */\r\n lengthSquared(): number;\r\n\r\n /**\r\n * Normalize the vector\r\n * @returns the current updated Vector\r\n */\r\n normalize(): this;\r\n\r\n /**\r\n * Normalize the current Vector with the given input length.\r\n * Please note that this is an in place operation.\r\n * @param len the length of the vector\r\n * @returns the current updated Vector\r\n */\r\n normalizeFromLength(len: number): this;\r\n\r\n /**\r\n * Normalize the current Vector to a new vector\r\n * @returns the new Vector\r\n */\r\n normalizeToNew(): Vector;\r\n\r\n /**\r\n * Normalize the current Vector to the reference\r\n * @param reference define the Vector to update\r\n * @returns the updated Vector\r\n */\r\n normalizeToRef(reference: T): T;\r\n}\r\n\r\n/**\r\n * Static side of Vector\r\n */\r\nexport interface VectorStatic, _I = TensorLike> extends TensorStatic {\r\n /**\r\n * Checks if a given vector is inside a specific range\r\n * @param value defines the vector to test\r\n * @param min defines the minimum range\r\n * @param max defines the maximum range\r\n */\r\n CheckExtends(value: _I, min: _I, max: _I): void;\r\n\r\n /**\r\n * Returns a new Vector equal to the normalized given vector\r\n * @param vector defines the vector to normalize\r\n * @returns a new Vector\r\n */\r\n Normalize(vector: DeepImmutable): T;\r\n\r\n /**\r\n * Normalize a given vector into a second one\r\n * @param vector defines the vector to normalize\r\n * @param result defines the vector where to store the result\r\n * @returns result input\r\n */\r\n NormalizeToRef(vector: DeepImmutable, result: T): T;\r\n}\r\n\r\n/**\r\n * Class representing a vector containing 2 coordinates\r\n * Example Playground - Overview - https://playground.babylonjs.com/#QYBWV4#9\r\n */\r\nexport class Vector2 implements Vector, IVector2Like>, IVector2Like {\r\n /**\r\n * If the first vector is flagged with integers (as everything is 0,0), V8 stores all of the properties as integers internally because it doesn't know any better yet.\r\n * If subsequent vectors are created with non-integer values, V8 determines that it would be best to represent these properties as doubles instead of integers,\r\n * and henceforth it will use floating-point representation for all Vector2 instances that it creates.\r\n * But the original Vector2 instances are unchanged and has a \"deprecated map\".\r\n * If we keep using the Vector2 instances from step 1, it will now be a poison pill which will mess up optimizations in any code it touches.\r\n */\r\n static _V8PerformanceHack = new Vector2(0.5, 0.5) as DeepImmutable;\r\n private static _ZeroReadOnly = Vector2.Zero() as DeepImmutable;\r\n\r\n /**\r\n * @see Tensor.dimension\r\n */\r\n declare public readonly dimension: Readonly<[2]>;\r\n\r\n /**\r\n * @see Tensor.rank\r\n */\r\n declare public readonly rank: 1;\r\n\r\n /**\r\n * Creates a new Vector2 from the given x and y coordinates\r\n * @param x defines the first coordinate\r\n * @param y defines the second coordinate\r\n */\r\n constructor(\r\n /** [0] defines the first coordinate */\r\n public x: number = 0,\r\n /** [0] defines the second coordinate */\r\n public y: number = 0\r\n ) {}\r\n\r\n /**\r\n * Gets a string with the Vector2 coordinates\r\n * @returns a string with the Vector2 coordinates\r\n */\r\n public toString(): string {\r\n return `{X: ${this.x} Y: ${this.y}}`;\r\n }\r\n\r\n /**\r\n * Gets class name\r\n * @returns the string \"Vector2\"\r\n */\r\n public getClassName(): string {\r\n return \"Vector2\";\r\n }\r\n\r\n /**\r\n * Gets current vector hash code\r\n * @returns the Vector2 hash code as a number\r\n */\r\n public getHashCode(): number {\r\n const x = _ExtractAsInt(this.x);\r\n const y = _ExtractAsInt(this.y);\r\n let hash = x;\r\n hash = (hash * 397) ^ y;\r\n return hash;\r\n }\r\n\r\n // Operators\r\n\r\n /**\r\n * Sets the Vector2 coordinates in the given array or Float32Array from the given index.\r\n * Example Playground https://playground.babylonjs.com/#QYBWV4#15\r\n * @param array defines the source array\r\n * @param index defines the offset in source array\r\n * @returns the current Vector2\r\n */\r\n public toArray(array: FloatArray, index: number = 0): this {\r\n array[index] = this.x;\r\n array[index + 1] = this.y;\r\n return this;\r\n }\r\n\r\n /**\r\n * Update the current vector from an array\r\n * Example Playground https://playground.babylonjs.com/#QYBWV4#39\r\n * @param array defines the destination array\r\n * @param offset defines the offset in the destination array\r\n * @returns the current Vector2\r\n */\r\n public fromArray(array: FloatArray, offset: number = 0): this {\r\n Vector2.FromArrayToRef(array, offset, this);\r\n return this;\r\n }\r\n\r\n /**\r\n * Copy the current vector to an array\r\n * Example Playground https://playground.babylonjs.com/#QYBWV4#40\r\n * @returns a new array with 2 elements: the Vector2 coordinates.\r\n */\r\n public asArray(): [number, number] {\r\n return [this.x, this.y];\r\n }\r\n\r\n /**\r\n * Sets the Vector2 coordinates with the given Vector2 coordinates\r\n * Example Playground https://playground.babylonjs.com/#QYBWV4#24\r\n * @param source defines the source Vector2\r\n * @returns the current updated Vector2\r\n */\r\n public copyFrom(source: DeepImmutable): this {\r\n this.x = source.x;\r\n this.y = source.y;\r\n return this;\r\n }\r\n\r\n /**\r\n * Sets the Vector2 coordinates with the given floats\r\n * Example Playground https://playground.babylonjs.com/#QYBWV4#25\r\n * @param x defines the first coordinate\r\n * @param y defines the second coordinate\r\n * @returns the current updated Vector2\r\n */\r\n public copyFromFloats(x: number, y: number): this {\r\n this.x = x;\r\n this.y = y;\r\n return this;\r\n }\r\n\r\n /**\r\n * Sets the Vector2 coordinates with the given floats\r\n * Example Playground https://playground.babylonjs.com/#QYBWV4#62\r\n * @param x defines the first coordinate\r\n * @param y defines the second coordinate\r\n * @returns the current updated Vector2\r\n */\r\n public set(x: number, y: number): this {\r\n return this.copyFromFloats(x, y);\r\n }\r\n\r\n /**\r\n * Copies the given float to the current Vector2 coordinates\r\n * @param v defines the x and y coordinates of the operand\r\n * @returns the current updated Vector2\r\n */\r\n public setAll(v: number): this {\r\n return this.copyFromFloats(v, v);\r\n }\r\n\r\n /**\r\n * Add another vector with the current one\r\n * Example Playground https://playground.babylonjs.com/#QYBWV4#11\r\n * @param otherVector defines the other vector\r\n * @returns a new Vector2 set with the addition of the current Vector2 and the given one coordinates\r\n */\r\n public add(otherVector: DeepImmutable): Vector2 {\r\n return new Vector2(this.x + otherVector.x, this.y + otherVector.y);\r\n }\r\n\r\n /**\r\n * Sets the \"result\" coordinates with the addition of the current Vector2 and the given one coordinates\r\n * Example Playground https://playground.babylonjs.com/#QYBWV4#12\r\n * @param otherVector defines the other vector\r\n * @param result defines the target vector\r\n * @returns result input\r\n */\r\n public addToRef(otherVector: DeepImmutable, result: T): T {\r\n result.x = this.x + otherVector.x;\r\n result.y = this.y + otherVector.y;\r\n return result;\r\n }\r\n\r\n /**\r\n * Set the Vector2 coordinates by adding the given Vector2 coordinates\r\n * Example Playground https://playground.babylonjs.com/#QYBWV4#13\r\n * @param otherVector defines the other vector\r\n * @returns the current updated Vector2\r\n */\r\n public addInPlace(otherVector: DeepImmutable): this {\r\n this.x += otherVector.x;\r\n this.y += otherVector.y;\r\n return this;\r\n }\r\n\r\n /**\r\n * Adds the given coordinates to the current Vector2\r\n * @param x defines the x coordinate of the operand\r\n * @param y defines the y coordinate of the operand\r\n * @returns the current updated Vector2\r\n */\r\n public addInPlaceFromFloats(x: number, y: number): this {\r\n this.x += x;\r\n this.y += y;\r\n return this;\r\n }\r\n\r\n /**\r\n * Gets a new Vector2 by adding the current Vector2 coordinates to the given Vector3 x, y coordinates\r\n * Example Playground https://playground.babylonjs.com/#QYBWV4#14\r\n * @param otherVector defines the other vector\r\n * @returns a new Vector2\r\n */\r\n public addVector3(otherVector: IVector3Like): Vector2 {\r\n return new Vector2(this.x + otherVector.x, this.y + otherVector.y);\r\n }\r\n\r\n /**\r\n * Gets a new Vector2 set with the subtracted coordinates of the given one from the current Vector2\r\n * Example Playground https://playground.babylonjs.com/#QYBWV4#61\r\n * @param otherVector defines the other vector\r\n * @returns a new Vector2\r\n */\r\n public subtract(otherVector: DeepImmutable): Vector2 {\r\n return new Vector2(this.x - otherVector.x, this.y - otherVector.y);\r\n }\r\n\r\n /**\r\n * Sets the \"result\" coordinates with the subtraction of the given one from the current Vector2 coordinates.\r\n * Example Playground https://playground.babylonjs.com/#QYBWV4#63\r\n * @param otherVector defines the other vector\r\n * @param result defines the target vector\r\n * @returns result input\r\n */\r\n public subtractToRef(otherVector: DeepImmutable, result: T): T {\r\n result.x = this.x - otherVector.x;\r\n result.y = this.y - otherVector.y;\r\n return result;\r\n }\r\n /**\r\n * Sets the current Vector2 coordinates by subtracting from it the given one coordinates\r\n * Example Playground https://playground.babylonjs.com/#QYBWV4#88\r\n * @param otherVector defines the other vector\r\n * @returns the current updated Vector2\r\n */\r\n public subtractInPlace(otherVector: DeepImmutable): this {\r\n this.x -= otherVector.x;\r\n this.y -= otherVector.y;\r\n return this;\r\n }\r\n\r\n /**\r\n * Multiplies in place the current Vector2 coordinates by the given ones\r\n * Example Playground https://playground.babylonjs.com/#QYBWV4#43\r\n * @param otherVector defines the other vector\r\n * @returns the current updated Vector2\r\n */\r\n public multiplyInPlace(otherVector: DeepImmutable): this {\r\n this.x *= otherVector.x;\r\n this.y *= otherVector.y;\r\n return this;\r\n }\r\n\r\n /**\r\n * Returns a new Vector2 set with the multiplication of the current Vector2 and the given one coordinates\r\n * Example Playground https://playground.babylonjs.com/#QYBWV4#42\r\n * @param otherVector defines the other vector\r\n * @returns a new Vector2\r\n */\r\n public multiply(otherVector: DeepImmutable): Vector2 {\r\n return new Vector2(this.x * otherVector.x, this.y * otherVector.y);\r\n }\r\n\r\n /**\r\n * Sets \"result\" coordinates with the multiplication of the current Vector2 and the given one coordinates\r\n * Example Playground https://playground.babylonjs.com/#QYBWV4#44\r\n * @param otherVector defines the other vector\r\n * @param result defines the target vector\r\n * @returns result input\r\n */\r\n public multiplyToRef(otherVector: DeepImmutable, result: T): T {\r\n result.x = this.x * otherVector.x;\r\n result.y = this.y * otherVector.y;\r\n return result;\r\n }\r\n\r\n /**\r\n * Gets a new Vector2 set with the Vector2 coordinates multiplied by the given floats\r\n * Example Playground https://playground.babylonjs.com/#QYBWV4#89\r\n * @param x defines the first coordinate\r\n * @param y defines the second coordinate\r\n * @returns a new Vector2\r\n */\r\n public multiplyByFloats(x: number, y: number): Vector2 {\r\n return new Vector2(this.x * x, this.y * y);\r\n }\r\n\r\n /**\r\n * Returns a new Vector2 set with the Vector2 coordinates divided by the given one coordinates\r\n * Example Playground https://playground.babylonjs.com/#QYBWV4#27\r\n * @param otherVector defines the other vector\r\n * @returns a new Vector2\r\n */\r\n public divide(otherVector: DeepImmutable): Vector2 {\r\n return new Vector2(this.x / otherVector.x, this.y / otherVector.y);\r\n }\r\n\r\n /**\r\n * Sets the \"result\" coordinates with the Vector2 divided by the given one coordinates\r\n * Example Playground https://playground.babylonjs.com/#QYBWV4#30\r\n * @param otherVector defines the other vector\r\n * @param result defines the target vector\r\n * @returns result input\r\n */\r\n public divideToRef(otherVector: DeepImmutable, result: T): T {\r\n result.x = this.x / otherVector.x;\r\n result.y = this.y / otherVector.y;\r\n return result;\r\n }\r\n\r\n /**\r\n * Divides the current Vector2 coordinates by the given ones\r\n * Example Playground https://playground.babylonjs.com/#QYBWV4#28\r\n * @param otherVector defines the other vector\r\n * @returns the current updated Vector2\r\n */\r\n public divideInPlace(otherVector: DeepImmutable): this {\r\n this.x = this.x / otherVector.x;\r\n this.y = this.y / otherVector.y;\r\n return this;\r\n }\r\n\r\n /**\r\n * Updates the current Vector2 with the minimal coordinate values between its and the given vector ones\r\n * @param other defines the second operand\r\n * @returns the current updated Vector2\r\n */\r\n public minimizeInPlace(other: DeepImmutable): this {\r\n return this.minimizeInPlaceFromFloats(other.x, other.y);\r\n }\r\n\r\n /**\r\n * Updates the current Vector2 with the maximal coordinate values between its and the given vector ones.\r\n * @param other defines the second operand\r\n * @returns the current updated Vector2\r\n */\r\n public maximizeInPlace(other: DeepImmutable): this {\r\n return this.maximizeInPlaceFromFloats(other.x, other.y);\r\n }\r\n\r\n /**\r\n * Updates the current Vector2 with the minimal coordinate values between its and the given coordinates\r\n * @param x defines the x coordinate of the operand\r\n * @param y defines the y coordinate of the operand\r\n * @returns the current updated Vector2\r\n */\r\n public minimizeInPlaceFromFloats(x: number, y: number): this {\r\n this.x = Math.min(x, this.x);\r\n this.y = Math.min(y, this.y);\r\n return this;\r\n }\r\n\r\n /**\r\n * Updates the current Vector2 with the maximal coordinate values between its and the given coordinates.\r\n * @param x defines the x coordinate of the operand\r\n * @param y defines the y coordinate of the operand\r\n * @returns the current updated Vector2\r\n */\r\n public maximizeInPlaceFromFloats(x: number, y: number): this {\r\n this.x = Math.max(x, this.x);\r\n this.y = Math.max(y, this.y);\r\n return this;\r\n }\r\n\r\n /**\r\n * Returns a new Vector2 set with the subtraction of the given floats from the current Vector2 coordinates\r\n * @param x defines the x coordinate of the operand\r\n * @param y defines the y coordinate of the operand\r\n * @returns the resulting Vector2\r\n */\r\n public subtractFromFloats(x: number, y: number): Vector2 {\r\n return new Vector2(this.x - x, this.y - y);\r\n }\r\n\r\n /**\r\n * Subtracts the given floats from the current Vector2 coordinates and set the given vector \"result\" with this result\r\n * @param x defines the x coordinate of the operand\r\n * @param y defines the y coordinate of the operand\r\n * @param result defines the Vector2 object where to store the result\r\n * @returns the result\r\n */\r\n public subtractFromFloatsToRef(x: number, y: number, result: T): T {\r\n result.x = this.x - x;\r\n result.y = this.y - y;\r\n return result;\r\n }\r\n\r\n /**\r\n * Gets a new Vector2 with current Vector2 negated coordinates\r\n * @returns a new Vector2\r\n */\r\n public negate(): Vector2 {\r\n return new Vector2(-this.x, -this.y);\r\n }\r\n\r\n /**\r\n * Negate this vector in place\r\n * Example Playground https://playground.babylonjs.com/#QYBWV4#23\r\n * @returns this\r\n */\r\n public negateInPlace(): this {\r\n this.x *= -1;\r\n this.y *= -1;\r\n return this;\r\n }\r\n\r\n /**\r\n * Negate the current Vector2 and stores the result in the given vector \"result\" coordinates\r\n * Example Playground https://playground.babylonjs.com/#QYBWV4#41\r\n * @param result defines the Vector3 object where to store the result\r\n * @returns the result\r\n */\r\n public negateToRef(result: T): T {\r\n result.x = -this.x;\r\n result.y = -this.y;\r\n return result;\r\n }\r\n\r\n /**\r\n * Multiply the Vector2 coordinates by\r\n * Example Playground https://playground.babylonjs.com/#QYBWV4#59\r\n * @param scale defines the scaling factor\r\n * @returns the current updated Vector2\r\n */\r\n public scaleInPlace(scale: number): this {\r\n this.x *= scale;\r\n this.y *= scale;\r\n return this;\r\n }\r\n\r\n /**\r\n * Returns a new Vector2 scaled by \"scale\" from the current Vector2\r\n * Example Playground https://playground.babylonjs.com/#QYBWV4#52\r\n * @param scale defines the scaling factor\r\n * @returns a new Vector2\r\n */\r\n public scale(scale: number): Vector2 {\r\n return new Vector2(this.x * scale, this.y * scale);\r\n }\r\n\r\n /**\r\n * Scale the current Vector2 values by a factor to a given Vector2\r\n * Example Playground https://playground.babylonjs.com/#QYBWV4#57\r\n * @param scale defines the scale factor\r\n * @param result defines the Vector2 object where to store the result\r\n * @returns result input\r\n */\r\n public scaleToRef(scale: number, result: T): T {\r\n result.x = this.x * scale;\r\n result.y = this.y * scale;\r\n return result;\r\n }\r\n\r\n /**\r\n * Scale the current Vector2 values by a factor and add the result to a given Vector2\r\n * Example Playground https://playground.babylonjs.com/#QYBWV4#58\r\n * @param scale defines the scale factor\r\n * @param result defines the Vector2 object where to store the result\r\n * @returns result input\r\n */\r\n public scaleAndAddToRef(scale: number, result: T): T {\r\n result.x += this.x * scale;\r\n result.y += this.y * scale;\r\n return result;\r\n }\r\n\r\n /**\r\n * Gets a boolean if two vectors are equals\r\n * Example Playground https://playground.babylonjs.com/#QYBWV4#31\r\n * @param otherVector defines the other vector\r\n * @returns true if the given vector coordinates strictly equal the current Vector2 ones\r\n */\r\n public equals(otherVector: DeepImmutable): boolean {\r\n return otherVector && this.x === otherVector.x && this.y === otherVector.y;\r\n }\r\n\r\n /**\r\n * Gets a boolean if two vectors are equals (using an epsilon value)\r\n * Example Playground https://playground.babylonjs.com/#QYBWV4#32\r\n * @param otherVector defines the other vector\r\n * @param epsilon defines the minimal distance to consider equality\r\n * @returns true if the given vector coordinates are close to the current ones by a distance of epsilon.\r\n */\r\n public equalsWithEpsilon(otherVector: DeepImmutable, epsilon: number = Epsilon): boolean {\r\n return otherVector && WithinEpsilon(this.x, otherVector.x, epsilon) && WithinEpsilon(this.y, otherVector.y, epsilon);\r\n }\r\n\r\n /**\r\n * Returns true if the current Vector2 coordinates equals the given floats\r\n * @param x defines the x coordinate of the operand\r\n * @param y defines the y coordinate of the operand\r\n * @returns true if both vectors are equal\r\n */\r\n public equalsToFloats(x: number, y: number): boolean {\r\n return this.x === x && this.y === y;\r\n }\r\n\r\n /**\r\n * Gets a new Vector2 from current Vector2 floored values\r\n * Example Playground https://playground.babylonjs.com/#QYBWV4#35\r\n * eg (1.2, 2.31) returns (1, 2)\r\n * @returns a new Vector2\r\n */\r\n public floor(): Vector2 {\r\n return new Vector2(Math.floor(this.x), Math.floor(this.y));\r\n }\r\n\r\n /**\r\n * Gets the current Vector2's floored values and stores them in result\r\n * @param result the Vector2 to store the result in\r\n * @returns the result Vector2\r\n */\r\n public floorToRef(result: T): T {\r\n result.x = Math.floor(this.x);\r\n result.y = Math.floor(this.y);\r\n return result;\r\n }\r\n\r\n /**\r\n * Gets a new Vector2 from current Vector2 fractional values\r\n * Example Playground https://playground.babylonjs.com/#QYBWV4#34\r\n * eg (1.2, 2.31) returns (0.2, 0.31)\r\n * @returns a new Vector2\r\n */\r\n public fract(): Vector2 {\r\n return new Vector2(this.x - Math.floor(this.x), this.y - Math.floor(this.y));\r\n }\r\n\r\n /**\r\n * Gets the current Vector2's fractional values and stores them in result\r\n * @param result the Vector2 to store the result in\r\n * @returns the result Vector2\r\n */\r\n public fractToRef(result: T): T {\r\n result.x = this.x - Math.floor(this.x);\r\n result.y = this.y - Math.floor(this.y);\r\n return result;\r\n }\r\n\r\n /**\r\n * Rotate the current vector into a given result vector\r\n * Example Playground https://playground.babylonjs.com/#QYBWV4#49\r\n * @param angle defines the rotation angle\r\n * @param result defines the result vector where to store the rotated vector\r\n * @returns result input\r\n */\r\n public rotateToRef(angle: number, result: T): T {\r\n const cos = Math.cos(angle);\r\n const sin = Math.sin(angle);\r\n const x = cos * this.x - sin * this.y;\r\n const y = sin * this.x + cos * this.y;\r\n result.x = x;\r\n result.y = y;\r\n return result;\r\n }\r\n\r\n // Properties\r\n\r\n /**\r\n * Gets the length of the vector\r\n * @returns the vector length (float)\r\n */\r\n public length(): number {\r\n return Math.sqrt(this.x * this.x + this.y * this.y);\r\n }\r\n\r\n /**\r\n * Gets the vector squared length\r\n * @returns the vector squared length (float)\r\n */\r\n public lengthSquared(): number {\r\n return this.x * this.x + this.y * this.y;\r\n }\r\n\r\n // Methods\r\n\r\n /**\r\n * Normalize the vector\r\n * Example Playground https://playground.babylonjs.com/#QYBWV4#48\r\n * @returns the current updated Vector2\r\n */\r\n public normalize(): this {\r\n return this.normalizeFromLength(this.length());\r\n }\r\n\r\n /**\r\n * Normalize the current Vector2 with the given input length.\r\n * Please note that this is an in place operation.\r\n * @param len the length of the vector\r\n * @returns the current updated Vector2\r\n */\r\n public normalizeFromLength(len: number): this {\r\n if (len === 0 || len === 1.0) {\r\n return this;\r\n }\r\n\r\n return this.scaleInPlace(1.0 / len);\r\n }\r\n\r\n /**\r\n * Normalize the current Vector2 to a new vector\r\n * @returns the new Vector2\r\n */\r\n public normalizeToNew(): Vector2 {\r\n const normalized = new Vector2();\r\n this.normalizeToRef(normalized);\r\n return normalized;\r\n }\r\n\r\n /**\r\n * Normalize the current Vector2 to the reference\r\n * @param result define the Vector to update\r\n * @returns the updated Vector2\r\n */\r\n public normalizeToRef(result: T): T {\r\n const len = this.length();\r\n if (len === 0) {\r\n result.x = this.x;\r\n result.y = this.y;\r\n }\r\n return this.scaleToRef(1.0 / len, result);\r\n }\r\n\r\n /**\r\n * Gets a new Vector2 copied from the Vector2\r\n * Example Playground https://playground.babylonjs.com/#QYBWV4#20\r\n * @returns a new Vector2\r\n */\r\n public clone(): Vector2 {\r\n return new Vector2(this.x, this.y);\r\n }\r\n\r\n /**\r\n * Gets the dot product of the current vector and the vector \"otherVector\"\r\n * @param otherVector defines second vector\r\n * @returns the dot product (float)\r\n */\r\n public dot(otherVector: DeepImmutable): number {\r\n return this.x * otherVector.x + this.y * otherVector.y;\r\n }\r\n\r\n // Statics\r\n\r\n /**\r\n * Gets a new Vector2(0, 0)\r\n * @returns a new Vector2\r\n */\r\n public static Zero(): Vector2 {\r\n return new Vector2(0, 0);\r\n }\r\n\r\n /**\r\n * Gets a new Vector2(1, 1)\r\n * @returns a new Vector2\r\n */\r\n public static One(): Vector2 {\r\n return new Vector2(1, 1);\r\n }\r\n\r\n /**\r\n * Returns a new Vector2 with random values between min and max\r\n * @param min the minimum random value\r\n * @param max the maximum random value\r\n * @returns a Vector2 with random values between min and max\r\n */\r\n public static Random(min: number = 0, max: number = 1): Vector2 {\r\n return new Vector2(RandomRange(min, max), RandomRange(min, max));\r\n }\r\n\r\n /**\r\n * Sets a Vector2 with random values between min and max\r\n * @param min the minimum random value\r\n * @param max the maximum random value\r\n * @param ref the ref to store the values in\r\n * @returns the ref with random values between min and max\r\n */\r\n public static RandomToRef(min: number = 0, max: number = 1, ref: T): T {\r\n return ref.copyFromFloats(RandomRange(min, max), RandomRange(min, max));\r\n }\r\n\r\n /**\r\n * Gets a zero Vector2 that must not be updated\r\n */\r\n public static get ZeroReadOnly(): DeepImmutable {\r\n return Vector2._ZeroReadOnly;\r\n }\r\n\r\n /**\r\n * Gets a new Vector2 set from the given index element of the given array\r\n * Example Playground https://playground.babylonjs.com/#QYBWV4#79\r\n * @param array defines the data source\r\n * @param offset defines the offset in the data source\r\n * @returns a new Vector2\r\n */\r\n public static FromArray(array: DeepImmutable>, offset: number = 0): Vector2 {\r\n return new Vector2(array[offset], array[offset + 1]);\r\n }\r\n\r\n /**\r\n * Sets \"result\" from the given index element of the given array\r\n * Example Playground https://playground.babylonjs.com/#QYBWV4#80\r\n * @param array defines the data source\r\n * @param offset defines the offset in the data source\r\n * @param result defines the target vector\r\n * @returns result input\r\n */\r\n public static FromArrayToRef(array: DeepImmutable>, offset: number, result: T): T {\r\n result.x = array[offset];\r\n result.y = array[offset + 1];\r\n return result;\r\n }\r\n\r\n /**\r\n * Sets the given vector \"result\" with the given floats.\r\n * @param x defines the x coordinate of the source\r\n * @param y defines the y coordinate of the source\r\n * @param result defines the Vector2 where to store the result\r\n * @returns the result vector\r\n */\r\n public static FromFloatsToRef(x: number, y: number, result: T): T {\r\n result.copyFromFloats(x, y);\r\n return result;\r\n }\r\n\r\n /**\r\n * Gets a new Vector2 located for \"amount\" (float) on the CatmullRom spline defined by the given four Vector2\r\n * Example Playground https://playground.babylonjs.com/#QYBWV4#65\r\n * @param value1 defines 1st point of control\r\n * @param value2 defines 2nd point of control\r\n * @param value3 defines 3rd point of control\r\n * @param value4 defines 4th point of control\r\n * @param amount defines the interpolation factor\r\n * @returns a new Vector2\r\n */\r\n public static CatmullRom(\r\n value1: DeepImmutable,\r\n value2: DeepImmutable,\r\n value3: DeepImmutable,\r\n value4: DeepImmutable,\r\n amount: number\r\n ): Vector2 {\r\n const squared = amount * amount;\r\n const cubed = amount * squared;\r\n\r\n const x =\r\n 0.5 *\r\n (2.0 * value2.x +\r\n (-value1.x + value3.x) * amount +\r\n (2.0 * value1.x - 5.0 * value2.x + 4.0 * value3.x - value4.x) * squared +\r\n (-value1.x + 3.0 * value2.x - 3.0 * value3.x + value4.x) * cubed);\r\n\r\n const y =\r\n 0.5 *\r\n (2.0 * value2.y +\r\n (-value1.y + value3.y) * amount +\r\n (2.0 * value1.y - 5.0 * value2.y + 4.0 * value3.y - value4.y) * squared +\r\n (-value1.y + 3.0 * value2.y - 3.0 * value3.y + value4.y) * cubed);\r\n\r\n return new Vector2(x, y);\r\n }\r\n\r\n /**\r\n * Sets reference with same the coordinates than \"value\" ones if the vector \"value\" is in the square defined by \"min\" and \"max\".\r\n * If a coordinate of \"value\" is lower than \"min\" coordinates, the returned Vector2 is given this \"min\" coordinate.\r\n * If a coordinate of \"value\" is greater than \"max\" coordinates, the returned Vector2 is given this \"max\" coordinate\r\n * @param value defines the value to clamp\r\n * @param min defines the lower limit\r\n * @param max defines the upper limit\r\n * @param ref the reference\r\n * @returns the reference\r\n */\r\n public static ClampToRef(value: DeepImmutable, min: DeepImmutable, max: DeepImmutable, ref: T): T {\r\n ref.x = Clamp(value.x, min.x, max.x);\r\n ref.y = Clamp(value.y, min.y, max.y);\r\n return ref;\r\n }\r\n\r\n /**\r\n * Returns a new Vector2 set with same the coordinates than \"value\" ones if the vector \"value\" is in the square defined by \"min\" and \"max\".\r\n * If a coordinate of \"value\" is lower than \"min\" coordinates, the returned Vector2 is given this \"min\" coordinate.\r\n * If a coordinate of \"value\" is greater than \"max\" coordinates, the returned Vector2 is given this \"max\" coordinate\r\n * Example Playground https://playground.babylonjs.com/#QYBWV4#76\r\n * @param value defines the value to clamp\r\n * @param min defines the lower limit\r\n * @param max defines the upper limit\r\n * @returns a new Vector2\r\n */\r\n public static Clamp(value: DeepImmutable, min: DeepImmutable, max: DeepImmutable): Vector2 {\r\n const x = Clamp(value.x, min.x, max.x);\r\n const y = Clamp(value.y, min.y, max.y);\r\n return new Vector2(x, y);\r\n }\r\n\r\n /**\r\n * Returns a new Vector2 located for \"amount\" (float) on the Hermite spline defined by the vectors \"value1\", \"value2\", \"tangent1\", \"tangent2\"\r\n * Example Playground https://playground.babylonjs.com/#QYBWV4#81\r\n * @param value1 defines the 1st control point\r\n * @param tangent1 defines the outgoing tangent\r\n * @param value2 defines the 2nd control point\r\n * @param tangent2 defines the incoming tangent\r\n * @param amount defines the interpolation factor\r\n * @returns a new Vector2\r\n */\r\n public static Hermite(\r\n value1: DeepImmutable,\r\n tangent1: DeepImmutable,\r\n value2: DeepImmutable,\r\n tangent2: DeepImmutable,\r\n amount: number\r\n ): Vector2 {\r\n const squared = amount * amount;\r\n const cubed = amount * squared;\r\n const part1 = 2.0 * cubed - 3.0 * squared + 1.0;\r\n const part2 = -2.0 * cubed + 3.0 * squared;\r\n const part3 = cubed - 2.0 * squared + amount;\r\n const part4 = cubed - squared;\r\n\r\n const x = value1.x * part1 + value2.x * part2 + tangent1.x * part3 + tangent2.x * part4;\r\n const y = value1.y * part1 + value2.y * part2 + tangent1.y * part3 + tangent2.y * part4;\r\n\r\n return new Vector2(x, y);\r\n }\r\n\r\n /**\r\n * Returns a new Vector2 which is the 1st derivative of the Hermite spline defined by the vectors \"value1\", \"value2\", \"tangent1\", \"tangent2\".\r\n * Example Playground https://playground.babylonjs.com/#QYBWV4#82\r\n * @param value1 defines the first control point\r\n * @param tangent1 defines the first tangent\r\n * @param value2 defines the second control point\r\n * @param tangent2 defines the second tangent\r\n * @param time define where the derivative must be done\r\n * @returns 1st derivative\r\n */\r\n public static Hermite1stDerivative(\r\n value1: DeepImmutable,\r\n tangent1: DeepImmutable,\r\n value2: DeepImmutable,\r\n tangent2: DeepImmutable,\r\n time: number\r\n ): Vector2 {\r\n return this.Hermite1stDerivativeToRef(value1, tangent1, value2, tangent2, time, new Vector2());\r\n }\r\n\r\n /**\r\n * Returns a new Vector2 which is the 1st derivative of the Hermite spline defined by the vectors \"value1\", \"value2\", \"tangent1\", \"tangent2\".\r\n * Example Playground https://playground.babylonjs.com/#QYBWV4#83\r\n * @param value1 defines the first control point\r\n * @param tangent1 defines the first tangent\r\n * @param value2 defines the second control point\r\n * @param tangent2 defines the second tangent\r\n * @param time define where the derivative must be done\r\n * @param result define where the derivative will be stored\r\n * @returns result input\r\n */\r\n public static Hermite1stDerivativeToRef(\r\n value1: DeepImmutable,\r\n tangent1: DeepImmutable,\r\n value2: DeepImmutable,\r\n tangent2: DeepImmutable,\r\n time: number,\r\n result: T\r\n ): T {\r\n const t2 = time * time;\r\n\r\n result.x = (t2 - time) * 6 * value1.x + (3 * t2 - 4 * time + 1) * tangent1.x + (-t2 + time) * 6 * value2.x + (3 * t2 - 2 * time) * tangent2.x;\r\n result.y = (t2 - time) * 6 * value1.y + (3 * t2 - 4 * time + 1) * tangent1.y + (-t2 + time) * 6 * value2.y + (3 * t2 - 2 * time) * tangent2.y;\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Returns a new Vector2 located for \"amount\" (float) on the linear interpolation between the vector \"start\" adn the vector \"end\".\r\n * Example Playground https://playground.babylonjs.com/#QYBWV4#84\r\n * @param start defines the start vector\r\n * @param end defines the end vector\r\n * @param amount defines the interpolation factor\r\n * @returns a new Vector2\r\n */\r\n public static Lerp(start: DeepImmutable, end: DeepImmutable, amount: number): Vector2 {\r\n return Vector2.LerpToRef(start, end, amount, new Vector2());\r\n }\r\n\r\n /**\r\n * Sets the given vector \"result\" with the result of the linear interpolation from the vector \"start\" for \"amount\" to the vector \"end\"\r\n * @param start defines the start value\r\n * @param end defines the end value\r\n * @param amount max defines amount between both (between 0 and 1)\r\n * @param result defines the Vector2 where to store the result\r\n * @returns result input\r\n */\r\n public static LerpToRef(start: DeepImmutable, end: DeepImmutable, amount: number, result: Vector2): Vector2 {\r\n result.x = start.x + (end.x - start.x) * amount;\r\n result.y = start.y + (end.y - start.y) * amount;\r\n return result;\r\n }\r\n\r\n /**\r\n * Gets the dot product of the vector \"left\" and the vector \"right\"\r\n * Example Playground https://playground.babylonjs.com/#QYBWV4#90\r\n * @param left defines first vector\r\n * @param right defines second vector\r\n * @returns the dot product (float)\r\n */\r\n public static Dot(left: DeepImmutable, right: DeepImmutable): number {\r\n return left.x * right.x + left.y * right.y;\r\n }\r\n\r\n /**\r\n * Returns a new Vector2 equal to the normalized given vector\r\n * Example Playground https://playground.babylonjs.com/#QYBWV4#46\r\n * @param vector defines the vector to normalize\r\n * @returns a new Vector2\r\n */\r\n public static Normalize(vector: DeepImmutable): Vector2 {\r\n return Vector2.NormalizeToRef(vector, new Vector2());\r\n }\r\n\r\n /**\r\n * Normalize a given vector into a second one\r\n * Example Playground https://playground.babylonjs.com/#QYBWV4#50\r\n * @param vector defines the vector to normalize\r\n * @param result defines the vector where to store the result\r\n * @returns result input\r\n */\r\n public static NormalizeToRef(vector: DeepImmutable, result: T): T {\r\n vector.normalizeToRef(result);\r\n return result;\r\n }\r\n\r\n /**\r\n * Gets a new Vector2 set with the minimal coordinate values from the \"left\" and \"right\" vectors\r\n * Example Playground https://playground.babylonjs.com/#QYBWV4#86\r\n * @param left defines 1st vector\r\n * @param right defines 2nd vector\r\n * @returns a new Vector2\r\n */\r\n public static Minimize(left: DeepImmutable, right: DeepImmutable): Vector2 {\r\n const x = left.x < right.x ? left.x : right.x;\r\n const y = left.y < right.y ? left.y : right.y;\r\n return new Vector2(x, y);\r\n }\r\n\r\n /**\r\n * Gets a new Vector2 set with the maximal coordinate values from the \"left\" and \"right\" vectors\r\n * Example Playground https://playground.babylonjs.com/#QYBWV4#86\r\n * @param left defines 1st vector\r\n * @param right defines 2nd vector\r\n * @returns a new Vector2\r\n */\r\n public static Maximize(left: DeepImmutable, right: DeepImmutable): Vector2 {\r\n const x = left.x > right.x ? left.x : right.x;\r\n const y = left.y > right.y ? left.y : right.y;\r\n return new Vector2(x, y);\r\n }\r\n\r\n /**\r\n * Gets a new Vector2 set with the transformed coordinates of the given vector by the given transformation matrix\r\n * Example Playground https://playground.babylonjs.com/#QYBWV4#17\r\n * @param vector defines the vector to transform\r\n * @param transformation defines the matrix to apply\r\n * @returns a new Vector2\r\n */\r\n public static Transform(vector: DeepImmutable, transformation: DeepImmutable): Vector2 {\r\n return Vector2.TransformToRef(vector, transformation, new Vector2());\r\n }\r\n\r\n /**\r\n * Transforms the given vector coordinates by the given transformation matrix and stores the result in the vector \"result\" coordinates\r\n * Example Playground https://playground.babylonjs.com/#QYBWV4#19\r\n * @param vector defines the vector to transform\r\n * @param transformation defines the matrix to apply\r\n * @param result defines the target vector\r\n * @returns result input\r\n */\r\n public static TransformToRef(vector: DeepImmutable, transformation: DeepImmutable, result: T): T {\r\n const m = transformation.m;\r\n const x = vector.x * m[0] + vector.y * m[4] + m[12];\r\n const y = vector.x * m[1] + vector.y * m[5] + m[13];\r\n result.x = x;\r\n result.y = y;\r\n return result;\r\n }\r\n\r\n /**\r\n * Determines if a given vector is included in a triangle\r\n * Example Playground https://playground.babylonjs.com/#QYBWV4#87\r\n * @param p defines the vector to test\r\n * @param p0 defines 1st triangle point\r\n * @param p1 defines 2nd triangle point\r\n * @param p2 defines 3rd triangle point\r\n * @returns true if the point \"p\" is in the triangle defined by the vectors \"p0\", \"p1\", \"p2\"\r\n */\r\n public static PointInTriangle(p: DeepImmutable, p0: DeepImmutable, p1: DeepImmutable, p2: DeepImmutable): boolean {\r\n const a = (1 / 2) * (-p1.y * p2.x + p0.y * (-p1.x + p2.x) + p0.x * (p1.y - p2.y) + p1.x * p2.y);\r\n const sign = a < 0 ? -1 : 1;\r\n const s = (p0.y * p2.x - p0.x * p2.y + (p2.y - p0.y) * p.x + (p0.x - p2.x) * p.y) * sign;\r\n const t = (p0.x * p1.y - p0.y * p1.x + (p0.y - p1.y) * p.x + (p1.x - p0.x) * p.y) * sign;\r\n\r\n return s > 0 && t > 0 && s + t < 2 * a * sign;\r\n }\r\n\r\n /**\r\n * Gets the distance between the vectors \"value1\" and \"value2\"\r\n * Example Playground https://playground.babylonjs.com/#QYBWV4#71\r\n * @param value1 defines first vector\r\n * @param value2 defines second vector\r\n * @returns the distance between vectors\r\n */\r\n public static Distance(value1: DeepImmutable, value2: DeepImmutable): number {\r\n return Math.sqrt(Vector2.DistanceSquared(value1, value2));\r\n }\r\n\r\n /**\r\n * Returns the squared distance between the vectors \"value1\" and \"value2\"\r\n * Example Playground https://playground.babylonjs.com/#QYBWV4#72\r\n * @param value1 defines first vector\r\n * @param value2 defines second vector\r\n * @returns the squared distance between vectors\r\n */\r\n public static DistanceSquared(value1: DeepImmutable, value2: DeepImmutable): number {\r\n const x = value1.x - value2.x;\r\n const y = value1.y - value2.y;\r\n return x * x + y * y;\r\n }\r\n\r\n /**\r\n * Gets a new Vector2 located at the center of the vectors \"value1\" and \"value2\"\r\n * Example Playground https://playground.babylonjs.com/#QYBWV4#86\r\n * Example Playground https://playground.babylonjs.com/#QYBWV4#66\r\n * @param value1 defines first vector\r\n * @param value2 defines second vector\r\n * @returns a new Vector2\r\n */\r\n public static Center(value1: DeepImmutable, value2: DeepImmutable): Vector2 {\r\n return Vector2.CenterToRef(value1, value2, new Vector2());\r\n }\r\n\r\n /**\r\n * Gets the center of the vectors \"value1\" and \"value2\" and stores the result in the vector \"ref\"\r\n * Example Playground https://playground.babylonjs.com/#QYBWV4#66\r\n * @param value1 defines first vector\r\n * @param value2 defines second vector\r\n * @param ref defines third vector\r\n * @returns ref\r\n */\r\n public static CenterToRef(value1: DeepImmutable, value2: DeepImmutable, ref: T): T {\r\n return ref.copyFromFloats((value1.x + value2.x) / 2, (value1.y + value2.y) / 2);\r\n }\r\n\r\n /**\r\n * Gets the shortest distance (float) between the point \"p\" and the segment defined by the two points \"segA\" and \"segB\".\r\n * Example Playground https://playground.babylonjs.com/#QYBWV4#77\r\n * @param p defines the middle point\r\n * @param segA defines one point of the segment\r\n * @param segB defines the other point of the segment\r\n * @returns the shortest distance\r\n */\r\n public static DistanceOfPointFromSegment(p: DeepImmutable, segA: DeepImmutable, segB: DeepImmutable): number {\r\n const l2 = Vector2.DistanceSquared(segA, segB);\r\n if (l2 === 0.0) {\r\n return Vector2.Distance(p, segA);\r\n }\r\n const v = segB.subtract(segA);\r\n const t = Math.max(0, Math.min(1, Vector2.Dot(p.subtract(segA), v) / l2));\r\n const proj = segA.add(v.multiplyByFloats(t, t));\r\n return Vector2.Distance(p, proj);\r\n }\r\n}\r\nVector2 satisfies TensorStatic;\r\nObject.defineProperties(Vector2.prototype, {\r\n dimension: { value: [2] },\r\n rank: { value: 1 },\r\n});\r\n\r\n/**\r\n * Class used to store (x,y,z) vector representation\r\n * A Vector3 is the main object used in 3D geometry\r\n * It can represent either the coordinates of a point the space, either a direction\r\n * Reminder: js uses a left handed forward facing system\r\n * Example Playground - Overview - https://playground.babylonjs.com/#R1F8YU\r\n */\r\nexport class Vector3 implements Vector, Vector3LikeInternal>, IVector3Like {\r\n /**\r\n * If the first vector is flagged with integers (as everything is 0,0,0), V8 stores all of the properties as integers internally because it doesn't know any better yet.\r\n * If subsequent vectors are created with non-integer values, V8 determines that it would be best to represent these properties as doubles instead of integers,\r\n * and henceforth it will use floating-point representation for all Vector3 instances that it creates.\r\n * But the original Vector3 instances are unchanged and has a \"deprecated map\".\r\n * If we keep using the Vector3 instances from step 1, it will now be a poison pill which will mess up optimizations in any code it touches.\r\n */\r\n static _V8PerformanceHack = new Vector3(0.5, 0.5, 0.5) as DeepImmutable;\r\n private static _UpReadOnly = Vector3.Up() as DeepImmutable;\r\n private static _DownReadOnly = Vector3.Down() as DeepImmutable;\r\n private static _LeftHandedForwardReadOnly = Vector3.Forward(false) as DeepImmutable;\r\n private static _RightHandedForwardReadOnly = Vector3.Forward(true) as DeepImmutable;\r\n private static _LeftHandedBackwardReadOnly = Vector3.Backward(false) as DeepImmutable;\r\n private static _RightHandedBackwardReadOnly = Vector3.Backward(true) as DeepImmutable;\r\n private static _RightReadOnly = Vector3.Right() as DeepImmutable;\r\n private static _LeftReadOnly = Vector3.Left() as DeepImmutable;\r\n private static _ZeroReadOnly = Vector3.Zero() as DeepImmutable;\r\n private static _OneReadOnly = Vector3.One() as DeepImmutable;\r\n\r\n /**\r\n * @see Tensor.dimension\r\n */\r\n declare public readonly dimension: Readonly<[3]>;\r\n\r\n /**\r\n * @see Tensor.rank\r\n */\r\n declare public readonly rank: 1;\r\n\r\n /** @internal */\r\n public _x: number;\r\n\r\n /** @internal */\r\n public _y: number;\r\n\r\n /** @internal */\r\n public _z: number;\r\n\r\n /** @internal */\r\n public _isDirty = true;\r\n\r\n /** Gets or sets the x coordinate */\r\n public get x() {\r\n return this._x;\r\n }\r\n\r\n public set x(value: number) {\r\n this._x = value;\r\n this._isDirty = true;\r\n }\r\n\r\n /** Gets or sets the y coordinate */\r\n public get y() {\r\n return this._y;\r\n }\r\n\r\n public set y(value: number) {\r\n this._y = value;\r\n this._isDirty = true;\r\n }\r\n\r\n /** Gets or sets the z coordinate */\r\n public get z() {\r\n return this._z;\r\n }\r\n\r\n public set z(value: number) {\r\n this._z = value;\r\n this._isDirty = true;\r\n }\r\n\r\n /**\r\n * Creates a new Vector3 object from the given x, y, z (floats) coordinates.\r\n * @param x defines the first coordinates (on X axis)\r\n * @param y defines the second coordinates (on Y axis)\r\n * @param z defines the third coordinates (on Z axis)\r\n */\r\n constructor(x: number = 0, y: number = 0, z: number = 0) {\r\n this._x = x;\r\n this._y = y;\r\n this._z = z;\r\n }\r\n\r\n /**\r\n * Creates a string representation of the Vector3\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#67\r\n * @returns a string with the Vector3 coordinates.\r\n */\r\n public toString(): string {\r\n return `{X: ${this._x} Y: ${this._y} Z: ${this._z}}`;\r\n }\r\n\r\n /**\r\n * Gets the class name\r\n * @returns the string \"Vector3\"\r\n */\r\n public getClassName(): string {\r\n return \"Vector3\";\r\n }\r\n\r\n /**\r\n * Creates the Vector3 hash code\r\n * @returns a number which tends to be unique between Vector3 instances\r\n */\r\n public getHashCode(): number {\r\n const x = _ExtractAsInt(this._x);\r\n const y = _ExtractAsInt(this._y);\r\n const z = _ExtractAsInt(this._z);\r\n\r\n let hash = x;\r\n hash = (hash * 397) ^ y;\r\n hash = (hash * 397) ^ z;\r\n return hash;\r\n }\r\n\r\n // Operators\r\n\r\n /**\r\n * Creates an array containing three elements : the coordinates of the Vector3\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#10\r\n * @returns a new array of numbers\r\n */\r\n public asArray(): Tuple {\r\n return [this._x, this._y, this._z];\r\n }\r\n\r\n /**\r\n * Populates the given array or Float32Array from the given index with the successive coordinates of the Vector3\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#65\r\n * @param array defines the destination array\r\n * @param index defines the offset in the destination array\r\n * @returns the current Vector3\r\n */\r\n public toArray(array: FloatArray, index: number = 0): this {\r\n array[index] = this._x;\r\n array[index + 1] = this._y;\r\n array[index + 2] = this._z;\r\n return this;\r\n }\r\n\r\n /**\r\n * Update the current vector from an array\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#24\r\n * @param array defines the destination array\r\n * @param offset defines the offset in the destination array\r\n * @returns the current Vector3\r\n */\r\n public fromArray(array: DeepImmutable, offset: number = 0): this {\r\n Vector3.FromArrayToRef(array, offset, this);\r\n return this;\r\n }\r\n\r\n /**\r\n * Converts the current Vector3 into a quaternion (considering that the Vector3 contains Euler angles representation of a rotation)\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#66\r\n * @returns a new Quaternion object, computed from the Vector3 coordinates\r\n */\r\n public toQuaternion(): Quaternion {\r\n return Quaternion.RotationYawPitchRoll(this._y, this._x, this._z);\r\n }\r\n\r\n /**\r\n * Adds the given vector to the current Vector3\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#4\r\n * @param otherVector defines the second operand\r\n * @returns the current updated Vector3\r\n */\r\n public addInPlace(otherVector: DeepImmutable): this {\r\n this._x += otherVector._x;\r\n this._y += otherVector._y;\r\n this._z += otherVector._z;\r\n this._isDirty = true;\r\n return this;\r\n }\r\n\r\n /**\r\n * Adds the given coordinates to the current Vector3\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#5\r\n * @param x defines the x coordinate of the operand\r\n * @param y defines the y coordinate of the operand\r\n * @param z defines the z coordinate of the operand\r\n * @returns the current updated Vector3\r\n */\r\n public addInPlaceFromFloats(x: number, y: number, z: number): this {\r\n this._x += x;\r\n this._y += y;\r\n this._z += z;\r\n this._isDirty = true;\r\n return this;\r\n }\r\n\r\n /**\r\n * Gets a new Vector3, result of the addition the current Vector3 and the given vector\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#3\r\n * @param otherVector defines the second operand\r\n * @returns the resulting Vector3\r\n */\r\n public add(otherVector: DeepImmutable): Vector3 {\r\n return new Vector3(this._x + otherVector._x, this._y + otherVector._y, this._z + otherVector._z);\r\n }\r\n\r\n /**\r\n * Adds the current Vector3 to the given one and stores the result in the vector \"result\"\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#6\r\n * @param otherVector defines the second operand\r\n * @param result defines the Vector3 object where to store the result\r\n * @returns the result\r\n */\r\n public addToRef(otherVector: DeepImmutable, result: T): T {\r\n result._x = this._x + otherVector._x;\r\n result._y = this._y + otherVector._y;\r\n result._z = this._z + otherVector._z;\r\n result._isDirty = true;\r\n return result;\r\n }\r\n\r\n /**\r\n * Subtract the given vector from the current Vector3\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#61\r\n * @param otherVector defines the second operand\r\n * @returns the current updated Vector3\r\n */\r\n public subtractInPlace(otherVector: DeepImmutable): this {\r\n this._x -= otherVector._x;\r\n this._y -= otherVector._y;\r\n this._z -= otherVector._z;\r\n this._isDirty = true;\r\n return this;\r\n }\r\n\r\n /**\r\n * Returns a new Vector3, result of the subtraction of the given vector from the current Vector3\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#60\r\n * @param otherVector defines the second operand\r\n * @returns the resulting Vector3\r\n */\r\n public subtract(otherVector: DeepImmutable): Vector3 {\r\n return new Vector3(this._x - otherVector._x, this._y - otherVector._y, this._z - otherVector._z);\r\n }\r\n\r\n /**\r\n * Subtracts the given vector from the current Vector3 and stores the result in the vector \"result\".\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#63\r\n * @param otherVector defines the second operand\r\n * @param result defines the Vector3 object where to store the result\r\n * @returns the result\r\n */\r\n public subtractToRef(otherVector: DeepImmutable, result: T): T {\r\n return this.subtractFromFloatsToRef(otherVector._x, otherVector._y, otherVector._z, result);\r\n }\r\n\r\n /**\r\n * Returns a new Vector3 set with the subtraction of the given floats from the current Vector3 coordinates\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#62\r\n * @param x defines the x coordinate of the operand\r\n * @param y defines the y coordinate of the operand\r\n * @param z defines the z coordinate of the operand\r\n * @returns the resulting Vector3\r\n */\r\n public subtractFromFloats(x: number, y: number, z: number): Vector3 {\r\n return new Vector3(this._x - x, this._y - y, this._z - z);\r\n }\r\n\r\n /**\r\n * Subtracts the given floats from the current Vector3 coordinates and set the given vector \"result\" with this result\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#64\r\n * @param x defines the x coordinate of the operand\r\n * @param y defines the y coordinate of the operand\r\n * @param z defines the z coordinate of the operand\r\n * @param result defines the Vector3 object where to store the result\r\n * @returns the result\r\n */\r\n public subtractFromFloatsToRef(x: number, y: number, z: number, result: T): T {\r\n result._x = this._x - x;\r\n result._y = this._y - y;\r\n result._z = this._z - z;\r\n result._isDirty = true;\r\n return result;\r\n }\r\n\r\n /**\r\n * Gets a new Vector3 set with the current Vector3 negated coordinates\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#35\r\n * @returns a new Vector3\r\n */\r\n public negate(): Vector3 {\r\n return new Vector3(-this._x, -this._y, -this._z);\r\n }\r\n\r\n /**\r\n * Negate this vector in place\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#36\r\n * @returns this\r\n */\r\n public negateInPlace(): this {\r\n this._x *= -1;\r\n this._y *= -1;\r\n this._z *= -1;\r\n this._isDirty = true;\r\n return this;\r\n }\r\n\r\n /**\r\n * Negate the current Vector3 and stores the result in the given vector \"result\" coordinates\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#37\r\n * @param result defines the Vector3 object where to store the result\r\n * @returns the result\r\n */\r\n public negateToRef(result: T): T {\r\n result._x = this._x * -1;\r\n result._y = this._y * -1;\r\n result._z = this._z * -1;\r\n result._isDirty = true;\r\n return result;\r\n }\r\n\r\n /**\r\n * Multiplies the Vector3 coordinates by the float \"scale\"\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#56\r\n * @param scale defines the multiplier factor\r\n * @returns the current updated Vector3\r\n */\r\n public scaleInPlace(scale: number): this {\r\n this._x *= scale;\r\n this._y *= scale;\r\n this._z *= scale;\r\n this._isDirty = true;\r\n return this;\r\n }\r\n\r\n /**\r\n * Returns a new Vector3 set with the current Vector3 coordinates multiplied by the float \"scale\"\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#53\r\n * @param scale defines the multiplier factor\r\n * @returns a new Vector3\r\n */\r\n public scale(scale: number): Vector3 {\r\n return new Vector3(this._x * scale, this._y * scale, this._z * scale);\r\n }\r\n\r\n /**\r\n * Multiplies the current Vector3 coordinates by the float \"scale\" and stores the result in the given vector \"result\" coordinates\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#57\r\n * @param scale defines the multiplier factor\r\n * @param result defines the Vector3 object where to store the result\r\n * @returns the result\r\n */\r\n public scaleToRef(scale: number, result: T): T {\r\n result._x = this._x * scale;\r\n result._y = this._y * scale;\r\n result._z = this._z * scale;\r\n result._isDirty = true;\r\n return result;\r\n }\r\n\r\n /**\r\n * Creates a vector normal (perpendicular) to the current Vector3 and stores the result in the given vector\r\n * Out of the infinite possibilities the normal chosen is the one formed by rotating the current vector\r\n * 90 degrees about an axis which lies perpendicular to the current vector\r\n * and its projection on the xz plane. In the case of a current vector in the xz plane\r\n * the normal is calculated to be along the y axis.\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#230\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#231\r\n * @param result defines the Vector3 object where to store the resultant normal\r\n * @returns the result\r\n */\r\n public getNormalToRef(result: Vector3): Vector3 {\r\n /**\r\n * Calculates the spherical coordinates of the current vector\r\n * so saves on memory rather than importing whole Spherical Class\r\n */\r\n const radius: number = this.length();\r\n let theta: number = Math.acos(this.y / radius);\r\n const phi = Math.atan2(this.z, this.x);\r\n //makes angle 90 degs to current vector\r\n if (theta > Math.PI / 2) {\r\n theta -= Math.PI / 2;\r\n } else {\r\n theta += Math.PI / 2;\r\n }\r\n //Calculates resutant normal vector from spherical coordinate of perpendicular vector\r\n const x = radius * Math.sin(theta) * Math.cos(phi);\r\n const y = radius * Math.cos(theta);\r\n const z = radius * Math.sin(theta) * Math.sin(phi);\r\n result.set(x, y, z);\r\n return result;\r\n }\r\n\r\n /**\r\n * Rotates the vector using the given unit quaternion and stores the new vector in result\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#9\r\n * @param q the unit quaternion representing the rotation\r\n * @param result the output vector\r\n * @returns the result\r\n */\r\n public applyRotationQuaternionToRef(q: Quaternion, result: T): T {\r\n // Derived from https://raw.org/proof/vector-rotation-using-quaternions/\r\n\r\n const vx = this._x,\r\n vy = this._y,\r\n vz = this._z;\r\n const qx = q._x,\r\n qy = q._y,\r\n qz = q._z,\r\n qw = q._w;\r\n\r\n // t = 2q x v\r\n const tx = 2 * (qy * vz - qz * vy);\r\n const ty = 2 * (qz * vx - qx * vz);\r\n const tz = 2 * (qx * vy - qy * vx);\r\n\r\n // v + w t + q x t\r\n result._x = vx + qw * tx + qy * tz - qz * ty;\r\n result._y = vy + qw * ty + qz * tx - qx * tz;\r\n result._z = vz + qw * tz + qx * ty - qy * tx;\r\n\r\n result._isDirty = true;\r\n return result;\r\n }\r\n\r\n /**\r\n * Rotates the vector in place using the given unit quaternion\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#8\r\n * @param q the unit quaternion representing the rotation\r\n * @returns the current updated Vector3\r\n */\r\n public applyRotationQuaternionInPlace(q: Quaternion): this {\r\n return this.applyRotationQuaternionToRef(q, this);\r\n }\r\n\r\n /**\r\n * Rotates the vector using the given unit quaternion and returns the new vector\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#7\r\n * @param q the unit quaternion representing the rotation\r\n * @returns a new Vector3\r\n */\r\n public applyRotationQuaternion(q: Quaternion): Vector3 {\r\n return this.applyRotationQuaternionToRef(q, new Vector3());\r\n }\r\n\r\n /**\r\n * Scale the current Vector3 values by a factor and add the result to a given Vector3\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#55\r\n * @param scale defines the scale factor\r\n * @param result defines the Vector3 object where to store the result\r\n * @returns result input\r\n */\r\n public scaleAndAddToRef(scale: number, result: T): T {\r\n result._x += this._x * scale;\r\n result._y += this._y * scale;\r\n result._z += this._z * scale;\r\n result._isDirty = true;\r\n return result;\r\n }\r\n\r\n /**\r\n * Projects the current point Vector3 to a plane along a ray starting from a specified origin and passing through the current point Vector3.\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#48\r\n * @param plane defines the plane to project to\r\n * @param origin defines the origin of the projection ray\r\n * @returns the projected vector3\r\n */\r\n public projectOnPlane(plane: Plane, origin: Vector3): Vector3 {\r\n return this.projectOnPlaneToRef(plane, origin, new Vector3());\r\n }\r\n\r\n /**\r\n * Projects the current point Vector3 to a plane along a ray starting from a specified origin and passing through the current point Vector3.\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#49\r\n * @param plane defines the plane to project to\r\n * @param origin defines the origin of the projection ray\r\n * @param result defines the Vector3 where to store the result\r\n * @returns result input\r\n */\r\n public projectOnPlaneToRef(plane: Plane, origin: Vector3, result: T): T {\r\n const n = plane.normal;\r\n const d = plane.d;\r\n\r\n const V = MathTmp.Vector3[0];\r\n\r\n // ray direction\r\n this.subtractToRef(origin, V);\r\n\r\n V.normalize();\r\n\r\n const denom = Vector3.Dot(V, n);\r\n\r\n //When the ray is close to parallel to the plane return infinity vector\r\n if (Math.abs(denom) < 0.0000000001) {\r\n result.setAll(Infinity);\r\n } else {\r\n const t = -(Vector3.Dot(origin, n) + d) / denom;\r\n\r\n // P = P0 + t*V\r\n const scaledV = V.scaleInPlace(t);\r\n origin.addToRef(scaledV, result);\r\n }\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Returns true if the current Vector3 and the given vector coordinates are strictly equal\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#19\r\n * @param otherVector defines the second operand\r\n * @returns true if both vectors are equals\r\n */\r\n public equals(otherVector: DeepImmutable): boolean {\r\n return otherVector && this._x === otherVector._x && this._y === otherVector._y && this._z === otherVector._z;\r\n }\r\n\r\n /**\r\n * Returns true if the current Vector3 and the given vector coordinates are distant less than epsilon\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#21\r\n * @param otherVector defines the second operand\r\n * @param epsilon defines the minimal distance to define values as equals\r\n * @returns true if both vectors are distant less than epsilon\r\n */\r\n public equalsWithEpsilon(otherVector: DeepImmutable, epsilon: number = Epsilon): boolean {\r\n return otherVector && WithinEpsilon(this._x, otherVector._x, epsilon) && WithinEpsilon(this._y, otherVector._y, epsilon) && WithinEpsilon(this._z, otherVector._z, epsilon);\r\n }\r\n\r\n /**\r\n * Returns true if the current Vector3 coordinates equals the given floats\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#20\r\n * @param x defines the x coordinate of the operand\r\n * @param y defines the y coordinate of the operand\r\n * @param z defines the z coordinate of the operand\r\n * @returns true if both vectors are equal\r\n */\r\n public equalsToFloats(x: number, y: number, z: number): boolean {\r\n return this._x === x && this._y === y && this._z === z;\r\n }\r\n\r\n /**\r\n * Multiplies the current Vector3 coordinates by the given ones\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#32\r\n * @param otherVector defines the second operand\r\n * @returns the current updated Vector3\r\n */\r\n public multiplyInPlace(otherVector: DeepImmutable): this {\r\n this._x *= otherVector._x;\r\n this._y *= otherVector._y;\r\n this._z *= otherVector._z;\r\n this._isDirty = true;\r\n return this;\r\n }\r\n\r\n /**\r\n * Returns a new Vector3, result of the multiplication of the current Vector3 by the given vector\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#31\r\n * @param otherVector defines the second operand\r\n * @returns the new Vector3\r\n */\r\n public multiply(otherVector: DeepImmutable): Vector3 {\r\n return this.multiplyByFloats(otherVector._x, otherVector._y, otherVector._z);\r\n }\r\n\r\n /**\r\n * Multiplies the current Vector3 by the given one and stores the result in the given vector \"result\"\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#33\r\n * @param otherVector defines the second operand\r\n * @param result defines the Vector3 object where to store the result\r\n * @returns the result\r\n */\r\n public multiplyToRef(otherVector: DeepImmutable, result: T): T {\r\n result._x = this._x * otherVector._x;\r\n result._y = this._y * otherVector._y;\r\n result._z = this._z * otherVector._z;\r\n result._isDirty = true;\r\n return result;\r\n }\r\n\r\n /**\r\n * Returns a new Vector3 set with the result of the multiplication of the current Vector3 coordinates by the given floats\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#34\r\n * @param x defines the x coordinate of the operand\r\n * @param y defines the y coordinate of the operand\r\n * @param z defines the z coordinate of the operand\r\n * @returns the new Vector3\r\n */\r\n public multiplyByFloats(x: number, y: number, z: number): Vector3 {\r\n return new Vector3(this._x * x, this._y * y, this._z * z);\r\n }\r\n\r\n /**\r\n * Returns a new Vector3 set with the result of the division of the current Vector3 coordinates by the given ones\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#16\r\n * @param otherVector defines the second operand\r\n * @returns the new Vector3\r\n */\r\n public divide(otherVector: DeepImmutable): Vector3 {\r\n return new Vector3(this._x / otherVector._x, this._y / otherVector._y, this._z / otherVector._z);\r\n }\r\n\r\n /**\r\n * Divides the current Vector3 coordinates by the given ones and stores the result in the given vector \"result\"\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#18\r\n * @param otherVector defines the second operand\r\n * @param result defines the Vector3 object where to store the result\r\n * @returns the result\r\n */\r\n public divideToRef(otherVector: DeepImmutable, result: T): T {\r\n result._x = this._x / otherVector._x;\r\n result._y = this._y / otherVector._y;\r\n result._z = this._z / otherVector._z;\r\n result._isDirty = true;\r\n return result;\r\n }\r\n\r\n /**\r\n * Divides the current Vector3 coordinates by the given ones.\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#17\r\n * @param otherVector defines the second operand\r\n * @returns the current updated Vector3\r\n */\r\n public divideInPlace(otherVector: DeepImmutable): this {\r\n this._x = this._x / otherVector._x;\r\n this._y = this._y / otherVector._y;\r\n this._z = this._z / otherVector._z;\r\n this._isDirty = true;\r\n return this;\r\n }\r\n\r\n /**\r\n * Updates the current Vector3 with the minimal coordinate values between its and the given vector ones\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#29\r\n * @param other defines the second operand\r\n * @returns the current updated Vector3\r\n */\r\n public minimizeInPlace(other: DeepImmutable): this {\r\n return this.minimizeInPlaceFromFloats(other._x, other._y, other._z);\r\n }\r\n\r\n /**\r\n * Updates the current Vector3 with the maximal coordinate values between its and the given vector ones.\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#27\r\n * @param other defines the second operand\r\n * @returns the current updated Vector3\r\n */\r\n public maximizeInPlace(other: DeepImmutable): this {\r\n return this.maximizeInPlaceFromFloats(other._x, other._y, other._z);\r\n }\r\n\r\n /**\r\n * Updates the current Vector3 with the minimal coordinate values between its and the given coordinates\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#30\r\n * @param x defines the x coordinate of the operand\r\n * @param y defines the y coordinate of the operand\r\n * @param z defines the z coordinate of the operand\r\n * @returns the current updated Vector3\r\n */\r\n public minimizeInPlaceFromFloats(x: number, y: number, z: number): this {\r\n if (x < this._x) {\r\n this.x = x;\r\n }\r\n if (y < this._y) {\r\n this.y = y;\r\n }\r\n if (z < this._z) {\r\n this.z = z;\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Updates the current Vector3 with the maximal coordinate values between its and the given coordinates.\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#28\r\n * @param x defines the x coordinate of the operand\r\n * @param y defines the y coordinate of the operand\r\n * @param z defines the z coordinate of the operand\r\n * @returns the current updated Vector3\r\n */\r\n public maximizeInPlaceFromFloats(x: number, y: number, z: number): this {\r\n if (x > this._x) {\r\n this.x = x;\r\n }\r\n if (y > this._y) {\r\n this.y = y;\r\n }\r\n if (z > this._z) {\r\n this.z = z;\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Due to float precision, scale of a mesh could be uniform but float values are off by a small fraction\r\n * Check if is non uniform within a certain amount of decimal places to account for this\r\n * @param epsilon the amount the values can differ\r\n * @returns if the vector is non uniform to a certain number of decimal places\r\n */\r\n public isNonUniformWithinEpsilon(epsilon: number) {\r\n const absX = Math.abs(this._x);\r\n const absY = Math.abs(this._y);\r\n if (!WithinEpsilon(absX, absY, epsilon)) {\r\n return true;\r\n }\r\n\r\n const absZ = Math.abs(this._z);\r\n if (!WithinEpsilon(absX, absZ, epsilon)) {\r\n return true;\r\n }\r\n\r\n if (!WithinEpsilon(absY, absZ, epsilon)) {\r\n return true;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n /**\r\n * Gets a boolean indicating that the vector is non uniform meaning x, y or z are not all the same\r\n */\r\n public get isNonUniform(): boolean {\r\n const absX = Math.abs(this._x);\r\n const absY = Math.abs(this._y);\r\n if (absX !== absY) {\r\n return true;\r\n }\r\n\r\n const absZ = Math.abs(this._z);\r\n if (absX !== absZ) {\r\n return true;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n /**\r\n * Gets the current Vector3's floored values and stores them in result\r\n * @param result the vector to store the result in\r\n * @returns the result vector\r\n */\r\n public floorToRef(result: T): T {\r\n result._x = Math.floor(this._x);\r\n result._y = Math.floor(this._y);\r\n result._z = Math.floor(this._z);\r\n result._isDirty = true;\r\n return result;\r\n }\r\n\r\n /**\r\n * Gets a new Vector3 from current Vector3 floored values\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#22\r\n * @returns a new Vector3\r\n */\r\n public floor(): Vector3 {\r\n return new Vector3(Math.floor(this.x), Math.floor(this.y), Math.floor(this.z));\r\n }\r\n\r\n /**\r\n * Gets the current Vector3's fractional values and stores them in result\r\n * @param result the vector to store the result in\r\n * @returns the result vector\r\n */\r\n public fractToRef(result: T): T {\r\n result._x = this.x - Math.floor(this._x);\r\n result._y = this.y - Math.floor(this._y);\r\n result._z = this.z - Math.floor(this._z);\r\n result._isDirty = true;\r\n return result;\r\n }\r\n\r\n /**\r\n * Gets a new Vector3 from current Vector3 fractional values\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#23\r\n * @returns a new Vector3\r\n */\r\n public fract(): Vector3 {\r\n return new Vector3(this.x - Math.floor(this._x), this.y - Math.floor(this._y), this.z - Math.floor(this._z));\r\n }\r\n\r\n // Properties\r\n /**\r\n * Gets the length of the Vector3\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#25\r\n * @returns the length of the Vector3\r\n */\r\n public length(): number {\r\n return Math.sqrt(this.lengthSquared());\r\n }\r\n\r\n /**\r\n * Gets the squared length of the Vector3\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#26\r\n * @returns squared length of the Vector3\r\n */\r\n public lengthSquared(): number {\r\n return this._x * this._x + this._y * this._y + this._z * this._z;\r\n }\r\n\r\n /**\r\n * Gets a boolean indicating if the vector contains a zero in one of its components\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#1\r\n */\r\n public get hasAZeroComponent(): boolean {\r\n return this._x * this._y * this._z === 0;\r\n }\r\n\r\n /**\r\n * Normalize the current Vector3.\r\n * Please note that this is an in place operation.\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#122\r\n * @returns the current updated Vector3\r\n */\r\n public normalize(): this {\r\n return this.normalizeFromLength(this.length());\r\n }\r\n\r\n /**\r\n * Reorders the x y z properties of the vector in place\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#44\r\n * @param order new ordering of the properties (eg. for vector 1,2,3 with \"ZYX\" will produce 3,2,1)\r\n * @returns the current updated vector\r\n */\r\n public reorderInPlace(order: string) {\r\n order = order.toLowerCase();\r\n if (order === \"xyz\") {\r\n return this;\r\n }\r\n const tem = MathTmp.Vector3[0].copyFrom(this);\r\n this.x = (tem)[order[0]];\r\n this.y = (tem)[order[1]];\r\n this.z = (tem)[order[2]];\r\n return this;\r\n }\r\n\r\n /**\r\n * Rotates the vector around 0,0,0 by a quaternion\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#47\r\n * @param quaternion the rotation quaternion\r\n * @param result vector to store the result\r\n * @returns the resulting vector\r\n */\r\n public rotateByQuaternionToRef(quaternion: Quaternion, result: T): T {\r\n quaternion.toRotationMatrix(MathTmp.Matrix[0]);\r\n Vector3.TransformCoordinatesToRef(this, MathTmp.Matrix[0], result);\r\n return result;\r\n }\r\n\r\n /**\r\n * Rotates a vector around a given point\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#46\r\n * @param quaternion the rotation quaternion\r\n * @param point the point to rotate around\r\n * @param result vector to store the result\r\n * @returns the resulting vector\r\n */\r\n public rotateByQuaternionAroundPointToRef(quaternion: Quaternion, point: Vector3, result: T): T {\r\n this.subtractToRef(point, MathTmp.Vector3[0]);\r\n MathTmp.Vector3[0].rotateByQuaternionToRef(quaternion, MathTmp.Vector3[0]);\r\n point.addToRef(MathTmp.Vector3[0], result);\r\n return result;\r\n }\r\n\r\n /**\r\n * Returns a new Vector3 as the cross product of the current vector and the \"other\" one\r\n * The cross product is then orthogonal to both current and \"other\"\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#14\r\n * @param other defines the right operand\r\n * @returns the cross product\r\n */\r\n public cross(other: Vector3): Vector3 {\r\n return Vector3.CrossToRef(this, other, new Vector3());\r\n }\r\n\r\n /**\r\n * Normalize the current Vector3 with the given input length.\r\n * Please note that this is an in place operation.\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#123\r\n * @param len the length of the vector\r\n * @returns the current updated Vector3\r\n */\r\n public normalizeFromLength(len: number): this {\r\n if (len === 0 || len === 1.0) {\r\n return this;\r\n }\r\n\r\n return this.scaleInPlace(1.0 / len);\r\n }\r\n\r\n /**\r\n * Normalize the current Vector3 to a new vector\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#124\r\n * @returns the new Vector3\r\n */\r\n public normalizeToNew(): Vector3 {\r\n return this.normalizeToRef(new Vector3());\r\n }\r\n\r\n /**\r\n * Normalize the current Vector3 to the reference\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#125\r\n * @param result define the Vector3 to update\r\n * @returns the updated Vector3\r\n */\r\n public normalizeToRef(result: T): T {\r\n const len = this.length();\r\n if (len === 0 || len === 1.0) {\r\n result._x = this._x;\r\n result._y = this._y;\r\n result._z = this._z;\r\n result._isDirty = true;\r\n return result;\r\n }\r\n\r\n return this.scaleToRef(1.0 / len, result);\r\n }\r\n\r\n /**\r\n * Creates a new Vector3 copied from the current Vector3\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#11\r\n * @returns the new Vector3\r\n */\r\n public clone(): Vector3 {\r\n return new Vector3(this._x, this._y, this._z);\r\n }\r\n\r\n /**\r\n * Copies the given vector coordinates to the current Vector3 ones\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#12\r\n * @param source defines the source Vector3\r\n * @returns the current updated Vector3\r\n */\r\n public copyFrom(source: DeepImmutable): this {\r\n return this.copyFromFloats(source._x, source._y, source._z);\r\n }\r\n\r\n /**\r\n * Copies the given floats to the current Vector3 coordinates\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#13\r\n * @param x defines the x coordinate of the operand\r\n * @param y defines the y coordinate of the operand\r\n * @param z defines the z coordinate of the operand\r\n * @returns the current updated Vector3\r\n */\r\n public copyFromFloats(x: number, y: number, z: number): this {\r\n this._x = x;\r\n this._y = y;\r\n this._z = z;\r\n this._isDirty = true;\r\n return this;\r\n }\r\n\r\n /**\r\n * Copies the given floats to the current Vector3 coordinates\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#58\r\n * @param x defines the x coordinate of the operand\r\n * @param y defines the y coordinate of the operand\r\n * @param z defines the z coordinate of the operand\r\n * @returns the current updated Vector3\r\n */\r\n public set(x: number, y: number, z: number): this {\r\n return this.copyFromFloats(x, y, z);\r\n }\r\n\r\n /**\r\n * Copies the given float to the current Vector3 coordinates\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#59\r\n * @param v defines the x, y and z coordinates of the operand\r\n * @returns the current updated Vector3\r\n */\r\n public setAll(v: number): this {\r\n this._x = this._y = this._z = v;\r\n this._isDirty = true;\r\n return this;\r\n }\r\n\r\n // Statics\r\n\r\n /**\r\n * Get the clip factor between two vectors\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#126\r\n * @param vector0 defines the first operand\r\n * @param vector1 defines the second operand\r\n * @param axis defines the axis to use\r\n * @param size defines the size along the axis\r\n * @returns the clip factor\r\n */\r\n public static GetClipFactor(vector0: DeepImmutable, vector1: DeepImmutable, axis: DeepImmutable, size: number): number {\r\n const d0 = Vector3.Dot(vector0, axis);\r\n const d1 = Vector3.Dot(vector1, axis);\r\n\r\n return (d0 - size) / (d0 - d1);\r\n }\r\n\r\n /**\r\n * Get angle between two vectors\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#86\r\n * @param vector0 the starting point\r\n * @param vector1 the ending point\r\n * @param normal direction of the normal\r\n * @returns the angle between vector0 and vector1\r\n */\r\n public static GetAngleBetweenVectors(vector0: DeepImmutable, vector1: DeepImmutable, normal: DeepImmutable): number {\r\n const v0: Vector3 = vector0.normalizeToRef(MathTmp.Vector3[1]);\r\n const v1: Vector3 = vector1.normalizeToRef(MathTmp.Vector3[2]);\r\n let dot: number = Vector3.Dot(v0, v1);\r\n // Vectors are normalized so dot will be in [-1, 1] (aside precision issues enough to break the result which explains the below clamp)\r\n dot = Clamp(dot, -1, 1);\r\n\r\n const angle = Math.acos(dot);\r\n const n = MathTmp.Vector3[3];\r\n Vector3.CrossToRef(v0, v1, n);\r\n if (Vector3.Dot(n, normal) > 0) {\r\n return isNaN(angle) ? 0 : angle;\r\n }\r\n return isNaN(angle) ? -Math.PI : -Math.acos(dot);\r\n }\r\n\r\n /**\r\n * Get angle between two vectors projected on a plane\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#87\r\n * Expectation compute time: 0.01 ms (median) and 0.02 ms (percentile 95%)\r\n * @param vector0 angle between vector0 and vector1\r\n * @param vector1 angle between vector0 and vector1\r\n * @param normal Normal of the projection plane\r\n * @returns the angle in radians (float) between vector0 and vector1 projected on the plane with the specified normal\r\n */\r\n public static GetAngleBetweenVectorsOnPlane(vector0: DeepImmutable, vector1: DeepImmutable, normal: DeepImmutable): number {\r\n MathTmp.Vector3[0].copyFrom(vector0);\r\n const v0 = MathTmp.Vector3[0];\r\n MathTmp.Vector3[1].copyFrom(vector1);\r\n const v1 = MathTmp.Vector3[1];\r\n MathTmp.Vector3[2].copyFrom(normal);\r\n const vNormal = MathTmp.Vector3[2];\r\n const right = MathTmp.Vector3[3];\r\n const forward = MathTmp.Vector3[4];\r\n\r\n v0.normalize();\r\n v1.normalize();\r\n vNormal.normalize();\r\n\r\n Vector3.CrossToRef(vNormal, v0, right);\r\n Vector3.CrossToRef(right, vNormal, forward);\r\n\r\n const angle = Math.atan2(Vector3.Dot(v1, right), Vector3.Dot(v1, forward));\r\n\r\n return NormalizeRadians(angle);\r\n }\r\n\r\n /**\r\n * Gets the rotation that aligns the roll axis (Y) to the line joining the start point to the target point and stores it in the ref Vector3\r\n * Example PG https://playground.babylonjs.com/#R1F8YU#189\r\n * @param start the starting point\r\n * @param target the target point\r\n * @param ref the vector3 to store the result\r\n * @returns ref in the form (pitch, yaw, 0)\r\n */\r\n public static PitchYawRollToMoveBetweenPointsToRef(start: Vector3, target: Vector3, ref: T): T {\r\n const diff = TmpVectors.Vector3[0];\r\n target.subtractToRef(start, diff);\r\n ref._y = Math.atan2(diff.x, diff.z) || 0;\r\n ref._x = Math.atan2(Math.sqrt(diff.x ** 2 + diff.z ** 2), diff.y) || 0;\r\n ref._z = 0;\r\n ref._isDirty = true;\r\n return ref;\r\n }\r\n\r\n /**\r\n * Gets the rotation that aligns the roll axis (Y) to the line joining the start point to the target point\r\n * Example PG https://playground.babylonjs.com/#R1F8YU#188\r\n * @param start the starting point\r\n * @param target the target point\r\n * @returns the rotation in the form (pitch, yaw, 0)\r\n */\r\n public static PitchYawRollToMoveBetweenPoints(start: Vector3, target: Vector3): Vector3 {\r\n const ref = Vector3.Zero();\r\n return Vector3.PitchYawRollToMoveBetweenPointsToRef(start, target, ref);\r\n }\r\n\r\n /**\r\n * Slerp between two vectors. See also `SmoothToRef`\r\n * Slerp is a spherical linear interpolation\r\n * giving a slow in and out effect\r\n * Example Playground 1 https://playground.babylonjs.com/#R1F8YU#108\r\n * Example Playground 2 https://playground.babylonjs.com/#R1F8YU#109\r\n * @param vector0 Start vector\r\n * @param vector1 End vector\r\n * @param slerp amount (will be clamped between 0 and 1)\r\n * @param result The slerped vector\r\n * @returns The slerped vector\r\n */\r\n public static SlerpToRef(vector0: Vector3, vector1: Vector3, slerp: number, result: T): T {\r\n slerp = Clamp(slerp, 0, 1);\r\n const vector0Dir = MathTmp.Vector3[0];\r\n const vector1Dir = MathTmp.Vector3[1];\r\n\r\n vector0Dir.copyFrom(vector0);\r\n const vector0Length = vector0Dir.length();\r\n vector0Dir.normalizeFromLength(vector0Length);\r\n\r\n vector1Dir.copyFrom(vector1);\r\n const vector1Length = vector1Dir.length();\r\n vector1Dir.normalizeFromLength(vector1Length);\r\n\r\n const dot = Vector3.Dot(vector0Dir, vector1Dir);\r\n\r\n let scale0;\r\n let scale1;\r\n\r\n if (dot < 1 - Epsilon) {\r\n const omega = Math.acos(dot);\r\n const invSin = 1 / Math.sin(omega);\r\n scale0 = Math.sin((1 - slerp) * omega) * invSin;\r\n scale1 = Math.sin(slerp * omega) * invSin;\r\n } else {\r\n // Use linear interpolation\r\n scale0 = 1 - slerp;\r\n scale1 = slerp;\r\n }\r\n\r\n vector0Dir.scaleInPlace(scale0);\r\n vector1Dir.scaleInPlace(scale1);\r\n result.copyFrom(vector0Dir).addInPlace(vector1Dir);\r\n result.scaleInPlace(Lerp(vector0Length, vector1Length, slerp));\r\n return result;\r\n }\r\n\r\n /**\r\n * Smooth interpolation between two vectors using Slerp\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#110\r\n * @param source source vector\r\n * @param goal goal vector\r\n * @param deltaTime current interpolation frame\r\n * @param lerpTime total interpolation time\r\n * @param result the smoothed vector\r\n * @returns the smoothed vector\r\n */\r\n public static SmoothToRef(source: Vector3, goal: Vector3, deltaTime: number, lerpTime: number, result: T): T {\r\n Vector3.SlerpToRef(source, goal, lerpTime === 0 ? 1 : deltaTime / lerpTime, result);\r\n return result;\r\n }\r\n\r\n /**\r\n * Returns a new Vector3 set from the index \"offset\" of the given array\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#83\r\n * @param array defines the source array\r\n * @param offset defines the offset in the source array\r\n * @returns the new Vector3\r\n */\r\n public static FromArray(array: DeepImmutable>, offset: number = 0): Vector3 {\r\n return new Vector3(array[offset], array[offset + 1], array[offset + 2]);\r\n }\r\n\r\n /**\r\n * Returns a new Vector3 set from the index \"offset\" of the given Float32Array\r\n * @param array defines the source array\r\n * @param offset defines the offset in the source array\r\n * @returns the new Vector3\r\n * @deprecated Please use FromArray instead.\r\n */\r\n public static FromFloatArray(array: DeepImmutable, offset?: number): Vector3 {\r\n return Vector3.FromArray(array, offset);\r\n }\r\n\r\n /**\r\n * Sets the given vector \"result\" with the element values from the index \"offset\" of the given array\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#84\r\n * @param array defines the source array\r\n * @param offset defines the offset in the source array\r\n * @param result defines the Vector3 where to store the result\r\n * @returns result input\r\n */\r\n public static FromArrayToRef(array: DeepImmutable>, offset: number, result: T): T {\r\n result._x = array[offset];\r\n result._y = array[offset + 1];\r\n result._z = array[offset + 2];\r\n result._isDirty = true;\r\n return result;\r\n }\r\n\r\n /**\r\n * Sets the given vector \"result\" with the element values from the index \"offset\" of the given Float32Array\r\n * @param array defines the source array\r\n * @param offset defines the offset in the source array\r\n * @param result defines the Vector3 where to store the result\r\n * @deprecated Please use FromArrayToRef instead.\r\n * @returns result input\r\n */\r\n public static FromFloatArrayToRef(array: DeepImmutable, offset: number, result: T): T {\r\n return Vector3.FromArrayToRef(array, offset, result);\r\n }\r\n\r\n /**\r\n * Sets the given vector \"result\" with the given floats.\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#85\r\n * @param x defines the x coordinate of the source\r\n * @param y defines the y coordinate of the source\r\n * @param z defines the z coordinate of the source\r\n * @param result defines the Vector3 where to store the result\r\n * @returns the result vector\r\n */\r\n public static FromFloatsToRef(x: number, y: number, z: number, result: T): T {\r\n result.copyFromFloats(x, y, z);\r\n return result;\r\n }\r\n\r\n /**\r\n * Returns a new Vector3 set to (0.0, 0.0, 0.0)\r\n * @returns a new empty Vector3\r\n */\r\n public static Zero(): Vector3 {\r\n return new Vector3(0.0, 0.0, 0.0);\r\n }\r\n /**\r\n * Returns a new Vector3 set to (1.0, 1.0, 1.0)\r\n * @returns a new Vector3\r\n */\r\n public static One(): Vector3 {\r\n return new Vector3(1.0, 1.0, 1.0);\r\n }\r\n /**\r\n * Returns a new Vector3 set to (0.0, 1.0, 0.0)\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#71\r\n * @returns a new up Vector3\r\n */\r\n public static Up(): Vector3 {\r\n return new Vector3(0.0, 1.0, 0.0);\r\n }\r\n\r\n /**\r\n * Gets an up Vector3 that must not be updated\r\n */\r\n public static get UpReadOnly(): DeepImmutable {\r\n return Vector3._UpReadOnly;\r\n }\r\n\r\n /**\r\n * Gets a down Vector3 that must not be updated\r\n */\r\n public static get DownReadOnly(): DeepImmutable {\r\n return Vector3._DownReadOnly;\r\n }\r\n\r\n /**\r\n * Gets a right Vector3 that must not be updated\r\n */\r\n public static get RightReadOnly(): DeepImmutable {\r\n return Vector3._RightReadOnly;\r\n }\r\n\r\n /**\r\n * Gets a left Vector3 that must not be updated\r\n */\r\n public static get LeftReadOnly(): DeepImmutable {\r\n return Vector3._LeftReadOnly;\r\n }\r\n\r\n /**\r\n * Gets a forward Vector3 that must not be updated\r\n */\r\n public static get LeftHandedForwardReadOnly(): DeepImmutable {\r\n return Vector3._LeftHandedForwardReadOnly;\r\n }\r\n\r\n /**\r\n * Gets a forward Vector3 that must not be updated\r\n */\r\n public static get RightHandedForwardReadOnly(): DeepImmutable {\r\n return Vector3._RightHandedForwardReadOnly;\r\n }\r\n\r\n /**\r\n * Gets a backward Vector3 that must not be updated\r\n */\r\n public static get LeftHandedBackwardReadOnly(): DeepImmutable {\r\n return Vector3._LeftHandedBackwardReadOnly;\r\n }\r\n\r\n /**\r\n * Gets a backward Vector3 that must not be updated\r\n */\r\n public static get RightHandedBackwardReadOnly(): DeepImmutable {\r\n return Vector3._RightHandedBackwardReadOnly;\r\n }\r\n\r\n /**\r\n * Gets a zero Vector3 that must not be updated\r\n */\r\n public static get ZeroReadOnly(): DeepImmutable {\r\n return Vector3._ZeroReadOnly;\r\n }\r\n\r\n /**\r\n * Gets a one Vector3 that must not be updated\r\n */\r\n public static get OneReadOnly(): DeepImmutable {\r\n return Vector3._OneReadOnly;\r\n }\r\n\r\n /**\r\n * Returns a new Vector3 set to (0.0, -1.0, 0.0)\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#71\r\n * @returns a new down Vector3\r\n */\r\n public static Down(): Vector3 {\r\n return new Vector3(0.0, -1.0, 0.0);\r\n }\r\n /**\r\n * Returns a new Vector3 set to (0.0, 0.0, 1.0)\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#71\r\n * @param rightHandedSystem is the scene right-handed (negative z)\r\n * @returns a new forward Vector3\r\n */\r\n public static Forward(rightHandedSystem: boolean = false): Vector3 {\r\n return new Vector3(0.0, 0.0, rightHandedSystem ? -1.0 : 1.0);\r\n }\r\n /**\r\n * Returns a new Vector3 set to (0.0, 0.0, -1.0)\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#71\r\n * @param rightHandedSystem is the scene right-handed (negative-z)\r\n * @returns a new Backward Vector3\r\n */\r\n public static Backward(rightHandedSystem: boolean = false): Vector3 {\r\n return new Vector3(0.0, 0.0, rightHandedSystem ? 1.0 : -1.0);\r\n }\r\n /**\r\n * Returns a new Vector3 set to (1.0, 0.0, 0.0)\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#71\r\n * @returns a new right Vector3\r\n */\r\n public static Right(): Vector3 {\r\n return new Vector3(1.0, 0.0, 0.0);\r\n }\r\n /**\r\n * Returns a new Vector3 set to (-1.0, 0.0, 0.0)\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#71\r\n * @returns a new left Vector3\r\n */\r\n public static Left(): Vector3 {\r\n return new Vector3(-1.0, 0.0, 0.0);\r\n }\r\n\r\n /**\r\n * Returns a new Vector3 with random values between min and max\r\n * @param min the minimum random value\r\n * @param max the maximum random value\r\n * @returns a Vector3 with random values between min and max\r\n */\r\n public static Random(min: number = 0, max: number = 1): Vector3 {\r\n return new Vector3(RandomRange(min, max), RandomRange(min, max), RandomRange(min, max));\r\n }\r\n\r\n /**\r\n * Sets a Vector3 with random values between min and max\r\n * @param min the minimum random value\r\n * @param max the maximum random value\r\n * @param ref the ref to store the values in\r\n * @returns the ref with random values between min and max\r\n */\r\n public static RandomToRef(min: number = 0, max: number = 1, ref: T): T {\r\n return ref.copyFromFloats(RandomRange(min, max), RandomRange(min, max), RandomRange(min, max));\r\n }\r\n\r\n /**\r\n * Returns a new Vector3 set with the result of the transformation by the given matrix of the given vector.\r\n * This method computes transformed coordinates only, not transformed direction vectors (ie. it takes translation in account)\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#111\r\n * @param vector defines the Vector3 to transform\r\n * @param transformation defines the transformation matrix\r\n * @returns the transformed Vector3\r\n */\r\n public static TransformCoordinates(vector: DeepImmutable, transformation: DeepImmutable): Vector3 {\r\n const result = Vector3.Zero();\r\n Vector3.TransformCoordinatesToRef(vector, transformation, result);\r\n return result;\r\n }\r\n\r\n /**\r\n * Sets the given vector \"result\" coordinates with the result of the transformation by the given matrix of the given vector\r\n * This method computes transformed coordinates only, not transformed direction vectors (ie. it takes translation in account)\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#113\r\n * @param vector defines the Vector3 to transform\r\n * @param transformation defines the transformation matrix\r\n * @param result defines the Vector3 where to store the result\r\n * @returns result input\r\n */\r\n public static TransformCoordinatesToRef(vector: DeepImmutable, transformation: DeepImmutable, result: T): T {\r\n Vector3.TransformCoordinatesFromFloatsToRef(vector._x, vector._y, vector._z, transformation, result);\r\n return result;\r\n }\r\n\r\n /**\r\n * Sets the given vector \"result\" coordinates with the result of the transformation by the given matrix of the given floats (x, y, z)\r\n * This method computes transformed coordinates only, not transformed direction vectors\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#115\r\n * @param x define the x coordinate of the source vector\r\n * @param y define the y coordinate of the source vector\r\n * @param z define the z coordinate of the source vector\r\n * @param transformation defines the transformation matrix\r\n * @param result defines the Vector3 where to store the result\r\n * @returns result input\r\n */\r\n public static TransformCoordinatesFromFloatsToRef(x: number, y: number, z: number, transformation: DeepImmutable, result: T): T {\r\n const m = transformation.m;\r\n const rx = x * m[0] + y * m[4] + z * m[8] + m[12];\r\n const ry = x * m[1] + y * m[5] + z * m[9] + m[13];\r\n const rz = x * m[2] + y * m[6] + z * m[10] + m[14];\r\n const rw = 1 / (x * m[3] + y * m[7] + z * m[11] + m[15]);\r\n\r\n result._x = rx * rw;\r\n result._y = ry * rw;\r\n result._z = rz * rw;\r\n result._isDirty = true;\r\n return result;\r\n }\r\n\r\n /**\r\n * Returns a new Vector3 set with the result of the normal transformation by the given matrix of the given vector\r\n * This methods computes transformed normalized direction vectors only (ie. it does not apply translation)\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#112\r\n * @param vector defines the Vector3 to transform\r\n * @param transformation defines the transformation matrix\r\n * @returns the new Vector3\r\n */\r\n public static TransformNormal(vector: DeepImmutable, transformation: DeepImmutable): Vector3 {\r\n const result = Vector3.Zero();\r\n Vector3.TransformNormalToRef(vector, transformation, result);\r\n return result;\r\n }\r\n\r\n /**\r\n * Sets the given vector \"result\" with the result of the normal transformation by the given matrix of the given vector\r\n * This methods computes transformed normalized direction vectors only (ie. it does not apply translation)\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#114\r\n * @param vector defines the Vector3 to transform\r\n * @param transformation defines the transformation matrix\r\n * @param result defines the Vector3 where to store the result\r\n * @returns result input\r\n */\r\n public static TransformNormalToRef(vector: DeepImmutable, transformation: DeepImmutable, result: T): T {\r\n this.TransformNormalFromFloatsToRef(vector._x, vector._y, vector._z, transformation, result);\r\n return result;\r\n }\r\n\r\n /**\r\n * Sets the given vector \"result\" with the result of the normal transformation by the given matrix of the given floats (x, y, z)\r\n * This methods computes transformed normalized direction vectors only (ie. it does not apply translation)\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#116\r\n * @param x define the x coordinate of the source vector\r\n * @param y define the y coordinate of the source vector\r\n * @param z define the z coordinate of the source vector\r\n * @param transformation defines the transformation matrix\r\n * @param result defines the Vector3 where to store the result\r\n * @returns result input\r\n */\r\n public static TransformNormalFromFloatsToRef(x: number, y: number, z: number, transformation: DeepImmutable, result: T): T {\r\n const m = transformation.m;\r\n result._x = x * m[0] + y * m[4] + z * m[8];\r\n result._y = x * m[1] + y * m[5] + z * m[9];\r\n result._z = x * m[2] + y * m[6] + z * m[10];\r\n result._isDirty = true;\r\n return result;\r\n }\r\n\r\n /**\r\n * Returns a new Vector3 located for \"amount\" on the CatmullRom interpolation spline defined by the vectors \"value1\", \"value2\", \"value3\", \"value4\"\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#69\r\n * @param value1 defines the first control point\r\n * @param value2 defines the second control point\r\n * @param value3 defines the third control point\r\n * @param value4 defines the fourth control point\r\n * @param amount defines the amount on the spline to use\r\n * @returns the new Vector3\r\n */\r\n public static CatmullRom(\r\n value1: DeepImmutable,\r\n value2: DeepImmutable,\r\n value3: DeepImmutable,\r\n value4: DeepImmutable,\r\n amount: number\r\n ): Vector3 {\r\n const squared = amount * amount;\r\n const cubed = amount * squared;\r\n\r\n const x =\r\n 0.5 *\r\n (2.0 * value2._x +\r\n (-value1._x + value3._x) * amount +\r\n (2.0 * value1._x - 5.0 * value2._x + 4.0 * value3._x - value4._x) * squared +\r\n (-value1._x + 3.0 * value2._x - 3.0 * value3._x + value4._x) * cubed);\r\n\r\n const y =\r\n 0.5 *\r\n (2.0 * value2._y +\r\n (-value1._y + value3._y) * amount +\r\n (2.0 * value1._y - 5.0 * value2._y + 4.0 * value3._y - value4._y) * squared +\r\n (-value1._y + 3.0 * value2._y - 3.0 * value3._y + value4._y) * cubed);\r\n\r\n const z =\r\n 0.5 *\r\n (2.0 * value2._z +\r\n (-value1._z + value3._z) * amount +\r\n (2.0 * value1._z - 5.0 * value2._z + 4.0 * value3._z - value4._z) * squared +\r\n (-value1._z + 3.0 * value2._z - 3.0 * value3._z + value4._z) * cubed);\r\n\r\n return new Vector3(x, y, z);\r\n }\r\n\r\n /**\r\n * Returns a new Vector3 set with the coordinates of \"value\", if the vector \"value\" is in the cube defined by the vectors \"min\" and \"max\"\r\n * If a coordinate value of \"value\" is lower than one of the \"min\" coordinate, then this \"value\" coordinate is set with the \"min\" one\r\n * If a coordinate value of \"value\" is greater than one of the \"max\" coordinate, then this \"value\" coordinate is set with the \"max\" one\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#76\r\n * @param value defines the current value\r\n * @param min defines the lower range value\r\n * @param max defines the upper range value\r\n * @returns the new Vector3\r\n */\r\n public static Clamp(value: DeepImmutable, min: DeepImmutable, max: DeepImmutable): Vector3 {\r\n const result = new Vector3();\r\n Vector3.ClampToRef(value, min, max, result);\r\n return result;\r\n }\r\n\r\n /**\r\n * Sets the given vector \"result\" with the coordinates of \"value\", if the vector \"value\" is in the cube defined by the vectors \"min\" and \"max\"\r\n * If a coordinate value of \"value\" is lower than one of the \"min\" coordinate, then this \"value\" coordinate is set with the \"min\" one\r\n * If a coordinate value of \"value\" is greater than one of the \"max\" coordinate, then this \"value\" coordinate is set with the \"max\" one\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#77\r\n * @param value defines the current value\r\n * @param min defines the lower range value\r\n * @param max defines the upper range value\r\n * @param result defines the Vector3 where to store the result\r\n * @returns result input\r\n */\r\n public static ClampToRef(value: DeepImmutable, min: DeepImmutable, max: DeepImmutable, result: T): T {\r\n let x = value._x;\r\n x = x > max._x ? max._x : x;\r\n x = x < min._x ? min._x : x;\r\n\r\n let y = value._y;\r\n y = y > max._y ? max._y : y;\r\n y = y < min._y ? min._y : y;\r\n\r\n let z = value._z;\r\n z = z > max._z ? max._z : z;\r\n z = z < min._z ? min._z : z;\r\n\r\n result.copyFromFloats(x, y, z);\r\n return result;\r\n }\r\n\r\n /**\r\n * Checks if a given vector is inside a specific range\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#75\r\n * @param v defines the vector to test\r\n * @param min defines the minimum range\r\n * @param max defines the maximum range\r\n */\r\n public static CheckExtends(v: Vector3, min: Vector3, max: Vector3): void {\r\n min.minimizeInPlace(v);\r\n max.maximizeInPlace(v);\r\n }\r\n\r\n /**\r\n * Returns a new Vector3 located for \"amount\" (float) on the Hermite interpolation spline defined by the vectors \"value1\", \"tangent1\", \"value2\", \"tangent2\"\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#89\r\n * @param value1 defines the first control point\r\n * @param tangent1 defines the first tangent vector\r\n * @param value2 defines the second control point\r\n * @param tangent2 defines the second tangent vector\r\n * @param amount defines the amount on the interpolation spline (between 0 and 1)\r\n * @returns the new Vector3\r\n */\r\n public static Hermite(\r\n value1: DeepImmutable,\r\n tangent1: DeepImmutable,\r\n value2: DeepImmutable,\r\n tangent2: DeepImmutable,\r\n amount: number\r\n ): Vector3 {\r\n const squared = amount * amount;\r\n const cubed = amount * squared;\r\n const part1 = 2.0 * cubed - 3.0 * squared + 1.0;\r\n const part2 = -2.0 * cubed + 3.0 * squared;\r\n const part3 = cubed - 2.0 * squared + amount;\r\n const part4 = cubed - squared;\r\n\r\n const x = value1._x * part1 + value2._x * part2 + tangent1._x * part3 + tangent2._x * part4;\r\n const y = value1._y * part1 + value2._y * part2 + tangent1._y * part3 + tangent2._y * part4;\r\n const z = value1._z * part1 + value2._z * part2 + tangent1._z * part3 + tangent2._z * part4;\r\n return new Vector3(x, y, z);\r\n }\r\n\r\n /**\r\n * Returns a new Vector3 which is the 1st derivative of the Hermite spline defined by the vectors \"value1\", \"value2\", \"tangent1\", \"tangent2\".\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#90\r\n * @param value1 defines the first control point\r\n * @param tangent1 defines the first tangent\r\n * @param value2 defines the second control point\r\n * @param tangent2 defines the second tangent\r\n * @param time define where the derivative must be done\r\n * @returns 1st derivative\r\n */\r\n public static Hermite1stDerivative(\r\n value1: DeepImmutable,\r\n tangent1: DeepImmutable,\r\n value2: DeepImmutable,\r\n tangent2: DeepImmutable,\r\n time: number\r\n ): Vector3 {\r\n const result = new Vector3();\r\n\r\n this.Hermite1stDerivativeToRef(value1, tangent1, value2, tangent2, time, result);\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Update a Vector3 with the 1st derivative of the Hermite spline defined by the vectors \"value1\", \"value2\", \"tangent1\", \"tangent2\".\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#91\r\n * @param value1 defines the first control point\r\n * @param tangent1 defines the first tangent\r\n * @param value2 defines the second control point\r\n * @param tangent2 defines the second tangent\r\n * @param time define where the derivative must be done\r\n * @param result define where to store the derivative\r\n * @returns result input\r\n */\r\n public static Hermite1stDerivativeToRef(\r\n value1: DeepImmutable,\r\n tangent1: DeepImmutable,\r\n value2: DeepImmutable,\r\n tangent2: DeepImmutable,\r\n time: number,\r\n result: T\r\n ): T {\r\n const t2 = time * time;\r\n\r\n result._x = (t2 - time) * 6 * value1._x + (3 * t2 - 4 * time + 1) * tangent1._x + (-t2 + time) * 6 * value2._x + (3 * t2 - 2 * time) * tangent2._x;\r\n result._y = (t2 - time) * 6 * value1._y + (3 * t2 - 4 * time + 1) * tangent1._y + (-t2 + time) * 6 * value2._y + (3 * t2 - 2 * time) * tangent2._y;\r\n result._z = (t2 - time) * 6 * value1._z + (3 * t2 - 4 * time + 1) * tangent1._z + (-t2 + time) * 6 * value2._z + (3 * t2 - 2 * time) * tangent2._z;\r\n result._isDirty = true;\r\n return result;\r\n }\r\n\r\n /**\r\n * Returns a new Vector3 located for \"amount\" (float) on the linear interpolation between the vectors \"start\" and \"end\"\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#95\r\n * @param start defines the start value\r\n * @param end defines the end value\r\n * @param amount max defines amount between both (between 0 and 1)\r\n * @returns the new Vector3\r\n */\r\n public static Lerp(start: DeepImmutable, end: DeepImmutable, amount: number): Vector3 {\r\n const result = new Vector3(0, 0, 0);\r\n Vector3.LerpToRef(start, end, amount, result);\r\n return result;\r\n }\r\n\r\n /**\r\n * Sets the given vector \"result\" with the result of the linear interpolation from the vector \"start\" for \"amount\" to the vector \"end\"\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#93\r\n * @param start defines the start value\r\n * @param end defines the end value\r\n * @param amount max defines amount between both (between 0 and 1)\r\n * @param result defines the Vector3 where to store the result\r\n * @returns result input\r\n */\r\n public static LerpToRef(start: DeepImmutable, end: DeepImmutable, amount: number, result: T): T {\r\n result._x = start._x + (end._x - start._x) * amount;\r\n result._y = start._y + (end._y - start._y) * amount;\r\n result._z = start._z + (end._z - start._z) * amount;\r\n result._isDirty = true;\r\n return result;\r\n }\r\n\r\n /**\r\n * Returns the dot product (float) between the vectors \"left\" and \"right\"\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#82\r\n * @param left defines the left operand\r\n * @param right defines the right operand\r\n * @returns the dot product\r\n */\r\n public static Dot(left: DeepImmutable, right: DeepImmutable): number {\r\n return left._x * right._x + left._y * right._y + left._z * right._z;\r\n }\r\n\r\n /**\r\n * Returns the dot product (float) between the current vectors and \"otherVector\"\r\n * @param otherVector defines the right operand\r\n * @returns the dot product\r\n */\r\n public dot(otherVector: DeepImmutable): number {\r\n return this._x * otherVector._x + this._y * otherVector._y + this._z * otherVector._z;\r\n }\r\n\r\n /**\r\n * Returns a new Vector3 as the cross product of the vectors \"left\" and \"right\"\r\n * The cross product is then orthogonal to both \"left\" and \"right\"\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#15\r\n * @param left defines the left operand\r\n * @param right defines the right operand\r\n * @returns the cross product\r\n */\r\n public static Cross(left: DeepImmutable, right: DeepImmutable): Vector3 {\r\n const result = new Vector3();\r\n Vector3.CrossToRef(left, right, result);\r\n return result;\r\n }\r\n\r\n /**\r\n * Sets the given vector \"result\" with the cross product of \"left\" and \"right\"\r\n * The cross product is then orthogonal to both \"left\" and \"right\"\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#78\r\n * @param left defines the left operand\r\n * @param right defines the right operand\r\n * @param result defines the Vector3 where to store the result\r\n * @returns result input\r\n */\r\n public static CrossToRef(left: DeepImmutable, right: DeepImmutable, result: T): T {\r\n const x = left._y * right._z - left._z * right._y;\r\n const y = left._z * right._x - left._x * right._z;\r\n const z = left._x * right._y - left._y * right._x;\r\n result.copyFromFloats(x, y, z);\r\n return result;\r\n }\r\n\r\n /**\r\n * Returns a new Vector3 as the normalization of the given vector\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#98\r\n * @param vector defines the Vector3 to normalize\r\n * @returns the new Vector3\r\n */\r\n public static Normalize(vector: DeepImmutable): Vector3 {\r\n const result = Vector3.Zero();\r\n Vector3.NormalizeToRef(vector, result);\r\n return result;\r\n }\r\n\r\n /**\r\n * Sets the given vector \"result\" with the normalization of the given first vector\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#98\r\n * @param vector defines the Vector3 to normalize\r\n * @param result defines the Vector3 where to store the result\r\n * @returns result input\r\n */\r\n public static NormalizeToRef(vector: DeepImmutable, result: T): T {\r\n vector.normalizeToRef(result);\r\n return result;\r\n }\r\n\r\n /**\r\n * Project a Vector3 onto screen space\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#101\r\n * @param vector defines the Vector3 to project\r\n * @param world defines the world matrix to use\r\n * @param transform defines the transform (view x projection) matrix to use\r\n * @param viewport defines the screen viewport to use\r\n * @returns the new Vector3\r\n */\r\n public static Project(vector: DeepImmutable, world: DeepImmutable, transform: DeepImmutable, viewport: DeepImmutable): Vector3 {\r\n const result = new Vector3();\r\n Vector3.ProjectToRef(vector, world, transform, viewport, result);\r\n return result;\r\n }\r\n\r\n /**\r\n * Project a Vector3 onto screen space to reference\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#102\r\n * @param vector defines the Vector3 to project\r\n * @param world defines the world matrix to use\r\n * @param transform defines the transform (view x projection) matrix to use\r\n * @param viewport defines the screen viewport to use\r\n * @param result the vector in which the screen space will be stored\r\n * @returns result input\r\n */\r\n public static ProjectToRef(\r\n vector: DeepImmutable,\r\n world: DeepImmutable,\r\n transform: DeepImmutable,\r\n viewport: DeepImmutable,\r\n result: T\r\n ): T {\r\n const cw = viewport.width;\r\n const ch = viewport.height;\r\n const cx = viewport.x;\r\n const cy = viewport.y;\r\n\r\n const viewportMatrix = MathTmp.Matrix[1];\r\n\r\n const isNDCHalfZRange = EngineStore.LastCreatedEngine?.isNDCHalfZRange;\r\n const zScale = isNDCHalfZRange ? 1 : 0.5;\r\n const zOffset = isNDCHalfZRange ? 0 : 0.5;\r\n\r\n Matrix.FromValuesToRef(cw / 2.0, 0, 0, 0, 0, -ch / 2.0, 0, 0, 0, 0, zScale, 0, cx + cw / 2.0, ch / 2.0 + cy, zOffset, 1, viewportMatrix);\r\n\r\n const matrix = MathTmp.Matrix[0];\r\n world.multiplyToRef(transform, matrix);\r\n matrix.multiplyToRef(viewportMatrix, matrix);\r\n\r\n Vector3.TransformCoordinatesToRef(vector, matrix, result);\r\n return result;\r\n }\r\n\r\n /**\r\n * Reflects a vector off the plane defined by a normalized normal\r\n * @param inDirection defines the vector direction\r\n * @param normal defines the normal - Must be normalized\r\n * @returns the resulting vector\r\n */\r\n public static Reflect(inDirection: DeepImmutable, normal: DeepImmutable): Vector3 {\r\n return this.ReflectToRef(inDirection, normal, new Vector3());\r\n }\r\n\r\n /**\r\n * Reflects a vector off the plane defined by a normalized normal to reference\r\n * @param inDirection defines the vector direction\r\n * @param normal defines the normal - Must be normalized\r\n * @param ref defines the Vector3 where to store the result\r\n * @returns the resulting vector\r\n */\r\n public static ReflectToRef(inDirection: DeepImmutable, normal: DeepImmutable, ref: T): T {\r\n const tmp = TmpVectors.Vector3[0];\r\n tmp.copyFrom(normal).scaleInPlace(2 * Vector3.Dot(inDirection, normal));\r\n\r\n return ref.copyFrom(inDirection).subtractInPlace(tmp);\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n public static _UnprojectFromInvertedMatrixToRef(source: DeepImmutable, matrix: DeepImmutable, result: T): T {\r\n Vector3.TransformCoordinatesToRef(source, matrix, result);\r\n const m = matrix.m;\r\n const num = source._x * m[3] + source._y * m[7] + source._z * m[11] + m[15];\r\n if (WithinEpsilon(num, 1.0)) {\r\n result.scaleInPlace(1.0 / num);\r\n }\r\n return result;\r\n }\r\n\r\n /**\r\n * Unproject from screen space to object space\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#121\r\n * @param source defines the screen space Vector3 to use\r\n * @param viewportWidth defines the current width of the viewport\r\n * @param viewportHeight defines the current height of the viewport\r\n * @param world defines the world matrix to use (can be set to Identity to go to world space)\r\n * @param transform defines the transform (view x projection) matrix to use\r\n * @returns the new Vector3\r\n */\r\n public static UnprojectFromTransform(\r\n source: DeepImmutable,\r\n viewportWidth: number,\r\n viewportHeight: number,\r\n world: DeepImmutable,\r\n transform: DeepImmutable\r\n ): Vector3 {\r\n return this.Unproject(source, viewportWidth, viewportHeight, world, transform, Matrix.IdentityReadOnly);\r\n }\r\n\r\n /**\r\n * Unproject from screen space to object space\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#117\r\n * @param source defines the screen space Vector3 to use\r\n * @param viewportWidth defines the current width of the viewport\r\n * @param viewportHeight defines the current height of the viewport\r\n * @param world defines the world matrix to use (can be set to Identity to go to world space)\r\n * @param view defines the view matrix to use\r\n * @param projection defines the projection matrix to use\r\n * @returns the new Vector3\r\n */\r\n public static Unproject(\r\n source: DeepImmutable,\r\n viewportWidth: number,\r\n viewportHeight: number,\r\n world: DeepImmutable,\r\n view: DeepImmutable,\r\n projection: DeepImmutable\r\n ): Vector3 {\r\n const result = new Vector3();\r\n\r\n Vector3.UnprojectToRef(source, viewportWidth, viewportHeight, world, view, projection, result);\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Unproject from screen space to object space\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#119\r\n * @param source defines the screen space Vector3 to use\r\n * @param viewportWidth defines the current width of the viewport\r\n * @param viewportHeight defines the current height of the viewport\r\n * @param world defines the world matrix to use (can be set to Identity to go to world space)\r\n * @param view defines the view matrix to use\r\n * @param projection defines the projection matrix to use\r\n * @param result defines the Vector3 where to store the result\r\n * @returns result input\r\n */\r\n public static UnprojectToRef(\r\n source: DeepImmutable,\r\n viewportWidth: number,\r\n viewportHeight: number,\r\n world: DeepImmutable,\r\n view: DeepImmutable,\r\n projection: DeepImmutable,\r\n result: T\r\n ): T {\r\n Vector3.UnprojectFloatsToRef(source._x, source._y, source._z, viewportWidth, viewportHeight, world, view, projection, result);\r\n return result;\r\n }\r\n\r\n /**\r\n * Unproject from screen space to object space\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#120\r\n * @param sourceX defines the screen space x coordinate to use\r\n * @param sourceY defines the screen space y coordinate to use\r\n * @param sourceZ defines the screen space z coordinate to use\r\n * @param viewportWidth defines the current width of the viewport\r\n * @param viewportHeight defines the current height of the viewport\r\n * @param world defines the world matrix to use (can be set to Identity to go to world space)\r\n * @param view defines the view matrix to use\r\n * @param projection defines the projection matrix to use\r\n * @param result defines the Vector3 where to store the result\r\n * @returns result input\r\n */\r\n public static UnprojectFloatsToRef(\r\n sourceX: float,\r\n sourceY: float,\r\n sourceZ: float,\r\n viewportWidth: number,\r\n viewportHeight: number,\r\n world: DeepImmutable,\r\n view: DeepImmutable,\r\n projection: DeepImmutable,\r\n result: T\r\n ): T {\r\n const matrix = MathTmp.Matrix[0];\r\n world.multiplyToRef(view, matrix);\r\n matrix.multiplyToRef(projection, matrix);\r\n matrix.invert();\r\n\r\n const screenSource = MathTmp.Vector3[0];\r\n screenSource.x = (sourceX / viewportWidth) * 2 - 1;\r\n screenSource.y = -((sourceY / viewportHeight) * 2 - 1);\r\n if (EngineStore.LastCreatedEngine?.isNDCHalfZRange) {\r\n screenSource.z = sourceZ;\r\n } else {\r\n screenSource.z = 2 * sourceZ - 1.0;\r\n }\r\n\r\n Vector3._UnprojectFromInvertedMatrixToRef(screenSource, matrix, result);\r\n return result;\r\n }\r\n\r\n /**\r\n * Gets the minimal coordinate values between two Vector3\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#97\r\n * @param left defines the first operand\r\n * @param right defines the second operand\r\n * @returns the new Vector3\r\n */\r\n public static Minimize(left: DeepImmutable, right: DeepImmutable): Vector3 {\r\n const min = new Vector3();\r\n min.copyFrom(left);\r\n min.minimizeInPlace(right);\r\n return min;\r\n }\r\n\r\n /**\r\n * Gets the maximal coordinate values between two Vector3\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#96\r\n * @param left defines the first operand\r\n * @param right defines the second operand\r\n * @returns the new Vector3\r\n */\r\n public static Maximize(left: DeepImmutable, right: DeepImmutable): Vector3 {\r\n const max = new Vector3();\r\n max.copyFrom(left);\r\n max.maximizeInPlace(right);\r\n return max;\r\n }\r\n\r\n /**\r\n * Returns the distance between the vectors \"value1\" and \"value2\"\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#81\r\n * @param value1 defines the first operand\r\n * @param value2 defines the second operand\r\n * @returns the distance\r\n */\r\n public static Distance(value1: DeepImmutable, value2: DeepImmutable): number {\r\n return Math.sqrt(Vector3.DistanceSquared(value1, value2));\r\n }\r\n\r\n /**\r\n * Returns the squared distance between the vectors \"value1\" and \"value2\"\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#80\r\n * @param value1 defines the first operand\r\n * @param value2 defines the second operand\r\n * @returns the squared distance\r\n */\r\n public static DistanceSquared(value1: DeepImmutable, value2: DeepImmutable): number {\r\n const x = value1._x - value2._x;\r\n const y = value1._y - value2._y;\r\n const z = value1._z - value2._z;\r\n\r\n return x * x + y * y + z * z;\r\n }\r\n\r\n /**\r\n * Projects \"vector\" on the triangle determined by its extremities \"p0\", \"p1\" and \"p2\", stores the result in \"ref\"\r\n * and returns the distance to the projected point.\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#104\r\n * From http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.104.4264&rep=rep1&type=pdf\r\n *\r\n * @param vector the vector to get distance from\r\n * @param p0 extremity of the triangle\r\n * @param p1 extremity of the triangle\r\n * @param p2 extremity of the triangle\r\n * @param ref variable to store the result to\r\n * @returns The distance between \"ref\" and \"vector\"\r\n */\r\n public static ProjectOnTriangleToRef(vector: DeepImmutable, p0: DeepImmutable, p1: DeepImmutable, p2: DeepImmutable, ref: Vector3): number {\r\n const p1p0 = MathTmp.Vector3[0];\r\n const p2p0 = MathTmp.Vector3[1];\r\n const p2p1 = MathTmp.Vector3[2];\r\n const normal = MathTmp.Vector3[3];\r\n const vectorp0 = MathTmp.Vector3[4];\r\n\r\n // Triangle vectors\r\n p1.subtractToRef(p0, p1p0);\r\n p2.subtractToRef(p0, p2p0);\r\n p2.subtractToRef(p1, p2p1);\r\n\r\n const p1p0L = p1p0.length();\r\n const p2p0L = p2p0.length();\r\n const p2p1L = p2p1.length();\r\n\r\n if (p1p0L < Epsilon || p2p0L < Epsilon || p2p1L < Epsilon) {\r\n // This is a degenerate triangle. As we assume this is part of a non-degenerate mesh,\r\n // we will find a better intersection later.\r\n // Let's just return one of the extremities\r\n ref.copyFrom(p0);\r\n return Vector3.Distance(vector, p0);\r\n }\r\n\r\n // Compute normal and vector to p0\r\n vector.subtractToRef(p0, vectorp0);\r\n Vector3.CrossToRef(p1p0, p2p0, normal);\r\n const nl = normal.length();\r\n if (nl < Epsilon) {\r\n // Extremities are aligned, we are back on the case of a degenerate triangle\r\n ref.copyFrom(p0);\r\n return Vector3.Distance(vector, p0);\r\n }\r\n normal.normalizeFromLength(nl);\r\n let l = vectorp0.length();\r\n if (l < Epsilon) {\r\n // Vector is p0\r\n ref.copyFrom(p0);\r\n return 0;\r\n }\r\n vectorp0.normalizeFromLength(l);\r\n\r\n // Project to \"proj\" that lies on the triangle plane\r\n const cosA = Vector3.Dot(normal, vectorp0);\r\n const projVector = MathTmp.Vector3[5];\r\n const proj = MathTmp.Vector3[6];\r\n projVector.copyFrom(normal).scaleInPlace(-l * cosA);\r\n proj.copyFrom(vector).addInPlace(projVector);\r\n\r\n // Compute barycentric coordinates (v0, v1 and v2 are axis from barycenter to extremities)\r\n const v0 = MathTmp.Vector3[4];\r\n const v1 = MathTmp.Vector3[5];\r\n const v2 = MathTmp.Vector3[7];\r\n const tmp = MathTmp.Vector3[8];\r\n\r\n v0.copyFrom(p1p0).scaleInPlace(1 / p1p0L);\r\n tmp.copyFrom(p2p0).scaleInPlace(1 / p2p0L);\r\n v0.addInPlace(tmp).scaleInPlace(-1);\r\n\r\n v1.copyFrom(p1p0).scaleInPlace(-1 / p1p0L);\r\n tmp.copyFrom(p2p1).scaleInPlace(1 / p2p1L);\r\n v1.addInPlace(tmp).scaleInPlace(-1);\r\n\r\n v2.copyFrom(p2p1).scaleInPlace(-1 / p2p1L);\r\n tmp.copyFrom(p2p0).scaleInPlace(-1 / p2p0L);\r\n v2.addInPlace(tmp).scaleInPlace(-1);\r\n\r\n // Determines which edge of the triangle is closest to \"proj\"\r\n const projP = MathTmp.Vector3[9];\r\n let dot;\r\n projP.copyFrom(proj).subtractInPlace(p0);\r\n Vector3.CrossToRef(v0, projP, tmp);\r\n dot = Vector3.Dot(tmp, normal);\r\n const s0 = dot;\r\n\r\n projP.copyFrom(proj).subtractInPlace(p1);\r\n Vector3.CrossToRef(v1, projP, tmp);\r\n dot = Vector3.Dot(tmp, normal);\r\n const s1 = dot;\r\n\r\n projP.copyFrom(proj).subtractInPlace(p2);\r\n Vector3.CrossToRef(v2, projP, tmp);\r\n dot = Vector3.Dot(tmp, normal);\r\n const s2 = dot;\r\n\r\n const edge = MathTmp.Vector3[10];\r\n let e0, e1;\r\n if (s0 > 0 && s1 < 0) {\r\n edge.copyFrom(p1p0);\r\n e0 = p0;\r\n e1 = p1;\r\n } else if (s1 > 0 && s2 < 0) {\r\n edge.copyFrom(p2p1);\r\n e0 = p1;\r\n e1 = p2;\r\n } else {\r\n edge.copyFrom(p2p0).scaleInPlace(-1);\r\n e0 = p2;\r\n e1 = p0;\r\n }\r\n\r\n // Determines if \"proj\" lies inside the triangle\r\n const tmp2 = MathTmp.Vector3[9];\r\n const tmp3 = MathTmp.Vector3[4];\r\n e0.subtractToRef(proj, tmp);\r\n e1.subtractToRef(proj, tmp2);\r\n Vector3.CrossToRef(tmp, tmp2, tmp3);\r\n const isOutside = Vector3.Dot(tmp3, normal) < 0;\r\n\r\n // If inside, we already found the projected point, \"proj\"\r\n if (!isOutside) {\r\n ref.copyFrom(proj);\r\n return Math.abs(l * cosA);\r\n }\r\n\r\n // If outside, we find \"triProj\", the closest point from \"proj\" on the closest edge\r\n const r = MathTmp.Vector3[5];\r\n Vector3.CrossToRef(edge, tmp3, r);\r\n r.normalize();\r\n const e0proj = MathTmp.Vector3[9];\r\n e0proj.copyFrom(e0).subtractInPlace(proj);\r\n const e0projL = e0proj.length();\r\n if (e0projL < Epsilon) {\r\n // Proj is e0\r\n ref.copyFrom(e0);\r\n return Vector3.Distance(vector, e0);\r\n }\r\n e0proj.normalizeFromLength(e0projL);\r\n const cosG = Vector3.Dot(r, e0proj);\r\n const triProj = MathTmp.Vector3[7];\r\n triProj.copyFrom(proj).addInPlace(r.scaleInPlace(e0projL * cosG));\r\n\r\n // Now we clamp \"triProj\" so it lies between e0 and e1\r\n tmp.copyFrom(triProj).subtractInPlace(e0);\r\n l = edge.length();\r\n edge.normalizeFromLength(l);\r\n let t = Vector3.Dot(tmp, edge) / Math.max(l, Epsilon);\r\n t = Clamp(t, 0, 1);\r\n triProj.copyFrom(e0).addInPlace(edge.scaleInPlace(t * l));\r\n ref.copyFrom(triProj);\r\n\r\n return Vector3.Distance(vector, triProj);\r\n }\r\n\r\n /**\r\n * Returns a new Vector3 located at the center between \"value1\" and \"value2\"\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#72\r\n * @param value1 defines the first operand\r\n * @param value2 defines the second operand\r\n * @returns the new Vector3\r\n */\r\n public static Center(value1: DeepImmutable, value2: DeepImmutable): Vector3 {\r\n return Vector3.CenterToRef(value1, value2, Vector3.Zero());\r\n }\r\n\r\n /**\r\n * Gets the center of the vectors \"value1\" and \"value2\" and stores the result in the vector \"ref\"\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#73\r\n * @param value1 defines first vector\r\n * @param value2 defines second vector\r\n * @param ref defines third vector\r\n * @returns ref\r\n */\r\n public static CenterToRef(value1: DeepImmutable, value2: DeepImmutable, ref: T): T {\r\n return ref.copyFromFloats((value1._x + value2._x) / 2, (value1._y + value2._y) / 2, (value1._z + value2._z) / 2);\r\n }\r\n\r\n /**\r\n * Given three orthogonal normalized left-handed oriented Vector3 axis in space (target system),\r\n * RotationFromAxis() returns the rotation Euler angles (ex : rotation.x, rotation.y, rotation.z) to apply\r\n * to something in order to rotate it from its local system to the given target system\r\n * Note: axis1, axis2 and axis3 are normalized during this operation\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#106\r\n * @param axis1 defines the first axis\r\n * @param axis2 defines the second axis\r\n * @param axis3 defines the third axis\r\n * @returns a new Vector3\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/transforms/center_origin/target_align\r\n */\r\n public static RotationFromAxis(axis1: DeepImmutable, axis2: DeepImmutable, axis3: DeepImmutable): Vector3 {\r\n const rotation = new Vector3();\r\n Vector3.RotationFromAxisToRef(axis1, axis2, axis3, rotation);\r\n return rotation;\r\n }\r\n\r\n /**\r\n * The same than RotationFromAxis but updates the given ref Vector3 parameter instead of returning a new Vector3\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#107\r\n * @param axis1 defines the first axis\r\n * @param axis2 defines the second axis\r\n * @param axis3 defines the third axis\r\n * @param ref defines the Vector3 where to store the result\r\n * @returns result input\r\n */\r\n public static RotationFromAxisToRef(axis1: DeepImmutable, axis2: DeepImmutable, axis3: DeepImmutable, ref: T): T {\r\n const quat = MathTmp.Quaternion[0];\r\n Quaternion.RotationQuaternionFromAxisToRef(axis1, axis2, axis3, quat);\r\n quat.toEulerAnglesToRef(ref);\r\n return ref;\r\n }\r\n}\r\nVector3 satisfies VectorStatic;\r\nObject.defineProperties(Vector3.prototype, {\r\n dimension: { value: [3] },\r\n rank: { value: 1 },\r\n});\r\n\r\n/**\r\n * Vector4 class created for EulerAngle class conversion to Quaternion\r\n */\r\nexport class Vector4 implements Vector, IVector4Like>, IVector4Like {\r\n /**\r\n * If the first vector is flagged with integers (as everything is 0,0,0,0), V8 stores all of the properties as integers internally because it doesn't know any better yet.\r\n * If subsequent vectors are created with non-integer values, V8 determines that it would be best to represent these properties as doubles instead of integers,\r\n * and henceforth it will use floating-point representation for all Vector4 instances that it creates.\r\n * But the original Vector4 instances are unchanged and has a \"deprecated map\".\r\n * If we keep using the Vector4 instances from step 1, it will now be a poison pill which will mess up optimizations in any code it touches.\r\n */\r\n static _V8PerformanceHack = new Vector4(0.5, 0.5, 0.5, 0.5) as DeepImmutable;\r\n private static _ZeroReadOnly = Vector4.Zero() as DeepImmutable;\r\n\r\n /**\r\n * @see Tensor.dimension\r\n */\r\n declare public readonly dimension: Readonly<[4]>;\r\n\r\n /**\r\n * @see Tensor.rank\r\n */\r\n declare public readonly rank: 1;\r\n\r\n /**\r\n * Creates a Vector4 object from the given floats.\r\n * @param x x value of the vector\r\n * @param y y value of the vector\r\n * @param z z value of the vector\r\n * @param w w value of the vector\r\n */\r\n constructor(\r\n /** [0] x value of the vector */\r\n public x: number = 0,\r\n /** [0] y value of the vector */\r\n public y: number = 0,\r\n /** [0] z value of the vector */\r\n public z: number = 0,\r\n /** [0] w value of the vector */\r\n public w: number = 0\r\n ) {}\r\n\r\n /**\r\n * Returns the string with the Vector4 coordinates.\r\n * @returns a string containing all the vector values\r\n */\r\n public toString(): string {\r\n return `{X: ${this.x} Y: ${this.y} Z: ${this.z} W: ${this.w}}`;\r\n }\r\n\r\n /**\r\n * Returns the string \"Vector4\".\r\n * @returns \"Vector4\"\r\n */\r\n public getClassName(): string {\r\n return \"Vector4\";\r\n }\r\n\r\n /**\r\n * Returns the Vector4 hash code.\r\n * @returns a unique hash code\r\n */\r\n public getHashCode(): number {\r\n const x = _ExtractAsInt(this.x);\r\n const y = _ExtractAsInt(this.y);\r\n const z = _ExtractAsInt(this.z);\r\n const w = _ExtractAsInt(this.w);\r\n\r\n let hash = x;\r\n hash = (hash * 397) ^ y;\r\n hash = (hash * 397) ^ z;\r\n hash = (hash * 397) ^ w;\r\n return hash;\r\n }\r\n\r\n // Operators\r\n /**\r\n * Returns a new array populated with 4 elements : the Vector4 coordinates.\r\n * @returns the resulting array\r\n */\r\n public asArray(): Tuple {\r\n return [this.x, this.y, this.z, this.w];\r\n }\r\n\r\n /**\r\n * Populates the given array from the given index with the Vector4 coordinates.\r\n * @param array array to populate\r\n * @param index index of the array to start at (default: 0)\r\n * @returns the Vector4.\r\n */\r\n public toArray(array: FloatArray, index?: number): this {\r\n if (index === undefined) {\r\n index = 0;\r\n }\r\n array[index] = this.x;\r\n array[index + 1] = this.y;\r\n array[index + 2] = this.z;\r\n array[index + 3] = this.w;\r\n return this;\r\n }\r\n\r\n /**\r\n * Update the current vector from an array\r\n * @param array defines the destination array\r\n * @param offset defines the offset in the destination array\r\n * @returns the current Vector3\r\n */\r\n public fromArray(array: FloatArray, offset: number = 0): this {\r\n Vector4.FromArrayToRef(array, offset, this);\r\n return this;\r\n }\r\n\r\n /**\r\n * Adds the given vector to the current Vector4.\r\n * @param otherVector the vector to add\r\n * @returns the updated Vector4.\r\n */\r\n public addInPlace(otherVector: DeepImmutable): this {\r\n this.x += otherVector.x;\r\n this.y += otherVector.y;\r\n this.z += otherVector.z;\r\n this.w += otherVector.w;\r\n return this;\r\n }\r\n\r\n /**\r\n * Adds the given coordinates to the current Vector4\r\n * @param x defines the x coordinate of the operand\r\n * @param y defines the y coordinate of the operand\r\n * @param z defines the z coordinate of the operand\r\n * @param w defines the w coordinate of the operand\r\n * @returns the current updated Vector4\r\n */\r\n public addInPlaceFromFloats(x: number, y: number, z: number, w: number): this {\r\n this.x += x;\r\n this.y += y;\r\n this.z += z;\r\n this.w += w;\r\n return this;\r\n }\r\n\r\n /**\r\n * Returns a new Vector4 as the result of the addition of the current Vector4 and the given one.\r\n * @param otherVector the vector to add\r\n * @returns the resulting vector\r\n */\r\n public add(otherVector: DeepImmutable): Vector4 {\r\n return new Vector4(this.x + otherVector.x, this.y + otherVector.y, this.z + otherVector.z, this.w + otherVector.w);\r\n }\r\n\r\n /**\r\n * Updates the given vector \"result\" with the result of the addition of the current Vector4 and the given one.\r\n * @param otherVector the vector to add\r\n * @param result the vector to store the result\r\n * @returns result input\r\n */\r\n public addToRef(otherVector: DeepImmutable, result: T): T {\r\n result.x = this.x + otherVector.x;\r\n result.y = this.y + otherVector.y;\r\n result.z = this.z + otherVector.z;\r\n result.w = this.w + otherVector.w;\r\n return result;\r\n }\r\n\r\n /**\r\n * Subtract in place the given vector from the current Vector4.\r\n * @param otherVector the vector to subtract\r\n * @returns the updated Vector4.\r\n */\r\n public subtractInPlace(otherVector: DeepImmutable): this {\r\n this.x -= otherVector.x;\r\n this.y -= otherVector.y;\r\n this.z -= otherVector.z;\r\n this.w -= otherVector.w;\r\n return this;\r\n }\r\n\r\n /**\r\n * Returns a new Vector4 with the result of the subtraction of the given vector from the current Vector4.\r\n * @param otherVector the vector to add\r\n * @returns the new vector with the result\r\n */\r\n public subtract(otherVector: DeepImmutable): Vector4 {\r\n return new Vector4(this.x - otherVector.x, this.y - otherVector.y, this.z - otherVector.z, this.w - otherVector.w);\r\n }\r\n\r\n /**\r\n * Sets the given vector \"result\" with the result of the subtraction of the given vector from the current Vector4.\r\n * @param otherVector the vector to subtract\r\n * @param result the vector to store the result\r\n * @returns result input\r\n */\r\n public subtractToRef(otherVector: DeepImmutable, result: T): T {\r\n result.x = this.x - otherVector.x;\r\n result.y = this.y - otherVector.y;\r\n result.z = this.z - otherVector.z;\r\n result.w = this.w - otherVector.w;\r\n return result;\r\n }\r\n\r\n /**\r\n * Returns a new Vector4 set with the result of the subtraction of the given floats from the current Vector4 coordinates.\r\n * @param x value to subtract\r\n * @param y value to subtract\r\n * @param z value to subtract\r\n * @param w value to subtract\r\n * @returns new vector containing the result\r\n */\r\n public subtractFromFloats(x: number, y: number, z: number, w: number): Vector4 {\r\n return new Vector4(this.x - x, this.y - y, this.z - z, this.w - w);\r\n }\r\n\r\n /**\r\n * Sets the given vector \"result\" set with the result of the subtraction of the given floats from the current Vector4 coordinates.\r\n * @param x value to subtract\r\n * @param y value to subtract\r\n * @param z value to subtract\r\n * @param w value to subtract\r\n * @param result the vector to store the result in\r\n * @returns result input\r\n */\r\n public subtractFromFloatsToRef(x: number, y: number, z: number, w: number, result: T): T {\r\n result.x = this.x - x;\r\n result.y = this.y - y;\r\n result.z = this.z - z;\r\n result.w = this.w - w;\r\n return result;\r\n }\r\n\r\n /**\r\n * Returns a new Vector4 set with the current Vector4 negated coordinates.\r\n * @returns a new vector with the negated values\r\n */\r\n public negate(): Vector4 {\r\n return new Vector4(-this.x, -this.y, -this.z, -this.w);\r\n }\r\n\r\n /**\r\n * Negate this vector in place\r\n * @returns this\r\n */\r\n public negateInPlace(): this {\r\n this.x *= -1;\r\n this.y *= -1;\r\n this.z *= -1;\r\n this.w *= -1;\r\n return this;\r\n }\r\n\r\n /**\r\n * Negate the current Vector4 and stores the result in the given vector \"result\" coordinates\r\n * @param result defines the Vector3 object where to store the result\r\n * @returns the result\r\n */\r\n public negateToRef(result: T): T {\r\n result.x = -this.x;\r\n result.y = -this.y;\r\n result.z = -this.z;\r\n result.w = -this.w;\r\n return result;\r\n }\r\n\r\n /**\r\n * Multiplies the current Vector4 coordinates by scale (float).\r\n * @param scale the number to scale with\r\n * @returns the updated Vector4.\r\n */\r\n public scaleInPlace(scale: number): this {\r\n this.x *= scale;\r\n this.y *= scale;\r\n this.z *= scale;\r\n this.w *= scale;\r\n return this;\r\n }\r\n\r\n /**\r\n * Returns a new Vector4 set with the current Vector4 coordinates multiplied by scale (float).\r\n * @param scale the number to scale with\r\n * @returns a new vector with the result\r\n */\r\n public scale(scale: number): Vector4 {\r\n return new Vector4(this.x * scale, this.y * scale, this.z * scale, this.w * scale);\r\n }\r\n\r\n /**\r\n * Sets the given vector \"result\" with the current Vector4 coordinates multiplied by scale (float).\r\n * @param scale the number to scale with\r\n * @param result a vector to store the result in\r\n * @returns result input\r\n */\r\n public scaleToRef(scale: number, result: T): T {\r\n result.x = this.x * scale;\r\n result.y = this.y * scale;\r\n result.z = this.z * scale;\r\n result.w = this.w * scale;\r\n return result;\r\n }\r\n\r\n /**\r\n * Scale the current Vector4 values by a factor and add the result to a given Vector4\r\n * @param scale defines the scale factor\r\n * @param result defines the Vector4 object where to store the result\r\n * @returns result input\r\n */\r\n public scaleAndAddToRef(scale: number, result: T): T {\r\n result.x += this.x * scale;\r\n result.y += this.y * scale;\r\n result.z += this.z * scale;\r\n result.w += this.w * scale;\r\n return result;\r\n }\r\n\r\n /**\r\n * Boolean : True if the current Vector4 coordinates are stricly equal to the given ones.\r\n * @param otherVector the vector to compare against\r\n * @returns true if they are equal\r\n */\r\n public equals(otherVector: DeepImmutable): boolean {\r\n return otherVector && this.x === otherVector.x && this.y === otherVector.y && this.z === otherVector.z && this.w === otherVector.w;\r\n }\r\n\r\n /**\r\n * Boolean : True if the current Vector4 coordinates are each beneath the distance \"epsilon\" from the given vector ones.\r\n * @param otherVector vector to compare against\r\n * @param epsilon (Default: very small number)\r\n * @returns true if they are equal\r\n */\r\n public equalsWithEpsilon(otherVector: DeepImmutable, epsilon: number = Epsilon): boolean {\r\n return (\r\n otherVector &&\r\n WithinEpsilon(this.x, otherVector.x, epsilon) &&\r\n WithinEpsilon(this.y, otherVector.y, epsilon) &&\r\n WithinEpsilon(this.z, otherVector.z, epsilon) &&\r\n WithinEpsilon(this.w, otherVector.w, epsilon)\r\n );\r\n }\r\n\r\n /**\r\n * Boolean : True if the given floats are strictly equal to the current Vector4 coordinates.\r\n * @param x x value to compare against\r\n * @param y y value to compare against\r\n * @param z z value to compare against\r\n * @param w w value to compare against\r\n * @returns true if equal\r\n */\r\n public equalsToFloats(x: number, y: number, z: number, w: number): boolean {\r\n return this.x === x && this.y === y && this.z === z && this.w === w;\r\n }\r\n\r\n /**\r\n * Multiplies in place the current Vector4 by the given one.\r\n * @param otherVector vector to multiple with\r\n * @returns the updated Vector4.\r\n */\r\n public multiplyInPlace(otherVector: DeepImmutable): this {\r\n this.x *= otherVector.x;\r\n this.y *= otherVector.y;\r\n this.z *= otherVector.z;\r\n this.w *= otherVector.w;\r\n return this;\r\n }\r\n\r\n /**\r\n * Returns a new Vector4 set with the multiplication result of the current Vector4 and the given one.\r\n * @param otherVector vector to multiple with\r\n * @returns resulting new vector\r\n */\r\n public multiply(otherVector: DeepImmutable): Vector4 {\r\n return new Vector4(this.x * otherVector.x, this.y * otherVector.y, this.z * otherVector.z, this.w * otherVector.w);\r\n }\r\n /**\r\n * Updates the given vector \"result\" with the multiplication result of the current Vector4 and the given one.\r\n * @param otherVector vector to multiple with\r\n * @param result vector to store the result\r\n * @returns result input\r\n */\r\n public multiplyToRef(otherVector: DeepImmutable, result: T): T {\r\n result.x = this.x * otherVector.x;\r\n result.y = this.y * otherVector.y;\r\n result.z = this.z * otherVector.z;\r\n result.w = this.w * otherVector.w;\r\n return result;\r\n }\r\n /**\r\n * Returns a new Vector4 set with the multiplication result of the given floats and the current Vector4 coordinates.\r\n * @param x x value multiply with\r\n * @param y y value multiply with\r\n * @param z z value multiply with\r\n * @param w w value multiply with\r\n * @returns resulting new vector\r\n */\r\n public multiplyByFloats(x: number, y: number, z: number, w: number): Vector4 {\r\n return new Vector4(this.x * x, this.y * y, this.z * z, this.w * w);\r\n }\r\n /**\r\n * Returns a new Vector4 set with the division result of the current Vector4 by the given one.\r\n * @param otherVector vector to devide with\r\n * @returns resulting new vector\r\n */\r\n public divide(otherVector: DeepImmutable): Vector4 {\r\n return new Vector4(this.x / otherVector.x, this.y / otherVector.y, this.z / otherVector.z, this.w / otherVector.w);\r\n }\r\n /**\r\n * Updates the given vector \"result\" with the division result of the current Vector4 by the given one.\r\n * @param otherVector vector to devide with\r\n * @param result vector to store the result\r\n * @returns result input\r\n */\r\n public divideToRef(otherVector: DeepImmutable, result: T): T {\r\n result.x = this.x / otherVector.x;\r\n result.y = this.y / otherVector.y;\r\n result.z = this.z / otherVector.z;\r\n result.w = this.w / otherVector.w;\r\n return result;\r\n }\r\n\r\n /**\r\n * Divides the current Vector3 coordinates by the given ones.\r\n * @param otherVector vector to devide with\r\n * @returns the updated Vector3.\r\n */\r\n public divideInPlace(otherVector: DeepImmutable): this {\r\n return this.divideToRef(otherVector, this);\r\n }\r\n\r\n /**\r\n * Updates the Vector4 coordinates with the minimum values between its own and the given vector ones\r\n * @param other defines the second operand\r\n * @returns the current updated Vector4\r\n */\r\n public minimizeInPlace(other: DeepImmutable): this {\r\n if (other.x < this.x) {\r\n this.x = other.x;\r\n }\r\n if (other.y < this.y) {\r\n this.y = other.y;\r\n }\r\n if (other.z < this.z) {\r\n this.z = other.z;\r\n }\r\n if (other.w < this.w) {\r\n this.w = other.w;\r\n }\r\n return this;\r\n }\r\n /**\r\n * Updates the Vector4 coordinates with the maximum values between its own and the given vector ones\r\n * @param other defines the second operand\r\n * @returns the current updated Vector4\r\n */\r\n public maximizeInPlace(other: DeepImmutable): this {\r\n if (other.x > this.x) {\r\n this.x = other.x;\r\n }\r\n if (other.y > this.y) {\r\n this.y = other.y;\r\n }\r\n if (other.z > this.z) {\r\n this.z = other.z;\r\n }\r\n if (other.w > this.w) {\r\n this.w = other.w;\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Updates the current Vector4 with the minimal coordinate values between its and the given coordinates\r\n * @param x defines the x coordinate of the operand\r\n * @param y defines the y coordinate of the operand\r\n * @param z defines the z coordinate of the operand\r\n * @param w defines the w coordinate of the operand\r\n * @returns the current updated Vector4\r\n */\r\n public minimizeInPlaceFromFloats(x: number, y: number, z: number, w: number): this {\r\n this.x = Math.min(x, this.x);\r\n this.y = Math.min(y, this.y);\r\n this.z = Math.min(z, this.z);\r\n this.w = Math.min(w, this.w);\r\n return this;\r\n }\r\n\r\n /**\r\n * Updates the current Vector4 with the maximal coordinate values between its and the given coordinates.\r\n * @param x defines the x coordinate of the operand\r\n * @param y defines the y coordinate of the operand\r\n * @param z defines the z coordinate of the operand\r\n * @param w defines the w coordinate of the operand\r\n * @returns the current updated Vector4\r\n */\r\n public maximizeInPlaceFromFloats(x: number, y: number, z: number, w: number): this {\r\n this.x = Math.max(x, this.x);\r\n this.y = Math.max(y, this.y);\r\n this.z = Math.max(z, this.z);\r\n this.w = Math.max(w, this.w);\r\n return this;\r\n }\r\n\r\n /**\r\n * Gets the current Vector4's floored values and stores them in result\r\n * @param result the vector to store the result in\r\n * @returns the result vector\r\n */\r\n public floorToRef(result: T): T {\r\n result.x = Math.floor(this.x);\r\n result.y = Math.floor(this.y);\r\n result.z = Math.floor(this.z);\r\n result.w = Math.floor(this.w);\r\n return result;\r\n }\r\n\r\n /**\r\n * Gets a new Vector4 from current Vector4 floored values\r\n * @returns a new Vector4\r\n */\r\n public floor(): Vector4 {\r\n return new Vector4(Math.floor(this.x), Math.floor(this.y), Math.floor(this.z), Math.floor(this.w));\r\n }\r\n\r\n /**\r\n * Gets the current Vector4's fractional values and stores them in result\r\n * @param result the vector to store the result in\r\n * @returns the result vector\r\n */\r\n public fractToRef(result: T): T {\r\n result.x = this.x - Math.floor(this.x);\r\n result.y = this.y - Math.floor(this.y);\r\n result.z = this.z - Math.floor(this.z);\r\n result.w = this.w - Math.floor(this.w);\r\n return result;\r\n }\r\n\r\n /**\r\n * Gets a new Vector4 from current Vector4 fractional values\r\n * @returns a new Vector4\r\n */\r\n public fract(): Vector4 {\r\n return new Vector4(this.x - Math.floor(this.x), this.y - Math.floor(this.y), this.z - Math.floor(this.z), this.w - Math.floor(this.w));\r\n }\r\n\r\n // Properties\r\n /**\r\n * Returns the Vector4 length (float).\r\n * @returns the length\r\n */\r\n public length(): number {\r\n return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w);\r\n }\r\n /**\r\n * Returns the Vector4 squared length (float).\r\n * @returns the length squared\r\n */\r\n public lengthSquared(): number {\r\n return this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w;\r\n }\r\n\r\n // Methods\r\n /**\r\n * Normalizes in place the Vector4.\r\n * @returns the updated Vector4.\r\n */\r\n public normalize(): this {\r\n return this.normalizeFromLength(this.length());\r\n }\r\n\r\n /**\r\n * Normalize the current Vector4 with the given input length.\r\n * Please note that this is an in place operation.\r\n * @param len the length of the vector\r\n * @returns the current updated Vector4\r\n */\r\n public normalizeFromLength(len: number): this {\r\n if (len === 0 || len === 1.0) {\r\n return this;\r\n }\r\n\r\n return this.scaleInPlace(1.0 / len);\r\n }\r\n\r\n /**\r\n * Normalize the current Vector4 to a new vector\r\n * @returns the new Vector4\r\n */\r\n public normalizeToNew(): Vector4 {\r\n return this.normalizeToRef(new Vector4());\r\n }\r\n\r\n /**\r\n * Normalize the current Vector4 to the reference\r\n * @param reference define the Vector4 to update\r\n * @returns the updated Vector4\r\n */\r\n public normalizeToRef(reference: T): T {\r\n const len = this.length();\r\n if (len === 0 || len === 1.0) {\r\n reference.x = this.x;\r\n reference.y = this.y;\r\n reference.z = this.z;\r\n reference.w = this.w;\r\n return reference;\r\n }\r\n\r\n return this.scaleToRef(1.0 / len, reference);\r\n }\r\n\r\n /**\r\n * Returns a new Vector3 from the Vector4 (x, y, z) coordinates.\r\n * @returns this converted to a new vector3\r\n */\r\n public toVector3(): Vector3 {\r\n return new Vector3(this.x, this.y, this.z);\r\n }\r\n\r\n /**\r\n * Returns a new Vector4 copied from the current one.\r\n * @returns the new cloned vector\r\n */\r\n public clone(): Vector4 {\r\n return new Vector4(this.x, this.y, this.z, this.w);\r\n }\r\n /**\r\n * Updates the current Vector4 with the given one coordinates.\r\n * @param source the source vector to copy from\r\n * @returns the updated Vector4.\r\n */\r\n public copyFrom(source: DeepImmutable): this {\r\n this.x = source.x;\r\n this.y = source.y;\r\n this.z = source.z;\r\n this.w = source.w;\r\n return this;\r\n }\r\n /**\r\n * Updates the current Vector4 coordinates with the given floats.\r\n * @param x float to copy from\r\n * @param y float to copy from\r\n * @param z float to copy from\r\n * @param w float to copy from\r\n * @returns the updated Vector4.\r\n */\r\n public copyFromFloats(x: number, y: number, z: number, w: number): this {\r\n this.x = x;\r\n this.y = y;\r\n this.z = z;\r\n this.w = w;\r\n return this;\r\n }\r\n /**\r\n * Updates the current Vector4 coordinates with the given floats.\r\n * @param x float to set from\r\n * @param y float to set from\r\n * @param z float to set from\r\n * @param w float to set from\r\n * @returns the updated Vector4.\r\n */\r\n public set(x: number, y: number, z: number, w: number): this {\r\n return this.copyFromFloats(x, y, z, w);\r\n }\r\n\r\n /**\r\n * Copies the given float to the current Vector4 coordinates\r\n * @param v defines the x, y, z and w coordinates of the operand\r\n * @returns the current updated Vector4\r\n */\r\n public setAll(v: number): this {\r\n this.x = this.y = this.z = this.w = v;\r\n return this;\r\n }\r\n\r\n /**\r\n * Returns the dot product (float) between the current vectors and \"otherVector\"\r\n * @param otherVector defines the right operand\r\n * @returns the dot product\r\n */\r\n public dot(otherVector: DeepImmutable): number {\r\n return this.x * otherVector.x + this.y * otherVector.y + this.z * otherVector.z + this.w * otherVector.w;\r\n }\r\n\r\n // Statics\r\n /**\r\n * Returns a new Vector4 set from the starting index of the given array.\r\n * @param array the array to pull values from\r\n * @param offset the offset into the array to start at\r\n * @returns the new vector\r\n */\r\n public static FromArray(array: DeepImmutable>, offset?: number): Vector4 {\r\n if (!offset) {\r\n offset = 0;\r\n }\r\n return new Vector4(array[offset], array[offset + 1], array[offset + 2], array[offset + 3]);\r\n }\r\n /**\r\n * Updates the given vector \"result\" from the starting index of the given array.\r\n * @param array the array to pull values from\r\n * @param offset the offset into the array to start at\r\n * @param result the vector to store the result in\r\n * @returns result input\r\n */\r\n public static FromArrayToRef(array: DeepImmutable>, offset: number, result: T): T {\r\n result.x = array[offset];\r\n result.y = array[offset + 1];\r\n result.z = array[offset + 2];\r\n result.w = array[offset + 3];\r\n return result;\r\n }\r\n /**\r\n * Updates the given vector \"result\" from the starting index of the given Float32Array.\r\n * @param array the array to pull values from\r\n * @param offset the offset into the array to start at\r\n * @param result the vector to store the result in\r\n * @returns result input\r\n */\r\n public static FromFloatArrayToRef(array: DeepImmutable, offset: number, result: T): T {\r\n Vector4.FromArrayToRef(array, offset, result);\r\n return result;\r\n }\r\n /**\r\n * Updates the given vector \"result\" coordinates from the given floats.\r\n * @param x float to set from\r\n * @param y float to set from\r\n * @param z float to set from\r\n * @param w float to set from\r\n * @param result the vector to the floats in\r\n * @returns result input\r\n */\r\n public static FromFloatsToRef(x: number, y: number, z: number, w: number, result: T): T {\r\n result.x = x;\r\n result.y = y;\r\n result.z = z;\r\n result.w = w;\r\n return result;\r\n }\r\n /**\r\n * Returns a new Vector4 set to (0.0, 0.0, 0.0, 0.0)\r\n * @returns the new vector\r\n */\r\n public static Zero(): Vector4 {\r\n return new Vector4(0.0, 0.0, 0.0, 0.0);\r\n }\r\n /**\r\n * Returns a new Vector4 set to (1.0, 1.0, 1.0, 1.0)\r\n * @returns the new vector\r\n */\r\n public static One(): Vector4 {\r\n return new Vector4(1.0, 1.0, 1.0, 1.0);\r\n }\r\n\r\n /**\r\n * Returns a new Vector4 with random values between min and max\r\n * @param min the minimum random value\r\n * @param max the maximum random value\r\n * @returns a Vector4 with random values between min and max\r\n */\r\n public static Random(min: number = 0, max: number = 1): Vector4 {\r\n return new Vector4(RandomRange(min, max), RandomRange(min, max), RandomRange(min, max), RandomRange(min, max));\r\n }\r\n\r\n /**\r\n * Sets a Vector4 with random values between min and max\r\n * @param min the minimum random value\r\n * @param max the maximum random value\r\n * @param ref the ref to store the values in\r\n * @returns the ref with random values between min and max\r\n */\r\n public static RandomToRef(min: number = 0, max: number = 1, ref: T): T {\r\n ref.x = RandomRange(min, max);\r\n ref.y = RandomRange(min, max);\r\n ref.z = RandomRange(min, max);\r\n ref.w = RandomRange(min, max);\r\n return ref;\r\n }\r\n\r\n /**\r\n * Returns a new Vector4 set with the coordinates of \"value\", if the vector \"value\" is in the cube defined by the vectors \"min\" and \"max\"\r\n * If a coordinate value of \"value\" is lower than one of the \"min\" coordinate, then this \"value\" coordinate is set with the \"min\" one\r\n * If a coordinate value of \"value\" is greater than one of the \"max\" coordinate, then this \"value\" coordinate is set with the \"max\" one\r\n * @param value defines the current value\r\n * @param min defines the lower range value\r\n * @param max defines the upper range value\r\n * @returns the new Vector4\r\n */\r\n public static Clamp(value: DeepImmutable, min: DeepImmutable, max: DeepImmutable): Vector4 {\r\n return Vector4.ClampToRef(value, min, max, new Vector4());\r\n }\r\n\r\n /**\r\n * Sets the given vector \"result\" with the coordinates of \"value\", if the vector \"value\" is in the cube defined by the vectors \"min\" and \"max\"\r\n * If a coordinate value of \"value\" is lower than one of the \"min\" coordinate, then this \"value\" coordinate is set with the \"min\" one\r\n * If a coordinate value of \"value\" is greater than one of the \"max\" coordinate, then this \"value\" coordinate is set with the \"max\" one\r\n * @param value defines the current value\r\n * @param min defines the lower range value\r\n * @param max defines the upper range value\r\n * @param result defines the Vector4 where to store the result\r\n * @returns result input\r\n */\r\n public static ClampToRef(value: DeepImmutable, min: DeepImmutable, max: DeepImmutable, result: T): T {\r\n result.x = Clamp(value.x, min.x, max.x);\r\n result.y = Clamp(value.y, min.y, max.y);\r\n result.z = Clamp(value.z, min.z, max.z);\r\n result.w = Clamp(value.w, min.w, max.w);\r\n return result;\r\n }\r\n\r\n /**\r\n * Checks if a given vector is inside a specific range\r\n * Example Playground https://playground.babylonjs.com/#R1F8YU#75\r\n * @param v defines the vector to test\r\n * @param min defines the minimum range\r\n * @param max defines the maximum range\r\n */\r\n public static CheckExtends(v: IVector4Like, min: Vector4, max: Vector4): void {\r\n min.minimizeInPlace(v);\r\n max.maximizeInPlace(v);\r\n }\r\n\r\n /**\r\n * Gets a zero Vector4 that must not be updated\r\n */\r\n public static get ZeroReadOnly(): DeepImmutable {\r\n return Vector4._ZeroReadOnly;\r\n }\r\n /**\r\n * Returns a new normalized Vector4 from the given one.\r\n * @param vector the vector to normalize\r\n * @returns the vector\r\n */\r\n public static Normalize(vector: DeepImmutable): Vector4 {\r\n return Vector4.NormalizeToRef(vector, new Vector4());\r\n }\r\n /**\r\n * Updates the given vector \"result\" from the normalization of the given one.\r\n * @param vector the vector to normalize\r\n * @param result the vector to store the result in\r\n * @returns result input\r\n */\r\n public static NormalizeToRef(vector: DeepImmutable, result: T): T {\r\n vector.normalizeToRef(result);\r\n return result;\r\n }\r\n\r\n /**\r\n * Returns a vector with the minimum values from the left and right vectors\r\n * @param left left vector to minimize\r\n * @param right right vector to minimize\r\n * @returns a new vector with the minimum of the left and right vector values\r\n */\r\n public static Minimize(left: DeepImmutable, right: DeepImmutable): Vector4 {\r\n const min = new Vector4();\r\n min.copyFrom(left);\r\n min.minimizeInPlace(right);\r\n return min;\r\n }\r\n\r\n /**\r\n * Returns a vector with the maximum values from the left and right vectors\r\n * @param left left vector to maximize\r\n * @param right right vector to maximize\r\n * @returns a new vector with the maximum of the left and right vector values\r\n */\r\n public static Maximize(left: DeepImmutable, right: DeepImmutable): Vector4 {\r\n const max = new Vector4();\r\n max.copyFrom(left);\r\n max.maximizeInPlace(right);\r\n return max;\r\n }\r\n /**\r\n * Returns the distance (float) between the vectors \"value1\" and \"value2\".\r\n * @param value1 value to calulate the distance between\r\n * @param value2 value to calulate the distance between\r\n * @returns the distance between the two vectors\r\n */\r\n public static Distance(value1: DeepImmutable, value2: DeepImmutable): number {\r\n return Math.sqrt(Vector4.DistanceSquared(value1, value2));\r\n }\r\n /**\r\n * Returns the squared distance (float) between the vectors \"value1\" and \"value2\".\r\n * @param value1 value to calulate the distance between\r\n * @param value2 value to calulate the distance between\r\n * @returns the distance between the two vectors squared\r\n */\r\n public static DistanceSquared(value1: DeepImmutable, value2: DeepImmutable): number {\r\n const x = value1.x - value2.x;\r\n const y = value1.y - value2.y;\r\n const z = value1.z - value2.z;\r\n const w = value1.w - value2.w;\r\n\r\n return x * x + y * y + z * z + w * w;\r\n }\r\n /**\r\n * Returns a new Vector4 located at the center between the vectors \"value1\" and \"value2\".\r\n * @param value1 value to calulate the center between\r\n * @param value2 value to calulate the center between\r\n * @returns the center between the two vectors\r\n */\r\n public static Center(value1: DeepImmutable, value2: DeepImmutable): Vector4 {\r\n return Vector4.CenterToRef(value1, value2, new Vector4());\r\n }\r\n\r\n /**\r\n * Gets the center of the vectors \"value1\" and \"value2\" and stores the result in the vector \"ref\"\r\n * @param value1 defines first vector\r\n * @param value2 defines second vector\r\n * @param ref defines third vector\r\n * @returns ref\r\n */\r\n public static CenterToRef(value1: DeepImmutable, value2: DeepImmutable, ref: T): T {\r\n ref.x = (value1.x + value2.x) / 2;\r\n ref.y = (value1.y + value2.y) / 2;\r\n ref.z = (value1.z + value2.z) / 2;\r\n ref.w = (value1.w + value2.w) / 2;\r\n return ref;\r\n }\r\n\r\n /**\r\n * Returns a new Vector4 set with the result of the transformation by the given matrix of the given vector.\r\n * This method computes tranformed coordinates only, not transformed direction vectors (ie. it takes translation in account)\r\n * The difference with Vector3.TransformCoordinates is that the w component is not used to divide the other coordinates but is returned in the w coordinate instead\r\n * @param vector defines the Vector3 to transform\r\n * @param transformation defines the transformation matrix\r\n * @returns the transformed Vector4\r\n */\r\n public static TransformCoordinates(vector: DeepImmutable, transformation: DeepImmutable): Vector4 {\r\n return Vector4.TransformCoordinatesToRef(vector, transformation, new Vector4());\r\n }\r\n\r\n /**\r\n * Sets the given vector \"result\" coordinates with the result of the transformation by the given matrix of the given vector\r\n * This method computes tranformed coordinates only, not transformed direction vectors (ie. it takes translation in account)\r\n * The difference with Vector3.TransformCoordinatesToRef is that the w component is not used to divide the other coordinates but is returned in the w coordinate instead\r\n * @param vector defines the Vector3 to transform\r\n * @param transformation defines the transformation matrix\r\n * @param result defines the Vector4 where to store the result\r\n * @returns result input\r\n */\r\n public static TransformCoordinatesToRef(vector: DeepImmutable, transformation: DeepImmutable, result: T): T {\r\n Vector4.TransformCoordinatesFromFloatsToRef(vector._x, vector._y, vector._z, transformation, result);\r\n return result;\r\n }\r\n\r\n /**\r\n * Sets the given vector \"result\" coordinates with the result of the transformation by the given matrix of the given floats (x, y, z)\r\n * This method computes tranformed coordinates only, not transformed direction vectors\r\n * The difference with Vector3.TransformCoordinatesFromFloatsToRef is that the w component is not used to divide the other coordinates but is returned in the w coordinate instead\r\n * @param x define the x coordinate of the source vector\r\n * @param y define the y coordinate of the source vector\r\n * @param z define the z coordinate of the source vector\r\n * @param transformation defines the transformation matrix\r\n * @param result defines the Vector4 where to store the result\r\n * @returns result input\r\n */\r\n public static TransformCoordinatesFromFloatsToRef(x: number, y: number, z: number, transformation: DeepImmutable, result: T): T {\r\n const m = transformation.m;\r\n const rx = x * m[0] + y * m[4] + z * m[8] + m[12];\r\n const ry = x * m[1] + y * m[5] + z * m[9] + m[13];\r\n const rz = x * m[2] + y * m[6] + z * m[10] + m[14];\r\n const rw = x * m[3] + y * m[7] + z * m[11] + m[15];\r\n\r\n result.x = rx;\r\n result.y = ry;\r\n result.z = rz;\r\n result.w = rw;\r\n return result;\r\n }\r\n\r\n /**\r\n * Returns a new Vector4 set with the result of the normal transformation by the given matrix of the given vector.\r\n * This methods computes transformed normalized direction vectors only.\r\n * @param vector the vector to transform\r\n * @param transformation the transformation matrix to apply\r\n * @returns the new vector\r\n */\r\n public static TransformNormal(vector: DeepImmutable, transformation: DeepImmutable): Vector4 {\r\n return Vector4.TransformNormalToRef(vector, transformation, new Vector4());\r\n }\r\n\r\n /**\r\n * Sets the given vector \"result\" with the result of the normal transformation by the given matrix of the given vector.\r\n * This methods computes transformed normalized direction vectors only.\r\n * @param vector the vector to transform\r\n * @param transformation the transformation matrix to apply\r\n * @param result the vector to store the result in\r\n * @returns result input\r\n */\r\n public static TransformNormalToRef(vector: DeepImmutable, transformation: DeepImmutable, result: T): T {\r\n const m = transformation.m;\r\n const x = vector.x * m[0] + vector.y * m[4] + vector.z * m[8];\r\n const y = vector.x * m[1] + vector.y * m[5] + vector.z * m[9];\r\n const z = vector.x * m[2] + vector.y * m[6] + vector.z * m[10];\r\n result.x = x;\r\n result.y = y;\r\n result.z = z;\r\n result.w = vector.w;\r\n return result;\r\n }\r\n\r\n /**\r\n * Sets the given vector \"result\" with the result of the normal transformation by the given matrix of the given floats (x, y, z, w).\r\n * This methods computes transformed normalized direction vectors only.\r\n * @param x value to transform\r\n * @param y value to transform\r\n * @param z value to transform\r\n * @param w value to transform\r\n * @param transformation the transformation matrix to apply\r\n * @param result the vector to store the results in\r\n * @returns result input\r\n */\r\n public static TransformNormalFromFloatsToRef(x: number, y: number, z: number, w: number, transformation: DeepImmutable, result: T): T {\r\n const m = transformation.m;\r\n result.x = x * m[0] + y * m[4] + z * m[8];\r\n result.y = x * m[1] + y * m[5] + z * m[9];\r\n result.z = x * m[2] + y * m[6] + z * m[10];\r\n result.w = w;\r\n return result;\r\n }\r\n\r\n /**\r\n * Creates a new Vector4 from a Vector3\r\n * @param source defines the source data\r\n * @param w defines the 4th component (default is 0)\r\n * @returns a new Vector4\r\n */\r\n public static FromVector3(source: Vector3, w: number = 0): Vector4 {\r\n return new Vector4(source._x, source._y, source._z, w);\r\n }\r\n\r\n /**\r\n * Returns the dot product (float) between the vectors \"left\" and \"right\"\r\n * @param left defines the left operand\r\n * @param right defines the right operand\r\n * @returns the dot product\r\n */\r\n public static Dot(left: DeepImmutable, right: DeepImmutable): number {\r\n return left.x * right.x + left.y * right.y + left.z * right.z + left.w * right.w;\r\n }\r\n}\r\nVector4 satisfies VectorStatic;\r\nObject.defineProperties(Vector4.prototype, {\r\n dimension: { value: [4] },\r\n rank: { value: 1 },\r\n});\r\n\r\n/**\r\n * Class used to store quaternion data\r\n * Example Playground - Overview - https://playground.babylonjs.com/#L49EJ7#100\r\n * @see https://en.wikipedia.org/wiki/Quaternion\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/transforms\r\n */\r\nexport class Quaternion implements Tensor, Quaternion>, IQuaternionLike {\r\n /**\r\n * If the first quaternion is flagged with integers (as everything is 0,0,0,0), V8 stores all of the properties as integers internally because it doesn't know any better yet.\r\n * If subsequent quaternion are created with non-integer values, V8 determines that it would be best to represent these properties as doubles instead of integers,\r\n * and henceforth it will use floating-point representation for all quaternion instances that it creates.\r\n * But the original quaternion instances are unchanged and has a \"deprecated map\".\r\n * If we keep using the quaternion instances from step 1, it will now be a poison pill which will mess up optimizations in any code it touches.\r\n */\r\n static _V8PerformanceHack = new Quaternion(0.5, 0.5, 0.5, 0.5) as DeepImmutable;\r\n /** @internal */\r\n public _x: number;\r\n\r\n /** @internal */\r\n public _y: number;\r\n\r\n /** @internal */\r\n public _z: number;\r\n\r\n /** @internal */\r\n public _w: number;\r\n\r\n /** @internal */\r\n public _isDirty = true;\r\n\r\n /** Gets or sets the x coordinate */\r\n public get x() {\r\n return this._x;\r\n }\r\n\r\n public set x(value: number) {\r\n this._x = value;\r\n this._isDirty = true;\r\n }\r\n\r\n /** Gets or sets the y coordinate */\r\n public get y() {\r\n return this._y;\r\n }\r\n\r\n public set y(value: number) {\r\n this._y = value;\r\n this._isDirty = true;\r\n }\r\n\r\n /** Gets or sets the z coordinate */\r\n public get z() {\r\n return this._z;\r\n }\r\n\r\n public set z(value: number) {\r\n this._z = value;\r\n this._isDirty = true;\r\n }\r\n\r\n /** Gets or sets the w coordinate */\r\n public get w() {\r\n return this._w;\r\n }\r\n\r\n public set w(value: number) {\r\n this._w = value;\r\n this._isDirty = true;\r\n }\r\n\r\n /**\r\n * @see Tensor.dimension\r\n */\r\n declare public readonly dimension: Readonly<[4]>;\r\n\r\n /**\r\n * @see Tensor.rank\r\n */\r\n declare public readonly rank: 1;\r\n\r\n /**\r\n * Creates a new Quaternion from the given floats\r\n * @param x defines the first component (0 by default)\r\n * @param y defines the second component (0 by default)\r\n * @param z defines the third component (0 by default)\r\n * @param w defines the fourth component (1.0 by default)\r\n */\r\n constructor(x: number = 0.0, y: number = 0.0, z: number = 0.0, w: number = 1.0) {\r\n this._x = x;\r\n this._y = y;\r\n this._z = z;\r\n this._w = w;\r\n }\r\n\r\n /**\r\n * Gets a string representation for the current quaternion\r\n * @returns a string with the Quaternion coordinates\r\n */\r\n public toString(): string {\r\n return `{X: ${this._x} Y: ${this._y} Z: ${this._z} W: ${this._w}}`;\r\n }\r\n\r\n /**\r\n * Gets the class name of the quaternion\r\n * @returns the string \"Quaternion\"\r\n */\r\n public getClassName(): string {\r\n return \"Quaternion\";\r\n }\r\n\r\n /**\r\n * Gets a hash code for this quaternion\r\n * @returns the quaternion hash code\r\n */\r\n public getHashCode(): number {\r\n const x = _ExtractAsInt(this._x);\r\n const y = _ExtractAsInt(this._y);\r\n const z = _ExtractAsInt(this._z);\r\n const w = _ExtractAsInt(this._w);\r\n\r\n let hash = x;\r\n hash = (hash * 397) ^ y;\r\n hash = (hash * 397) ^ z;\r\n hash = (hash * 397) ^ w;\r\n return hash;\r\n }\r\n\r\n /**\r\n * Copy the quaternion to an array\r\n * Example Playground https://playground.babylonjs.com/#L49EJ7#13\r\n * @returns a new array populated with 4 elements from the quaternion coordinates\r\n */\r\n public asArray(): Tuple {\r\n return [this._x, this._y, this._z, this._w];\r\n }\r\n\r\n /**\r\n * Stores from the starting index in the given array the Quaternion successive values\r\n * Example Playground https://playground.babylonjs.com/#L49EJ7#59\r\n * @param array defines the array where to store the x,y,z,w components\r\n * @param index defines an optional index in the target array to define where to start storing values\r\n * @returns the current Quaternion object\r\n */\r\n public toArray(array: FloatArray, index: number = 0): this {\r\n array[index] = this._x;\r\n array[index + 1] = this._y;\r\n array[index + 2] = this._z;\r\n array[index + 3] = this._w;\r\n return this;\r\n }\r\n\r\n public fromArray(array: FloatArray, index: number = 0): this {\r\n return Quaternion.FromArrayToRef(array, index, this);\r\n }\r\n\r\n /**\r\n * Check if two quaternions are equals\r\n * Example Playground https://playground.babylonjs.com/#L49EJ7#38\r\n * @param otherQuaternion defines the second operand\r\n * @returns true if the current quaternion and the given one coordinates are strictly equals\r\n */\r\n public equals(otherQuaternion: DeepImmutable): boolean {\r\n return otherQuaternion && this._x === otherQuaternion._x && this._y === otherQuaternion._y && this._z === otherQuaternion._z && this._w === otherQuaternion._w;\r\n }\r\n\r\n /**\r\n * Gets a boolean if two quaternions are equals (using an epsilon value)\r\n * Example Playground https://playground.babylonjs.com/#L49EJ7#37\r\n * @param otherQuaternion defines the other quaternion\r\n * @param epsilon defines the minimal distance to consider equality\r\n * @returns true if the given quaternion coordinates are close to the current ones by a distance of epsilon.\r\n */\r\n public equalsWithEpsilon(otherQuaternion: DeepImmutable, epsilon: number = Epsilon): boolean {\r\n return (\r\n otherQuaternion &&\r\n WithinEpsilon(this._x, otherQuaternion._x, epsilon) &&\r\n WithinEpsilon(this._y, otherQuaternion._y, epsilon) &&\r\n WithinEpsilon(this._z, otherQuaternion._z, epsilon) &&\r\n WithinEpsilon(this._w, otherQuaternion._w, epsilon)\r\n );\r\n }\r\n\r\n /**\r\n * Clone the current quaternion\r\n * Example Playground https://playground.babylonjs.com/#L49EJ7#12\r\n * @returns a new quaternion copied from the current one\r\n */\r\n public clone(): Quaternion {\r\n return new Quaternion(this._x, this._y, this._z, this._w);\r\n }\r\n\r\n /**\r\n * Copy a quaternion to the current one\r\n * Example Playground https://playground.babylonjs.com/#L49EJ7#86\r\n * @param other defines the other quaternion\r\n * @returns the updated current quaternion\r\n */\r\n public copyFrom(other: DeepImmutable): this {\r\n this._x = other._x;\r\n this._y = other._y;\r\n this._z = other._z;\r\n this._w = other._w;\r\n this._isDirty = true;\r\n return this;\r\n }\r\n\r\n /**\r\n * Updates the current quaternion with the given float coordinates\r\n * Example Playground https://playground.babylonjs.com/#L49EJ7#87\r\n * @param x defines the x coordinate\r\n * @param y defines the y coordinate\r\n * @param z defines the z coordinate\r\n * @param w defines the w coordinate\r\n * @returns the updated current quaternion\r\n */\r\n public copyFromFloats(x: number, y: number, z: number, w: number): this {\r\n this._x = x;\r\n this._y = y;\r\n this._z = z;\r\n this._w = w;\r\n this._isDirty = true;\r\n return this;\r\n }\r\n\r\n /**\r\n * Updates the current quaternion from the given float coordinates\r\n * Example Playground https://playground.babylonjs.com/#L49EJ7#56\r\n * @param x defines the x coordinate\r\n * @param y defines the y coordinate\r\n * @param z defines the z coordinate\r\n * @param w defines the w coordinate\r\n * @returns the updated current quaternion\r\n */\r\n public set(x: number, y: number, z: number, w: number): this {\r\n return this.copyFromFloats(x, y, z, w);\r\n }\r\n\r\n public setAll(value: number): this {\r\n return this.copyFromFloats(value, value, value, value);\r\n }\r\n\r\n /**\r\n * Adds two quaternions\r\n * Example Playground https://playground.babylonjs.com/#L49EJ7#10\r\n * @param other defines the second operand\r\n * @returns a new quaternion as the addition result of the given one and the current quaternion\r\n */\r\n public add(other: DeepImmutable): Quaternion {\r\n return new Quaternion(this._x + other._x, this._y + other._y, this._z + other._z, this._w + other._w);\r\n }\r\n\r\n /**\r\n * Add a quaternion to the current one\r\n * Example Playground https://playground.babylonjs.com/#L49EJ7#11\r\n * @param other defines the quaternion to add\r\n * @returns the current quaternion\r\n */\r\n public addInPlace(other: DeepImmutable): this {\r\n this._x += other._x;\r\n this._y += other._y;\r\n this._z += other._z;\r\n this._w += other._w;\r\n this._isDirty = true;\r\n return this;\r\n }\r\n\r\n public addToRef(other: DeepImmutable, result: T): T {\r\n result._x = this._x + other._x;\r\n result._y = this._y + other._y;\r\n result._z = this._z + other._z;\r\n result._w = this._w + other._w;\r\n result._isDirty = true;\r\n return result;\r\n }\r\n\r\n public addInPlaceFromFloats(x: number, y: number, z: number, w: number): this {\r\n this._x += x;\r\n this._y += y;\r\n this._z += z;\r\n this._w += w;\r\n this._isDirty = true;\r\n return this;\r\n }\r\n\r\n public subtractToRef(other: DeepImmutable, result: T): T {\r\n result._x = this._x - other._x;\r\n result._y = this._y - other._y;\r\n result._z = this._z - other._z;\r\n result._w = this._w - other._w;\r\n result._isDirty = true;\r\n return result;\r\n }\r\n\r\n public subtractFromFloats(x: number, y: number, z: number, w: number): Quaternion {\r\n return this.subtractFromFloatsToRef(x, y, z, w, new Quaternion());\r\n }\r\n\r\n public subtractFromFloatsToRef(x: number, y: number, z: number, w: number, result: T): T {\r\n result._x = this._x - x;\r\n result._y = this._y - y;\r\n result._z = this._z - z;\r\n result._w = this._w - w;\r\n result._isDirty = true;\r\n return result;\r\n }\r\n\r\n /**\r\n * Subtract two quaternions\r\n * Example Playground https://playground.babylonjs.com/#L49EJ7#57\r\n * @param other defines the second operand\r\n * @returns a new quaternion as the subtraction result of the given one from the current one\r\n */\r\n public subtract(other: DeepImmutable): Quaternion {\r\n return new Quaternion(this._x - other._x, this._y - other._y, this._z - other._z, this._w - other._w);\r\n }\r\n\r\n /**\r\n * Subtract a quaternion to the current one\r\n * Example Playground https://playground.babylonjs.com/#L49EJ7#58\r\n * @param other defines the quaternion to subtract\r\n * @returns the current quaternion\r\n */\r\n public subtractInPlace(other: DeepImmutable): this {\r\n this._x -= other._x;\r\n this._y -= other._y;\r\n this._z -= other._z;\r\n this._w -= other._w;\r\n this._isDirty = true;\r\n return this;\r\n }\r\n\r\n /**\r\n * Multiplies the current quaternion by a scale factor\r\n * Example Playground https://playground.babylonjs.com/#L49EJ7#88\r\n * @param value defines the scale factor\r\n * @returns a new quaternion set by multiplying the current quaternion coordinates by the float \"scale\"\r\n */\r\n public scale(value: number): Quaternion {\r\n return new Quaternion(this._x * value, this._y * value, this._z * value, this._w * value);\r\n }\r\n\r\n /**\r\n * Scale the current quaternion values by a factor and stores the result to a given quaternion\r\n * Example Playground https://playground.babylonjs.com/#L49EJ7#89\r\n * @param scale defines the scale factor\r\n * @param result defines the Quaternion object where to store the result\r\n * @returns result input\r\n */\r\n public scaleToRef(scale: number, result: T): T {\r\n result._x = this._x * scale;\r\n result._y = this._y * scale;\r\n result._z = this._z * scale;\r\n result._w = this._w * scale;\r\n result._isDirty = true;\r\n return result;\r\n }\r\n\r\n /**\r\n * Multiplies in place the current quaternion by a scale factor\r\n * Example Playground https://playground.babylonjs.com/#L49EJ7#90\r\n * @param value defines the scale factor\r\n * @returns the current modified quaternion\r\n */\r\n public scaleInPlace(value: number): this {\r\n this._x *= value;\r\n this._y *= value;\r\n this._z *= value;\r\n this._w *= value;\r\n this._isDirty = true;\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Scale the current quaternion values by a factor and add the result to a given quaternion\r\n * Example Playground https://playground.babylonjs.com/#L49EJ7#91\r\n * @param scale defines the scale factor\r\n * @param result defines the Quaternion object where to store the result\r\n * @returns result input\r\n */\r\n public scaleAndAddToRef(scale: number, result: T): T {\r\n result._x += this._x * scale;\r\n result._y += this._y * scale;\r\n result._z += this._z * scale;\r\n result._w += this._w * scale;\r\n result._isDirty = true;\r\n return result;\r\n }\r\n\r\n /**\r\n * Multiplies two quaternions\r\n * Example Playground https://playground.babylonjs.com/#L49EJ7#43\r\n * @param q1 defines the second operand\r\n * @returns a new quaternion set as the multiplication result of the current one with the given one \"q1\"\r\n */\r\n public multiply(q1: DeepImmutable): Quaternion {\r\n const result = new Quaternion(0, 0, 0, 1.0);\r\n this.multiplyToRef(q1, result);\r\n return result;\r\n }\r\n\r\n /**\r\n * Sets the given \"result\" as the multiplication result of the current one with the given one \"q1\"\r\n * Example Playground https://playground.babylonjs.com/#L49EJ7#45\r\n * @param q1 defines the second operand\r\n * @param result defines the target quaternion\r\n * @returns the current quaternion\r\n */\r\n public multiplyToRef(q1: DeepImmutable, result: T): T {\r\n const x = this._x * q1._w + this._y * q1._z - this._z * q1._y + this._w * q1._x;\r\n const y = -this._x * q1._z + this._y * q1._w + this._z * q1._x + this._w * q1._y;\r\n const z = this._x * q1._y - this._y * q1._x + this._z * q1._w + this._w * q1._z;\r\n const w = -this._x * q1._x - this._y * q1._y - this._z * q1._z + this._w * q1._w;\r\n result.copyFromFloats(x, y, z, w);\r\n return result;\r\n }\r\n\r\n /**\r\n * Updates the current quaternion with the multiplication of itself with the given one \"q1\"\r\n * Example Playground https://playground.babylonjs.com/#L49EJ7#46\r\n * @param other defines the second operand\r\n * @returns the currentupdated quaternion\r\n */\r\n public multiplyInPlace(other: DeepImmutable): this {\r\n return this.multiplyToRef(other, this);\r\n }\r\n\r\n public multiplyByFloats(x: number, y: number, z: number, w: number): this {\r\n this._x *= x;\r\n this._y *= y;\r\n this._z *= z;\r\n this._w *= w;\r\n this._isDirty = true;\r\n return this;\r\n }\r\n\r\n /**\r\n * @internal\r\n * Do not use\r\n */\r\n public divide(_other: DeepImmutable): this {\r\n throw new ReferenceError(\"Can not divide a quaternion\");\r\n }\r\n\r\n /**\r\n * @internal\r\n * Do not use\r\n */\r\n public divideToRef(_other: DeepImmutable, _result: T): T {\r\n throw new ReferenceError(\"Can not divide a quaternion\");\r\n }\r\n\r\n /**\r\n * @internal\r\n * Do not use\r\n */\r\n public divideInPlace(_other: DeepImmutable): this {\r\n throw new ReferenceError(\"Can not divide a quaternion\");\r\n }\r\n\r\n /**\r\n * @internal\r\n * Do not use\r\n */\r\n public minimizeInPlace(): this {\r\n throw new ReferenceError(\"Can not minimize a quaternion\");\r\n }\r\n\r\n /**\r\n * @internal\r\n * Do not use\r\n */\r\n public minimizeInPlaceFromFloats(): this {\r\n throw new ReferenceError(\"Can not minimize a quaternion\");\r\n }\r\n\r\n /**\r\n * @internal\r\n * Do not use\r\n */\r\n public maximizeInPlace(): this {\r\n throw new ReferenceError(\"Can not maximize a quaternion\");\r\n }\r\n\r\n /**\r\n * @internal\r\n * Do not use\r\n */\r\n public maximizeInPlaceFromFloats(): this {\r\n throw new ReferenceError(\"Can not maximize a quaternion\");\r\n }\r\n\r\n public negate(): Quaternion {\r\n return this.negateToRef(new Quaternion());\r\n }\r\n\r\n public negateInPlace(): this {\r\n this._x = -this._x;\r\n this._y = -this._y;\r\n this._z = -this._z;\r\n this._w = -this._w;\r\n this._isDirty = true;\r\n return this;\r\n }\r\n\r\n public negateToRef(result: T): T {\r\n result._x = -this._x;\r\n result._y = -this._y;\r\n result._z = -this._z;\r\n result._w = -this._w;\r\n result._isDirty = true;\r\n return result;\r\n }\r\n\r\n public equalsToFloats(x: number, y: number, z: number, w: number): boolean {\r\n return this._x === x && this._y === y && this._z === z && this._w === w;\r\n }\r\n\r\n /**\r\n * @internal\r\n * Do not use\r\n */\r\n public floorToRef(_result: T): T {\r\n throw new ReferenceError(\"Can not floor a quaternion\");\r\n }\r\n\r\n /**\r\n * @internal\r\n * Do not use\r\n */\r\n public floor(): Quaternion {\r\n throw new ReferenceError(\"Can not floor a quaternion\");\r\n }\r\n\r\n /**\r\n * @internal\r\n * Do not use\r\n */\r\n public fractToRef(_result: T): T {\r\n throw new ReferenceError(\"Can not fract a quaternion\");\r\n }\r\n\r\n /**\r\n * @internal\r\n * Do not use\r\n */\r\n public fract(): Quaternion {\r\n throw new ReferenceError(\"Can not fract a quaternion\");\r\n }\r\n\r\n /**\r\n * Conjugates the current quaternion and stores the result in the given quaternion\r\n * Example Playground https://playground.babylonjs.com/#L49EJ7#81\r\n * @param ref defines the target quaternion\r\n * @returns result input\r\n */\r\n public conjugateToRef(ref: T): T {\r\n ref.copyFromFloats(-this._x, -this._y, -this._z, this._w);\r\n return ref;\r\n }\r\n\r\n /**\r\n * Conjugates in place the current quaternion\r\n * Example Playground https://playground.babylonjs.com/#L49EJ7#82\r\n * @returns the current updated quaternion\r\n */\r\n public conjugateInPlace(): this {\r\n this._x *= -1;\r\n this._y *= -1;\r\n this._z *= -1;\r\n this._isDirty = true;\r\n return this;\r\n }\r\n\r\n /**\r\n * Conjugates (1-q) the current quaternion\r\n * Example Playground https://playground.babylonjs.com/#L49EJ7#83\r\n * @returns a new quaternion\r\n */\r\n public conjugate(): Quaternion {\r\n return new Quaternion(-this._x, -this._y, -this._z, this._w);\r\n }\r\n\r\n /**\r\n * Returns the inverse of the current quaternion\r\n * Example Playground https://playground.babylonjs.com/#L49EJ7#84\r\n * @returns a new quaternion\r\n */\r\n public invert(): Quaternion {\r\n const conjugate = this.conjugate();\r\n const lengthSquared = this.lengthSquared();\r\n if (lengthSquared == 0 || lengthSquared == 1) {\r\n return conjugate;\r\n }\r\n conjugate.scaleInPlace(1 / lengthSquared);\r\n return conjugate;\r\n }\r\n\r\n /**\r\n * Invert in place the current quaternion\r\n * Example Playground https://playground.babylonjs.com/#L49EJ7#85\r\n * @returns this quaternion\r\n */\r\n public invertInPlace(): this {\r\n this.conjugateInPlace();\r\n const lengthSquared = this.lengthSquared();\r\n if (lengthSquared == 0 || lengthSquared == 1) {\r\n return this;\r\n }\r\n this.scaleInPlace(1 / lengthSquared);\r\n return this;\r\n }\r\n\r\n /**\r\n * Gets squared length of current quaternion\r\n * Example Playground https://playground.babylonjs.com/#L49EJ7#29\r\n * @returns the quaternion length (float)\r\n */\r\n public lengthSquared(): number {\r\n return this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w;\r\n }\r\n\r\n /**\r\n * Gets length of current quaternion\r\n * Example Playground https://playground.babylonjs.com/#L49EJ7#28\r\n * @returns the quaternion length (float)\r\n */\r\n public length(): number {\r\n return Math.sqrt(this.lengthSquared());\r\n }\r\n\r\n /**\r\n * Normalize in place the current quaternion\r\n * Example Playground https://playground.babylonjs.com/#L49EJ7#54\r\n * @returns the current updated quaternion\r\n */\r\n public normalize(): this {\r\n return this.normalizeFromLength(this.length());\r\n }\r\n\r\n /**\r\n * Normalize the current quaternion with the given input length.\r\n * Please note that this is an in place operation.\r\n * @param len the length of the quaternion\r\n * @returns the current updated Quaternion\r\n */\r\n public normalizeFromLength(len: number): this {\r\n if (len === 0 || len === 1.0) {\r\n return this;\r\n }\r\n\r\n return this.scaleInPlace(1.0 / len);\r\n }\r\n\r\n /**\r\n * Normalize a copy of the current quaternion\r\n * Example Playground https://playground.babylonjs.com/#L49EJ7#55\r\n * @returns the normalized quaternion\r\n */\r\n public normalizeToNew(): Quaternion {\r\n const normalized = new Quaternion(0, 0, 0, 1);\r\n this.normalizeToRef(normalized);\r\n return normalized;\r\n }\r\n\r\n /**\r\n * Normalize the current Quaternion to the reference\r\n * @param reference define the Quaternion to update\r\n * @returns the updated Quaternion\r\n */\r\n public normalizeToRef(reference: T): T {\r\n const len = this.length();\r\n if (len === 0 || len === 1.0) {\r\n return reference.copyFromFloats(this._x, this._y, this._z, this._w);\r\n }\r\n\r\n return this.scaleToRef(1.0 / len, reference);\r\n }\r\n\r\n /**\r\n * Returns a new Vector3 set with the Euler angles translated from the current quaternion\r\n * Example Playground https://playground.babylonjs.com/#L49EJ7#32\r\n * @returns a new Vector3 containing the Euler angles\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/transforms/center_origin/rotation_conventions\r\n */\r\n public toEulerAngles(): Vector3 {\r\n const result = Vector3.Zero();\r\n this.toEulerAnglesToRef(result);\r\n return result;\r\n }\r\n\r\n /**\r\n * Sets the given vector3 \"result\" with the Euler angles translated from the current quaternion\r\n * Example Playground https://playground.babylonjs.com/#L49EJ7#31\r\n * @param result defines the vector which will be filled with the Euler angles\r\n * @returns result input\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/transforms/center_origin/rotation_conventions\r\n */\r\n public toEulerAnglesToRef(result: T): T {\r\n const qz = this._z;\r\n const qx = this._x;\r\n const qy = this._y;\r\n const qw = this._w;\r\n\r\n const zAxisY = qy * qz - qx * qw;\r\n const limit = 0.4999999;\r\n\r\n if (zAxisY < -limit) {\r\n result._y = 2 * Math.atan2(qy, qw);\r\n result._x = Math.PI / 2;\r\n result._z = 0;\r\n result._isDirty = true;\r\n } else if (zAxisY > limit) {\r\n result._y = 2 * Math.atan2(qy, qw);\r\n result._x = -Math.PI / 2;\r\n result._z = 0;\r\n result._isDirty = true;\r\n } else {\r\n const sqw = qw * qw;\r\n const sqz = qz * qz;\r\n const sqx = qx * qx;\r\n const sqy = qy * qy;\r\n result._z = Math.atan2(2.0 * (qx * qy + qz * qw), -sqz - sqx + sqy + sqw);\r\n result._x = Math.asin(-2.0 * zAxisY);\r\n result._y = Math.atan2(2.0 * (qz * qx + qy * qw), sqz - sqx - sqy + sqw);\r\n result._isDirty = true;\r\n }\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Sets the given vector3 \"result\" with the Alpha, Beta, Gamma Euler angles translated from the current quaternion\r\n * @param result defines the vector which will be filled with the Euler angles\r\n * @returns result input\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/transforms/center_origin/rotation_conventions\r\n */\r\n public toAlphaBetaGammaToRef(result: T): T {\r\n const qz = this._z;\r\n const qx = this._x;\r\n const qy = this._y;\r\n const qw = this._w;\r\n\r\n // Compute intermediate values\r\n const sinHalfBeta = Math.sqrt(qx * qx + qy * qy);\r\n const cosHalfBeta = Math.sqrt(qz * qz + qw * qw);\r\n\r\n // Calculate beta\r\n const beta = 2 * Math.atan2(sinHalfBeta, cosHalfBeta);\r\n\r\n // Calculate gamma + alpha\r\n const gammaPlusAlpha = 2 * Math.atan2(qz, qw);\r\n\r\n // Calculate gamma - alpha\r\n const gammaMinusAlpha = 2 * Math.atan2(qy, qx);\r\n\r\n // Calculate gamma and alpha\r\n const gamma = (gammaPlusAlpha + gammaMinusAlpha) / 2;\r\n const alpha = (gammaPlusAlpha - gammaMinusAlpha) / 2;\r\n\r\n result.set(alpha, beta, gamma);\r\n return result;\r\n }\r\n\r\n /**\r\n * Updates the given rotation matrix with the current quaternion values\r\n * Example Playground https://playground.babylonjs.com/#L49EJ7#67\r\n * @param result defines the target matrix\r\n * @returns the updated matrix with the rotation\r\n */\r\n public toRotationMatrix(result: T): T {\r\n Matrix.FromQuaternionToRef(this, result);\r\n return result;\r\n }\r\n\r\n /**\r\n * Updates the current quaternion from the given rotation matrix values\r\n * Example Playground https://playground.babylonjs.com/#L49EJ7#41\r\n * @param matrix defines the source matrix\r\n * @returns the current updated quaternion\r\n */\r\n public fromRotationMatrix(matrix: DeepImmutable): this {\r\n Quaternion.FromRotationMatrixToRef(matrix, this);\r\n return this;\r\n }\r\n\r\n /**\r\n * Returns the dot product (float) between the current quaternions and \"other\"\r\n * @param other defines the right operand\r\n * @returns the dot product\r\n */\r\n public dot(other: DeepImmutable): number {\r\n return this._x * other._x + this._y * other._y + this._z * other._z + this._w * other._w;\r\n }\r\n\r\n // Statics\r\n\r\n /**\r\n * Creates a new quaternion from a rotation matrix\r\n * Example Playground https://playground.babylonjs.com/#L49EJ7#101\r\n * @param matrix defines the source matrix\r\n * @returns a new quaternion created from the given rotation matrix values\r\n */\r\n public static FromRotationMatrix(matrix: DeepImmutable): Quaternion {\r\n const result = new Quaternion();\r\n Quaternion.FromRotationMatrixToRef(matrix, result);\r\n return result;\r\n }\r\n\r\n /**\r\n * Updates the given quaternion with the given rotation matrix values\r\n * Example Playground https://playground.babylonjs.com/#L49EJ7#102\r\n * @param matrix defines the source matrix\r\n * @param result defines the target quaternion\r\n * @returns result input\r\n */\r\n public static FromRotationMatrixToRef(matrix: DeepImmutable, result: T): T {\r\n const data = matrix.m;\r\n const m11 = data[0],\r\n m12 = data[4],\r\n m13 = data[8];\r\n const m21 = data[1],\r\n m22 = data[5],\r\n m23 = data[9];\r\n const m31 = data[2],\r\n m32 = data[6],\r\n m33 = data[10];\r\n const trace = m11 + m22 + m33;\r\n let s;\r\n\r\n if (trace > 0) {\r\n s = 0.5 / Math.sqrt(trace + 1.0);\r\n\r\n result._w = 0.25 / s;\r\n result._x = (m32 - m23) * s;\r\n result._y = (m13 - m31) * s;\r\n result._z = (m21 - m12) * s;\r\n result._isDirty = true;\r\n } else if (m11 > m22 && m11 > m33) {\r\n s = 2.0 * Math.sqrt(1.0 + m11 - m22 - m33);\r\n\r\n result._w = (m32 - m23) / s;\r\n result._x = 0.25 * s;\r\n result._y = (m12 + m21) / s;\r\n result._z = (m13 + m31) / s;\r\n result._isDirty = true;\r\n } else if (m22 > m33) {\r\n s = 2.0 * Math.sqrt(1.0 + m22 - m11 - m33);\r\n\r\n result._w = (m13 - m31) / s;\r\n result._x = (m12 + m21) / s;\r\n result._y = 0.25 * s;\r\n result._z = (m23 + m32) / s;\r\n result._isDirty = true;\r\n } else {\r\n s = 2.0 * Math.sqrt(1.0 + m33 - m11 - m22);\r\n\r\n result._w = (m21 - m12) / s;\r\n result._x = (m13 + m31) / s;\r\n result._y = (m23 + m32) / s;\r\n result._z = 0.25 * s;\r\n result._isDirty = true;\r\n }\r\n return result;\r\n }\r\n\r\n /**\r\n * Returns the dot product (float) between the quaternions \"left\" and \"right\"\r\n * Example Playground https://playground.babylonjs.com/#L49EJ7#61\r\n * @param left defines the left operand\r\n * @param right defines the right operand\r\n * @returns the dot product\r\n */\r\n public static Dot(left: DeepImmutable, right: DeepImmutable): number {\r\n return left._x * right._x + left._y * right._y + left._z * right._z + left._w * right._w;\r\n }\r\n\r\n /**\r\n * Checks if the orientations of two rotation quaternions are close to each other\r\n * Example Playground https://playground.babylonjs.com/#L49EJ7#60\r\n * @param quat0 defines the first quaternion to check\r\n * @param quat1 defines the second quaternion to check\r\n * @param epsilon defines closeness, 0 same orientation, 1 PI apart, default 0.1\r\n * @returns true if the two quaternions are close to each other within epsilon\r\n */\r\n public static AreClose(quat0: DeepImmutable, quat1: DeepImmutable, epsilon: number = 0.1): boolean {\r\n const dot = Quaternion.Dot(quat0, quat1);\r\n\r\n return 1 - dot * dot <= epsilon;\r\n }\r\n\r\n /**\r\n * Smooth interpolation between two quaternions using Slerp\r\n * Example Playground https://playground.babylonjs.com/#L49EJ7#93\r\n * @param source source quaternion\r\n * @param goal goal quaternion\r\n * @param deltaTime current interpolation frame\r\n * @param lerpTime total interpolation time\r\n * @param result the smoothed quaternion\r\n * @returns the smoothed quaternion\r\n */\r\n public static SmoothToRef(source: Quaternion, goal: Quaternion, deltaTime: number, lerpTime: number, result: T): T {\r\n let slerp = lerpTime === 0 ? 1 : deltaTime / lerpTime;\r\n slerp = Clamp(slerp, 0, 1);\r\n\r\n Quaternion.SlerpToRef(source, goal, slerp, result);\r\n return result;\r\n }\r\n\r\n /**\r\n * Creates an empty quaternion\r\n * @returns a new quaternion set to (0.0, 0.0, 0.0)\r\n */\r\n public static Zero(): Quaternion {\r\n return new Quaternion(0.0, 0.0, 0.0, 0.0);\r\n }\r\n\r\n /**\r\n * Inverse a given quaternion\r\n * Example Playground https://playground.babylonjs.com/#L49EJ7#103\r\n * @param q defines the source quaternion\r\n * @returns a new quaternion as the inverted current quaternion\r\n */\r\n public static Inverse(q: DeepImmutable): Quaternion {\r\n return new Quaternion(-q._x, -q._y, -q._z, q._w);\r\n }\r\n\r\n /**\r\n * Inverse a given quaternion\r\n * Example Playground https://playground.babylonjs.com/#L49EJ7#104\r\n * @param q defines the source quaternion\r\n * @param result the quaternion the result will be stored in\r\n * @returns the result quaternion\r\n */\r\n public static InverseToRef(q: Quaternion, result: T): T {\r\n result.set(-q._x, -q._y, -q._z, q._w);\r\n return result;\r\n }\r\n\r\n /**\r\n * Creates an identity quaternion\r\n * @returns the identity quaternion\r\n */\r\n public static Identity(): Quaternion {\r\n return new Quaternion(0.0, 0.0, 0.0, 1.0);\r\n }\r\n\r\n /**\r\n * Gets a boolean indicating if the given quaternion is identity\r\n * @param quaternion defines the quaternion to check\r\n * @returns true if the quaternion is identity\r\n */\r\n public static IsIdentity(quaternion: DeepImmutable): boolean {\r\n return quaternion && quaternion._x === 0 && quaternion._y === 0 && quaternion._z === 0 && quaternion._w === 1;\r\n }\r\n\r\n /**\r\n * Creates a quaternion from a rotation around an axis\r\n * Example Playground https://playground.babylonjs.com/#L49EJ7#72\r\n * @param axis defines the axis to use\r\n * @param angle defines the angle to use\r\n * @returns a new quaternion created from the given axis (Vector3) and angle in radians (float)\r\n */\r\n public static RotationAxis(axis: DeepImmutable, angle: number): Quaternion {\r\n return Quaternion.RotationAxisToRef(axis, angle, new Quaternion());\r\n }\r\n\r\n /**\r\n * Creates a rotation around an axis and stores it into the given quaternion\r\n * Example Playground https://playground.babylonjs.com/#L49EJ7#73\r\n * @param axis defines the axis to use\r\n * @param angle defines the angle to use\r\n * @param result defines the target quaternion\r\n * @returns the target quaternion\r\n */\r\n public static RotationAxisToRef(axis: DeepImmutable, angle: number, result: T): T {\r\n result._w = Math.cos(angle / 2);\r\n const sinByLength = Math.sin(angle / 2) / axis.length();\r\n result._x = axis._x * sinByLength;\r\n result._y = axis._y * sinByLength;\r\n result._z = axis._z * sinByLength;\r\n result._isDirty = true;\r\n return result;\r\n }\r\n\r\n /**\r\n * Creates a new quaternion from data stored into an array\r\n * Example Playground https://playground.babylonjs.com/#L49EJ7#63\r\n * @param array defines the data source\r\n * @param offset defines the offset in the source array where the data starts\r\n * @returns a new quaternion\r\n */\r\n public static FromArray(array: DeepImmutable>, offset?: number): Quaternion {\r\n if (!offset) {\r\n offset = 0;\r\n }\r\n return new Quaternion(array[offset], array[offset + 1], array[offset + 2], array[offset + 3]);\r\n }\r\n\r\n /**\r\n * Updates the given quaternion \"result\" from the starting index of the given array.\r\n * Example Playground https://playground.babylonjs.com/#L49EJ7#64\r\n * @param array the array to pull values from\r\n * @param offset the offset into the array to start at\r\n * @param result the quaternion to store the result in\r\n * @returns result input\r\n */\r\n public static FromArrayToRef(array: DeepImmutable>, offset: number, result: T): T {\r\n result._x = array[offset];\r\n result._y = array[offset + 1];\r\n result._z = array[offset + 2];\r\n result._w = array[offset + 3];\r\n result._isDirty = true;\r\n return result;\r\n }\r\n\r\n /**\r\n * Sets the given quaternion \"result\" with the given floats.\r\n * @param x defines the x coordinate of the source\r\n * @param y defines the y coordinate of the source\r\n * @param z defines the z coordinate of the source\r\n * @param w defines the w coordinate of the source\r\n * @param result defines the quaternion where to store the result\r\n * @returns the result quaternion\r\n */\r\n public static FromFloatsToRef(x: number, y: number, z: number, w: number, result: T): T {\r\n result.copyFromFloats(x, y, z, w);\r\n return result;\r\n }\r\n\r\n /**\r\n * Create a quaternion from Euler rotation angles\r\n * Example Playground https://playground.babylonjs.com/#L49EJ7#33\r\n * @param x Pitch\r\n * @param y Yaw\r\n * @param z Roll\r\n * @returns the new Quaternion\r\n */\r\n public static FromEulerAngles(x: number, y: number, z: number): Quaternion {\r\n const q = new Quaternion();\r\n Quaternion.RotationYawPitchRollToRef(y, x, z, q);\r\n return q;\r\n }\r\n\r\n /**\r\n * Updates a quaternion from Euler rotation angles\r\n * Example Playground https://playground.babylonjs.com/#L49EJ7#34\r\n * @param x Pitch\r\n * @param y Yaw\r\n * @param z Roll\r\n * @param result the quaternion to store the result\r\n * @returns the updated quaternion\r\n */\r\n public static FromEulerAnglesToRef(x: number, y: number, z: number, result: T): T {\r\n Quaternion.RotationYawPitchRollToRef(y, x, z, result);\r\n return result;\r\n }\r\n\r\n /**\r\n * Create a quaternion from Euler rotation vector\r\n * Example Playground https://playground.babylonjs.com/#L49EJ7#35\r\n * @param vec the Euler vector (x Pitch, y Yaw, z Roll)\r\n * @returns the new Quaternion\r\n */\r\n public static FromEulerVector(vec: DeepImmutable): Quaternion {\r\n const q = new Quaternion();\r\n Quaternion.RotationYawPitchRollToRef(vec._y, vec._x, vec._z, q);\r\n return q;\r\n }\r\n\r\n /**\r\n * Updates a quaternion from Euler rotation vector\r\n * Example Playground https://playground.babylonjs.com/#L49EJ7#36\r\n * @param vec the Euler vector (x Pitch, y Yaw, z Roll)\r\n * @param result the quaternion to store the result\r\n * @returns the updated quaternion\r\n */\r\n public static FromEulerVectorToRef(vec: DeepImmutable, result: T): T {\r\n Quaternion.RotationYawPitchRollToRef(vec._y, vec._x, vec._z, result);\r\n return result;\r\n }\r\n\r\n /**\r\n * Updates a quaternion so that it rotates vector vecFrom to vector vecTo\r\n * Example Playground - https://playground.babylonjs.com/#L49EJ7#70\r\n * @param vecFrom defines the direction vector from which to rotate\r\n * @param vecTo defines the direction vector to which to rotate\r\n * @param result the quaternion to store the result\r\n * @param epsilon defines the minimal dot value to define vecs as opposite. Default: `BABYLON.Epsilon`\r\n * @returns the updated quaternion\r\n */\r\n public static FromUnitVectorsToRef(vecFrom: DeepImmutable, vecTo: DeepImmutable, result: T, epsilon = Epsilon): T {\r\n const r = Vector3.Dot(vecFrom, vecTo) + 1;\r\n\r\n if (r < epsilon) {\r\n if (Math.abs(vecFrom.x) > Math.abs(vecFrom.z)) {\r\n result.set(-vecFrom.y, vecFrom.x, 0, 0);\r\n } else {\r\n result.set(0, -vecFrom.z, vecFrom.y, 0);\r\n }\r\n } else {\r\n Vector3.CrossToRef(vecFrom, vecTo, TmpVectors.Vector3[0]);\r\n result.set(TmpVectors.Vector3[0].x, TmpVectors.Vector3[0].y, TmpVectors.Vector3[0].z, r);\r\n }\r\n\r\n return result.normalize();\r\n }\r\n\r\n /**\r\n * Creates a new quaternion from the given Euler float angles (y, x, z)\r\n * Example Playground https://playground.babylonjs.com/#L49EJ7#77\r\n * @param yaw defines the rotation around Y axis\r\n * @param pitch defines the rotation around X axis\r\n * @param roll defines the rotation around Z axis\r\n * @returns the new quaternion\r\n */\r\n public static RotationYawPitchRoll(yaw: number, pitch: number, roll: number): Quaternion {\r\n const q = new Quaternion();\r\n Quaternion.RotationYawPitchRollToRef(yaw, pitch, roll, q);\r\n return q;\r\n }\r\n\r\n /**\r\n * Creates a new rotation from the given Euler float angles (y, x, z) and stores it in the target quaternion\r\n * Example Playground https://playground.babylonjs.com/#L49EJ7#78\r\n * @param yaw defines the rotation around Y axis\r\n * @param pitch defines the rotation around X axis\r\n * @param roll defines the rotation around Z axis\r\n * @param result defines the target quaternion\r\n * @returns result input\r\n */\r\n public static RotationYawPitchRollToRef(yaw: number, pitch: number, roll: number, result: T): T {\r\n // Produces a quaternion from Euler angles in the z-y-x orientation (Tait-Bryan angles)\r\n const halfRoll = roll * 0.5;\r\n const halfPitch = pitch * 0.5;\r\n const halfYaw = yaw * 0.5;\r\n\r\n const sinRoll = Math.sin(halfRoll);\r\n const cosRoll = Math.cos(halfRoll);\r\n const sinPitch = Math.sin(halfPitch);\r\n const cosPitch = Math.cos(halfPitch);\r\n const sinYaw = Math.sin(halfYaw);\r\n const cosYaw = Math.cos(halfYaw);\r\n\r\n result._x = cosYaw * sinPitch * cosRoll + sinYaw * cosPitch * sinRoll;\r\n result._y = sinYaw * cosPitch * cosRoll - cosYaw * sinPitch * sinRoll;\r\n result._z = cosYaw * cosPitch * sinRoll - sinYaw * sinPitch * cosRoll;\r\n result._w = cosYaw * cosPitch * cosRoll + sinYaw * sinPitch * sinRoll;\r\n result._isDirty = true;\r\n return result;\r\n }\r\n\r\n /**\r\n * Creates a new quaternion from the given Euler float angles expressed in z-x-z orientation\r\n * Example Playground https://playground.babylonjs.com/#L49EJ7#68\r\n * @param alpha defines the rotation around first axis\r\n * @param beta defines the rotation around second axis\r\n * @param gamma defines the rotation around third axis\r\n * @returns the new quaternion\r\n */\r\n public static RotationAlphaBetaGamma(alpha: number, beta: number, gamma: number): Quaternion {\r\n const result = new Quaternion();\r\n Quaternion.RotationAlphaBetaGammaToRef(alpha, beta, gamma, result);\r\n return result;\r\n }\r\n\r\n /**\r\n * Creates a new quaternion from the given Euler float angles expressed in z-x-z orientation and stores it in the target quaternion\r\n * Example Playground https://playground.babylonjs.com/#L49EJ7#69\r\n * @param alpha defines the rotation around first axis\r\n * @param beta defines the rotation around second axis\r\n * @param gamma defines the rotation around third axis\r\n * @param result defines the target quaternion\r\n * @returns result input\r\n */\r\n public static RotationAlphaBetaGammaToRef(alpha: number, beta: number, gamma: number, result: T): T {\r\n // Produces a quaternion from Euler angles in the z-x-z orientation\r\n const halfGammaPlusAlpha = (gamma + alpha) * 0.5;\r\n const halfGammaMinusAlpha = (gamma - alpha) * 0.5;\r\n const halfBeta = beta * 0.5;\r\n\r\n result._x = Math.cos(halfGammaMinusAlpha) * Math.sin(halfBeta);\r\n result._y = Math.sin(halfGammaMinusAlpha) * Math.sin(halfBeta);\r\n result._z = Math.sin(halfGammaPlusAlpha) * Math.cos(halfBeta);\r\n result._w = Math.cos(halfGammaPlusAlpha) * Math.cos(halfBeta);\r\n result._isDirty = true;\r\n return result;\r\n }\r\n\r\n /**\r\n * Creates a new quaternion containing the rotation value to reach the target (axis1, axis2, axis3) orientation as a rotated XYZ system (axis1, axis2 and axis3 are normalized during this operation)\r\n * Example Playground https://playground.babylonjs.com/#L49EJ7#75\r\n * @param axis1 defines the first axis\r\n * @param axis2 defines the second axis\r\n * @param axis3 defines the third axis\r\n * @returns the new quaternion\r\n */\r\n public static RotationQuaternionFromAxis(axis1: DeepImmutable, axis2: DeepImmutable, axis3: DeepImmutable): Quaternion {\r\n const quat = new Quaternion(0.0, 0.0, 0.0, 0.0);\r\n Quaternion.RotationQuaternionFromAxisToRef(axis1, axis2, axis3, quat);\r\n return quat;\r\n }\r\n\r\n /**\r\n * Creates a rotation value to reach the target (axis1, axis2, axis3) orientation as a rotated XYZ system (axis1, axis2 and axis3 are normalized during this operation) and stores it in the target quaternion\r\n * Example Playground https://playground.babylonjs.com/#L49EJ7#76\r\n * @param axis1 defines the first axis\r\n * @param axis2 defines the second axis\r\n * @param axis3 defines the third axis\r\n * @param ref defines the target quaternion\r\n * @returns result input\r\n */\r\n public static RotationQuaternionFromAxisToRef(axis1: DeepImmutable, axis2: DeepImmutable, axis3: DeepImmutable, ref: T): T {\r\n const rotMat = MathTmp.Matrix[0];\r\n axis1 = axis1.normalizeToRef(MathTmp.Vector3[0]);\r\n axis2 = axis2.normalizeToRef(MathTmp.Vector3[1]);\r\n axis3 = axis3.normalizeToRef(MathTmp.Vector3[2]);\r\n Matrix.FromXYZAxesToRef(axis1, axis2, axis3, rotMat);\r\n Quaternion.FromRotationMatrixToRef(rotMat, ref);\r\n return ref;\r\n }\r\n\r\n /**\r\n * Creates a new rotation value to orient an object to look towards the given forward direction, the up direction being oriented like \"up\".\r\n * This function works in left handed mode\r\n * Example Playground https://playground.babylonjs.com/#L49EJ7#96\r\n * @param forward defines the forward direction - Must be normalized and orthogonal to up.\r\n * @param up defines the up vector for the entity - Must be normalized and orthogonal to forward.\r\n * @returns A new quaternion oriented toward the specified forward and up.\r\n */\r\n public static FromLookDirectionLH(forward: DeepImmutable, up: DeepImmutable): Quaternion {\r\n const quat = new Quaternion();\r\n Quaternion.FromLookDirectionLHToRef(forward, up, quat);\r\n return quat;\r\n }\r\n\r\n /**\r\n * Creates a new rotation value to orient an object to look towards the given forward direction with the up direction being oriented like \"up\", and stores it in the target quaternion.\r\n * This function works in left handed mode\r\n * Example Playground https://playground.babylonjs.com/#L49EJ7#97\r\n * @param forward defines the forward direction - Must be normalized and orthogonal to up.\r\n * @param up defines the up vector for the entity - Must be normalized and orthogonal to forward.\r\n * @param ref defines the target quaternion.\r\n * @returns result input\r\n */\r\n public static FromLookDirectionLHToRef(forward: DeepImmutable, up: DeepImmutable, ref: T): T {\r\n const rotMat = MathTmp.Matrix[0];\r\n Matrix.LookDirectionLHToRef(forward, up, rotMat);\r\n Quaternion.FromRotationMatrixToRef(rotMat, ref);\r\n return ref;\r\n }\r\n\r\n /**\r\n * Creates a new rotation value to orient an object to look towards the given forward direction, the up direction being oriented like \"up\".\r\n * This function works in right handed mode\r\n * Example Playground https://playground.babylonjs.com/#L49EJ7#98\r\n * @param forward defines the forward direction - Must be normalized and orthogonal to up.\r\n * @param up defines the up vector for the entity - Must be normalized and orthogonal to forward.\r\n * @returns A new quaternion oriented toward the specified forward and up.\r\n */\r\n public static FromLookDirectionRH(forward: DeepImmutable, up: DeepImmutable): Quaternion {\r\n const quat = new Quaternion();\r\n Quaternion.FromLookDirectionRHToRef(forward, up, quat);\r\n return quat;\r\n }\r\n\r\n /**\r\n * Creates a new rotation value to orient an object to look towards the given forward direction with the up direction being oriented like \"up\", and stores it in the target quaternion.\r\n * This function works in right handed mode\r\n * Example Playground https://playground.babylonjs.com/#L49EJ7#105\r\n * @param forward defines the forward direction - Must be normalized and orthogonal to up.\r\n * @param up defines the up vector for the entity - Must be normalized and orthogonal to forward.\r\n * @param ref defines the target quaternion.\r\n * @returns result input\r\n */\r\n public static FromLookDirectionRHToRef(forward: DeepImmutable, up: DeepImmutable, ref: T): T {\r\n const rotMat = MathTmp.Matrix[0];\r\n Matrix.LookDirectionRHToRef(forward, up, rotMat);\r\n return Quaternion.FromRotationMatrixToRef(rotMat, ref);\r\n }\r\n\r\n /**\r\n * Interpolates between two quaternions\r\n * Example Playground https://playground.babylonjs.com/#L49EJ7#79\r\n * @param left defines first quaternion\r\n * @param right defines second quaternion\r\n * @param amount defines the gradient to use\r\n * @returns the new interpolated quaternion\r\n */\r\n public static Slerp(left: DeepImmutable, right: DeepImmutable, amount: number): Quaternion {\r\n const result = Quaternion.Identity();\r\n\r\n Quaternion.SlerpToRef(left, right, amount, result);\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Interpolates between two quaternions and stores it into a target quaternion\r\n * Example Playground https://playground.babylonjs.com/#L49EJ7#92\r\n * @param left defines first quaternion\r\n * @param right defines second quaternion\r\n * @param amount defines the gradient to use\r\n * @param result defines the target quaternion\r\n * @returns result input\r\n */\r\n public static SlerpToRef(left: DeepImmutable, right: DeepImmutable, amount: number, result: T): T {\r\n let num2;\r\n let num3;\r\n let num4 = left._x * right._x + left._y * right._y + left._z * right._z + left._w * right._w;\r\n let flag = false;\r\n\r\n if (num4 < 0) {\r\n flag = true;\r\n num4 = -num4;\r\n }\r\n\r\n if (num4 > 0.999999) {\r\n num3 = 1 - amount;\r\n num2 = flag ? -amount : amount;\r\n } else {\r\n const num5 = Math.acos(num4);\r\n const num6 = 1.0 / Math.sin(num5);\r\n num3 = Math.sin((1.0 - amount) * num5) * num6;\r\n num2 = flag ? -Math.sin(amount * num5) * num6 : Math.sin(amount * num5) * num6;\r\n }\r\n\r\n result._x = num3 * left._x + num2 * right._x;\r\n result._y = num3 * left._y + num2 * right._y;\r\n result._z = num3 * left._z + num2 * right._z;\r\n result._w = num3 * left._w + num2 * right._w;\r\n result._isDirty = true;\r\n return result;\r\n }\r\n\r\n /**\r\n * Interpolate between two quaternions using Hermite interpolation\r\n * Example Playground https://playground.babylonjs.com/#L49EJ7#47\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/drawCurves#hermite-quaternion-spline\r\n * @param value1 defines first quaternion\r\n * @param tangent1 defines the incoming tangent\r\n * @param value2 defines second quaternion\r\n * @param tangent2 defines the outgoing tangent\r\n * @param amount defines the target quaternion\r\n * @returns the new interpolated quaternion\r\n */\r\n public static Hermite(\r\n value1: DeepImmutable,\r\n tangent1: DeepImmutable,\r\n value2: DeepImmutable,\r\n tangent2: DeepImmutable,\r\n amount: number\r\n ): Quaternion {\r\n const squared = amount * amount;\r\n const cubed = amount * squared;\r\n const part1 = 2.0 * cubed - 3.0 * squared + 1.0;\r\n const part2 = -2.0 * cubed + 3.0 * squared;\r\n const part3 = cubed - 2.0 * squared + amount;\r\n const part4 = cubed - squared;\r\n\r\n const x = value1._x * part1 + value2._x * part2 + tangent1._x * part3 + tangent2._x * part4;\r\n const y = value1._y * part1 + value2._y * part2 + tangent1._y * part3 + tangent2._y * part4;\r\n const z = value1._z * part1 + value2._z * part2 + tangent1._z * part3 + tangent2._z * part4;\r\n const w = value1._w * part1 + value2._w * part2 + tangent1._w * part3 + tangent2._w * part4;\r\n return new Quaternion(x, y, z, w);\r\n }\r\n\r\n /**\r\n * Returns a new Quaternion which is the 1st derivative of the Hermite spline defined by the quaternions \"value1\", \"value2\", \"tangent1\", \"tangent2\".\r\n * Example Playground https://playground.babylonjs.com/#L49EJ7#48\r\n * @param value1 defines the first control point\r\n * @param tangent1 defines the first tangent\r\n * @param value2 defines the second control point\r\n * @param tangent2 defines the second tangent\r\n * @param time define where the derivative must be done\r\n * @returns 1st derivative\r\n */\r\n public static Hermite1stDerivative(\r\n value1: DeepImmutable,\r\n tangent1: DeepImmutable,\r\n value2: DeepImmutable,\r\n tangent2: DeepImmutable,\r\n time: number\r\n ): Quaternion {\r\n const result = new Quaternion();\r\n\r\n this.Hermite1stDerivativeToRef(value1, tangent1, value2, tangent2, time, result);\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Update a Quaternion with the 1st derivative of the Hermite spline defined by the quaternions \"value1\", \"value2\", \"tangent1\", \"tangent2\".\r\n * Example Playground https://playground.babylonjs.com/#L49EJ7#49\r\n * @param value1 defines the first control point\r\n * @param tangent1 defines the first tangent\r\n * @param value2 defines the second control point\r\n * @param tangent2 defines the second tangent\r\n * @param time define where the derivative must be done\r\n * @param result define where to store the derivative\r\n * @returns result input\r\n */\r\n public static Hermite1stDerivativeToRef(\r\n value1: DeepImmutable,\r\n tangent1: DeepImmutable,\r\n value2: DeepImmutable,\r\n tangent2: DeepImmutable,\r\n time: number,\r\n result: T\r\n ): T {\r\n const t2 = time * time;\r\n\r\n result._x = (t2 - time) * 6 * value1._x + (3 * t2 - 4 * time + 1) * tangent1._x + (-t2 + time) * 6 * value2._x + (3 * t2 - 2 * time) * tangent2._x;\r\n result._y = (t2 - time) * 6 * value1._y + (3 * t2 - 4 * time + 1) * tangent1._y + (-t2 + time) * 6 * value2._y + (3 * t2 - 2 * time) * tangent2._y;\r\n result._z = (t2 - time) * 6 * value1._z + (3 * t2 - 4 * time + 1) * tangent1._z + (-t2 + time) * 6 * value2._z + (3 * t2 - 2 * time) * tangent2._z;\r\n result._w = (t2 - time) * 6 * value1._w + (3 * t2 - 4 * time + 1) * tangent1._w + (-t2 + time) * 6 * value2._w + (3 * t2 - 2 * time) * tangent2._w;\r\n result._isDirty = true;\r\n return result;\r\n }\r\n\r\n /**\r\n * Returns a new Quaternion as the normalization of the given Quaternion\r\n * @param quat defines the Quaternion to normalize\r\n * @returns the new Quaternion\r\n */\r\n public static Normalize(quat: DeepImmutable): Quaternion {\r\n const result = Quaternion.Zero();\r\n Quaternion.NormalizeToRef(quat, result);\r\n return result;\r\n }\r\n\r\n /**\r\n * Sets the given Quaternion \"result\" with the normalization of the given first Quaternion\r\n * @param quat defines the Quaternion to normalize\r\n * @param result defines the Quaternion where to store the result\r\n * @returns result input\r\n */\r\n public static NormalizeToRef(quat: DeepImmutable, result: T): T {\r\n quat.normalizeToRef(result);\r\n return result;\r\n }\r\n\r\n /**\r\n * Returns a new Quaternion set with the coordinates of \"value\", if the quaternion \"value\" is in the cube defined by the quaternions \"min\" and \"max\"\r\n * If a coordinate value of \"value\" is lower than one of the \"min\" coordinate, then this \"value\" coordinate is set with the \"min\" one\r\n * If a coordinate value of \"value\" is greater than one of the \"max\" coordinate, then this \"value\" coordinate is set with the \"max\" one\r\n * @param value defines the current value\r\n * @param min defines the lower range value\r\n * @param max defines the upper range value\r\n * @returns the new Quaternion\r\n */\r\n public static Clamp(value: DeepImmutable, min: DeepImmutable, max: DeepImmutable): Quaternion {\r\n const result = new Quaternion();\r\n Quaternion.ClampToRef(value, min, max, result);\r\n return result;\r\n }\r\n\r\n /**\r\n * Sets the given quaternion \"result\" with the coordinates of \"value\", if the quaternion \"value\" is in the cube defined by the quaternions \"min\" and \"max\"\r\n * If a coordinate value of \"value\" is lower than one of the \"min\" coordinate, then this \"value\" coordinate is set with the \"min\" one\r\n * If a coordinate value of \"value\" is greater than one of the \"max\" coordinate, then this \"value\" coordinate is set with the \"max\" one\r\n * @param value defines the current value\r\n * @param min defines the lower range value\r\n * @param max defines the upper range value\r\n * @param result defines the Quaternion where to store the result\r\n * @returns result input\r\n */\r\n public static ClampToRef(value: DeepImmutable, min: DeepImmutable, max: DeepImmutable, result: T): T {\r\n return result.copyFromFloats(Clamp(value.x, min.x, max.x), Clamp(value.y, min.y, max.y), Clamp(value.z, min.z, max.z), Clamp(value.w, min.w, max.w));\r\n }\r\n\r\n /**\r\n * Returns a new Quaternion with random values between min and max\r\n * @param min the minimum random value\r\n * @param max the maximum random value\r\n * @returns a Quaternion with random values between min and max\r\n */\r\n public static Random(min: number = 0, max: number = 1): Quaternion {\r\n return new Quaternion(RandomRange(min, max), RandomRange(min, max), RandomRange(min, max), RandomRange(min, max));\r\n }\r\n\r\n /**\r\n * Sets a Quaternion with random values between min and max\r\n * @param min the minimum random value\r\n * @param max the maximum random value\r\n * @param ref the ref to store the values in\r\n * @returns the ref with random values between min and max\r\n */\r\n public static RandomToRef(min: number = 0, max: number = 1, ref: T): T {\r\n return ref.copyFromFloats(RandomRange(min, max), RandomRange(min, max), RandomRange(min, max), RandomRange(min, max));\r\n }\r\n\r\n /**\r\n * Do not use\r\n * @internal\r\n */\r\n public static Minimize(): Quaternion {\r\n throw new ReferenceError(\"Quaternion.Minimize does not make sense\");\r\n }\r\n\r\n /**\r\n * Do not use\r\n * @internal\r\n */\r\n public static Maximize(): Quaternion {\r\n throw new ReferenceError(\"Quaternion.Maximize does not make sense\");\r\n }\r\n\r\n /**\r\n * Returns the distance (float) between the quaternions \"value1\" and \"value2\".\r\n * @param value1 value to calulate the distance between\r\n * @param value2 value to calulate the distance between\r\n * @returns the distance between the two quaternions\r\n */\r\n public static Distance(value1: DeepImmutable, value2: DeepImmutable): number {\r\n return Math.sqrt(Quaternion.DistanceSquared(value1, value2));\r\n }\r\n /**\r\n * Returns the squared distance (float) between the quaternions \"value1\" and \"value2\".\r\n * @param value1 value to calulate the distance between\r\n * @param value2 value to calulate the distance between\r\n * @returns the distance between the two quaternions squared\r\n */\r\n public static DistanceSquared(value1: DeepImmutable, value2: DeepImmutable): number {\r\n const x = value1.x - value2.x;\r\n const y = value1.y - value2.y;\r\n const z = value1.z - value2.z;\r\n const w = value1.w - value2.w;\r\n\r\n return x * x + y * y + z * z + w * w;\r\n }\r\n\r\n /**\r\n * Returns a new Quaternion located at the center between the quaternions \"value1\" and \"value2\".\r\n * @param value1 value to calulate the center between\r\n * @param value2 value to calulate the center between\r\n * @returns the center between the two quaternions\r\n */\r\n public static Center(value1: DeepImmutable, value2: DeepImmutable): Quaternion {\r\n return Quaternion.CenterToRef(value1, value2, Quaternion.Zero());\r\n }\r\n\r\n /**\r\n * Gets the center of the quaternions \"value1\" and \"value2\" and stores the result in the quaternion \"ref\"\r\n * @param value1 defines first quaternion\r\n * @param value2 defines second quaternion\r\n * @param ref defines third quaternion\r\n * @returns ref\r\n */\r\n public static CenterToRef(value1: DeepImmutable, value2: DeepImmutable, ref: T): T {\r\n return ref.copyFromFloats((value1.x + value2.x) / 2, (value1.y + value2.y) / 2, (value1.z + value2.z) / 2, (value1.w + value2.w) / 2);\r\n }\r\n}\r\nQuaternion satisfies TensorStatic;\r\nObject.defineProperties(Quaternion.prototype, {\r\n dimension: { value: [4] },\r\n rank: { value: 1 },\r\n});\r\n\r\n/**\r\n * Class used to store matrix data (4x4)\r\n * Note on matrix definitions in Babylon.js for setting values directly\r\n * rather than using one of the methods available.\r\n * Matrix size is given by rows x columns.\r\n * A Vector3 is a 1 X 3 matrix [x, y, z].\r\n *\r\n * In Babylon.js multiplying a 1 x 3 matrix by a 4 x 4 matrix\r\n * is done using BABYLON.Vector4.TransformCoordinates(Vector3, Matrix).\r\n * and extending the passed Vector3 to a Vector4, V = [x, y, z, 1].\r\n * Let M be a matrix with elements m(row, column), so that\r\n * m(2, 3) is the element in row 2 column 3 of M.\r\n *\r\n * Multiplication is of the form VM and has the resulting Vector4\r\n * VM = [xm(0, 0) + ym(1, 0) + zm(2, 0) + m(3, 0), xm(0, 1) + ym(1, 1) + zm(2, 1) + m(3, 1), xm(0, 2) + ym(1, 2) + zm(2, 2) + m(3, 2), xm(0, 3) + ym(1, 3) + zm(2, 3) + m(3, 3)].\r\n * On the web you will find many examples that use the opposite convention of MV,\r\n * in which case to make use of the examples you will need to transpose the matrix.\r\n *\r\n * Example Playground - Overview Linear Algebra - https://playground.babylonjs.com/#AV9X17\r\n * Example Playground - Overview Transformation - https://playground.babylonjs.com/#AV9X17#1\r\n * Example Playground - Overview Projection - https://playground.babylonjs.com/#AV9X17#2\r\n */\r\nexport class Matrix implements Tensor, 4>, Matrix>, IMatrixLike {\r\n /**\r\n * @see Tensor.dimension\r\n */\r\n declare public readonly dimension: Readonly<[4, 4]>;\r\n\r\n /**\r\n * @see Tensor.rank\r\n */\r\n declare public readonly rank: 2;\r\n\r\n /**\r\n * Gets the precision of matrix computations\r\n */\r\n public static get Use64Bits(): boolean {\r\n return PerformanceConfigurator.MatrixUse64Bits;\r\n }\r\n\r\n private static _UpdateFlagSeed = 0;\r\n private static _IdentityReadOnly = Matrix.Identity() as DeepImmutable;\r\n\r\n private _isIdentity = false;\r\n private _isIdentityDirty = true;\r\n private _isIdentity3x2 = true;\r\n private _isIdentity3x2Dirty = true;\r\n /**\r\n * Gets the update flag of the matrix which is an unique number for the matrix.\r\n * It will be incremented every time the matrix data change.\r\n * You can use it to speed the comparison between two versions of the same matrix.\r\n */\r\n public updateFlag: number = -1;\r\n\r\n private readonly _m: Tuple;\r\n\r\n /**\r\n * Gets the internal data of the matrix\r\n */\r\n public get m(): DeepImmutable> {\r\n return this._m;\r\n }\r\n\r\n /**\r\n * Update the updateFlag to indicate that the matrix has been updated\r\n */\r\n public markAsUpdated() {\r\n this.updateFlag = Matrix._UpdateFlagSeed++;\r\n this._isIdentity = false;\r\n this._isIdentity3x2 = false;\r\n this._isIdentityDirty = true;\r\n this._isIdentity3x2Dirty = true;\r\n }\r\n\r\n private _updateIdentityStatus(isIdentity: boolean, isIdentityDirty: boolean = false, isIdentity3x2: boolean = false, isIdentity3x2Dirty: boolean = true) {\r\n this._isIdentity = isIdentity;\r\n this._isIdentity3x2 = isIdentity || isIdentity3x2;\r\n this._isIdentityDirty = this._isIdentity ? false : isIdentityDirty;\r\n this._isIdentity3x2Dirty = this._isIdentity3x2 ? false : isIdentity3x2Dirty;\r\n }\r\n\r\n /**\r\n * Creates an empty matrix (filled with zeros)\r\n */\r\n public constructor() {\r\n if (PerformanceConfigurator.MatrixTrackPrecisionChange) {\r\n PerformanceConfigurator.MatrixTrackedMatrices!.push(this);\r\n }\r\n\r\n this._m = new PerformanceConfigurator.MatrixCurrentType(16);\r\n\r\n this.markAsUpdated();\r\n }\r\n\r\n // Properties\r\n\r\n /**\r\n * Check if the current matrix is identity\r\n * @returns true is the matrix is the identity matrix\r\n */\r\n public isIdentity(): boolean {\r\n if (this._isIdentityDirty) {\r\n this._isIdentityDirty = false;\r\n const m = this._m;\r\n this._isIdentity =\r\n m[0] === 1.0 &&\r\n m[1] === 0.0 &&\r\n m[2] === 0.0 &&\r\n m[3] === 0.0 &&\r\n m[4] === 0.0 &&\r\n m[5] === 1.0 &&\r\n m[6] === 0.0 &&\r\n m[7] === 0.0 &&\r\n m[8] === 0.0 &&\r\n m[9] === 0.0 &&\r\n m[10] === 1.0 &&\r\n m[11] === 0.0 &&\r\n m[12] === 0.0 &&\r\n m[13] === 0.0 &&\r\n m[14] === 0.0 &&\r\n m[15] === 1.0;\r\n }\r\n\r\n return this._isIdentity;\r\n }\r\n\r\n /**\r\n * Check if the current matrix is identity as a texture matrix (3x2 store in 4x4)\r\n * @returns true is the matrix is the identity matrix\r\n */\r\n public isIdentityAs3x2(): boolean {\r\n if (this._isIdentity3x2Dirty) {\r\n this._isIdentity3x2Dirty = false;\r\n if (this._m[0] !== 1.0 || this._m[5] !== 1.0 || this._m[15] !== 1.0) {\r\n this._isIdentity3x2 = false;\r\n } else if (\r\n this._m[1] !== 0.0 ||\r\n this._m[2] !== 0.0 ||\r\n this._m[3] !== 0.0 ||\r\n this._m[4] !== 0.0 ||\r\n this._m[6] !== 0.0 ||\r\n this._m[7] !== 0.0 ||\r\n this._m[8] !== 0.0 ||\r\n this._m[9] !== 0.0 ||\r\n this._m[10] !== 0.0 ||\r\n this._m[11] !== 0.0 ||\r\n this._m[12] !== 0.0 ||\r\n this._m[13] !== 0.0 ||\r\n this._m[14] !== 0.0\r\n ) {\r\n this._isIdentity3x2 = false;\r\n } else {\r\n this._isIdentity3x2 = true;\r\n }\r\n }\r\n\r\n return this._isIdentity3x2;\r\n }\r\n\r\n /**\r\n * Gets the determinant of the matrix\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#34\r\n * @returns the matrix determinant\r\n */\r\n public determinant(): number {\r\n if (this._isIdentity === true) {\r\n return 1;\r\n }\r\n\r\n const m = this._m;\r\n const m00 = m[0],\r\n m01 = m[1],\r\n m02 = m[2],\r\n m03 = m[3];\r\n const m10 = m[4],\r\n m11 = m[5],\r\n m12 = m[6],\r\n m13 = m[7];\r\n const m20 = m[8],\r\n m21 = m[9],\r\n m22 = m[10],\r\n m23 = m[11];\r\n const m30 = m[12],\r\n m31 = m[13],\r\n m32 = m[14],\r\n m33 = m[15];\r\n // https://en.wikipedia.org/wiki/Laplace_expansion\r\n // to compute the deterrminant of a 4x4 Matrix we compute the cofactors of any row or column,\r\n // then we multiply each Cofactor by its corresponding matrix value and sum them all to get the determinant\r\n // Cofactor(i, j) = sign(i,j) * det(Minor(i, j))\r\n // where\r\n // - sign(i,j) = (i+j) % 2 === 0 ? 1 : -1\r\n // - Minor(i, j) is the 3x3 matrix we get by removing row i and column j from current Matrix\r\n //\r\n // Here we do that for the 1st row.\r\n\r\n const det_22_33 = m22 * m33 - m32 * m23;\r\n const det_21_33 = m21 * m33 - m31 * m23;\r\n const det_21_32 = m21 * m32 - m31 * m22;\r\n const det_20_33 = m20 * m33 - m30 * m23;\r\n const det_20_32 = m20 * m32 - m22 * m30;\r\n const det_20_31 = m20 * m31 - m30 * m21;\r\n const cofact_00 = +(m11 * det_22_33 - m12 * det_21_33 + m13 * det_21_32);\r\n const cofact_01 = -(m10 * det_22_33 - m12 * det_20_33 + m13 * det_20_32);\r\n const cofact_02 = +(m10 * det_21_33 - m11 * det_20_33 + m13 * det_20_31);\r\n const cofact_03 = -(m10 * det_21_32 - m11 * det_20_32 + m12 * det_20_31);\r\n return m00 * cofact_00 + m01 * cofact_01 + m02 * cofact_02 + m03 * cofact_03;\r\n }\r\n\r\n // Methods\r\n\r\n /**\r\n * Gets a string with the Matrix values\r\n * @returns a string with the Matrix values\r\n */\r\n public toString(): string {\r\n return `{${this.m[0]}, ${this.m[1]}, ${this.m[2]}, ${this.m[3]}\\n${this.m[4]}, ${this.m[5]}, ${this.m[6]}, ${this.m[7]}\\n${this.m[8]}, ${this.m[9]}, ${this.m[10]}, ${this.m[11]}\\n${this.m[12]}, ${this.m[13]}, ${this.m[14]}, ${this.m[15]}}`;\r\n }\r\n\r\n /**\r\n * Returns the matrix as a Float32Array or Array\r\n * @deprecated Use asArray\r\n */\r\n public toArray(): FloatArray;\r\n\r\n /**\r\n * Stores the matrix in a Float32Array or Array\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#49\r\n * @param array The destination array\r\n * @param index The destination index to start ay\r\n * @returns the matrix\r\n */\r\n public toArray(array: FloatArray, index: number): this;\r\n public toArray(array: Nullable = null, index: number = 0): this | FloatArray {\r\n if (!array) {\r\n return this._m;\r\n }\r\n const m = this._m;\r\n for (let i = 0; i < 16; i++) {\r\n array[index + i] = m[i];\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Returns the matrix as a Float32Array or Array\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#114\r\n * @returns the matrix underlying array.\r\n */\r\n public asArray(): Tuple {\r\n return this._m;\r\n }\r\n\r\n public fromArray(array: FloatArray, index: number = 0): this {\r\n return Matrix.FromArrayToRef(array, index, this);\r\n }\r\n\r\n public copyFromFloats(...floats: Tuple): this {\r\n return Matrix.FromArrayToRef(floats, 0, this);\r\n }\r\n\r\n public set(...values: Tuple): this {\r\n const m = this._m;\r\n for (let i = 0; i < 16; i++) {\r\n m[i] = values[i];\r\n }\r\n this.markAsUpdated();\r\n return this;\r\n }\r\n\r\n public setAll(value: number): this {\r\n const m = this._m;\r\n for (let i = 0; i < 16; i++) {\r\n m[i] = value;\r\n }\r\n this.markAsUpdated();\r\n return this;\r\n }\r\n\r\n /**\r\n * Inverts the current matrix in place\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#118\r\n * @returns the current inverted matrix\r\n */\r\n public invert(): this {\r\n this.invertToRef(this);\r\n return this;\r\n }\r\n /**\r\n * Sets all the matrix elements to zero\r\n * @returns the current matrix\r\n */\r\n public reset(): this {\r\n Matrix.FromValuesToRef(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, this);\r\n this._updateIdentityStatus(false);\r\n return this;\r\n }\r\n\r\n /**\r\n * Adds the current matrix with a second one\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#44\r\n * @param other defines the matrix to add\r\n * @returns a new matrix as the addition of the current matrix and the given one\r\n */\r\n public add(other: DeepImmutable): Matrix {\r\n const result = new Matrix();\r\n this.addToRef(other, result);\r\n return result;\r\n }\r\n\r\n /**\r\n * Sets the given matrix \"result\" to the addition of the current matrix and the given one\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#45\r\n * @param other defines the matrix to add\r\n * @param result defines the target matrix\r\n * @returns result input\r\n */\r\n public addToRef(other: DeepImmutable, result: T): T {\r\n const m = this._m;\r\n const resultM = result._m;\r\n const otherM = other.m;\r\n for (let index = 0; index < 16; index++) {\r\n resultM[index] = m[index] + otherM[index];\r\n }\r\n result.markAsUpdated();\r\n return result;\r\n }\r\n\r\n /**\r\n * Adds in place the given matrix to the current matrix\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#46\r\n * @param other defines the second operand\r\n * @returns the current updated matrix\r\n */\r\n public addToSelf(other: DeepImmutable): this {\r\n const m = this._m;\r\n const otherM = other.m;\r\n m[0] += otherM[0];\r\n m[1] += otherM[1];\r\n m[2] += otherM[2];\r\n m[3] += otherM[3];\r\n m[4] += otherM[4];\r\n m[5] += otherM[5];\r\n m[6] += otherM[6];\r\n m[7] += otherM[7];\r\n m[8] += otherM[8];\r\n m[9] += otherM[9];\r\n m[10] += otherM[10];\r\n m[11] += otherM[11];\r\n m[12] += otherM[12];\r\n m[13] += otherM[13];\r\n m[14] += otherM[14];\r\n m[15] += otherM[15];\r\n this.markAsUpdated();\r\n return this;\r\n }\r\n\r\n public addInPlace(other: DeepImmutable): this {\r\n const m = this._m,\r\n otherM = other.m;\r\n for (let i = 0; i < 16; i++) {\r\n m[i] += otherM[i];\r\n }\r\n this.markAsUpdated();\r\n return this;\r\n }\r\n\r\n public addInPlaceFromFloats(...floats: Tuple): this {\r\n const m = this._m;\r\n for (let i = 0; i < 16; i++) {\r\n m[i] += floats[i];\r\n }\r\n this.markAsUpdated();\r\n return this;\r\n }\r\n\r\n public subtract(other: DeepImmutable): this {\r\n const m = this._m,\r\n otherM = other.m;\r\n for (let i = 0; i < 16; i++) {\r\n m[i] -= otherM[i];\r\n }\r\n this.markAsUpdated();\r\n return this;\r\n }\r\n public subtractToRef(other: DeepImmutable, result: T): T {\r\n const m = this._m,\r\n otherM = other.m,\r\n resultM = result._m;\r\n for (let i = 0; i < 16; i++) {\r\n resultM[i] = m[i] - otherM[i];\r\n }\r\n result.markAsUpdated();\r\n return result;\r\n }\r\n public subtractInPlace(other: DeepImmutable): this {\r\n const m = this._m,\r\n otherM = other.m;\r\n for (let i = 0; i < 16; i++) {\r\n m[i] -= otherM[i];\r\n }\r\n this.markAsUpdated();\r\n return this;\r\n }\r\n\r\n public subtractFromFloats(...floats: Tuple): Matrix {\r\n return this.subtractFromFloatsToRef(...floats, new Matrix());\r\n }\r\n\r\n public subtractFromFloatsToRef(...args: [...Tuple, T]): T {\r\n const result = args.pop() as T,\r\n m = this._m,\r\n resultM = result._m,\r\n values = args as unknown as Tuple;\r\n for (let i = 0; i < 16; i++) {\r\n resultM[i] = m[i] - values[i];\r\n }\r\n result.markAsUpdated();\r\n return result;\r\n }\r\n\r\n /**\r\n * Sets the given matrix to the current inverted Matrix\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#119\r\n * @param other defines the target matrix\r\n * @returns result input\r\n */\r\n public invertToRef(other: T): T {\r\n if (this._isIdentity === true) {\r\n Matrix.IdentityToRef(other);\r\n return other;\r\n }\r\n\r\n // the inverse of a Matrix is the transpose of cofactor matrix divided by the determinant\r\n const m = this._m;\r\n const m00 = m[0],\r\n m01 = m[1],\r\n m02 = m[2],\r\n m03 = m[3];\r\n const m10 = m[4],\r\n m11 = m[5],\r\n m12 = m[6],\r\n m13 = m[7];\r\n const m20 = m[8],\r\n m21 = m[9],\r\n m22 = m[10],\r\n m23 = m[11];\r\n const m30 = m[12],\r\n m31 = m[13],\r\n m32 = m[14],\r\n m33 = m[15];\r\n\r\n const det_22_33 = m22 * m33 - m32 * m23;\r\n const det_21_33 = m21 * m33 - m31 * m23;\r\n const det_21_32 = m21 * m32 - m31 * m22;\r\n const det_20_33 = m20 * m33 - m30 * m23;\r\n const det_20_32 = m20 * m32 - m22 * m30;\r\n const det_20_31 = m20 * m31 - m30 * m21;\r\n\r\n const cofact_00 = +(m11 * det_22_33 - m12 * det_21_33 + m13 * det_21_32);\r\n const cofact_01 = -(m10 * det_22_33 - m12 * det_20_33 + m13 * det_20_32);\r\n const cofact_02 = +(m10 * det_21_33 - m11 * det_20_33 + m13 * det_20_31);\r\n const cofact_03 = -(m10 * det_21_32 - m11 * det_20_32 + m12 * det_20_31);\r\n\r\n const det = m00 * cofact_00 + m01 * cofact_01 + m02 * cofact_02 + m03 * cofact_03;\r\n\r\n if (det === 0) {\r\n // not invertible\r\n other.copyFrom(this);\r\n return other;\r\n }\r\n\r\n const detInv = 1 / det;\r\n const det_12_33 = m12 * m33 - m32 * m13;\r\n const det_11_33 = m11 * m33 - m31 * m13;\r\n const det_11_32 = m11 * m32 - m31 * m12;\r\n const det_10_33 = m10 * m33 - m30 * m13;\r\n const det_10_32 = m10 * m32 - m30 * m12;\r\n const det_10_31 = m10 * m31 - m30 * m11;\r\n const det_12_23 = m12 * m23 - m22 * m13;\r\n const det_11_23 = m11 * m23 - m21 * m13;\r\n const det_11_22 = m11 * m22 - m21 * m12;\r\n const det_10_23 = m10 * m23 - m20 * m13;\r\n const det_10_22 = m10 * m22 - m20 * m12;\r\n const det_10_21 = m10 * m21 - m20 * m11;\r\n\r\n const cofact_10 = -(m01 * det_22_33 - m02 * det_21_33 + m03 * det_21_32);\r\n const cofact_11 = +(m00 * det_22_33 - m02 * det_20_33 + m03 * det_20_32);\r\n const cofact_12 = -(m00 * det_21_33 - m01 * det_20_33 + m03 * det_20_31);\r\n const cofact_13 = +(m00 * det_21_32 - m01 * det_20_32 + m02 * det_20_31);\r\n\r\n const cofact_20 = +(m01 * det_12_33 - m02 * det_11_33 + m03 * det_11_32);\r\n const cofact_21 = -(m00 * det_12_33 - m02 * det_10_33 + m03 * det_10_32);\r\n const cofact_22 = +(m00 * det_11_33 - m01 * det_10_33 + m03 * det_10_31);\r\n const cofact_23 = -(m00 * det_11_32 - m01 * det_10_32 + m02 * det_10_31);\r\n\r\n const cofact_30 = -(m01 * det_12_23 - m02 * det_11_23 + m03 * det_11_22);\r\n const cofact_31 = +(m00 * det_12_23 - m02 * det_10_23 + m03 * det_10_22);\r\n const cofact_32 = -(m00 * det_11_23 - m01 * det_10_23 + m03 * det_10_21);\r\n const cofact_33 = +(m00 * det_11_22 - m01 * det_10_22 + m02 * det_10_21);\r\n\r\n Matrix.FromValuesToRef(\r\n cofact_00 * detInv,\r\n cofact_10 * detInv,\r\n cofact_20 * detInv,\r\n cofact_30 * detInv,\r\n cofact_01 * detInv,\r\n cofact_11 * detInv,\r\n cofact_21 * detInv,\r\n cofact_31 * detInv,\r\n cofact_02 * detInv,\r\n cofact_12 * detInv,\r\n cofact_22 * detInv,\r\n cofact_32 * detInv,\r\n cofact_03 * detInv,\r\n cofact_13 * detInv,\r\n cofact_23 * detInv,\r\n cofact_33 * detInv,\r\n other\r\n );\r\n\r\n return other;\r\n }\r\n\r\n /**\r\n * add a value at the specified position in the current Matrix\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#47\r\n * @param index the index of the value within the matrix. between 0 and 15.\r\n * @param value the value to be added\r\n * @returns the current updated matrix\r\n */\r\n public addAtIndex(index: number, value: number): this {\r\n this._m[index] += value;\r\n this.markAsUpdated();\r\n return this;\r\n }\r\n\r\n /**\r\n * mutiply the specified position in the current Matrix by a value\r\n * @param index the index of the value within the matrix. between 0 and 15.\r\n * @param value the value to be added\r\n * @returns the current updated matrix\r\n */\r\n public multiplyAtIndex(index: number, value: number): this {\r\n this._m[index] *= value;\r\n this.markAsUpdated();\r\n return this;\r\n }\r\n\r\n /**\r\n * Inserts the translation vector (using 3 floats) in the current matrix\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#120\r\n * @param x defines the 1st component of the translation\r\n * @param y defines the 2nd component of the translation\r\n * @param z defines the 3rd component of the translation\r\n * @returns the current updated matrix\r\n */\r\n public setTranslationFromFloats(x: number, y: number, z: number): this {\r\n this._m[12] = x;\r\n this._m[13] = y;\r\n this._m[14] = z;\r\n this.markAsUpdated();\r\n return this;\r\n }\r\n\r\n /**\r\n * Adds the translation vector (using 3 floats) in the current matrix\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#20\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#48\r\n * @param x defines the 1st component of the translation\r\n * @param y defines the 2nd component of the translation\r\n * @param z defines the 3rd component of the translation\r\n * @returns the current updated matrix\r\n */\r\n public addTranslationFromFloats(x: number, y: number, z: number): this {\r\n this._m[12] += x;\r\n this._m[13] += y;\r\n this._m[14] += z;\r\n this.markAsUpdated();\r\n return this;\r\n }\r\n\r\n /**\r\n * Inserts the translation vector in the current matrix\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#121\r\n * @param vector3 defines the translation to insert\r\n * @returns the current updated matrix\r\n */\r\n public setTranslation(vector3: DeepImmutable): this {\r\n return this.setTranslationFromFloats(vector3._x, vector3._y, vector3._z);\r\n }\r\n\r\n /**\r\n * Gets the translation value of the current matrix\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#122\r\n * @returns a new Vector3 as the extracted translation from the matrix\r\n */\r\n public getTranslation(): Vector3 {\r\n return new Vector3(this._m[12], this._m[13], this._m[14]);\r\n }\r\n\r\n /**\r\n * Fill a Vector3 with the extracted translation from the matrix\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#123\r\n * @param result defines the Vector3 where to store the translation\r\n * @returns the current matrix\r\n */\r\n public getTranslationToRef(result: T): T {\r\n result.x = this._m[12];\r\n result.y = this._m[13];\r\n result.z = this._m[14];\r\n return result;\r\n }\r\n\r\n /**\r\n * Remove rotation and scaling part from the matrix\r\n * @returns the updated matrix\r\n */\r\n public removeRotationAndScaling(): this {\r\n const m = this.m;\r\n Matrix.FromValuesToRef(1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, m[12], m[13], m[14], m[15], this);\r\n this._updateIdentityStatus(m[12] === 0 && m[13] === 0 && m[14] === 0 && m[15] === 1);\r\n return this;\r\n }\r\n\r\n /**\r\n * Copy the current matrix from the given one\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#21\r\n * @param other defines the source matrix\r\n * @returns the current updated matrix\r\n */\r\n public copyFrom(other: DeepImmutable): this {\r\n other.copyToArray(this._m);\r\n const o = other as Matrix;\r\n this.updateFlag = o.updateFlag;\r\n this._updateIdentityStatus(o._isIdentity, o._isIdentityDirty, o._isIdentity3x2, o._isIdentity3x2Dirty);\r\n return this;\r\n }\r\n\r\n /**\r\n * Populates the given array from the starting index with the current matrix values\r\n * @param array defines the target array\r\n * @param offset defines the offset in the target array where to start storing values\r\n * @returns the current matrix\r\n */\r\n public copyToArray(array: Float32Array | Array, offset: number = 0): this {\r\n const source = this._m;\r\n array[offset] = source[0];\r\n array[offset + 1] = source[1];\r\n array[offset + 2] = source[2];\r\n array[offset + 3] = source[3];\r\n array[offset + 4] = source[4];\r\n array[offset + 5] = source[5];\r\n array[offset + 6] = source[6];\r\n array[offset + 7] = source[7];\r\n array[offset + 8] = source[8];\r\n array[offset + 9] = source[9];\r\n array[offset + 10] = source[10];\r\n array[offset + 11] = source[11];\r\n array[offset + 12] = source[12];\r\n array[offset + 13] = source[13];\r\n array[offset + 14] = source[14];\r\n array[offset + 15] = source[15];\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Multiply two matrices\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#15\r\n * A.multiply(B) means apply B to A so result is B x A\r\n * @param other defines the second operand\r\n * @returns a new matrix set with the multiplication result of the current Matrix and the given one\r\n */\r\n public multiply(other: DeepImmutable): Matrix {\r\n const result = new Matrix();\r\n this.multiplyToRef(other, result);\r\n return result;\r\n }\r\n\r\n /**\r\n * This method performs component-by-component in-place multiplication, rather than true matrix multiplication.\r\n * Use multiply or multiplyToRef for matrix multiplication.\r\n * @param other defines the second operand\r\n * @returns the current updated matrix\r\n */\r\n public multiplyInPlace(other: DeepImmutable): this {\r\n const m = this._m,\r\n otherM = other.m;\r\n for (let i = 0; i < 16; i++) {\r\n m[i] *= otherM[i];\r\n }\r\n this.markAsUpdated();\r\n return this;\r\n }\r\n\r\n /**\r\n * This method performs a component-by-component multiplication of the current matrix with the array of transmitted numbers.\r\n * Use multiply or multiplyToRef for matrix multiplication.\r\n * @param floats defines the array of numbers to multiply the matrix by\r\n * @returns the current updated matrix\r\n */\r\n public multiplyByFloats(...floats: Tuple): this {\r\n const m = this._m;\r\n for (let i = 0; i < 16; i++) {\r\n m[i] *= floats[i];\r\n }\r\n this.markAsUpdated();\r\n return this;\r\n }\r\n\r\n /**\r\n * Multiples the current matrix by the given floats and stores them in the given ref\r\n * @param args The floats and ref\r\n * @returns The updated ref\r\n */\r\n public multiplyByFloatsToRef(...args: [...Tuple, T]): T {\r\n const result = args.pop() as T,\r\n m = this._m,\r\n resultM = result._m,\r\n values = args as unknown as Tuple;\r\n for (let i = 0; i < 16; i++) {\r\n resultM[i] = m[i] * values[i];\r\n }\r\n result.markAsUpdated();\r\n return result;\r\n }\r\n\r\n /**\r\n * Sets the given matrix \"result\" with the multiplication result of the current Matrix and the given one\r\n * A.multiplyToRef(B, R) means apply B to A and store in R and R = B x A\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#16\r\n * @param other defines the second operand\r\n * @param result defines the matrix where to store the multiplication\r\n * @returns result input\r\n */\r\n public multiplyToRef(other: DeepImmutable, result: T): T {\r\n if (this._isIdentity) {\r\n result.copyFrom(other);\r\n return result;\r\n }\r\n if ((other as Matrix)._isIdentity) {\r\n result.copyFrom(this);\r\n return result;\r\n }\r\n\r\n this.multiplyToArray(other, result._m, 0);\r\n result.markAsUpdated();\r\n return result;\r\n }\r\n\r\n /**\r\n * Sets the Float32Array \"result\" from the given index \"offset\" with the multiplication of the current matrix and the given one\r\n * @param other defines the second operand\r\n * @param result defines the array where to store the multiplication\r\n * @param offset defines the offset in the target array where to start storing values\r\n * @returns the current matrix\r\n */\r\n public multiplyToArray(other: DeepImmutable, result: Float32Array | Array, offset: number): this {\r\n const m = this._m;\r\n const otherM = other.m;\r\n const tm0 = m[0],\r\n tm1 = m[1],\r\n tm2 = m[2],\r\n tm3 = m[3];\r\n const tm4 = m[4],\r\n tm5 = m[5],\r\n tm6 = m[6],\r\n tm7 = m[7];\r\n const tm8 = m[8],\r\n tm9 = m[9],\r\n tm10 = m[10],\r\n tm11 = m[11];\r\n const tm12 = m[12],\r\n tm13 = m[13],\r\n tm14 = m[14],\r\n tm15 = m[15];\r\n\r\n const om0 = otherM[0],\r\n om1 = otherM[1],\r\n om2 = otherM[2],\r\n om3 = otherM[3];\r\n const om4 = otherM[4],\r\n om5 = otherM[5],\r\n om6 = otherM[6],\r\n om7 = otherM[7];\r\n const om8 = otherM[8],\r\n om9 = otherM[9],\r\n om10 = otherM[10],\r\n om11 = otherM[11];\r\n const om12 = otherM[12],\r\n om13 = otherM[13],\r\n om14 = otherM[14],\r\n om15 = otherM[15];\r\n\r\n result[offset] = tm0 * om0 + tm1 * om4 + tm2 * om8 + tm3 * om12;\r\n result[offset + 1] = tm0 * om1 + tm1 * om5 + tm2 * om9 + tm3 * om13;\r\n result[offset + 2] = tm0 * om2 + tm1 * om6 + tm2 * om10 + tm3 * om14;\r\n result[offset + 3] = tm0 * om3 + tm1 * om7 + tm2 * om11 + tm3 * om15;\r\n\r\n result[offset + 4] = tm4 * om0 + tm5 * om4 + tm6 * om8 + tm7 * om12;\r\n result[offset + 5] = tm4 * om1 + tm5 * om5 + tm6 * om9 + tm7 * om13;\r\n result[offset + 6] = tm4 * om2 + tm5 * om6 + tm6 * om10 + tm7 * om14;\r\n result[offset + 7] = tm4 * om3 + tm5 * om7 + tm6 * om11 + tm7 * om15;\r\n\r\n result[offset + 8] = tm8 * om0 + tm9 * om4 + tm10 * om8 + tm11 * om12;\r\n result[offset + 9] = tm8 * om1 + tm9 * om5 + tm10 * om9 + tm11 * om13;\r\n result[offset + 10] = tm8 * om2 + tm9 * om6 + tm10 * om10 + tm11 * om14;\r\n result[offset + 11] = tm8 * om3 + tm9 * om7 + tm10 * om11 + tm11 * om15;\r\n\r\n result[offset + 12] = tm12 * om0 + tm13 * om4 + tm14 * om8 + tm15 * om12;\r\n result[offset + 13] = tm12 * om1 + tm13 * om5 + tm14 * om9 + tm15 * om13;\r\n result[offset + 14] = tm12 * om2 + tm13 * om6 + tm14 * om10 + tm15 * om14;\r\n result[offset + 15] = tm12 * om3 + tm13 * om7 + tm14 * om11 + tm15 * om15;\r\n return this;\r\n }\r\n\r\n public divide(other: DeepImmutable): Matrix {\r\n return this.divideToRef(other, new Matrix());\r\n }\r\n\r\n public divideToRef(other: DeepImmutable, result: T): T {\r\n const m = this._m,\r\n otherM = other.m,\r\n resultM = result._m;\r\n for (let i = 0; i < 16; i++) {\r\n resultM[i] = m[i] / otherM[i];\r\n }\r\n result.markAsUpdated();\r\n return result;\r\n }\r\n\r\n public divideInPlace(other: DeepImmutable): this {\r\n const m = this._m,\r\n otherM = other.m;\r\n for (let i = 0; i < 16; i++) {\r\n m[i] /= otherM[i];\r\n }\r\n this.markAsUpdated();\r\n return this;\r\n }\r\n\r\n public minimizeInPlace(other: DeepImmutable): this {\r\n const m = this._m,\r\n otherM = other.m;\r\n for (let i = 0; i < 16; i++) {\r\n m[i] = Math.min(m[i], otherM[i]);\r\n }\r\n this.markAsUpdated();\r\n return this;\r\n }\r\n\r\n public minimizeInPlaceFromFloats(...floats: Tuple): this {\r\n const m = this._m;\r\n for (let i = 0; i < 16; i++) {\r\n m[i] = Math.min(m[i], floats[i]);\r\n }\r\n this.markAsUpdated();\r\n return this;\r\n }\r\n\r\n public maximizeInPlace(other: DeepImmutable): this {\r\n const m = this._m,\r\n otherM = other.m;\r\n for (let i = 0; i < 16; i++) {\r\n m[i] = Math.min(m[i], otherM[i]);\r\n }\r\n this.markAsUpdated();\r\n return this;\r\n }\r\n\r\n public maximizeInPlaceFromFloats(...floats: Tuple): this {\r\n const m = this._m;\r\n for (let i = 0; i < 16; i++) {\r\n m[i] = Math.min(m[i], floats[i]);\r\n }\r\n this.markAsUpdated();\r\n return this;\r\n }\r\n\r\n public negate(): Matrix {\r\n return this.negateToRef(new Matrix());\r\n }\r\n\r\n public negateInPlace(): this {\r\n const m = this._m;\r\n for (let i = 0; i < 16; i++) {\r\n m[i] = -m[i];\r\n }\r\n this.markAsUpdated();\r\n return this;\r\n }\r\n\r\n public negateToRef(result: T): T {\r\n const m = this._m,\r\n resultM = result._m;\r\n for (let i = 0; i < 16; i++) {\r\n resultM[i] = -m[i];\r\n }\r\n result.markAsUpdated();\r\n return result;\r\n }\r\n\r\n /**\r\n * Check equality between this matrix and a second one\r\n * @param value defines the second matrix to compare\r\n * @returns true is the current matrix and the given one values are strictly equal\r\n */\r\n public equals(value: DeepImmutable): boolean {\r\n const other = value as Matrix;\r\n if (!other) {\r\n return false;\r\n }\r\n\r\n if (this._isIdentity || other._isIdentity) {\r\n if (!this._isIdentityDirty && !other._isIdentityDirty) {\r\n return this._isIdentity && other._isIdentity;\r\n }\r\n }\r\n\r\n const m = this.m;\r\n const om = other.m;\r\n return (\r\n m[0] === om[0] &&\r\n m[1] === om[1] &&\r\n m[2] === om[2] &&\r\n m[3] === om[3] &&\r\n m[4] === om[4] &&\r\n m[5] === om[5] &&\r\n m[6] === om[6] &&\r\n m[7] === om[7] &&\r\n m[8] === om[8] &&\r\n m[9] === om[9] &&\r\n m[10] === om[10] &&\r\n m[11] === om[11] &&\r\n m[12] === om[12] &&\r\n m[13] === om[13] &&\r\n m[14] === om[14] &&\r\n m[15] === om[15]\r\n );\r\n }\r\n\r\n public equalsWithEpsilon(other: DeepImmutable, epsilon: number = 0): boolean {\r\n const m = this._m,\r\n otherM = other.m;\r\n for (let i = 0; i < 16; i++) {\r\n if (!WithinEpsilon(m[i], otherM[i], epsilon)) {\r\n return false;\r\n }\r\n }\r\n return true;\r\n }\r\n\r\n public equalsToFloats(...floats: Tuple): boolean {\r\n const m = this._m;\r\n for (let i = 0; i < 16; i++) {\r\n if (m[i] != floats[i]) {\r\n return false;\r\n }\r\n }\r\n return true;\r\n }\r\n\r\n public floor(): Matrix {\r\n return this.floorToRef(new Matrix());\r\n }\r\n\r\n public floorToRef(result: T): T {\r\n const m = this._m,\r\n resultM = result._m;\r\n for (let i = 0; i < 16; i++) {\r\n resultM[i] = Math.floor(m[i]);\r\n }\r\n result.markAsUpdated();\r\n return result;\r\n }\r\n\r\n public fract(): Matrix {\r\n return this.fractToRef(new Matrix());\r\n }\r\n\r\n public fractToRef(result: T): T {\r\n const m = this._m,\r\n resultM = result._m;\r\n for (let i = 0; i < 16; i++) {\r\n resultM[i] = m[i] - Math.floor(m[i]);\r\n }\r\n result.markAsUpdated();\r\n return result;\r\n }\r\n\r\n /**\r\n * Clone the current matrix\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#18\r\n * @returns a new matrix from the current matrix\r\n */\r\n public clone(): Matrix {\r\n const matrix = new Matrix();\r\n matrix.copyFrom(this);\r\n return matrix;\r\n }\r\n\r\n /**\r\n * Returns the name of the current matrix class\r\n * @returns the string \"Matrix\"\r\n */\r\n public getClassName(): string {\r\n return \"Matrix\";\r\n }\r\n\r\n /**\r\n * Gets the hash code of the current matrix\r\n * @returns the hash code\r\n */\r\n public getHashCode(): number {\r\n let hash = _ExtractAsInt(this._m[0]);\r\n for (let i = 1; i < 16; i++) {\r\n hash = (hash * 397) ^ _ExtractAsInt(this._m[i]);\r\n }\r\n return hash;\r\n }\r\n\r\n /**\r\n * Decomposes the current Matrix into a translation, rotation and scaling components of the provided node\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#13\r\n * @param node the node to decompose the matrix to\r\n * @returns true if operation was successful\r\n */\r\n public decomposeToTransformNode(node: TransformNode): boolean {\r\n node.rotationQuaternion = node.rotationQuaternion || new Quaternion();\r\n return this.decompose(node.scaling, node.rotationQuaternion, node.position);\r\n }\r\n /**\r\n * Decomposes the current Matrix into a translation, rotation and scaling components\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#12\r\n * @param scale defines the scale vector3 given as a reference to update\r\n * @param rotation defines the rotation quaternion given as a reference to update\r\n * @param translation defines the translation vector3 given as a reference to update\r\n * @param preserveScalingNode Use scaling sign coming from this node. Otherwise scaling sign might change.\r\n * @param useAbsoluteScaling Use scaling sign coming from this absoluteScaling when true or scaling otherwise.\r\n * @returns true if operation was successful\r\n */\r\n public decompose(scale?: Vector3, rotation?: Quaternion, translation?: Vector3, preserveScalingNode?: TransformNode, useAbsoluteScaling: boolean = true): boolean {\r\n if (this._isIdentity) {\r\n if (translation) {\r\n translation.setAll(0);\r\n }\r\n if (scale) {\r\n scale.setAll(1);\r\n }\r\n if (rotation) {\r\n rotation.copyFromFloats(0, 0, 0, 1);\r\n }\r\n return true;\r\n }\r\n\r\n const m = this._m;\r\n if (translation) {\r\n translation.copyFromFloats(m[12], m[13], m[14]);\r\n }\r\n\r\n scale = scale || MathTmp.Vector3[0];\r\n\r\n scale.x = Math.sqrt(m[0] * m[0] + m[1] * m[1] + m[2] * m[2]);\r\n scale.y = Math.sqrt(m[4] * m[4] + m[5] * m[5] + m[6] * m[6]);\r\n scale.z = Math.sqrt(m[8] * m[8] + m[9] * m[9] + m[10] * m[10]);\r\n\r\n if (preserveScalingNode) {\r\n const signX = (useAbsoluteScaling ? preserveScalingNode.absoluteScaling.x : preserveScalingNode.scaling.x) < 0 ? -1 : 1;\r\n const signY = (useAbsoluteScaling ? preserveScalingNode.absoluteScaling.y : preserveScalingNode.scaling.y) < 0 ? -1 : 1;\r\n const signZ = (useAbsoluteScaling ? preserveScalingNode.absoluteScaling.z : preserveScalingNode.scaling.z) < 0 ? -1 : 1;\r\n\r\n scale.x *= signX;\r\n scale.y *= signY;\r\n scale.z *= signZ;\r\n } else {\r\n if (this.determinant() <= 0) {\r\n scale.y *= -1;\r\n }\r\n }\r\n\r\n if (scale._x === 0 || scale._y === 0 || scale._z === 0) {\r\n if (rotation) {\r\n rotation.copyFromFloats(0.0, 0.0, 0.0, 1.0);\r\n }\r\n return false;\r\n }\r\n\r\n if (rotation) {\r\n const sx = 1 / scale._x,\r\n sy = 1 / scale._y,\r\n sz = 1 / scale._z;\r\n Matrix.FromValuesToRef(\r\n m[0] * sx,\r\n m[1] * sx,\r\n m[2] * sx,\r\n 0.0,\r\n m[4] * sy,\r\n m[5] * sy,\r\n m[6] * sy,\r\n 0.0,\r\n m[8] * sz,\r\n m[9] * sz,\r\n m[10] * sz,\r\n 0.0,\r\n 0.0,\r\n 0.0,\r\n 0.0,\r\n 1.0,\r\n MathTmp.Matrix[0]\r\n );\r\n\r\n Quaternion.FromRotationMatrixToRef(MathTmp.Matrix[0], rotation);\r\n }\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * Gets specific row of the matrix\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#36\r\n * @param index defines the number of the row to get\r\n * @returns the index-th row of the current matrix as a new Vector4\r\n */\r\n public getRow(index: number): Nullable {\r\n if (index < 0 || index > 3) {\r\n return null;\r\n }\r\n const i = index * 4;\r\n return new Vector4(this._m[i + 0], this._m[i + 1], this._m[i + 2], this._m[i + 3]);\r\n }\r\n\r\n /**\r\n * Gets specific row of the matrix to ref\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#36\r\n * @param index defines the number of the row to get\r\n * @param rowVector vector to store the index-th row of the current matrix\r\n * @returns result input\r\n */\r\n public getRowToRef(index: number, rowVector: T): T {\r\n if (index >= 0 && index <= 3) {\r\n const i = index * 4;\r\n rowVector.x = this._m[i + 0];\r\n rowVector.y = this._m[i + 1];\r\n rowVector.z = this._m[i + 2];\r\n rowVector.w = this._m[i + 3];\r\n }\r\n return rowVector;\r\n }\r\n\r\n /**\r\n * Sets the index-th row of the current matrix to the vector4 values\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#36\r\n * @param index defines the number of the row to set\r\n * @param row defines the target vector4\r\n * @returns the updated current matrix\r\n */\r\n public setRow(index: number, row: Vector4): this {\r\n return this.setRowFromFloats(index, row.x, row.y, row.z, row.w);\r\n }\r\n\r\n /**\r\n * Compute the transpose of the matrix\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#40\r\n * @returns the new transposed matrix\r\n */\r\n public transpose(): Matrix {\r\n const result = new Matrix();\r\n Matrix.TransposeToRef(this, result);\r\n return result;\r\n }\r\n\r\n /**\r\n * Compute the transpose of the matrix and store it in a given matrix\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#41\r\n * @param result defines the target matrix\r\n * @returns result input\r\n */\r\n public transposeToRef(result: T): T {\r\n Matrix.TransposeToRef(this, result);\r\n return result;\r\n }\r\n\r\n /**\r\n * Sets the index-th row of the current matrix with the given 4 x float values\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#36\r\n * @param index defines the row index\r\n * @param x defines the x component to set\r\n * @param y defines the y component to set\r\n * @param z defines the z component to set\r\n * @param w defines the w component to set\r\n * @returns the updated current matrix\r\n */\r\n public setRowFromFloats(index: number, x: number, y: number, z: number, w: number): this {\r\n if (index < 0 || index > 3) {\r\n return this;\r\n }\r\n const i = index * 4;\r\n this._m[i + 0] = x;\r\n this._m[i + 1] = y;\r\n this._m[i + 2] = z;\r\n this._m[i + 3] = w;\r\n\r\n this.markAsUpdated();\r\n return this;\r\n }\r\n\r\n /**\r\n * Compute a new matrix set with the current matrix values multiplied by scale (float)\r\n * @param scale defines the scale factor\r\n * @returns a new matrix\r\n */\r\n public scale(scale: number): Matrix {\r\n const result = new Matrix();\r\n this.scaleToRef(scale, result);\r\n return result;\r\n }\r\n\r\n /**\r\n * Scale the current matrix values by a factor to a given result matrix\r\n * @param scale defines the scale factor\r\n * @param result defines the matrix to store the result\r\n * @returns result input\r\n */\r\n public scaleToRef(scale: number, result: T): T {\r\n for (let index = 0; index < 16; index++) {\r\n result._m[index] = this._m[index] * scale;\r\n }\r\n result.markAsUpdated();\r\n return result;\r\n }\r\n\r\n /**\r\n * Scale the current matrix values by a factor and add the result to a given matrix\r\n * @param scale defines the scale factor\r\n * @param result defines the Matrix to store the result\r\n * @returns result input\r\n */\r\n public scaleAndAddToRef(scale: number, result: T): T {\r\n for (let index = 0; index < 16; index++) {\r\n result._m[index] += this._m[index] * scale;\r\n }\r\n result.markAsUpdated();\r\n return result;\r\n }\r\n\r\n public scaleInPlace(scale: number): this {\r\n const m = this._m;\r\n for (let i = 0; i < 16; i++) {\r\n m[i] *= scale;\r\n }\r\n this.markAsUpdated();\r\n return this;\r\n }\r\n\r\n /**\r\n * Writes to the given matrix a normal matrix, computed from this one (using values from identity matrix for fourth row and column).\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#17\r\n * @param ref matrix to store the result\r\n * @returns the reference matrix\r\n */\r\n public toNormalMatrix(ref: T): T {\r\n const tmp = MathTmp.Matrix[0];\r\n this.invertToRef(tmp);\r\n tmp.transposeToRef(ref);\r\n const m = ref._m;\r\n Matrix.FromValuesToRef(m[0], m[1], m[2], 0.0, m[4], m[5], m[6], 0.0, m[8], m[9], m[10], 0.0, 0.0, 0.0, 0.0, 1.0, ref);\r\n return ref;\r\n }\r\n\r\n /**\r\n * Gets only rotation part of the current matrix\r\n * @returns a new matrix sets to the extracted rotation matrix from the current one\r\n */\r\n public getRotationMatrix(): Matrix {\r\n const result = new Matrix();\r\n this.getRotationMatrixToRef(result);\r\n return result;\r\n }\r\n\r\n /**\r\n * Extracts the rotation matrix from the current one and sets it as the given \"result\"\r\n * @param result defines the target matrix to store data to\r\n * @returns result input\r\n */\r\n public getRotationMatrixToRef(result: T): T {\r\n const scale = MathTmp.Vector3[0];\r\n if (!this.decompose(scale)) {\r\n Matrix.IdentityToRef(result);\r\n return result;\r\n }\r\n\r\n const m = this._m;\r\n const sx = 1 / scale._x,\r\n sy = 1 / scale._y,\r\n sz = 1 / scale._z;\r\n Matrix.FromValuesToRef(m[0] * sx, m[1] * sx, m[2] * sx, 0.0, m[4] * sy, m[5] * sy, m[6] * sy, 0.0, m[8] * sz, m[9] * sz, m[10] * sz, 0.0, 0.0, 0.0, 0.0, 1.0, result);\r\n return result;\r\n }\r\n\r\n /**\r\n * Toggles model matrix from being right handed to left handed in place and vice versa\r\n * @returns the current updated matrix\r\n */\r\n public toggleModelMatrixHandInPlace(): this {\r\n const m = this._m;\r\n m[2] *= -1;\r\n m[6] *= -1;\r\n m[8] *= -1;\r\n m[9] *= -1;\r\n m[14] *= -1;\r\n this.markAsUpdated();\r\n return this;\r\n }\r\n\r\n /**\r\n * Toggles projection matrix from being right handed to left handed in place and vice versa\r\n * @returns the current updated matrix\r\n */\r\n public toggleProjectionMatrixHandInPlace(): this {\r\n const m = this._m;\r\n m[8] *= -1;\r\n m[9] *= -1;\r\n m[10] *= -1;\r\n m[11] *= -1;\r\n this.markAsUpdated();\r\n return this;\r\n }\r\n\r\n // Statics\r\n /**\r\n * Creates a matrix from an array\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#42\r\n * @param array defines the source array\r\n * @param offset defines an offset in the source array\r\n * @returns a new Matrix set from the starting index of the given array\r\n */\r\n public static FromArray(array: DeepImmutable>, offset: number = 0): Matrix {\r\n const result = new Matrix();\r\n Matrix.FromArrayToRef(array, offset, result);\r\n return result;\r\n }\r\n\r\n /**\r\n * Copy the content of an array into a given matrix\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#43\r\n * @param array defines the source array\r\n * @param offset defines an offset in the source array\r\n * @param result defines the target matrix\r\n * @returns result input\r\n */\r\n public static FromArrayToRef(array: DeepImmutable>, offset: number, result: T): T {\r\n for (let index = 0; index < 16; index++) {\r\n result._m[index] = array[index + offset];\r\n }\r\n result.markAsUpdated();\r\n return result;\r\n }\r\n\r\n /**\r\n * Stores an array into a matrix after having multiplied each component by a given factor\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#50\r\n * @param array defines the source array\r\n * @param offset defines the offset in the source array\r\n * @param scale defines the scaling factor\r\n * @param result defines the target matrix\r\n * @returns result input\r\n */\r\n public static FromFloat32ArrayToRefScaled(array: DeepImmutable>, offset: number, scale: number, result: T): T {\r\n result._m[0] = array[0 + offset] * scale;\r\n result._m[1] = array[1 + offset] * scale;\r\n result._m[2] = array[2 + offset] * scale;\r\n result._m[3] = array[3 + offset] * scale;\r\n result._m[4] = array[4 + offset] * scale;\r\n result._m[5] = array[5 + offset] * scale;\r\n result._m[6] = array[6 + offset] * scale;\r\n result._m[7] = array[7 + offset] * scale;\r\n result._m[8] = array[8 + offset] * scale;\r\n result._m[9] = array[9 + offset] * scale;\r\n result._m[10] = array[10 + offset] * scale;\r\n result._m[11] = array[11 + offset] * scale;\r\n result._m[12] = array[12 + offset] * scale;\r\n result._m[13] = array[13 + offset] * scale;\r\n result._m[14] = array[14 + offset] * scale;\r\n result._m[15] = array[15 + offset] * scale;\r\n result.markAsUpdated();\r\n return result;\r\n }\r\n\r\n /**\r\n * Gets an identity matrix that must not be updated\r\n */\r\n public static get IdentityReadOnly(): DeepImmutable {\r\n return Matrix._IdentityReadOnly;\r\n }\r\n\r\n /**\r\n * Stores a list of values (16) inside a given matrix\r\n * @param initialM11 defines 1st value of 1st row\r\n * @param initialM12 defines 2nd value of 1st row\r\n * @param initialM13 defines 3rd value of 1st row\r\n * @param initialM14 defines 4th value of 1st row\r\n * @param initialM21 defines 1st value of 2nd row\r\n * @param initialM22 defines 2nd value of 2nd row\r\n * @param initialM23 defines 3rd value of 2nd row\r\n * @param initialM24 defines 4th value of 2nd row\r\n * @param initialM31 defines 1st value of 3rd row\r\n * @param initialM32 defines 2nd value of 3rd row\r\n * @param initialM33 defines 3rd value of 3rd row\r\n * @param initialM34 defines 4th value of 3rd row\r\n * @param initialM41 defines 1st value of 4th row\r\n * @param initialM42 defines 2nd value of 4th row\r\n * @param initialM43 defines 3rd value of 4th row\r\n * @param initialM44 defines 4th value of 4th row\r\n * @param result defines the target matrix\r\n */\r\n public static FromValuesToRef(\r\n initialM11: number,\r\n initialM12: number,\r\n initialM13: number,\r\n initialM14: number,\r\n initialM21: number,\r\n initialM22: number,\r\n initialM23: number,\r\n initialM24: number,\r\n initialM31: number,\r\n initialM32: number,\r\n initialM33: number,\r\n initialM34: number,\r\n initialM41: number,\r\n initialM42: number,\r\n initialM43: number,\r\n initialM44: number,\r\n result: Matrix\r\n ): void {\r\n const m = result._m;\r\n m[0] = initialM11;\r\n m[1] = initialM12;\r\n m[2] = initialM13;\r\n m[3] = initialM14;\r\n m[4] = initialM21;\r\n m[5] = initialM22;\r\n m[6] = initialM23;\r\n m[7] = initialM24;\r\n m[8] = initialM31;\r\n m[9] = initialM32;\r\n m[10] = initialM33;\r\n m[11] = initialM34;\r\n m[12] = initialM41;\r\n m[13] = initialM42;\r\n m[14] = initialM43;\r\n m[15] = initialM44;\r\n\r\n result.markAsUpdated();\r\n }\r\n\r\n /**\r\n * Creates new matrix from a list of values (16)\r\n * @param initialM11 defines 1st value of 1st row\r\n * @param initialM12 defines 2nd value of 1st row\r\n * @param initialM13 defines 3rd value of 1st row\r\n * @param initialM14 defines 4th value of 1st row\r\n * @param initialM21 defines 1st value of 2nd row\r\n * @param initialM22 defines 2nd value of 2nd row\r\n * @param initialM23 defines 3rd value of 2nd row\r\n * @param initialM24 defines 4th value of 2nd row\r\n * @param initialM31 defines 1st value of 3rd row\r\n * @param initialM32 defines 2nd value of 3rd row\r\n * @param initialM33 defines 3rd value of 3rd row\r\n * @param initialM34 defines 4th value of 3rd row\r\n * @param initialM41 defines 1st value of 4th row\r\n * @param initialM42 defines 2nd value of 4th row\r\n * @param initialM43 defines 3rd value of 4th row\r\n * @param initialM44 defines 4th value of 4th row\r\n * @returns the new matrix\r\n */\r\n public static FromValues(\r\n initialM11: number,\r\n initialM12: number,\r\n initialM13: number,\r\n initialM14: number,\r\n initialM21: number,\r\n initialM22: number,\r\n initialM23: number,\r\n initialM24: number,\r\n initialM31: number,\r\n initialM32: number,\r\n initialM33: number,\r\n initialM34: number,\r\n initialM41: number,\r\n initialM42: number,\r\n initialM43: number,\r\n initialM44: number\r\n ): Matrix {\r\n const result = new Matrix();\r\n const m = result._m;\r\n m[0] = initialM11;\r\n m[1] = initialM12;\r\n m[2] = initialM13;\r\n m[3] = initialM14;\r\n m[4] = initialM21;\r\n m[5] = initialM22;\r\n m[6] = initialM23;\r\n m[7] = initialM24;\r\n m[8] = initialM31;\r\n m[9] = initialM32;\r\n m[10] = initialM33;\r\n m[11] = initialM34;\r\n m[12] = initialM41;\r\n m[13] = initialM42;\r\n m[14] = initialM43;\r\n m[15] = initialM44;\r\n result.markAsUpdated();\r\n return result;\r\n }\r\n\r\n /**\r\n * Creates a new matrix composed by merging scale (vector3), rotation (quaternion) and translation (vector3)\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#24\r\n * @param scale defines the scale vector3\r\n * @param rotation defines the rotation quaternion\r\n * @param translation defines the translation vector3\r\n * @returns a new matrix\r\n */\r\n public static Compose(scale: DeepImmutable, rotation: DeepImmutable, translation: DeepImmutable): Matrix {\r\n const result = new Matrix();\r\n Matrix.ComposeToRef(scale, rotation, translation, result);\r\n return result;\r\n }\r\n\r\n /**\r\n * Sets a matrix to a value composed by merging scale (vector3), rotation (quaternion) and translation (vector3)\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#25\r\n * @param scale defines the scale vector3\r\n * @param rotation defines the rotation quaternion\r\n * @param translation defines the translation vector3\r\n * @param result defines the target matrix\r\n * @returns result input\r\n */\r\n public static ComposeToRef(scale: DeepImmutable, rotation: DeepImmutable, translation: DeepImmutable, result: T): T {\r\n const m = result._m;\r\n const x = rotation._x,\r\n y = rotation._y,\r\n z = rotation._z,\r\n w = rotation._w;\r\n const x2 = x + x,\r\n y2 = y + y,\r\n z2 = z + z;\r\n const xx = x * x2,\r\n xy = x * y2,\r\n xz = x * z2;\r\n const yy = y * y2,\r\n yz = y * z2,\r\n zz = z * z2;\r\n const wx = w * x2,\r\n wy = w * y2,\r\n wz = w * z2;\r\n\r\n const sx = scale._x,\r\n sy = scale._y,\r\n sz = scale._z;\r\n\r\n m[0] = (1 - (yy + zz)) * sx;\r\n m[1] = (xy + wz) * sx;\r\n m[2] = (xz - wy) * sx;\r\n m[3] = 0;\r\n\r\n m[4] = (xy - wz) * sy;\r\n m[5] = (1 - (xx + zz)) * sy;\r\n m[6] = (yz + wx) * sy;\r\n m[7] = 0;\r\n\r\n m[8] = (xz + wy) * sz;\r\n m[9] = (yz - wx) * sz;\r\n m[10] = (1 - (xx + yy)) * sz;\r\n m[11] = 0;\r\n\r\n m[12] = translation._x;\r\n m[13] = translation._y;\r\n m[14] = translation._z;\r\n m[15] = 1;\r\n\r\n result.markAsUpdated();\r\n return result;\r\n }\r\n\r\n /**\r\n * Creates a new identity matrix\r\n * @returns a new identity matrix\r\n */\r\n public static Identity(): Matrix {\r\n const identity = Matrix.FromValues(1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0);\r\n identity._updateIdentityStatus(true);\r\n return identity;\r\n }\r\n\r\n /**\r\n * Creates a new identity matrix and stores the result in a given matrix\r\n * @param result defines the target matrix\r\n * @returns result input\r\n */\r\n public static IdentityToRef(result: T): T {\r\n Matrix.FromValuesToRef(1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, result);\r\n result._updateIdentityStatus(true);\r\n return result;\r\n }\r\n\r\n /**\r\n * Creates a new zero matrix\r\n * @returns a new zero matrix\r\n */\r\n public static Zero(): Matrix {\r\n const zero = Matrix.FromValues(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);\r\n zero._updateIdentityStatus(false);\r\n return zero;\r\n }\r\n\r\n /**\r\n * Creates a new rotation matrix for \"angle\" radians around the X axis\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#97\r\n * @param angle defines the angle (in radians) to use\r\n * @returns the new matrix\r\n */\r\n public static RotationX(angle: number): Matrix {\r\n const result = new Matrix();\r\n Matrix.RotationXToRef(angle, result);\r\n return result;\r\n }\r\n\r\n /**\r\n * Creates a new matrix as the invert of a given matrix\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#124\r\n * @param source defines the source matrix\r\n * @returns the new matrix\r\n */\r\n public static Invert(source: DeepImmutable): Matrix {\r\n const result = new Matrix();\r\n source.invertToRef(result);\r\n return result;\r\n }\r\n\r\n /**\r\n * Creates a new rotation matrix for \"angle\" radians around the X axis and stores it in a given matrix\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#98\r\n * @param angle defines the angle (in radians) to use\r\n * @param result defines the target matrix\r\n * @returns result input\r\n */\r\n public static RotationXToRef(angle: number, result: T): T {\r\n const s = Math.sin(angle);\r\n const c = Math.cos(angle);\r\n Matrix.FromValuesToRef(1.0, 0.0, 0.0, 0.0, 0.0, c, s, 0.0, 0.0, -s, c, 0.0, 0.0, 0.0, 0.0, 1.0, result);\r\n\r\n result._updateIdentityStatus(c === 1 && s === 0);\r\n return result;\r\n }\r\n\r\n /**\r\n * Creates a new rotation matrix for \"angle\" radians around the Y axis\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#99\r\n * @param angle defines the angle (in radians) to use\r\n * @returns the new matrix\r\n */\r\n public static RotationY(angle: number): Matrix {\r\n const result = new Matrix();\r\n Matrix.RotationYToRef(angle, result);\r\n return result;\r\n }\r\n\r\n /**\r\n * Creates a new rotation matrix for \"angle\" radians around the Y axis and stores it in a given matrix\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#100\r\n * @param angle defines the angle (in radians) to use\r\n * @param result defines the target matrix\r\n * @returns result input\r\n */\r\n public static RotationYToRef(angle: number, result: T): T {\r\n const s = Math.sin(angle);\r\n const c = Math.cos(angle);\r\n Matrix.FromValuesToRef(c, 0.0, -s, 0.0, 0.0, 1.0, 0.0, 0.0, s, 0.0, c, 0.0, 0.0, 0.0, 0.0, 1.0, result);\r\n\r\n result._updateIdentityStatus(c === 1 && s === 0);\r\n return result;\r\n }\r\n\r\n /**\r\n * Creates a new rotation matrix for \"angle\" radians around the Z axis\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#101\r\n * @param angle defines the angle (in radians) to use\r\n * @returns the new matrix\r\n */\r\n public static RotationZ(angle: number): Matrix {\r\n const result = new Matrix();\r\n Matrix.RotationZToRef(angle, result);\r\n return result;\r\n }\r\n\r\n /**\r\n * Creates a new rotation matrix for \"angle\" radians around the Z axis and stores it in a given matrix\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#102\r\n * @param angle defines the angle (in radians) to use\r\n * @param result defines the target matrix\r\n * @returns result input\r\n */\r\n public static RotationZToRef(angle: number, result: T): T {\r\n const s = Math.sin(angle);\r\n const c = Math.cos(angle);\r\n Matrix.FromValuesToRef(c, s, 0.0, 0.0, -s, c, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, result);\r\n\r\n result._updateIdentityStatus(c === 1 && s === 0);\r\n return result;\r\n }\r\n\r\n /**\r\n * Creates a new rotation matrix for \"angle\" radians around the given axis\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#96\r\n * @param axis defines the axis to use\r\n * @param angle defines the angle (in radians) to use\r\n * @returns the new matrix\r\n */\r\n public static RotationAxis(axis: DeepImmutable, angle: number): Matrix {\r\n const result = new Matrix();\r\n Matrix.RotationAxisToRef(axis, angle, result);\r\n return result;\r\n }\r\n\r\n /**\r\n * Creates a new rotation matrix for \"angle\" radians around the given axis and stores it in a given matrix\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#94\r\n * @param axis defines the axis to use\r\n * @param angle defines the angle (in radians) to use\r\n * @param result defines the target matrix\r\n * @returns result input\r\n */\r\n public static RotationAxisToRef(axis: DeepImmutable, angle: number, result: T): T {\r\n const s = Math.sin(-angle);\r\n const c = Math.cos(-angle);\r\n const c1 = 1 - c;\r\n\r\n axis = axis.normalizeToRef(MathTmp.Vector3[0]);\r\n const m = result._m;\r\n m[0] = axis._x * axis._x * c1 + c;\r\n m[1] = axis._x * axis._y * c1 - axis._z * s;\r\n m[2] = axis._x * axis._z * c1 + axis._y * s;\r\n m[3] = 0.0;\r\n\r\n m[4] = axis._y * axis._x * c1 + axis._z * s;\r\n m[5] = axis._y * axis._y * c1 + c;\r\n m[6] = axis._y * axis._z * c1 - axis._x * s;\r\n m[7] = 0.0;\r\n\r\n m[8] = axis._z * axis._x * c1 - axis._y * s;\r\n m[9] = axis._z * axis._y * c1 + axis._x * s;\r\n m[10] = axis._z * axis._z * c1 + c;\r\n m[11] = 0.0;\r\n\r\n m[12] = 0.0;\r\n m[13] = 0.0;\r\n m[14] = 0.0;\r\n m[15] = 1.0;\r\n\r\n result.markAsUpdated();\r\n return result;\r\n }\r\n\r\n /**\r\n * Takes normalised vectors and returns a rotation matrix to align \"from\" with \"to\".\r\n * Taken from http://www.iquilezles.org/www/articles/noacos/noacos.htm\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#93\r\n * @param from defines the vector to align\r\n * @param to defines the vector to align to\r\n * @param result defines the target matrix\r\n * @param useYAxisForCoplanar defines a boolean indicating that we should favor Y axis for coplanar vectors (default is false)\r\n * @returns result input\r\n */\r\n public static RotationAlignToRef(from: DeepImmutable, to: DeepImmutable, result: T, useYAxisForCoplanar = false): T {\r\n const c = Vector3.Dot(to, from);\r\n const m = result._m;\r\n if (c < -1 + Epsilon) {\r\n // from and to are colinear and opposite direction.\r\n // compute a PI rotation on Y axis\r\n m[0] = -1;\r\n m[1] = 0;\r\n m[2] = 0;\r\n m[3] = 0;\r\n m[4] = 0;\r\n m[5] = useYAxisForCoplanar ? 1 : -1;\r\n m[6] = 0;\r\n m[7] = 0;\r\n m[8] = 0;\r\n m[9] = 0;\r\n m[10] = useYAxisForCoplanar ? -1 : 1;\r\n m[11] = 0;\r\n } else {\r\n const v = Vector3.Cross(to, from);\r\n const k = 1 / (1 + c);\r\n\r\n m[0] = v._x * v._x * k + c;\r\n m[1] = v._y * v._x * k - v._z;\r\n m[2] = v._z * v._x * k + v._y;\r\n m[3] = 0;\r\n m[4] = v._x * v._y * k + v._z;\r\n m[5] = v._y * v._y * k + c;\r\n m[6] = v._z * v._y * k - v._x;\r\n m[7] = 0;\r\n m[8] = v._x * v._z * k - v._y;\r\n m[9] = v._y * v._z * k + v._x;\r\n m[10] = v._z * v._z * k + c;\r\n m[11] = 0;\r\n }\r\n m[12] = 0;\r\n m[13] = 0;\r\n m[14] = 0;\r\n m[15] = 1;\r\n result.markAsUpdated();\r\n return result;\r\n }\r\n\r\n /**\r\n * Creates a rotation matrix\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#103\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#105\r\n * @param yaw defines the yaw angle in radians (Y axis)\r\n * @param pitch defines the pitch angle in radians (X axis)\r\n * @param roll defines the roll angle in radians (Z axis)\r\n * @returns the new rotation matrix\r\n */\r\n public static RotationYawPitchRoll(yaw: number, pitch: number, roll: number): Matrix {\r\n const result = new Matrix();\r\n Matrix.RotationYawPitchRollToRef(yaw, pitch, roll, result);\r\n return result;\r\n }\r\n\r\n /**\r\n * Creates a rotation matrix and stores it in a given matrix\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#104\r\n * @param yaw defines the yaw angle in radians (Y axis)\r\n * @param pitch defines the pitch angle in radians (X axis)\r\n * @param roll defines the roll angle in radians (Z axis)\r\n * @param result defines the target matrix\r\n * @returns result input\r\n */\r\n public static RotationYawPitchRollToRef(yaw: number, pitch: number, roll: number, result: T): T {\r\n Quaternion.RotationYawPitchRollToRef(yaw, pitch, roll, MathTmp.Quaternion[0]);\r\n MathTmp.Quaternion[0].toRotationMatrix(result);\r\n return result;\r\n }\r\n\r\n /**\r\n * Creates a scaling matrix\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#107\r\n * @param x defines the scale factor on X axis\r\n * @param y defines the scale factor on Y axis\r\n * @param z defines the scale factor on Z axis\r\n * @returns the new matrix\r\n */\r\n public static Scaling(x: number, y: number, z: number): Matrix {\r\n const result = new Matrix();\r\n Matrix.ScalingToRef(x, y, z, result);\r\n return result;\r\n }\r\n\r\n /**\r\n * Creates a scaling matrix and stores it in a given matrix\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#108\r\n * @param x defines the scale factor on X axis\r\n * @param y defines the scale factor on Y axis\r\n * @param z defines the scale factor on Z axis\r\n * @param result defines the target matrix\r\n * @returns result input\r\n */\r\n public static ScalingToRef(x: number, y: number, z: number, result: T): T {\r\n Matrix.FromValuesToRef(x, 0.0, 0.0, 0.0, 0.0, y, 0.0, 0.0, 0.0, 0.0, z, 0.0, 0.0, 0.0, 0.0, 1.0, result);\r\n\r\n result._updateIdentityStatus(x === 1 && y === 1 && z === 1);\r\n return result;\r\n }\r\n\r\n /**\r\n * Creates a translation matrix\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#109\r\n * @param x defines the translation on X axis\r\n * @param y defines the translation on Y axis\r\n * @param z defines the translationon Z axis\r\n * @returns the new matrix\r\n */\r\n public static Translation(x: number, y: number, z: number): Matrix {\r\n const result = new Matrix();\r\n Matrix.TranslationToRef(x, y, z, result);\r\n return result;\r\n }\r\n\r\n /**\r\n * Creates a translation matrix and stores it in a given matrix\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#110\r\n * @param x defines the translation on X axis\r\n * @param y defines the translation on Y axis\r\n * @param z defines the translationon Z axis\r\n * @param result defines the target matrix\r\n * @returns result input\r\n */\r\n public static TranslationToRef(x: number, y: number, z: number, result: T): T {\r\n Matrix.FromValuesToRef(1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, x, y, z, 1.0, result);\r\n result._updateIdentityStatus(x === 0 && y === 0 && z === 0);\r\n return result;\r\n }\r\n\r\n /**\r\n * Returns a new Matrix whose values are the interpolated values for \"gradient\" (float) between the ones of the matrices \"startValue\" and \"endValue\".\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#55\r\n * @param startValue defines the start value\r\n * @param endValue defines the end value\r\n * @param gradient defines the gradient factor\r\n * @returns the new matrix\r\n */\r\n public static Lerp(startValue: DeepImmutable, endValue: DeepImmutable, gradient: number): Matrix {\r\n const result = new Matrix();\r\n Matrix.LerpToRef(startValue, endValue, gradient, result);\r\n return result;\r\n }\r\n\r\n /**\r\n * Set the given matrix \"result\" as the interpolated values for \"gradient\" (float) between the ones of the matrices \"startValue\" and \"endValue\".\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#54\r\n * @param startValue defines the start value\r\n * @param endValue defines the end value\r\n * @param gradient defines the gradient factor\r\n * @param result defines the Matrix object where to store data\r\n * @returns result input\r\n */\r\n public static LerpToRef(startValue: DeepImmutable, endValue: DeepImmutable, gradient: number, result: T): T {\r\n const resultM = result._m;\r\n const startM = startValue.m;\r\n const endM = endValue.m;\r\n for (let index = 0; index < 16; index++) {\r\n resultM[index] = startM[index] * (1.0 - gradient) + endM[index] * gradient;\r\n }\r\n result.markAsUpdated();\r\n return result;\r\n }\r\n\r\n /**\r\n * Builds a new matrix whose values are computed by:\r\n * * decomposing the \"startValue\" and \"endValue\" matrices into their respective scale, rotation and translation matrices\r\n * * interpolating for \"gradient\" (float) the values between each of these decomposed matrices between the start and the end\r\n * * recomposing a new matrix from these 3 interpolated scale, rotation and translation matrices\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#22\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#51\r\n * @param startValue defines the first matrix\r\n * @param endValue defines the second matrix\r\n * @param gradient defines the gradient between the two matrices\r\n * @returns the new matrix\r\n */\r\n public static DecomposeLerp(startValue: DeepImmutable, endValue: DeepImmutable, gradient: number): Matrix {\r\n const result = new Matrix();\r\n Matrix.DecomposeLerpToRef(startValue, endValue, gradient, result);\r\n return result;\r\n }\r\n\r\n /**\r\n * Update a matrix to values which are computed by:\r\n * * decomposing the \"startValue\" and \"endValue\" matrices into their respective scale, rotation and translation matrices\r\n * * interpolating for \"gradient\" (float) the values between each of these decomposed matrices between the start and the end\r\n * * recomposing a new matrix from these 3 interpolated scale, rotation and translation matrices\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#23\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#53\r\n * @param startValue defines the first matrix\r\n * @param endValue defines the second matrix\r\n * @param gradient defines the gradient between the two matrices\r\n * @param result defines the target matrix\r\n * @returns result input\r\n */\r\n public static DecomposeLerpToRef(startValue: DeepImmutable, endValue: DeepImmutable, gradient: number, result: T): T {\r\n const startScale = MathTmp.Vector3[0];\r\n const startRotation = MathTmp.Quaternion[0];\r\n const startTranslation = MathTmp.Vector3[1];\r\n startValue.decompose(startScale, startRotation, startTranslation);\r\n\r\n const endScale = MathTmp.Vector3[2];\r\n const endRotation = MathTmp.Quaternion[1];\r\n const endTranslation = MathTmp.Vector3[3];\r\n endValue.decompose(endScale, endRotation, endTranslation);\r\n\r\n const resultScale = MathTmp.Vector3[4];\r\n Vector3.LerpToRef(startScale, endScale, gradient, resultScale);\r\n const resultRotation = MathTmp.Quaternion[2];\r\n Quaternion.SlerpToRef(startRotation, endRotation, gradient, resultRotation);\r\n\r\n const resultTranslation = MathTmp.Vector3[5];\r\n Vector3.LerpToRef(startTranslation, endTranslation, gradient, resultTranslation);\r\n\r\n Matrix.ComposeToRef(resultScale, resultRotation, resultTranslation, result);\r\n return result;\r\n }\r\n\r\n /**\r\n * Creates a new matrix that transforms vertices from world space to camera space. It takes three vectors as arguments that together describe the position and orientation of the camera.\r\n * This function generates a matrix suitable for a left handed coordinate system\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#58\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#59\r\n * @param eye defines the final position of the entity\r\n * @param target defines where the entity should look at\r\n * @param up defines the up vector for the entity\r\n * @returns the new matrix\r\n */\r\n public static LookAtLH(eye: DeepImmutable, target: DeepImmutable, up: DeepImmutable): Matrix {\r\n const result = new Matrix();\r\n Matrix.LookAtLHToRef(eye, target, up, result);\r\n return result;\r\n }\r\n\r\n /**\r\n * Sets the given \"result\" Matrix to a matrix that transforms vertices from world space to camera space. It takes three vectors as arguments that together describe the position and orientation of the camera.\r\n * This function generates a matrix suitable for a left handed coordinate system\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#60\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#61\r\n * @param eye defines the final position of the entity\r\n * @param target defines where the entity should look at\r\n * @param up defines the up vector for the entity\r\n * @param result defines the target matrix\r\n * @returns result input\r\n */\r\n public static LookAtLHToRef(eye: DeepImmutable, target: DeepImmutable, up: DeepImmutable, result: Matrix): Matrix {\r\n const xAxis = MathTmp.Vector3[0];\r\n const yAxis = MathTmp.Vector3[1];\r\n const zAxis = MathTmp.Vector3[2];\r\n\r\n // Z axis\r\n target.subtractToRef(eye, zAxis);\r\n zAxis.normalize();\r\n\r\n // X axis\r\n Vector3.CrossToRef(up, zAxis, xAxis);\r\n\r\n const xSquareLength = xAxis.lengthSquared();\r\n if (xSquareLength === 0) {\r\n xAxis.x = 1.0;\r\n } else {\r\n xAxis.normalizeFromLength(Math.sqrt(xSquareLength));\r\n }\r\n\r\n // Y axis\r\n Vector3.CrossToRef(zAxis, xAxis, yAxis);\r\n yAxis.normalize();\r\n\r\n // Eye angles\r\n const ex = -Vector3.Dot(xAxis, eye);\r\n const ey = -Vector3.Dot(yAxis, eye);\r\n const ez = -Vector3.Dot(zAxis, eye);\r\n\r\n Matrix.FromValuesToRef(xAxis._x, yAxis._x, zAxis._x, 0.0, xAxis._y, yAxis._y, zAxis._y, 0.0, xAxis._z, yAxis._z, zAxis._z, 0.0, ex, ey, ez, 1.0, result);\r\n return result;\r\n }\r\n\r\n /**\r\n * Creates a new matrix that transforms vertices from world space to camera space. It takes three vectors as arguments that together describe the position and orientation of the camera.\r\n * This function generates a matrix suitable for a right handed coordinate system\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#62\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#63\r\n * @param eye defines the final position of the entity\r\n * @param target defines where the entity should look at\r\n * @param up defines the up vector for the entity\r\n * @returns the new matrix\r\n */\r\n public static LookAtRH(eye: DeepImmutable, target: DeepImmutable, up: DeepImmutable): Matrix {\r\n const result = new Matrix();\r\n Matrix.LookAtRHToRef(eye, target, up, result);\r\n return result;\r\n }\r\n\r\n /**\r\n * Sets the given \"result\" Matrix to a matrix that transforms vertices from world space to camera space. It takes three vectors as arguments that together describe the position and orientation of the camera.\r\n * This function generates a matrix suitable for a right handed coordinate system\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#64\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#65\r\n * @param eye defines the final position of the entity\r\n * @param target defines where the entity should look at\r\n * @param up defines the up vector for the entity\r\n * @param result defines the target matrix\r\n * @returns result input\r\n */\r\n public static LookAtRHToRef(eye: DeepImmutable, target: DeepImmutable, up: DeepImmutable, result: T): T {\r\n const xAxis = MathTmp.Vector3[0];\r\n const yAxis = MathTmp.Vector3[1];\r\n const zAxis = MathTmp.Vector3[2];\r\n\r\n // Z axis\r\n eye.subtractToRef(target, zAxis);\r\n zAxis.normalize();\r\n\r\n // X axis\r\n Vector3.CrossToRef(up, zAxis, xAxis);\r\n\r\n const xSquareLength = xAxis.lengthSquared();\r\n if (xSquareLength === 0) {\r\n xAxis.x = 1.0;\r\n } else {\r\n xAxis.normalizeFromLength(Math.sqrt(xSquareLength));\r\n }\r\n\r\n // Y axis\r\n Vector3.CrossToRef(zAxis, xAxis, yAxis);\r\n yAxis.normalize();\r\n\r\n // Eye angles\r\n const ex = -Vector3.Dot(xAxis, eye);\r\n const ey = -Vector3.Dot(yAxis, eye);\r\n const ez = -Vector3.Dot(zAxis, eye);\r\n\r\n Matrix.FromValuesToRef(xAxis._x, yAxis._x, zAxis._x, 0.0, xAxis._y, yAxis._y, zAxis._y, 0.0, xAxis._z, yAxis._z, zAxis._z, 0.0, ex, ey, ez, 1.0, result);\r\n return result;\r\n }\r\n\r\n /**\r\n * Creates a new matrix that transforms vertices from world space to camera space. It takes two vectors as arguments that together describe the orientation of the camera. The position is assumed to be at the origin (0,0,0)\r\n * This function generates a matrix suitable for a left handed coordinate system\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#66\r\n * @param forward defines the forward direction - Must be normalized and orthogonal to up.\r\n * @param up defines the up vector for the entity - Must be normalized and orthogonal to forward.\r\n * @returns the new matrix\r\n */\r\n public static LookDirectionLH(forward: DeepImmutable, up: DeepImmutable): Matrix {\r\n const result = new Matrix();\r\n Matrix.LookDirectionLHToRef(forward, up, result);\r\n return result;\r\n }\r\n\r\n /**\r\n * Sets the given \"result\" Matrix to a matrix that transforms vertices from world space to camera space. It takes two vectors as arguments that together describe the orientation of the camera. The position is assumed to be at the origin (0,0,0)\r\n * This function generates a matrix suitable for a left handed coordinate system\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#67\r\n * @param forward defines the forward direction - Must be normalized and orthogonal to up.\r\n * @param up defines the up vector for the entity - Must be normalized and orthogonal to forward.\r\n * @param result defines the target matrix\r\n * @returns result input\r\n */\r\n public static LookDirectionLHToRef(forward: DeepImmutable, up: DeepImmutable, result: T): T {\r\n const back = MathTmp.Vector3[0];\r\n back.copyFrom(forward);\r\n back.scaleInPlace(-1);\r\n const left = MathTmp.Vector3[1];\r\n Vector3.CrossToRef(up, back, left);\r\n\r\n // Generate the rotation matrix.\r\n Matrix.FromValuesToRef(left._x, left._y, left._z, 0.0, up._x, up._y, up._z, 0.0, back._x, back._y, back._z, 0.0, 0, 0, 0, 1.0, result);\r\n return result;\r\n }\r\n\r\n /**\r\n * Creates a new matrix that transforms vertices from world space to camera space. It takes two vectors as arguments that together describe the orientation of the camera. The position is assumed to be at the origin (0,0,0)\r\n * This function generates a matrix suitable for a right handed coordinate system\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#68\r\n * @param forward defines the forward direction - Must be normalized and orthogonal to up.\r\n * @param up defines the up vector for the entity - Must be normalized and orthogonal to forward.\r\n * @returns the new matrix\r\n */\r\n public static LookDirectionRH(forward: DeepImmutable, up: DeepImmutable): Matrix {\r\n const result = new Matrix();\r\n Matrix.LookDirectionRHToRef(forward, up, result);\r\n return result;\r\n }\r\n\r\n /**\r\n * Sets the given \"result\" Matrix to a matrix that transforms vertices from world space to camera space. It takes two vectors as arguments that together describe the orientation of the camera. The position is assumed to be at the origin (0,0,0)\r\n * This function generates a matrix suitable for a right handed coordinate system\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#69\r\n * @param forward defines the forward direction - Must be normalized and orthogonal to up.\r\n * @param up defines the up vector for the entity - Must be normalized and orthogonal to forward.\r\n * @param result defines the target matrix\r\n * @returns result input\r\n */\r\n public static LookDirectionRHToRef(forward: DeepImmutable, up: DeepImmutable, result: T): T {\r\n const right = MathTmp.Vector3[2];\r\n Vector3.CrossToRef(up, forward, right);\r\n\r\n // Generate the rotation matrix.\r\n Matrix.FromValuesToRef(right._x, right._y, right._z, 0.0, up._x, up._y, up._z, 0.0, forward._x, forward._y, forward._z, 0.0, 0, 0, 0, 1.0, result);\r\n return result;\r\n }\r\n\r\n /**\r\n * Create a left-handed orthographic projection matrix\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#70\r\n * @param width defines the viewport width\r\n * @param height defines the viewport height\r\n * @param znear defines the near clip plane\r\n * @param zfar defines the far clip plane\r\n * @param halfZRange true to generate NDC coordinates between 0 and 1 instead of -1 and 1 (default: false)\r\n * @returns a new matrix as a left-handed orthographic projection matrix\r\n */\r\n public static OrthoLH(width: number, height: number, znear: number, zfar: number, halfZRange?: boolean): Matrix {\r\n const matrix = new Matrix();\r\n Matrix.OrthoLHToRef(width, height, znear, zfar, matrix, halfZRange);\r\n return matrix;\r\n }\r\n\r\n /**\r\n * Store a left-handed orthographic projection to a given matrix\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#71\r\n * @param width defines the viewport width\r\n * @param height defines the viewport height\r\n * @param znear defines the near clip plane\r\n * @param zfar defines the far clip plane\r\n * @param result defines the target matrix\r\n * @param halfZRange true to generate NDC coordinates between 0 and 1 instead of -1 and 1 (default: false)\r\n * @returns result input\r\n */\r\n public static OrthoLHToRef(width: number, height: number, znear: number, zfar: number, result: T, halfZRange?: boolean): T {\r\n const n = znear;\r\n const f = zfar;\r\n\r\n const a = 2.0 / width;\r\n const b = 2.0 / height;\r\n const c = 2.0 / (f - n);\r\n const d = -(f + n) / (f - n);\r\n\r\n Matrix.FromValuesToRef(a, 0.0, 0.0, 0.0, 0.0, b, 0.0, 0.0, 0.0, 0.0, c, 0.0, 0.0, 0.0, d, 1.0, result);\r\n\r\n if (halfZRange) {\r\n result.multiplyToRef(mtxConvertNDCToHalfZRange, result);\r\n }\r\n\r\n result._updateIdentityStatus(a === 1 && b === 1 && c === 1 && d === 0);\r\n return result;\r\n }\r\n\r\n /**\r\n * Create a left-handed orthographic projection matrix\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#72\r\n * @param left defines the viewport left coordinate\r\n * @param right defines the viewport right coordinate\r\n * @param bottom defines the viewport bottom coordinate\r\n * @param top defines the viewport top coordinate\r\n * @param znear defines the near clip plane\r\n * @param zfar defines the far clip plane\r\n * @param halfZRange true to generate NDC coordinates between 0 and 1 instead of -1 and 1 (default: false)\r\n * @returns a new matrix as a left-handed orthographic projection matrix\r\n */\r\n public static OrthoOffCenterLH(left: number, right: number, bottom: number, top: number, znear: number, zfar: number, halfZRange?: boolean): Matrix {\r\n const matrix = new Matrix();\r\n Matrix.OrthoOffCenterLHToRef(left, right, bottom, top, znear, zfar, matrix, halfZRange);\r\n return matrix;\r\n }\r\n\r\n /**\r\n * Stores a left-handed orthographic projection into a given matrix\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#73\r\n * @param left defines the viewport left coordinate\r\n * @param right defines the viewport right coordinate\r\n * @param bottom defines the viewport bottom coordinate\r\n * @param top defines the viewport top coordinate\r\n * @param znear defines the near clip plane\r\n * @param zfar defines the far clip plane\r\n * @param result defines the target matrix\r\n * @param halfZRange true to generate NDC coordinates between 0 and 1 instead of -1 and 1 (default: false)\r\n * @returns result input\r\n */\r\n public static OrthoOffCenterLHToRef(\r\n left: number,\r\n right: number,\r\n bottom: number,\r\n top: number,\r\n znear: number,\r\n zfar: number,\r\n result: T,\r\n halfZRange?: boolean\r\n ): T {\r\n const n = znear;\r\n const f = zfar;\r\n\r\n const a = 2.0 / (right - left);\r\n const b = 2.0 / (top - bottom);\r\n const c = 2.0 / (f - n);\r\n const d = -(f + n) / (f - n);\r\n const i0 = (left + right) / (left - right);\r\n const i1 = (top + bottom) / (bottom - top);\r\n\r\n Matrix.FromValuesToRef(a, 0.0, 0.0, 0.0, 0.0, b, 0.0, 0.0, 0.0, 0.0, c, 0.0, i0, i1, d, 1.0, result);\r\n\r\n if (halfZRange) {\r\n result.multiplyToRef(mtxConvertNDCToHalfZRange, result);\r\n }\r\n\r\n result.markAsUpdated();\r\n return result;\r\n }\r\n\r\n /**\r\n * Stores a left-handed oblique projection into a given matrix\r\n * @param left defines the viewport left coordinate\r\n * @param right defines the viewport right coordinate\r\n * @param bottom defines the viewport bottom coordinate\r\n * @param top defines the viewport top coordinate\r\n * @param znear defines the near clip plane\r\n * @param zfar defines the far clip plane\r\n * @param length Length of the shear\r\n * @param angle Angle (along X/Y Plane) to apply shear\r\n * @param distance Distance from shear point\r\n * @param result defines the target matrix\r\n * @param halfZRange true to generate NDC coordinates between 0 and 1 instead of -1 and 1 (default: false)\r\n * @returns result input\r\n */\r\n public static ObliqueOffCenterLHToRef(\r\n left: number,\r\n right: number,\r\n bottom: number,\r\n top: number,\r\n znear: number,\r\n zfar: number,\r\n length: number,\r\n angle: number,\r\n distance: number,\r\n result: T,\r\n halfZRange?: boolean\r\n ): T {\r\n const a = -length * Math.cos(angle);\r\n const b = -length * Math.sin(angle);\r\n\r\n Matrix.TranslationToRef(0, 0, -distance, MathTmp.Matrix[1]);\r\n Matrix.FromValuesToRef(1, 0, 0, 0, 0, 1, 0, 0, a, b, 1, 0, 0, 0, 0, 1, MathTmp.Matrix[0]);\r\n MathTmp.Matrix[1].multiplyToRef(MathTmp.Matrix[0], MathTmp.Matrix[0]);\r\n Matrix.TranslationToRef(0, 0, distance, MathTmp.Matrix[1]);\r\n MathTmp.Matrix[0].multiplyToRef(MathTmp.Matrix[1], MathTmp.Matrix[0]);\r\n\r\n Matrix.OrthoOffCenterLHToRef(left, right, bottom, top, znear, zfar, result, halfZRange);\r\n MathTmp.Matrix[0].multiplyToRef(result, result);\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Creates a right-handed orthographic projection matrix\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#76\r\n * @param left defines the viewport left coordinate\r\n * @param right defines the viewport right coordinate\r\n * @param bottom defines the viewport bottom coordinate\r\n * @param top defines the viewport top coordinate\r\n * @param znear defines the near clip plane\r\n * @param zfar defines the far clip plane\r\n * @param halfZRange true to generate NDC coordinates between 0 and 1 instead of -1 and 1 (default: false)\r\n * @returns a new matrix as a right-handed orthographic projection matrix\r\n */\r\n public static OrthoOffCenterRH(left: number, right: number, bottom: number, top: number, znear: number, zfar: number, halfZRange?: boolean): Matrix {\r\n const matrix = new Matrix();\r\n Matrix.OrthoOffCenterRHToRef(left, right, bottom, top, znear, zfar, matrix, halfZRange);\r\n return matrix;\r\n }\r\n\r\n /**\r\n * Stores a right-handed orthographic projection into a given matrix\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#77\r\n * @param left defines the viewport left coordinate\r\n * @param right defines the viewport right coordinate\r\n * @param bottom defines the viewport bottom coordinate\r\n * @param top defines the viewport top coordinate\r\n * @param znear defines the near clip plane\r\n * @param zfar defines the far clip plane\r\n * @param result defines the target matrix\r\n * @param halfZRange true to generate NDC coordinates between 0 and 1 instead of -1 and 1 (default: false)\r\n * @returns result input\r\n */\r\n public static OrthoOffCenterRHToRef(\r\n left: number,\r\n right: number,\r\n bottom: number,\r\n top: number,\r\n znear: number,\r\n zfar: number,\r\n result: T,\r\n halfZRange?: boolean\r\n ): T {\r\n Matrix.OrthoOffCenterLHToRef(left, right, bottom, top, znear, zfar, result, halfZRange);\r\n result._m[10] *= -1; // No need to call markAsUpdated as previous function already called it and let _isIdentityDirty to true\r\n return result;\r\n }\r\n\r\n /**\r\n * Stores a right-handed oblique projection into a given matrix\r\n * @param left defines the viewport left coordinate\r\n * @param right defines the viewport right coordinate\r\n * @param bottom defines the viewport bottom coordinate\r\n * @param top defines the viewport top coordinate\r\n * @param znear defines the near clip plane\r\n * @param zfar defines the far clip plane\r\n * @param length Length of the shear\r\n * @param angle Angle (along X/Y Plane) to apply shear\r\n * @param distance Distance from shear point\r\n * @param result defines the target matrix\r\n * @param halfZRange true to generate NDC coordinates between 0 and 1 instead of -1 and 1 (default: false)\r\n * @returns result input\r\n */\r\n public static ObliqueOffCenterRHToRef(\r\n left: number,\r\n right: number,\r\n bottom: number,\r\n top: number,\r\n znear: number,\r\n zfar: number,\r\n length: number,\r\n angle: number,\r\n distance: number,\r\n result: T,\r\n halfZRange?: boolean\r\n ): T {\r\n const a = length * Math.cos(angle);\r\n const b = length * Math.sin(angle);\r\n\r\n Matrix.TranslationToRef(0, 0, distance, MathTmp.Matrix[1]);\r\n Matrix.FromValuesToRef(1, 0, 0, 0, 0, 1, 0, 0, a, b, 1, 0, 0, 0, 0, 1, MathTmp.Matrix[0]);\r\n MathTmp.Matrix[1].multiplyToRef(MathTmp.Matrix[0], MathTmp.Matrix[0]);\r\n Matrix.TranslationToRef(0, 0, -distance, MathTmp.Matrix[1]);\r\n MathTmp.Matrix[0].multiplyToRef(MathTmp.Matrix[1], MathTmp.Matrix[0]);\r\n\r\n Matrix.OrthoOffCenterRHToRef(left, right, bottom, top, znear, zfar, result, halfZRange);\r\n MathTmp.Matrix[0].multiplyToRef(result, result);\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Creates a left-handed perspective projection matrix\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#85\r\n * @param width defines the viewport width\r\n * @param height defines the viewport height\r\n * @param znear defines the near clip plane\r\n * @param zfar defines the far clip plane\r\n * @param halfZRange true to generate NDC coordinates between 0 and 1 instead of -1 and 1 (default: false)\r\n * @param projectionPlaneTilt optional tilt angle of the projection plane around the X axis (horizontal)\r\n * @returns a new matrix as a left-handed perspective projection matrix\r\n */\r\n public static PerspectiveLH(width: number, height: number, znear: number, zfar: number, halfZRange?: boolean, projectionPlaneTilt: number = 0): Matrix {\r\n const matrix = new Matrix();\r\n\r\n const n = znear;\r\n const f = zfar;\r\n\r\n const a = (2.0 * n) / width;\r\n const b = (2.0 * n) / height;\r\n const c = (f + n) / (f - n);\r\n const d = (-2.0 * f * n) / (f - n);\r\n const rot = Math.tan(projectionPlaneTilt);\r\n\r\n Matrix.FromValuesToRef(a, 0.0, 0.0, 0.0, 0.0, b, 0.0, rot, 0.0, 0.0, c, 1.0, 0.0, 0.0, d, 0.0, matrix);\r\n\r\n if (halfZRange) {\r\n matrix.multiplyToRef(mtxConvertNDCToHalfZRange, matrix);\r\n }\r\n\r\n matrix._updateIdentityStatus(false);\r\n return matrix;\r\n }\r\n\r\n /**\r\n * Creates a left-handed perspective projection matrix\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#78\r\n * @param fov defines the horizontal field of view\r\n * @param aspect defines the aspect ratio\r\n * @param znear defines the near clip plane\r\n * @param zfar defines the far clip plane. If 0, assume we are in \"infinite zfar\" mode\r\n * @param halfZRange true to generate NDC coordinates between 0 and 1 instead of -1 and 1 (default: false)\r\n * @param projectionPlaneTilt optional tilt angle of the projection plane around the X axis (horizontal)\r\n * @param reverseDepthBufferMode true to indicate that we are in a reverse depth buffer mode (meaning znear and zfar have been inverted when calling the function)\r\n * @returns a new matrix as a left-handed perspective projection matrix\r\n */\r\n public static PerspectiveFovLH(\r\n fov: number,\r\n aspect: number,\r\n znear: number,\r\n zfar: number,\r\n halfZRange?: boolean,\r\n projectionPlaneTilt: number = 0,\r\n reverseDepthBufferMode: boolean = false\r\n ): Matrix {\r\n const matrix = new Matrix();\r\n Matrix.PerspectiveFovLHToRef(fov, aspect, znear, zfar, matrix, true, halfZRange, projectionPlaneTilt, reverseDepthBufferMode);\r\n return matrix;\r\n }\r\n\r\n /**\r\n * Stores a left-handed perspective projection into a given matrix\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#81\r\n * @param fov defines the horizontal field of view\r\n * @param aspect defines the aspect ratio\r\n * @param znear defines the near clip plane\r\n * @param zfar defines the far clip plane. If 0, assume we are in \"infinite zfar\" mode\r\n * @param result defines the target matrix\r\n * @param isVerticalFovFixed defines it the fov is vertically fixed (default) or horizontally\r\n * @param halfZRange true to generate NDC coordinates between 0 and 1 instead of -1 and 1 (default: false)\r\n * @param projectionPlaneTilt optional tilt angle of the projection plane around the X axis (horizontal)\r\n * @param reverseDepthBufferMode true to indicate that we are in a reverse depth buffer mode (meaning znear and zfar have been inverted when calling the function)\r\n * @returns result input\r\n */\r\n public static PerspectiveFovLHToRef(\r\n fov: number,\r\n aspect: number,\r\n znear: number,\r\n zfar: number,\r\n result: T,\r\n isVerticalFovFixed = true,\r\n halfZRange?: boolean,\r\n projectionPlaneTilt: number = 0,\r\n reverseDepthBufferMode: boolean = false\r\n ): T {\r\n const n = znear;\r\n const f = zfar;\r\n\r\n const t = 1.0 / Math.tan(fov * 0.5);\r\n const a = isVerticalFovFixed ? t / aspect : t;\r\n const b = isVerticalFovFixed ? t : t * aspect;\r\n const c = reverseDepthBufferMode && n === 0 ? -1 : f !== 0 ? (f + n) / (f - n) : 1;\r\n const d = reverseDepthBufferMode && n === 0 ? 2 * f : f !== 0 ? (-2.0 * f * n) / (f - n) : -2 * n;\r\n const rot = Math.tan(projectionPlaneTilt);\r\n\r\n Matrix.FromValuesToRef(a, 0.0, 0.0, 0.0, 0.0, b, 0.0, rot, 0.0, 0.0, c, 1.0, 0.0, 0.0, d, 0.0, result);\r\n\r\n if (halfZRange) {\r\n result.multiplyToRef(mtxConvertNDCToHalfZRange, result);\r\n }\r\n\r\n result._updateIdentityStatus(false);\r\n return result;\r\n }\r\n\r\n /**\r\n * Stores a left-handed perspective projection into a given matrix with depth reversed\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#89\r\n * @param fov defines the horizontal field of view\r\n * @param aspect defines the aspect ratio\r\n * @param znear defines the near clip plane\r\n * @param zfar not used as infinity is used as far clip\r\n * @param result defines the target matrix\r\n * @param isVerticalFovFixed defines it the fov is vertically fixed (default) or horizontally\r\n * @param halfZRange true to generate NDC coordinates between 0 and 1 instead of -1 and 1 (default: false)\r\n * @param projectionPlaneTilt optional tilt angle of the projection plane around the X axis (horizontal)\r\n * @returns result input\r\n */\r\n public static PerspectiveFovReverseLHToRef(\r\n fov: number,\r\n aspect: number,\r\n znear: number,\r\n zfar: number,\r\n result: T,\r\n isVerticalFovFixed = true,\r\n halfZRange?: boolean,\r\n projectionPlaneTilt: number = 0\r\n ): T {\r\n const t = 1.0 / Math.tan(fov * 0.5);\r\n const a = isVerticalFovFixed ? t / aspect : t;\r\n const b = isVerticalFovFixed ? t : t * aspect;\r\n const rot = Math.tan(projectionPlaneTilt);\r\n\r\n Matrix.FromValuesToRef(a, 0.0, 0.0, 0.0, 0.0, b, 0.0, rot, 0.0, 0.0, -znear, 1.0, 0.0, 0.0, 1.0, 0.0, result);\r\n if (halfZRange) {\r\n result.multiplyToRef(mtxConvertNDCToHalfZRange, result);\r\n }\r\n result._updateIdentityStatus(false);\r\n return result;\r\n }\r\n\r\n /**\r\n * Creates a right-handed perspective projection matrix\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#83\r\n * @param fov defines the horizontal field of view\r\n * @param aspect defines the aspect ratio\r\n * @param znear defines the near clip plane\r\n * @param zfar defines the far clip plane. If 0, assume we are in \"infinite zfar\" mode\r\n * @param halfZRange true to generate NDC coordinates between 0 and 1 instead of -1 and 1 (default: false)\r\n * @param projectionPlaneTilt optional tilt angle of the projection plane around the X axis (horizontal)\r\n * @param reverseDepthBufferMode true to indicate that we are in a reverse depth buffer mode (meaning znear and zfar have been inverted when calling the function)\r\n * @returns a new matrix as a right-handed perspective projection matrix\r\n */\r\n public static PerspectiveFovRH(\r\n fov: number,\r\n aspect: number,\r\n znear: number,\r\n zfar: number,\r\n halfZRange?: boolean,\r\n projectionPlaneTilt: number = 0,\r\n reverseDepthBufferMode: boolean = false\r\n ): Matrix {\r\n const matrix = new Matrix();\r\n Matrix.PerspectiveFovRHToRef(fov, aspect, znear, zfar, matrix, true, halfZRange, projectionPlaneTilt, reverseDepthBufferMode);\r\n return matrix;\r\n }\r\n\r\n /**\r\n * Stores a right-handed perspective projection into a given matrix\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#84\r\n * @param fov defines the horizontal field of view\r\n * @param aspect defines the aspect ratio\r\n * @param znear defines the near clip plane\r\n * @param zfar defines the far clip plane. If 0, assume we are in \"infinite zfar\" mode\r\n * @param result defines the target matrix\r\n * @param isVerticalFovFixed defines it the fov is vertically fixed (default) or horizontally\r\n * @param halfZRange true to generate NDC coordinates between 0 and 1 instead of -1 and 1 (default: false)\r\n * @param projectionPlaneTilt optional tilt angle of the projection plane around the X axis (horizontal)\r\n * @param reverseDepthBufferMode true to indicate that we are in a reverse depth buffer mode (meaning znear and zfar have been inverted when calling the function)\r\n * @returns result input\r\n */\r\n public static PerspectiveFovRHToRef(\r\n fov: number,\r\n aspect: number,\r\n znear: number,\r\n zfar: number,\r\n result: T,\r\n isVerticalFovFixed = true,\r\n halfZRange?: boolean,\r\n projectionPlaneTilt: number = 0,\r\n reverseDepthBufferMode: boolean = false\r\n ): T {\r\n //alternatively this could be expressed as:\r\n // m = PerspectiveFovLHToRef\r\n // m[10] *= -1.0;\r\n // m[11] *= -1.0;\r\n\r\n const n = znear;\r\n const f = zfar;\r\n\r\n const t = 1.0 / Math.tan(fov * 0.5);\r\n const a = isVerticalFovFixed ? t / aspect : t;\r\n const b = isVerticalFovFixed ? t : t * aspect;\r\n const c = reverseDepthBufferMode && n === 0 ? 1 : f !== 0 ? -(f + n) / (f - n) : -1;\r\n const d = reverseDepthBufferMode && n === 0 ? 2 * f : f !== 0 ? (-2 * f * n) / (f - n) : -2 * n;\r\n const rot = Math.tan(projectionPlaneTilt);\r\n\r\n Matrix.FromValuesToRef(a, 0.0, 0.0, 0.0, 0.0, b, 0.0, rot, 0.0, 0.0, c, -1.0, 0.0, 0.0, d, 0.0, result);\r\n\r\n if (halfZRange) {\r\n result.multiplyToRef(mtxConvertNDCToHalfZRange, result);\r\n }\r\n\r\n result._updateIdentityStatus(false);\r\n return result;\r\n }\r\n\r\n /**\r\n * Stores a right-handed perspective projection into a given matrix\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#90\r\n * @param fov defines the horizontal field of view\r\n * @param aspect defines the aspect ratio\r\n * @param znear defines the near clip plane\r\n * @param zfar not used as infinity is used as far clip\r\n * @param result defines the target matrix\r\n * @param isVerticalFovFixed defines it the fov is vertically fixed (default) or horizontally\r\n * @param halfZRange true to generate NDC coordinates between 0 and 1 instead of -1 and 1 (default: false)\r\n * @param projectionPlaneTilt optional tilt angle of the projection plane around the X axis (horizontal)\r\n * @returns result input\r\n */\r\n public static PerspectiveFovReverseRHToRef(\r\n fov: number,\r\n aspect: number,\r\n znear: number,\r\n zfar: number,\r\n result: T,\r\n isVerticalFovFixed = true,\r\n halfZRange?: boolean,\r\n projectionPlaneTilt: number = 0\r\n ): T {\r\n const t = 1.0 / Math.tan(fov * 0.5);\r\n const a = isVerticalFovFixed ? t / aspect : t;\r\n const b = isVerticalFovFixed ? t : t * aspect;\r\n const rot = Math.tan(projectionPlaneTilt);\r\n\r\n Matrix.FromValuesToRef(a, 0.0, 0.0, 0.0, 0.0, b, 0.0, rot, 0.0, 0.0, -znear, -1.0, 0.0, 0.0, -1.0, 0.0, result);\r\n\r\n if (halfZRange) {\r\n result.multiplyToRef(mtxConvertNDCToHalfZRange, result);\r\n }\r\n\r\n result._updateIdentityStatus(false);\r\n return result;\r\n }\r\n\r\n /**\r\n * Computes a complete transformation matrix\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#113\r\n * @param viewport defines the viewport to use\r\n * @param world defines the world matrix\r\n * @param view defines the view matrix\r\n * @param projection defines the projection matrix\r\n * @param zmin defines the near clip plane\r\n * @param zmax defines the far clip plane\r\n * @returns the transformation matrix\r\n */\r\n public static GetFinalMatrix(\r\n viewport: DeepImmutable,\r\n world: DeepImmutable,\r\n view: DeepImmutable,\r\n projection: DeepImmutable,\r\n zmin: number,\r\n zmax: number\r\n ): Matrix {\r\n const cw = viewport.width;\r\n const ch = viewport.height;\r\n const cx = viewport.x;\r\n const cy = viewport.y;\r\n\r\n const viewportMatrix = Matrix.FromValues(cw / 2.0, 0.0, 0.0, 0.0, 0.0, -ch / 2.0, 0.0, 0.0, 0.0, 0.0, zmax - zmin, 0.0, cx + cw / 2.0, ch / 2.0 + cy, zmin, 1.0);\r\n\r\n const matrix = new Matrix();\r\n world.multiplyToRef(view, matrix);\r\n matrix.multiplyToRef(projection, matrix);\r\n return matrix.multiplyToRef(viewportMatrix, matrix);\r\n }\r\n\r\n /**\r\n * Extracts a 2x2 matrix from a given matrix and store the result in a Float32Array\r\n * @param matrix defines the matrix to use\r\n * @returns a new Float32Array array with 4 elements : the 2x2 matrix extracted from the given matrix\r\n */\r\n public static GetAsMatrix2x2(matrix: DeepImmutable): Float32Array | Array {\r\n const m = matrix.m;\r\n const arr = [m[0], m[1], m[4], m[5]];\r\n return PerformanceConfigurator.MatrixUse64Bits ? arr : new Float32Array(arr);\r\n }\r\n /**\r\n * Extracts a 3x3 matrix from a given matrix and store the result in a Float32Array\r\n * @param matrix defines the matrix to use\r\n * @returns a new Float32Array array with 9 elements : the 3x3 matrix extracted from the given matrix\r\n */\r\n public static GetAsMatrix3x3(matrix: DeepImmutable): Float32Array | Array {\r\n const m = matrix.m;\r\n const arr = [m[0], m[1], m[2], m[4], m[5], m[6], m[8], m[9], m[10]];\r\n return PerformanceConfigurator.MatrixUse64Bits ? arr : new Float32Array(arr);\r\n }\r\n\r\n /**\r\n * Compute the transpose of a given matrix\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#111\r\n * @param matrix defines the matrix to transpose\r\n * @returns the new matrix\r\n */\r\n public static Transpose(matrix: DeepImmutable): Matrix {\r\n const result = new Matrix();\r\n Matrix.TransposeToRef(matrix, result);\r\n return result;\r\n }\r\n\r\n /**\r\n * Compute the transpose of a matrix and store it in a target matrix\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#112\r\n * @param matrix defines the matrix to transpose\r\n * @param result defines the target matrix\r\n * @returns result input\r\n */\r\n public static TransposeToRef(matrix: DeepImmutable, result: T): T {\r\n const mm = matrix.m;\r\n const rm0 = mm[0];\r\n const rm1 = mm[4];\r\n const rm2 = mm[8];\r\n const rm3 = mm[12];\r\n\r\n const rm4 = mm[1];\r\n const rm5 = mm[5];\r\n const rm6 = mm[9];\r\n const rm7 = mm[13];\r\n\r\n const rm8 = mm[2];\r\n const rm9 = mm[6];\r\n const rm10 = mm[10];\r\n const rm11 = mm[14];\r\n\r\n const rm12 = mm[3];\r\n const rm13 = mm[7];\r\n const rm14 = mm[11];\r\n const rm15 = mm[15];\r\n\r\n const rm = result._m;\r\n rm[0] = rm0;\r\n rm[1] = rm1;\r\n rm[2] = rm2;\r\n rm[3] = rm3;\r\n rm[4] = rm4;\r\n rm[5] = rm5;\r\n rm[6] = rm6;\r\n rm[7] = rm7;\r\n rm[8] = rm8;\r\n rm[9] = rm9;\r\n rm[10] = rm10;\r\n rm[11] = rm11;\r\n rm[12] = rm12;\r\n rm[13] = rm13;\r\n rm[14] = rm14;\r\n rm[15] = rm15;\r\n result.markAsUpdated();\r\n\r\n // identity-ness does not change when transposing\r\n result._updateIdentityStatus((matrix as Matrix)._isIdentity, (matrix as Matrix)._isIdentityDirty);\r\n return result;\r\n }\r\n\r\n /**\r\n * Computes a reflection matrix from a plane\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#87\r\n * @param plane defines the reflection plane\r\n * @returns a new matrix\r\n */\r\n public static Reflection(plane: DeepImmutable): Matrix {\r\n const matrix = new Matrix();\r\n Matrix.ReflectionToRef(plane, matrix);\r\n return matrix;\r\n }\r\n\r\n /**\r\n * Computes a reflection matrix from a plane\r\n * Example Playground - https://playground.babylonjs.com/#AV9X17#88\r\n * @param plane defines the reflection plane\r\n * @param result defines the target matrix\r\n * @returns result input\r\n */\r\n public static ReflectionToRef(plane: DeepImmutable, result: T): T {\r\n plane.normalize();\r\n const x = plane.normal.x;\r\n const y = plane.normal.y;\r\n const z = plane.normal.z;\r\n const temp = -2 * x;\r\n const temp2 = -2 * y;\r\n const temp3 = -2 * z;\r\n Matrix.FromValuesToRef(\r\n temp * x + 1,\r\n temp2 * x,\r\n temp3 * x,\r\n 0.0,\r\n temp * y,\r\n temp2 * y + 1,\r\n temp3 * y,\r\n 0.0,\r\n temp * z,\r\n temp2 * z,\r\n temp3 * z + 1,\r\n 0.0,\r\n temp * plane.d,\r\n temp2 * plane.d,\r\n temp3 * plane.d,\r\n 1.0,\r\n result\r\n );\r\n return result;\r\n }\r\n\r\n /**\r\n * Sets the given matrix as a rotation matrix composed from the 3 left handed axes\r\n * @param xaxis defines the value of the 1st axis\r\n * @param yaxis defines the value of the 2nd axis\r\n * @param zaxis defines the value of the 3rd axis\r\n * @param result defines the target matrix\r\n * @returns result input\r\n */\r\n public static FromXYZAxesToRef(xaxis: DeepImmutable, yaxis: DeepImmutable, zaxis: DeepImmutable, result: T): T {\r\n Matrix.FromValuesToRef(xaxis._x, xaxis._y, xaxis._z, 0.0, yaxis._x, yaxis._y, yaxis._z, 0.0, zaxis._x, zaxis._y, zaxis._z, 0.0, 0.0, 0.0, 0.0, 1.0, result);\r\n return result;\r\n }\r\n\r\n /**\r\n * Creates a rotation matrix from a quaternion and stores it in a target matrix\r\n * @param quat defines the quaternion to use\r\n * @param result defines the target matrix\r\n * @returns result input\r\n */\r\n public static FromQuaternionToRef(quat: DeepImmutable, result: T): T {\r\n const xx = quat._x * quat._x;\r\n const yy = quat._y * quat._y;\r\n const zz = quat._z * quat._z;\r\n const xy = quat._x * quat._y;\r\n const zw = quat._z * quat._w;\r\n const zx = quat._z * quat._x;\r\n const yw = quat._y * quat._w;\r\n const yz = quat._y * quat._z;\r\n const xw = quat._x * quat._w;\r\n\r\n result._m[0] = 1.0 - 2.0 * (yy + zz);\r\n result._m[1] = 2.0 * (xy + zw);\r\n result._m[2] = 2.0 * (zx - yw);\r\n result._m[3] = 0.0;\r\n\r\n result._m[4] = 2.0 * (xy - zw);\r\n result._m[5] = 1.0 - 2.0 * (zz + xx);\r\n result._m[6] = 2.0 * (yz + xw);\r\n result._m[7] = 0.0;\r\n\r\n result._m[8] = 2.0 * (zx + yw);\r\n result._m[9] = 2.0 * (yz - xw);\r\n result._m[10] = 1.0 - 2.0 * (yy + xx);\r\n result._m[11] = 0.0;\r\n\r\n result._m[12] = 0.0;\r\n result._m[13] = 0.0;\r\n result._m[14] = 0.0;\r\n result._m[15] = 1.0;\r\n\r\n result.markAsUpdated();\r\n return result;\r\n }\r\n}\r\nObject.defineProperties(Matrix.prototype, {\r\n dimension: { value: [4, 4] },\r\n rank: { value: 2 },\r\n});\r\n\r\n/**\r\n * @internal\r\n * Same as Tmp but not exported to keep it only for math functions to avoid conflicts\r\n */\r\nclass MathTmp {\r\n // Temporary Vector3s\r\n public static Vector3 = BuildTuple(11, Vector3.Zero);\r\n\r\n // Temporary Matricies\r\n public static Matrix = BuildTuple(2, Matrix.Identity);\r\n\r\n // Temporary Quaternions\r\n public static Quaternion = BuildTuple(3, Quaternion.Zero);\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\nexport class TmpVectors {\r\n /** 3 temp Vector2 at once should be enough */\r\n public static Vector2 = BuildTuple(3, Vector2.Zero);\r\n\r\n /** 13 temp Vector3 at once should be enough */\r\n public static Vector3 = BuildTuple(13, Vector3.Zero);\r\n\r\n /** 3 temp Vector4 at once should be enough */\r\n public static Vector4 = BuildTuple(3, Vector4.Zero);\r\n\r\n /** 3 temp Quaternion at once should be enough */\r\n public static Quaternion = BuildTuple(3, Quaternion.Zero);\r\n\r\n /** 8 temp Matrices at once should be enough */\r\n public static Matrix = BuildTuple(8, Matrix.Identity);\r\n}\r\n\r\nRegisterClass(\"BABYLON.Vector2\", Vector2);\r\nRegisterClass(\"BABYLON.Vector3\", Vector3);\r\nRegisterClass(\"BABYLON.Vector4\", Vector4);\r\nRegisterClass(\"BABYLON.Matrix\", Matrix);\r\n\r\nconst mtxConvertNDCToHalfZRange = Matrix.FromValues(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 1);\r\n","import type { DeepImmutable, Nullable } from \"../types\";\r\nimport { Clamp, WithinEpsilon } from \"./math.scalar.functions\";\r\nimport { Vector2, Vector3, Quaternion, Matrix } from \"./math.vector\";\r\nimport type { Vector4 } from \"./math.vector\";\r\nimport { Epsilon } from \"./math.constants\";\r\n\r\n/**\r\n * Defines potential orientation for back face culling\r\n */\r\nexport const enum Orientation {\r\n /**\r\n * Clockwise\r\n */\r\n CW = 0,\r\n /** Counter clockwise */\r\n CCW = 1,\r\n}\r\n\r\n/** Class used to represent a Bezier curve */\r\nexport class BezierCurve {\r\n /**\r\n * Returns the cubic Bezier interpolated value (float) at \"t\" (float) from the given x1, y1, x2, y2 floats\r\n * @param t defines the time\r\n * @param x1 defines the left coordinate on X axis\r\n * @param y1 defines the left coordinate on Y axis\r\n * @param x2 defines the right coordinate on X axis\r\n * @param y2 defines the right coordinate on Y axis\r\n * @returns the interpolated value\r\n */\r\n public static Interpolate(t: number, x1: number, y1: number, x2: number, y2: number): number {\r\n // Extract X (which is equal to time here)\r\n const f0 = 1 - 3 * x2 + 3 * x1;\r\n const f1 = 3 * x2 - 6 * x1;\r\n const f2 = 3 * x1;\r\n\r\n let refinedT = t;\r\n for (let i = 0; i < 5; i++) {\r\n const refinedT2 = refinedT * refinedT;\r\n const refinedT3 = refinedT2 * refinedT;\r\n\r\n const x = f0 * refinedT3 + f1 * refinedT2 + f2 * refinedT;\r\n const slope = 1.0 / (3.0 * f0 * refinedT2 + 2.0 * f1 * refinedT + f2);\r\n refinedT -= (x - t) * slope;\r\n refinedT = Math.min(1, Math.max(0, refinedT));\r\n }\r\n\r\n // Resolve cubic bezier for the given x\r\n return 3 * Math.pow(1 - refinedT, 2) * refinedT * y1 + 3 * (1 - refinedT) * Math.pow(refinedT, 2) * y2 + Math.pow(refinedT, 3);\r\n }\r\n}\r\n\r\n/**\r\n * Defines angle representation\r\n */\r\nexport class Angle {\r\n private _radians: number;\r\n\r\n /**\r\n * Creates an Angle object of \"radians\" radians (float).\r\n * @param radians the angle in radians\r\n */\r\n constructor(radians: number) {\r\n this._radians = radians;\r\n if (this._radians < 0.0) {\r\n this._radians += 2.0 * Math.PI;\r\n }\r\n }\r\n\r\n /**\r\n * Get value in degrees\r\n * @returns the Angle value in degrees (float)\r\n */\r\n public degrees() {\r\n return (this._radians * 180.0) / Math.PI;\r\n }\r\n\r\n /**\r\n * Get value in radians\r\n * @returns the Angle value in radians (float)\r\n */\r\n public radians() {\r\n return this._radians;\r\n }\r\n\r\n /**\r\n * Gets a new Angle object with a value of the angle (in radians) between the line connecting the two points and the x-axis\r\n * @param a defines first point as the origin\r\n * @param b defines point\r\n * @returns a new Angle\r\n */\r\n public static BetweenTwoPoints(a: DeepImmutable, b: DeepImmutable): Angle {\r\n const delta = b.subtract(a);\r\n const theta = Math.atan2(delta.y, delta.x);\r\n return new Angle(theta);\r\n }\r\n\r\n /**\r\n * Gets the angle between the two vectors\r\n * @param a defines first vector\r\n * @param b defines vector\r\n * @returns Returns an new Angle between 0 and PI\r\n */\r\n public static BetweenTwoVectors(a: DeepImmutable, b: DeepImmutable): Angle {\r\n let product = a.lengthSquared() * b.lengthSquared();\r\n if (product === 0) return new Angle(Math.PI / 2);\r\n product = Math.sqrt(product);\r\n let cosVal = a.dot(b as any) / product;\r\n cosVal = Clamp(cosVal, -1, 1);\r\n const angle = Math.acos(cosVal);\r\n return new Angle(angle);\r\n }\r\n\r\n /**\r\n * Gets a new Angle object from the given float in radians\r\n * @param radians defines the angle value in radians\r\n * @returns a new Angle\r\n */\r\n public static FromRadians(radians: number): Angle {\r\n return new Angle(radians);\r\n }\r\n /**\r\n * Gets a new Angle object from the given float in degrees\r\n * @param degrees defines the angle value in degrees\r\n * @returns a new Angle\r\n */\r\n public static FromDegrees(degrees: number): Angle {\r\n return new Angle((degrees * Math.PI) / 180.0);\r\n }\r\n}\r\n\r\n/**\r\n * This represents an arc in a 2d space.\r\n */\r\nexport class Arc2 {\r\n /**\r\n * Defines the center point of the arc.\r\n */\r\n public centerPoint: Vector2;\r\n /**\r\n * Defines the radius of the arc.\r\n */\r\n public radius: number;\r\n /**\r\n * Defines the angle of the arc (from mid point to end point).\r\n */\r\n public angle: Angle;\r\n /**\r\n * Defines the start angle of the arc (from start point to middle point).\r\n */\r\n public startAngle: Angle;\r\n /**\r\n * Defines the orientation of the arc (clock wise/counter clock wise).\r\n */\r\n public orientation: Orientation;\r\n\r\n /**\r\n * Creates an Arc object from the three given points : start, middle and end.\r\n * @param startPoint Defines the start point of the arc\r\n * @param midPoint Defines the middle point of the arc\r\n * @param endPoint Defines the end point of the arc\r\n */\r\n constructor(\r\n /** Defines the start point of the arc */\r\n public startPoint: Vector2,\r\n /** Defines the mid point of the arc */\r\n public midPoint: Vector2,\r\n /** Defines the end point of the arc */\r\n public endPoint: Vector2\r\n ) {\r\n const temp = Math.pow(midPoint.x, 2) + Math.pow(midPoint.y, 2);\r\n const startToMid = (Math.pow(startPoint.x, 2) + Math.pow(startPoint.y, 2) - temp) / 2;\r\n const midToEnd = (temp - Math.pow(endPoint.x, 2) - Math.pow(endPoint.y, 2)) / 2;\r\n const det = (startPoint.x - midPoint.x) * (midPoint.y - endPoint.y) - (midPoint.x - endPoint.x) * (startPoint.y - midPoint.y);\r\n\r\n this.centerPoint = new Vector2(\r\n (startToMid * (midPoint.y - endPoint.y) - midToEnd * (startPoint.y - midPoint.y)) / det,\r\n ((startPoint.x - midPoint.x) * midToEnd - (midPoint.x - endPoint.x) * startToMid) / det\r\n );\r\n\r\n this.radius = this.centerPoint.subtract(this.startPoint).length();\r\n\r\n this.startAngle = Angle.BetweenTwoPoints(this.centerPoint, this.startPoint);\r\n\r\n const a1 = this.startAngle.degrees();\r\n let a2 = Angle.BetweenTwoPoints(this.centerPoint, this.midPoint).degrees();\r\n let a3 = Angle.BetweenTwoPoints(this.centerPoint, this.endPoint).degrees();\r\n\r\n // angles correction\r\n if (a2 - a1 > +180.0) {\r\n a2 -= 360.0;\r\n }\r\n if (a2 - a1 < -180.0) {\r\n a2 += 360.0;\r\n }\r\n if (a3 - a2 > +180.0) {\r\n a3 -= 360.0;\r\n }\r\n if (a3 - a2 < -180.0) {\r\n a3 += 360.0;\r\n }\r\n\r\n this.orientation = a2 - a1 < 0 ? Orientation.CW : Orientation.CCW;\r\n this.angle = Angle.FromDegrees(this.orientation === Orientation.CW ? a1 - a3 : a3 - a1);\r\n }\r\n}\r\n\r\n/**\r\n * Represents a 2D path made up of multiple 2D points\r\n */\r\nexport class Path2 {\r\n private _points = new Array();\r\n private _length = 0.0;\r\n\r\n /**\r\n * If the path start and end point are the same\r\n */\r\n public closed = false;\r\n\r\n /**\r\n * Creates a Path2 object from the starting 2D coordinates x and y.\r\n * @param x the starting points x value\r\n * @param y the starting points y value\r\n */\r\n constructor(x: number, y: number) {\r\n this._points.push(new Vector2(x, y));\r\n }\r\n\r\n /**\r\n * Adds a new segment until the given coordinates (x, y) to the current Path2.\r\n * @param x the added points x value\r\n * @param y the added points y value\r\n * @returns the updated Path2.\r\n */\r\n public addLineTo(x: number, y: number): Path2 {\r\n if (this.closed) {\r\n return this;\r\n }\r\n const newPoint = new Vector2(x, y);\r\n const previousPoint = this._points[this._points.length - 1];\r\n this._points.push(newPoint);\r\n this._length += newPoint.subtract(previousPoint).length();\r\n return this;\r\n }\r\n\r\n /**\r\n * Adds _numberOfSegments_ segments according to the arc definition (middle point coordinates, end point coordinates, the arc start point being the current Path2 last point) to the current Path2.\r\n * @param midX middle point x value\r\n * @param midY middle point y value\r\n * @param endX end point x value\r\n * @param endY end point y value\r\n * @param numberOfSegments (default: 36)\r\n * @returns the updated Path2.\r\n */\r\n public addArcTo(midX: number, midY: number, endX: number, endY: number, numberOfSegments = 36): Path2 {\r\n if (this.closed) {\r\n return this;\r\n }\r\n const startPoint = this._points[this._points.length - 1];\r\n const midPoint = new Vector2(midX, midY);\r\n const endPoint = new Vector2(endX, endY);\r\n\r\n const arc = new Arc2(startPoint, midPoint, endPoint);\r\n\r\n let increment = arc.angle.radians() / numberOfSegments;\r\n if (arc.orientation === Orientation.CW) {\r\n increment *= -1;\r\n }\r\n let currentAngle = arc.startAngle.radians() + increment;\r\n\r\n for (let i = 0; i < numberOfSegments; i++) {\r\n const x = Math.cos(currentAngle) * arc.radius + arc.centerPoint.x;\r\n const y = Math.sin(currentAngle) * arc.radius + arc.centerPoint.y;\r\n this.addLineTo(x, y);\r\n currentAngle += increment;\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Adds _numberOfSegments_ segments according to the quadratic curve definition to the current Path2.\r\n * @param controlX control point x value\r\n * @param controlY control point y value\r\n * @param endX end point x value\r\n * @param endY end point y value\r\n * @param numberOfSegments (default: 36)\r\n * @returns the updated Path2.\r\n */\r\n public addQuadraticCurveTo(controlX: number, controlY: number, endX: number, endY: number, numberOfSegments = 36): Path2 {\r\n if (this.closed) {\r\n return this;\r\n }\r\n\r\n const equation = (t: number, val0: number, val1: number, val2: number) => {\r\n const res = (1.0 - t) * (1.0 - t) * val0 + 2.0 * t * (1.0 - t) * val1 + t * t * val2;\r\n return res;\r\n };\r\n const startPoint = this._points[this._points.length - 1];\r\n for (let i = 0; i <= numberOfSegments; i++) {\r\n const step = i / numberOfSegments;\r\n const x = equation(step, startPoint.x, controlX, endX);\r\n const y = equation(step, startPoint.y, controlY, endY);\r\n this.addLineTo(x, y);\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Adds _numberOfSegments_ segments according to the bezier curve definition to the current Path2.\r\n * @param originTangentX tangent vector at the origin point x value\r\n * @param originTangentY tangent vector at the origin point y value\r\n * @param destinationTangentX tangent vector at the destination point x value\r\n * @param destinationTangentY tangent vector at the destination point y value\r\n * @param endX end point x value\r\n * @param endY end point y value\r\n * @param numberOfSegments (default: 36)\r\n * @returns the updated Path2.\r\n */\r\n public addBezierCurveTo(\r\n originTangentX: number,\r\n originTangentY: number,\r\n destinationTangentX: number,\r\n destinationTangentY: number,\r\n endX: number,\r\n endY: number,\r\n numberOfSegments = 36\r\n ): Path2 {\r\n if (this.closed) {\r\n return this;\r\n }\r\n\r\n const equation = (t: number, val0: number, val1: number, val2: number, val3: number) => {\r\n const res = (1.0 - t) * (1.0 - t) * (1.0 - t) * val0 + 3.0 * t * (1.0 - t) * (1.0 - t) * val1 + 3.0 * t * t * (1.0 - t) * val2 + t * t * t * val3;\r\n return res;\r\n };\r\n const startPoint = this._points[this._points.length - 1];\r\n for (let i = 0; i <= numberOfSegments; i++) {\r\n const step = i / numberOfSegments;\r\n const x = equation(step, startPoint.x, originTangentX, destinationTangentX, endX);\r\n const y = equation(step, startPoint.y, originTangentY, destinationTangentY, endY);\r\n this.addLineTo(x, y);\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Defines if a given point is inside the polygon defines by the path\r\n * @param point defines the point to test\r\n * @returns true if the point is inside\r\n */\r\n public isPointInside(point: Vector2) {\r\n let isInside = false;\r\n const count = this._points.length;\r\n for (let p = count - 1, q = 0; q < count; p = q++) {\r\n let edgeLow = this._points[p];\r\n let edgeHigh = this._points[q];\r\n\r\n let edgeDx = edgeHigh.x - edgeLow.x;\r\n let edgeDy = edgeHigh.y - edgeLow.y;\r\n\r\n if (Math.abs(edgeDy) > Number.EPSILON) {\r\n // Not parallel\r\n if (edgeDy < 0) {\r\n edgeLow = this._points[q];\r\n edgeDx = -edgeDx;\r\n edgeHigh = this._points[p];\r\n edgeDy = -edgeDy;\r\n }\r\n\r\n if (point.y < edgeLow.y || point.y > edgeHigh.y) {\r\n continue;\r\n }\r\n\r\n if (point.y === edgeLow.y && point.x === edgeLow.x) {\r\n return true;\r\n } else {\r\n const perpEdge = edgeDy * (point.x - edgeLow.x) - edgeDx * (point.y - edgeLow.y);\r\n if (perpEdge === 0) {\r\n return true;\r\n }\r\n if (perpEdge < 0) {\r\n continue;\r\n }\r\n isInside = !isInside;\r\n }\r\n } else {\r\n // parallel or collinear\r\n if (point.y !== edgeLow.y) {\r\n continue;\r\n }\r\n\r\n if ((edgeHigh.x <= point.x && point.x <= edgeLow.x) || (edgeLow.x <= point.x && point.x <= edgeHigh.x)) {\r\n return true;\r\n }\r\n }\r\n }\r\n\r\n return isInside;\r\n }\r\n\r\n /**\r\n * Closes the Path2.\r\n * @returns the Path2.\r\n */\r\n public close(): Path2 {\r\n this.closed = true;\r\n return this;\r\n }\r\n /**\r\n * Gets the sum of the distance between each sequential point in the path\r\n * @returns the Path2 total length (float).\r\n */\r\n public length(): number {\r\n let result = this._length;\r\n\r\n if (this.closed) {\r\n const lastPoint = this._points[this._points.length - 1];\r\n const firstPoint = this._points[0];\r\n result += firstPoint.subtract(lastPoint).length();\r\n }\r\n return result;\r\n }\r\n\r\n /**\r\n * Gets the area of the polygon defined by the path\r\n * @returns area value\r\n */\r\n public area(): number {\r\n const n = this._points.length;\r\n let value = 0.0;\r\n\r\n for (let p = n - 1, q = 0; q < n; p = q++) {\r\n value += this._points[p].x * this._points[q].y - this._points[q].x * this._points[p].y;\r\n }\r\n\r\n return value * 0.5;\r\n }\r\n\r\n /**\r\n * Gets the points which construct the path\r\n * @returns the Path2 internal array of points.\r\n */\r\n public getPoints(): Vector2[] {\r\n return this._points;\r\n }\r\n\r\n /**\r\n * Retrieves the point at the distance aways from the starting point\r\n * @param normalizedLengthPosition the length along the path to retrieve the point from\r\n * @returns a new Vector2 located at a percentage of the Path2 total length on this path.\r\n */\r\n public getPointAtLengthPosition(normalizedLengthPosition: number): Vector2 {\r\n if (normalizedLengthPosition < 0 || normalizedLengthPosition > 1) {\r\n return Vector2.Zero();\r\n }\r\n\r\n const lengthPosition = normalizedLengthPosition * this.length();\r\n\r\n let previousOffset = 0;\r\n for (let i = 0; i < this._points.length; i++) {\r\n const j = (i + 1) % this._points.length;\r\n\r\n const a = this._points[i];\r\n const b = this._points[j];\r\n const bToA = b.subtract(a);\r\n\r\n const nextOffset = bToA.length() + previousOffset;\r\n if (lengthPosition >= previousOffset && lengthPosition <= nextOffset) {\r\n const dir = bToA.normalize();\r\n const localOffset = lengthPosition - previousOffset;\r\n\r\n return new Vector2(a.x + dir.x * localOffset, a.y + dir.y * localOffset);\r\n }\r\n previousOffset = nextOffset;\r\n }\r\n\r\n return Vector2.Zero();\r\n }\r\n\r\n /**\r\n * Creates a new path starting from an x and y position\r\n * @param x starting x value\r\n * @param y starting y value\r\n * @returns a new Path2 starting at the coordinates (x, y).\r\n */\r\n public static StartingAt(x: number, y: number): Path2 {\r\n return new Path2(x, y);\r\n }\r\n}\r\n\r\n/**\r\n * Represents a 3D path made up of multiple 3D points\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/path3D\r\n */\r\nexport class Path3D {\r\n private _curve = new Array();\r\n private _distances = new Array();\r\n private _tangents = new Array();\r\n private _normals = new Array();\r\n private _binormals = new Array();\r\n private _raw: boolean;\r\n private _alignTangentsWithPath: boolean;\r\n\r\n // holds interpolated point data\r\n private readonly _pointAtData = {\r\n id: 0,\r\n point: Vector3.Zero(),\r\n previousPointArrayIndex: 0,\r\n\r\n position: 0,\r\n subPosition: 0,\r\n\r\n interpolateReady: false,\r\n interpolationMatrix: Matrix.Identity(),\r\n };\r\n\r\n /**\r\n * new Path3D(path, normal, raw)\r\n * Creates a Path3D. A Path3D is a logical math object, so not a mesh.\r\n * please read the description in the tutorial : https://doc.babylonjs.com/features/featuresDeepDive/mesh/path3D\r\n * @param path an array of Vector3, the curve axis of the Path3D\r\n * @param firstNormal (options) Vector3, the first wanted normal to the curve. Ex (0, 1, 0) for a vertical normal.\r\n * @param raw (optional, default false) : boolean, if true the returned Path3D isn't normalized. Useful to depict path acceleration or speed.\r\n * @param alignTangentsWithPath (optional, default false) : boolean, if true the tangents will be aligned with the path.\r\n */\r\n constructor(\r\n /**\r\n * an array of Vector3, the curve axis of the Path3D\r\n */\r\n public path: Vector3[],\r\n firstNormal: Nullable = null,\r\n raw?: boolean,\r\n alignTangentsWithPath = false\r\n ) {\r\n for (let p = 0; p < path.length; p++) {\r\n this._curve[p] = path[p].clone(); // hard copy\r\n }\r\n this._raw = raw || false;\r\n this._alignTangentsWithPath = alignTangentsWithPath;\r\n this._compute(firstNormal, alignTangentsWithPath);\r\n }\r\n\r\n /**\r\n * Returns the Path3D array of successive Vector3 designing its curve.\r\n * @returns the Path3D array of successive Vector3 designing its curve.\r\n */\r\n public getCurve(): Vector3[] {\r\n return this._curve;\r\n }\r\n\r\n /**\r\n * Returns the Path3D array of successive Vector3 designing its curve.\r\n * @returns the Path3D array of successive Vector3 designing its curve.\r\n */\r\n public getPoints(): Vector3[] {\r\n return this._curve;\r\n }\r\n\r\n /**\r\n * @returns the computed length (float) of the path.\r\n */\r\n public length() {\r\n return this._distances[this._distances.length - 1];\r\n }\r\n\r\n /**\r\n * Returns an array populated with tangent vectors on each Path3D curve point.\r\n * @returns an array populated with tangent vectors on each Path3D curve point.\r\n */\r\n public getTangents(): Vector3[] {\r\n return this._tangents;\r\n }\r\n\r\n /**\r\n * Returns an array populated with normal vectors on each Path3D curve point.\r\n * @returns an array populated with normal vectors on each Path3D curve point.\r\n */\r\n public getNormals(): Vector3[] {\r\n return this._normals;\r\n }\r\n\r\n /**\r\n * Returns an array populated with binormal vectors on each Path3D curve point.\r\n * @returns an array populated with binormal vectors on each Path3D curve point.\r\n */\r\n public getBinormals(): Vector3[] {\r\n return this._binormals;\r\n }\r\n\r\n /**\r\n * Returns an array populated with distances (float) of the i-th point from the first curve point.\r\n * @returns an array populated with distances (float) of the i-th point from the first curve point.\r\n */\r\n public getDistances(): number[] {\r\n return this._distances;\r\n }\r\n\r\n /**\r\n * Returns an interpolated point along this path\r\n * @param position the position of the point along this path, from 0.0 to 1.0\r\n * @returns a new Vector3 as the point\r\n */\r\n public getPointAt(position: number): Vector3 {\r\n return this._updatePointAtData(position).point;\r\n }\r\n\r\n /**\r\n * Returns the tangent vector of an interpolated Path3D curve point at the specified position along this path.\r\n * @param position the position of the point along this path, from 0.0 to 1.0\r\n * @param interpolated (optional, default false) : boolean, if true returns an interpolated tangent instead of the tangent of the previous path point.\r\n * @returns a tangent vector corresponding to the interpolated Path3D curve point, if not interpolated, the tangent is taken from the precomputed tangents array.\r\n */\r\n public getTangentAt(position: number, interpolated = false): Vector3 {\r\n this._updatePointAtData(position, interpolated);\r\n return interpolated ? Vector3.TransformCoordinates(Vector3.Forward(), this._pointAtData.interpolationMatrix) : this._tangents[this._pointAtData.previousPointArrayIndex];\r\n }\r\n\r\n /**\r\n * Returns the tangent vector of an interpolated Path3D curve point at the specified position along this path.\r\n * @param position the position of the point along this path, from 0.0 to 1.0\r\n * @param interpolated (optional, default false) : boolean, if true returns an interpolated normal instead of the normal of the previous path point.\r\n * @returns a normal vector corresponding to the interpolated Path3D curve point, if not interpolated, the normal is taken from the precomputed normals array.\r\n */\r\n public getNormalAt(position: number, interpolated = false): Vector3 {\r\n this._updatePointAtData(position, interpolated);\r\n return interpolated ? Vector3.TransformCoordinates(Vector3.Right(), this._pointAtData.interpolationMatrix) : this._normals[this._pointAtData.previousPointArrayIndex];\r\n }\r\n\r\n /**\r\n * Returns the binormal vector of an interpolated Path3D curve point at the specified position along this path.\r\n * @param position the position of the point along this path, from 0.0 to 1.0\r\n * @param interpolated (optional, default false) : boolean, if true returns an interpolated binormal instead of the binormal of the previous path point.\r\n * @returns a binormal vector corresponding to the interpolated Path3D curve point, if not interpolated, the binormal is taken from the precomputed binormals array.\r\n */\r\n public getBinormalAt(position: number, interpolated = false): Vector3 {\r\n this._updatePointAtData(position, interpolated);\r\n return interpolated ? Vector3.TransformCoordinates(Vector3.UpReadOnly, this._pointAtData.interpolationMatrix) : this._binormals[this._pointAtData.previousPointArrayIndex];\r\n }\r\n\r\n /**\r\n * Returns the distance (float) of an interpolated Path3D curve point at the specified position along this path.\r\n * @param position the position of the point along this path, from 0.0 to 1.0\r\n * @returns the distance of the interpolated Path3D curve point at the specified position along this path.\r\n */\r\n public getDistanceAt(position: number): number {\r\n return this.length() * position;\r\n }\r\n\r\n /**\r\n * Returns the array index of the previous point of an interpolated point along this path\r\n * @param position the position of the point to interpolate along this path, from 0.0 to 1.0\r\n * @returns the array index\r\n */\r\n public getPreviousPointIndexAt(position: number) {\r\n this._updatePointAtData(position);\r\n return this._pointAtData.previousPointArrayIndex;\r\n }\r\n\r\n /**\r\n * Returns the position of an interpolated point relative to the two path points it lies between, from 0.0 (point A) to 1.0 (point B)\r\n * @param position the position of the point to interpolate along this path, from 0.0 to 1.0\r\n * @returns the sub position\r\n */\r\n public getSubPositionAt(position: number) {\r\n this._updatePointAtData(position);\r\n return this._pointAtData.subPosition;\r\n }\r\n\r\n /**\r\n * Returns the position of the closest virtual point on this path to an arbitrary Vector3, from 0.0 to 1.0\r\n * @param target the vector of which to get the closest position to\r\n * @returns the position of the closest virtual point on this path to the target vector\r\n */\r\n public getClosestPositionTo(target: Vector3) {\r\n let smallestDistance = Number.MAX_VALUE;\r\n let closestPosition = 0.0;\r\n for (let i = 0; i < this._curve.length - 1; i++) {\r\n const point = this._curve[i + 0];\r\n const tangent = this._curve[i + 1].subtract(point).normalize();\r\n const subLength = this._distances[i + 1] - this._distances[i + 0];\r\n const subPosition = Math.min((Math.max(Vector3.Dot(tangent, target.subtract(point).normalize()), 0.0) * Vector3.Distance(point, target)) / subLength, 1.0);\r\n const distance = Vector3.Distance(point.add(tangent.scale(subPosition * subLength)), target);\r\n\r\n if (distance < smallestDistance) {\r\n smallestDistance = distance;\r\n closestPosition = (this._distances[i + 0] + subLength * subPosition) / this.length();\r\n }\r\n }\r\n return closestPosition;\r\n }\r\n\r\n /**\r\n * Returns a sub path (slice) of this path\r\n * @param start the position of the fist path point, from 0.0 to 1.0, or a negative value, which will get wrapped around from the end of the path to 0.0 to 1.0 values\r\n * @param end the position of the last path point, from 0.0 to 1.0, or a negative value, which will get wrapped around from the end of the path to 0.0 to 1.0 values\r\n * @returns a sub path (slice) of this path\r\n */\r\n public slice(start: number = 0.0, end: number = 1.0) {\r\n if (start < 0.0) {\r\n start = 1 - ((start * -1.0) % 1.0);\r\n }\r\n if (end < 0.0) {\r\n end = 1 - ((end * -1.0) % 1.0);\r\n }\r\n if (start > end) {\r\n const _start = start;\r\n start = end;\r\n end = _start;\r\n }\r\n const curvePoints = this.getCurve();\r\n\r\n const startPoint = this.getPointAt(start);\r\n let startIndex = this.getPreviousPointIndexAt(start);\r\n\r\n const endPoint = this.getPointAt(end);\r\n const endIndex = this.getPreviousPointIndexAt(end) + 1;\r\n\r\n const slicePoints: Vector3[] = [];\r\n if (start !== 0.0) {\r\n startIndex++;\r\n slicePoints.push(startPoint);\r\n }\r\n\r\n slicePoints.push(...curvePoints.slice(startIndex, endIndex));\r\n if (end !== 1.0 || start === 1.0) {\r\n slicePoints.push(endPoint);\r\n }\r\n return new Path3D(slicePoints, this.getNormalAt(start), this._raw, this._alignTangentsWithPath);\r\n }\r\n\r\n /**\r\n * Forces the Path3D tangent, normal, binormal and distance recomputation.\r\n * @param path path which all values are copied into the curves points\r\n * @param firstNormal which should be projected onto the curve\r\n * @param alignTangentsWithPath (optional, default false) : boolean, if true the tangents will be aligned with the path\r\n * @returns the same object updated.\r\n */\r\n public update(path: Vector3[], firstNormal: Nullable = null, alignTangentsWithPath = false): Path3D {\r\n for (let p = 0; p < path.length; p++) {\r\n this._curve[p].x = path[p].x;\r\n this._curve[p].y = path[p].y;\r\n this._curve[p].z = path[p].z;\r\n }\r\n this._compute(firstNormal, alignTangentsWithPath);\r\n return this;\r\n }\r\n\r\n // private function compute() : computes tangents, normals and binormals\r\n private _compute(firstNormal: Nullable, alignTangentsWithPath = false): void {\r\n const l = this._curve.length;\r\n\r\n if (l < 2) {\r\n return;\r\n }\r\n\r\n // first and last tangents\r\n this._tangents[0] = this._getFirstNonNullVector(0);\r\n if (!this._raw) {\r\n this._tangents[0].normalize();\r\n }\r\n this._tangents[l - 1] = this._curve[l - 1].subtract(this._curve[l - 2]);\r\n if (!this._raw) {\r\n this._tangents[l - 1].normalize();\r\n }\r\n\r\n // normals and binormals at first point : arbitrary vector with _normalVector()\r\n const tg0 = this._tangents[0];\r\n const pp0 = this._normalVector(tg0, firstNormal);\r\n this._normals[0] = pp0;\r\n if (!this._raw) {\r\n this._normals[0].normalize();\r\n }\r\n this._binormals[0] = Vector3.Cross(tg0, this._normals[0]);\r\n if (!this._raw) {\r\n this._binormals[0].normalize();\r\n }\r\n this._distances[0] = 0.0;\r\n\r\n // normals and binormals : next points\r\n let prev: Vector3; // previous vector (segment)\r\n let cur: Vector3; // current vector (segment)\r\n let curTang: Vector3; // current tangent\r\n // previous normal\r\n let prevNor: Vector3; // previous normal\r\n let prevBinor: Vector3; // previous binormal\r\n\r\n for (let i = 1; i < l; i++) {\r\n // tangents\r\n prev = this._getLastNonNullVector(i);\r\n if (i < l - 1) {\r\n cur = this._getFirstNonNullVector(i);\r\n this._tangents[i] = alignTangentsWithPath ? cur : prev.add(cur);\r\n this._tangents[i].normalize();\r\n }\r\n this._distances[i] = this._distances[i - 1] + this._curve[i].subtract(this._curve[i - 1]).length();\r\n\r\n // normals and binormals\r\n // http://www.cs.cmu.edu/afs/andrew/scs/cs/15-462/web/old/asst2camera.html\r\n curTang = this._tangents[i];\r\n prevBinor = this._binormals[i - 1];\r\n this._normals[i] = Vector3.Cross(prevBinor, curTang);\r\n if (!this._raw) {\r\n if (this._normals[i].length() === 0) {\r\n prevNor = this._normals[i - 1];\r\n this._normals[i] = prevNor.clone();\r\n } else {\r\n this._normals[i].normalize();\r\n }\r\n }\r\n this._binormals[i] = Vector3.Cross(curTang, this._normals[i]);\r\n if (!this._raw) {\r\n this._binormals[i].normalize();\r\n }\r\n }\r\n this._pointAtData.id = NaN;\r\n }\r\n\r\n // private function getFirstNonNullVector(index)\r\n // returns the first non null vector from index : curve[index + N].subtract(curve[index])\r\n private _getFirstNonNullVector(index: number): Vector3 {\r\n let i = 1;\r\n let nNVector: Vector3 = this._curve[index + i].subtract(this._curve[index]);\r\n while (nNVector.length() === 0 && index + i + 1 < this._curve.length) {\r\n i++;\r\n nNVector = this._curve[index + i].subtract(this._curve[index]);\r\n }\r\n return nNVector;\r\n }\r\n\r\n // private function getLastNonNullVector(index)\r\n // returns the last non null vector from index : curve[index].subtract(curve[index - N])\r\n private _getLastNonNullVector(index: number): Vector3 {\r\n let i = 1;\r\n let nLVector: Vector3 = this._curve[index].subtract(this._curve[index - i]);\r\n while (nLVector.length() === 0 && index > i + 1) {\r\n i++;\r\n nLVector = this._curve[index].subtract(this._curve[index - i]);\r\n }\r\n return nLVector;\r\n }\r\n\r\n // private function normalVector(v0, vt, va) :\r\n // returns an arbitrary point in the plane defined by the point v0 and the vector vt orthogonal to this plane\r\n // if va is passed, it returns the va projection on the plane orthogonal to vt at the point v0\r\n private _normalVector(vt: Vector3, va: Nullable): Vector3 {\r\n let normal0: Vector3;\r\n let tgl = vt.length();\r\n if (tgl === 0.0) {\r\n tgl = 1.0;\r\n }\r\n\r\n if (va === undefined || va === null) {\r\n let point: Vector3;\r\n if (!WithinEpsilon(Math.abs(vt.y) / tgl, 1.0, Epsilon)) {\r\n // search for a point in the plane\r\n point = new Vector3(0.0, -1.0, 0.0);\r\n } else if (!WithinEpsilon(Math.abs(vt.x) / tgl, 1.0, Epsilon)) {\r\n point = new Vector3(1.0, 0.0, 0.0);\r\n } else if (!WithinEpsilon(Math.abs(vt.z) / tgl, 1.0, Epsilon)) {\r\n point = new Vector3(0.0, 0.0, 1.0);\r\n } else {\r\n point = Vector3.Zero();\r\n }\r\n normal0 = Vector3.Cross(vt, point);\r\n } else {\r\n normal0 = Vector3.Cross(vt, va);\r\n Vector3.CrossToRef(normal0, vt, normal0);\r\n }\r\n normal0.normalize();\r\n return normal0;\r\n }\r\n\r\n /**\r\n * Updates the point at data for an interpolated point along this curve\r\n * @param position the position of the point along this curve, from 0.0 to 1.0\r\n * @param interpolateTNB\r\n * @interpolateTNB whether to compute the interpolated tangent, normal and binormal\r\n * @returns the (updated) point at data\r\n */\r\n private _updatePointAtData(position: number, interpolateTNB: boolean = false) {\r\n // set an id for caching the result\r\n if (this._pointAtData.id === position) {\r\n if (!this._pointAtData.interpolateReady) {\r\n this._updateInterpolationMatrix();\r\n }\r\n return this._pointAtData;\r\n } else {\r\n this._pointAtData.id = position;\r\n }\r\n const curvePoints = this.getPoints();\r\n\r\n // clamp position between 0.0 and 1.0\r\n if (position <= 0.0) {\r\n return this._setPointAtData(0.0, 0.0, curvePoints[0], 0, interpolateTNB);\r\n } else if (position >= 1.0) {\r\n return this._setPointAtData(1.0, 1.0, curvePoints[curvePoints.length - 1], curvePoints.length - 1, interpolateTNB);\r\n }\r\n\r\n let previousPoint: Vector3 = curvePoints[0];\r\n let currentPoint: Vector3;\r\n let currentLength = 0.0;\r\n const targetLength = position * this.length();\r\n\r\n for (let i = 1; i < curvePoints.length; i++) {\r\n currentPoint = curvePoints[i];\r\n const distance = Vector3.Distance(previousPoint, currentPoint);\r\n currentLength += distance;\r\n if (currentLength === targetLength) {\r\n return this._setPointAtData(position, 1.0, currentPoint, i, interpolateTNB);\r\n } else if (currentLength > targetLength) {\r\n const toLength = currentLength - targetLength;\r\n const diff = toLength / distance;\r\n const dir = previousPoint.subtract(currentPoint);\r\n const point = currentPoint.add(dir.scaleInPlace(diff));\r\n return this._setPointAtData(position, 1 - diff, point, i - 1, interpolateTNB);\r\n }\r\n previousPoint = currentPoint;\r\n }\r\n return this._pointAtData;\r\n }\r\n\r\n /**\r\n * Updates the point at data from the specified parameters\r\n * @param position where along the path the interpolated point is, from 0.0 to 1.0\r\n * @param subPosition\r\n * @param point the interpolated point\r\n * @param parentIndex the index of an existing curve point that is on, or else positionally the first behind, the interpolated point\r\n * @param interpolateTNB whether to compute the interpolated tangent, normal and binormal\r\n * @returns the (updated) point at data\r\n */\r\n private _setPointAtData(position: number, subPosition: number, point: Vector3, parentIndex: number, interpolateTNB: boolean) {\r\n this._pointAtData.point = point;\r\n this._pointAtData.position = position;\r\n this._pointAtData.subPosition = subPosition;\r\n this._pointAtData.previousPointArrayIndex = parentIndex;\r\n this._pointAtData.interpolateReady = interpolateTNB;\r\n\r\n if (interpolateTNB) {\r\n this._updateInterpolationMatrix();\r\n }\r\n return this._pointAtData;\r\n }\r\n\r\n /**\r\n * Updates the point at interpolation matrix for the tangents, normals and binormals\r\n */\r\n private _updateInterpolationMatrix() {\r\n this._pointAtData.interpolationMatrix = Matrix.Identity();\r\n const parentIndex = this._pointAtData.previousPointArrayIndex;\r\n\r\n if (parentIndex !== this._tangents.length - 1) {\r\n const index = parentIndex + 1;\r\n\r\n const tangentFrom = this._tangents[parentIndex].clone();\r\n const normalFrom = this._normals[parentIndex].clone();\r\n const binormalFrom = this._binormals[parentIndex].clone();\r\n\r\n const tangentTo = this._tangents[index].clone();\r\n const normalTo = this._normals[index].clone();\r\n const binormalTo = this._binormals[index].clone();\r\n\r\n const quatFrom = Quaternion.RotationQuaternionFromAxis(normalFrom, binormalFrom, tangentFrom);\r\n const quatTo = Quaternion.RotationQuaternionFromAxis(normalTo, binormalTo, tangentTo);\r\n const quatAt = Quaternion.Slerp(quatFrom, quatTo, this._pointAtData.subPosition);\r\n\r\n quatAt.toRotationMatrix(this._pointAtData.interpolationMatrix);\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * A Curve3 object is a logical object, so not a mesh, to handle curves in the 3D geometric space.\r\n * A Curve3 is designed from a series of successive Vector3.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/drawCurves\r\n */\r\nexport class Curve3 {\r\n private _points: Vector3[];\r\n private _length: number = 0.0;\r\n\r\n /**\r\n * Returns a Curve3 object along a Quadratic Bezier curve : https://doc.babylonjs.com/features/featuresDeepDive/mesh/drawCurves#quadratic-bezier-curve\r\n * @param v0 (Vector3) the origin point of the Quadratic Bezier\r\n * @param v1 (Vector3) the control point\r\n * @param v2 (Vector3) the end point of the Quadratic Bezier\r\n * @param nbPoints (integer) the wanted number of points in the curve\r\n * @returns the created Curve3\r\n */\r\n public static CreateQuadraticBezier(v0: DeepImmutable, v1: DeepImmutable, v2: DeepImmutable, nbPoints: number): Curve3 {\r\n nbPoints = nbPoints > 2 ? nbPoints : 3;\r\n const bez: Vector3[] = [];\r\n const equation = (t: number, val0: number, val1: number, val2: number) => {\r\n const res = (1.0 - t) * (1.0 - t) * val0 + 2.0 * t * (1.0 - t) * val1 + t * t * val2;\r\n return res;\r\n };\r\n for (let i = 0; i <= nbPoints; i++) {\r\n bez.push(new Vector3(equation(i / nbPoints, v0.x, v1.x, v2.x), equation(i / nbPoints, v0.y, v1.y, v2.y), equation(i / nbPoints, v0.z, v1.z, v2.z)));\r\n }\r\n return new Curve3(bez);\r\n }\r\n\r\n /**\r\n * Returns a Curve3 object along a Cubic Bezier curve : https://doc.babylonjs.com/features/featuresDeepDive/mesh/drawCurves#cubic-bezier-curve\r\n * @param v0 (Vector3) the origin point of the Cubic Bezier\r\n * @param v1 (Vector3) the first control point\r\n * @param v2 (Vector3) the second control point\r\n * @param v3 (Vector3) the end point of the Cubic Bezier\r\n * @param nbPoints (integer) the wanted number of points in the curve\r\n * @returns the created Curve3\r\n */\r\n public static CreateCubicBezier(v0: DeepImmutable, v1: DeepImmutable, v2: DeepImmutable, v3: DeepImmutable, nbPoints: number): Curve3 {\r\n nbPoints = nbPoints > 3 ? nbPoints : 4;\r\n const bez: Vector3[] = [];\r\n const equation = (t: number, val0: number, val1: number, val2: number, val3: number) => {\r\n const res = (1.0 - t) * (1.0 - t) * (1.0 - t) * val0 + 3.0 * t * (1.0 - t) * (1.0 - t) * val1 + 3.0 * t * t * (1.0 - t) * val2 + t * t * t * val3;\r\n return res;\r\n };\r\n for (let i = 0; i <= nbPoints; i++) {\r\n bez.push(new Vector3(equation(i / nbPoints, v0.x, v1.x, v2.x, v3.x), equation(i / nbPoints, v0.y, v1.y, v2.y, v3.y), equation(i / nbPoints, v0.z, v1.z, v2.z, v3.z)));\r\n }\r\n return new Curve3(bez);\r\n }\r\n\r\n /**\r\n * Returns a Curve3 object along a Hermite Spline curve : https://doc.babylonjs.com/features/featuresDeepDive/mesh/drawCurves#hermite-spline\r\n * @param p1 (Vector3) the origin point of the Hermite Spline\r\n * @param t1 (Vector3) the tangent vector at the origin point\r\n * @param p2 (Vector3) the end point of the Hermite Spline\r\n * @param t2 (Vector3) the tangent vector at the end point\r\n * @param nSeg (integer) the number of curve segments or nSeg + 1 points in the array\r\n * @returns the created Curve3\r\n */\r\n public static CreateHermiteSpline(p1: DeepImmutable, t1: DeepImmutable, p2: DeepImmutable, t2: DeepImmutable, nSeg: number): Curve3 {\r\n const hermite: Vector3[] = [];\r\n const step = 1.0 / nSeg;\r\n for (let i = 0; i <= nSeg; i++) {\r\n hermite.push(Vector3.Hermite(p1, t1, p2, t2, i * step));\r\n }\r\n return new Curve3(hermite);\r\n }\r\n\r\n /**\r\n * Returns a Curve3 object along a CatmullRom Spline curve :\r\n * @param points (array of Vector3) the points the spline must pass through. At least, four points required\r\n * @param nbPoints (integer) the wanted number of points between each curve control points\r\n * @param closed (boolean) optional with default false, when true forms a closed loop from the points\r\n * @returns the created Curve3\r\n */\r\n public static CreateCatmullRomSpline(points: DeepImmutable, nbPoints: number, closed?: boolean): Curve3 {\r\n const catmullRom: Vector3[] = [];\r\n const step = 1.0 / nbPoints;\r\n let amount = 0.0;\r\n if (closed) {\r\n const pointsCount = points.length;\r\n for (let i = 0; i < pointsCount; i++) {\r\n amount = 0;\r\n for (let c = 0; c < nbPoints; c++) {\r\n catmullRom.push(\r\n Vector3.CatmullRom(points[i % pointsCount], points[(i + 1) % pointsCount], points[(i + 2) % pointsCount], points[(i + 3) % pointsCount], amount)\r\n );\r\n amount += step;\r\n }\r\n }\r\n catmullRom.push(catmullRom[0]);\r\n } else {\r\n const totalPoints: Vector3[] = [];\r\n totalPoints.push(points[0].clone());\r\n Array.prototype.push.apply(totalPoints, points);\r\n totalPoints.push(points[points.length - 1].clone());\r\n let i = 0;\r\n for (; i < totalPoints.length - 3; i++) {\r\n amount = 0;\r\n for (let c = 0; c < nbPoints; c++) {\r\n catmullRom.push(Vector3.CatmullRom(totalPoints[i], totalPoints[i + 1], totalPoints[i + 2], totalPoints[i + 3], amount));\r\n amount += step;\r\n }\r\n }\r\n i--;\r\n catmullRom.push(Vector3.CatmullRom(totalPoints[i], totalPoints[i + 1], totalPoints[i + 2], totalPoints[i + 3], amount));\r\n }\r\n return new Curve3(catmullRom);\r\n }\r\n\r\n /**\r\n * Returns a Curve3 object along an arc through three vector3 points:\r\n * The three points should not be colinear. When they are the Curve3 is empty.\r\n * @param first (Vector3) the first point the arc must pass through.\r\n * @param second (Vector3) the second point the arc must pass through.\r\n * @param third (Vector3) the third point the arc must pass through.\r\n * @param steps (number) the larger the number of steps the more detailed the arc.\r\n * @param closed (boolean) optional with default false, when true forms the chord from the first and third point\r\n * @param fullCircle Circle (boolean) optional with default false, when true forms the complete circle through the three points\r\n * @returns the created Curve3\r\n */\r\n public static ArcThru3Points(first: Vector3, second: Vector3, third: Vector3, steps: number = 32, closed: boolean = false, fullCircle: boolean = false): Curve3 {\r\n const arc: Vector3[] = [];\r\n const vec1 = second.subtract(first);\r\n const vec2 = third.subtract(second);\r\n const vec3 = first.subtract(third);\r\n const zAxis = Vector3.Cross(vec1, vec2);\r\n const len4 = zAxis.length();\r\n if (len4 < Math.pow(10, -8)) {\r\n return new Curve3(arc); // colinear points arc is empty\r\n }\r\n const len1_sq = vec1.lengthSquared();\r\n const len2_sq = vec2.lengthSquared();\r\n const len3_sq = vec3.lengthSquared();\r\n const len4_sq = zAxis.lengthSquared();\r\n const len1 = vec1.length();\r\n const len2 = vec2.length();\r\n const len3 = vec3.length();\r\n const radius = (0.5 * len1 * len2 * len3) / len4;\r\n const dot1 = Vector3.Dot(vec1, vec3);\r\n const dot2 = Vector3.Dot(vec1, vec2);\r\n const dot3 = Vector3.Dot(vec2, vec3);\r\n const a = (-0.5 * len2_sq * dot1) / len4_sq;\r\n const b = (-0.5 * len3_sq * dot2) / len4_sq;\r\n const c = (-0.5 * len1_sq * dot3) / len4_sq;\r\n const center = first.scale(a).add(second.scale(b)).add(third.scale(c));\r\n const radiusVec = first.subtract(center);\r\n const xAxis = radiusVec.normalize();\r\n const yAxis = Vector3.Cross(zAxis, xAxis).normalize();\r\n if (fullCircle) {\r\n const dStep = (2 * Math.PI) / steps;\r\n for (let theta = 0; theta <= 2 * Math.PI; theta += dStep) {\r\n arc.push(center.add(xAxis.scale(radius * Math.cos(theta)).add(yAxis.scale(radius * Math.sin(theta)))));\r\n }\r\n arc.push(first);\r\n } else {\r\n const dStep = 1 / steps;\r\n let theta = 0;\r\n let point = Vector3.Zero();\r\n do {\r\n point = center.add(xAxis.scale(radius * Math.cos(theta)).add(yAxis.scale(radius * Math.sin(theta))));\r\n arc.push(point);\r\n theta += dStep;\r\n } while (!point.equalsWithEpsilon(third, radius * dStep * 1.1));\r\n arc.push(third);\r\n if (closed) {\r\n arc.push(first);\r\n }\r\n }\r\n return new Curve3(arc);\r\n }\r\n\r\n /**\r\n * A Curve3 object is a logical object, so not a mesh, to handle curves in the 3D geometric space.\r\n * A Curve3 is designed from a series of successive Vector3.\r\n * Tuto : https://doc.babylonjs.com/features/featuresDeepDive/mesh/drawCurves#curve3-object\r\n * @param points points which make up the curve\r\n */\r\n constructor(points: Vector3[]) {\r\n this._points = points;\r\n this._length = this._computeLength(points);\r\n }\r\n\r\n /**\r\n * @returns the Curve3 stored array of successive Vector3\r\n */\r\n public getPoints() {\r\n return this._points;\r\n }\r\n\r\n /**\r\n * @returns the computed length (float) of the curve.\r\n */\r\n public length() {\r\n return this._length;\r\n }\r\n\r\n /**\r\n * Returns a new instance of Curve3 object : var curve = curveA.continue(curveB);\r\n * This new Curve3 is built by translating and sticking the curveB at the end of the curveA.\r\n * curveA and curveB keep unchanged.\r\n * @param curve the curve to continue from this curve\r\n * @returns the newly constructed curve\r\n */\r\n public continue(curve: DeepImmutable): Curve3 {\r\n const lastPoint = this._points[this._points.length - 1];\r\n const continuedPoints = this._points.slice();\r\n const curvePoints = curve.getPoints();\r\n for (let i = 1; i < curvePoints.length; i++) {\r\n continuedPoints.push(curvePoints[i].subtract(curvePoints[0]).add(lastPoint));\r\n }\r\n const continuedCurve = new Curve3(continuedPoints);\r\n return continuedCurve;\r\n }\r\n\r\n private _computeLength(path: DeepImmutable): number {\r\n let l = 0;\r\n for (let i = 1; i < path.length; i++) {\r\n l += path[i].subtract(path[i - 1]).length();\r\n }\r\n return l;\r\n }\r\n}\r\n","/* eslint-disable @typescript-eslint/naming-convention */\r\nimport { Vector3 } from \"../Maths/math.vector\";\r\nimport type { Nullable } from \"../types\";\r\nimport type { Color3 } from \"../Maths/math.color\";\r\nimport { TmpVectors } from \"./math\";\r\n\r\n// https://dickyjim.wordpress.com/2013/09/04/spherical-harmonics-for-beginners/\r\n// http://silviojemma.com/public/papers/lighting/spherical-harmonic-lighting.pdf\r\n// https://www.ppsloan.org/publications/StupidSH36.pdf\r\n// http://cseweb.ucsd.edu/~ravir/papers/envmap/envmap.pdf\r\n// https://www.ppsloan.org/publications/SHJCGT.pdf\r\n// https://www.ppsloan.org/publications/shdering.pdf\r\n// https://google.github.io/filament/Filament.md.html#annex/sphericalharmonics\r\n// https://patapom.com/blog/SHPortal/\r\n// https://imdoingitwrong.wordpress.com/2011/04/14/spherical-harmonics-wtf/\r\n\r\n// Using real SH basis:\r\n// m>0 m m\r\n// y = sqrt(2) * K * P * cos(m*phi) * cos(theta)\r\n// l l l\r\n//\r\n// m<0 m |m|\r\n// y = sqrt(2) * K * P * sin(m*phi) * cos(theta)\r\n// l l l\r\n//\r\n// m=0 0 0\r\n// y = K * P * trigono terms\r\n// l l l\r\n//\r\n// m (2l + 1)(l - |m|)!\r\n// K = sqrt(------------------)\r\n// l 4pi(l + |m|)!\r\n//\r\n// and P by recursion:\r\n//\r\n// P00(x) = 1\r\n// P01(x) = x\r\n// Pll(x) = (-1^l)(2l - 1)!!(1-x*x)^(1/2)\r\n// ((2l - 1)x[Pl-1/m]-(l + m - 1)[Pl-2/m])\r\n// Plm(x) = ---------------------------------------\r\n// l - m\r\n// Leaving the trigonometric terms aside we can precompute the constants to :\r\nconst SH3ylmBasisConstants = [\r\n Math.sqrt(1 / (4 * Math.PI)), // l00\r\n\r\n -Math.sqrt(3 / (4 * Math.PI)), // l1_1\r\n Math.sqrt(3 / (4 * Math.PI)), // l10\r\n -Math.sqrt(3 / (4 * Math.PI)), // l11\r\n\r\n Math.sqrt(15 / (4 * Math.PI)), // l2_2\r\n -Math.sqrt(15 / (4 * Math.PI)), // l2_1\r\n Math.sqrt(5 / (16 * Math.PI)), // l20\r\n -Math.sqrt(15 / (4 * Math.PI)), // l21\r\n Math.sqrt(15 / (16 * Math.PI)), // l22\r\n];\r\n\r\n// cm = cos(m * phi)\r\n// sm = sin(m * phi)\r\n// {x,y,z} = {cos(phi)sin(theta), sin(phi)sin(theta), cos(theta)}\r\n// By recursion on using trigo identities:\r\nconst SH3ylmBasisTrigonometricTerms = [\r\n () => 1, // l00\r\n\r\n (direction: Vector3) => direction.y, // l1_1\r\n (direction: Vector3) => direction.z, // l10\r\n (direction: Vector3) => direction.x, // l11\r\n\r\n (direction: Vector3) => direction.x * direction.y, // l2_2\r\n (direction: Vector3) => direction.y * direction.z, // l2_1\r\n (direction: Vector3) => 3 * direction.z * direction.z - 1, // l20\r\n (direction: Vector3) => direction.x * direction.z, // l21\r\n (direction: Vector3) => direction.x * direction.x - direction.y * direction.y, // l22\r\n];\r\n\r\n// Wrap the full compute\r\nconst applySH3 = (lm: number, direction: Vector3) => {\r\n return SH3ylmBasisConstants[lm] * SH3ylmBasisTrigonometricTerms[lm](direction);\r\n};\r\n\r\n// Derived from the integration of the a kernel convolution to SH.\r\n// Great explanation here: https://patapom.com/blog/SHPortal/#about-distant-radiance-and-irradiance-environments\r\nconst SHCosKernelConvolution = [Math.PI, (2 * Math.PI) / 3, (2 * Math.PI) / 3, (2 * Math.PI) / 3, Math.PI / 4, Math.PI / 4, Math.PI / 4, Math.PI / 4, Math.PI / 4];\r\n\r\n/**\r\n * Class representing spherical harmonics coefficients to the 3rd degree\r\n */\r\nexport class SphericalHarmonics {\r\n /**\r\n * Defines whether or not the harmonics have been prescaled for rendering.\r\n */\r\n public preScaled = false;\r\n\r\n /**\r\n * The l0,0 coefficients of the spherical harmonics\r\n */\r\n public l00: Vector3 = Vector3.Zero();\r\n\r\n /**\r\n * The l1,-1 coefficients of the spherical harmonics\r\n */\r\n public l1_1: Vector3 = Vector3.Zero();\r\n\r\n /**\r\n * The l1,0 coefficients of the spherical harmonics\r\n */\r\n public l10: Vector3 = Vector3.Zero();\r\n\r\n /**\r\n * The l1,1 coefficients of the spherical harmonics\r\n */\r\n public l11: Vector3 = Vector3.Zero();\r\n\r\n /**\r\n * The l2,-2 coefficients of the spherical harmonics\r\n */\r\n public l2_2: Vector3 = Vector3.Zero();\r\n\r\n /**\r\n * The l2,-1 coefficients of the spherical harmonics\r\n */\r\n public l2_1: Vector3 = Vector3.Zero();\r\n\r\n /**\r\n * The l2,0 coefficients of the spherical harmonics\r\n */\r\n public l20: Vector3 = Vector3.Zero();\r\n\r\n /**\r\n * The l2,1 coefficients of the spherical harmonics\r\n */\r\n public l21: Vector3 = Vector3.Zero();\r\n\r\n /**\r\n * The l2,2 coefficients of the spherical harmonics\r\n */\r\n public l22: Vector3 = Vector3.Zero();\r\n\r\n /**\r\n * Adds a light to the spherical harmonics\r\n * @param direction the direction of the light\r\n * @param color the color of the light\r\n * @param deltaSolidAngle the delta solid angle of the light\r\n */\r\n public addLight(direction: Vector3, color: Color3, deltaSolidAngle: number): void {\r\n TmpVectors.Vector3[0].set(color.r, color.g, color.b);\r\n const colorVector = TmpVectors.Vector3[0];\r\n const c = TmpVectors.Vector3[1];\r\n colorVector.scaleToRef(deltaSolidAngle, c);\r\n\r\n c.scaleToRef(applySH3(0, direction), TmpVectors.Vector3[2]);\r\n this.l00.addInPlace(TmpVectors.Vector3[2]);\r\n\r\n c.scaleToRef(applySH3(1, direction), TmpVectors.Vector3[2]);\r\n this.l1_1.addInPlace(TmpVectors.Vector3[2]);\r\n c.scaleToRef(applySH3(2, direction), TmpVectors.Vector3[2]);\r\n this.l10.addInPlace(TmpVectors.Vector3[2]);\r\n c.scaleToRef(applySH3(3, direction), TmpVectors.Vector3[2]);\r\n this.l11.addInPlace(TmpVectors.Vector3[2]);\r\n\r\n c.scaleToRef(applySH3(4, direction), TmpVectors.Vector3[2]);\r\n this.l2_2.addInPlace(TmpVectors.Vector3[2]);\r\n c.scaleToRef(applySH3(5, direction), TmpVectors.Vector3[2]);\r\n this.l2_1.addInPlace(TmpVectors.Vector3[2]);\r\n c.scaleToRef(applySH3(6, direction), TmpVectors.Vector3[2]);\r\n this.l20.addInPlace(TmpVectors.Vector3[2]);\r\n c.scaleToRef(applySH3(7, direction), TmpVectors.Vector3[2]);\r\n this.l21.addInPlace(TmpVectors.Vector3[2]);\r\n c.scaleToRef(applySH3(8, direction), TmpVectors.Vector3[2]);\r\n this.l22.addInPlace(TmpVectors.Vector3[2]);\r\n }\r\n\r\n /**\r\n * Scales the spherical harmonics by the given amount\r\n * @param scale the amount to scale\r\n */\r\n public scaleInPlace(scale: number): void {\r\n this.l00.scaleInPlace(scale);\r\n this.l1_1.scaleInPlace(scale);\r\n this.l10.scaleInPlace(scale);\r\n this.l11.scaleInPlace(scale);\r\n this.l2_2.scaleInPlace(scale);\r\n this.l2_1.scaleInPlace(scale);\r\n this.l20.scaleInPlace(scale);\r\n this.l21.scaleInPlace(scale);\r\n this.l22.scaleInPlace(scale);\r\n }\r\n\r\n /**\r\n * Convert from incident radiance (Li) to irradiance (E) by applying convolution with the cosine-weighted hemisphere.\r\n *\r\n * ```\r\n * E_lm = A_l * L_lm\r\n * ```\r\n *\r\n * In spherical harmonics this convolution amounts to scaling factors for each frequency band.\r\n * This corresponds to equation 5 in \"An Efficient Representation for Irradiance Environment Maps\", where\r\n * the scaling factors are given in equation 9.\r\n */\r\n public convertIncidentRadianceToIrradiance(): void {\r\n // Constant (Band 0)\r\n this.l00.scaleInPlace(SHCosKernelConvolution[0]);\r\n\r\n // Linear (Band 1)\r\n this.l1_1.scaleInPlace(SHCosKernelConvolution[1]);\r\n this.l10.scaleInPlace(SHCosKernelConvolution[2]);\r\n this.l11.scaleInPlace(SHCosKernelConvolution[3]);\r\n\r\n // Quadratic (Band 2)\r\n this.l2_2.scaleInPlace(SHCosKernelConvolution[4]);\r\n this.l2_1.scaleInPlace(SHCosKernelConvolution[5]);\r\n this.l20.scaleInPlace(SHCosKernelConvolution[6]);\r\n this.l21.scaleInPlace(SHCosKernelConvolution[7]);\r\n this.l22.scaleInPlace(SHCosKernelConvolution[8]);\r\n }\r\n\r\n /**\r\n * Convert from irradiance to outgoing radiance for Lambertian BDRF, suitable for efficient shader evaluation.\r\n *\r\n * ```\r\n * L = (1/pi) * E * rho\r\n * ```\r\n *\r\n * This is done by an additional scale by 1/pi, so is a fairly trivial operation but important conceptually.\r\n */\r\n public convertIrradianceToLambertianRadiance(): void {\r\n this.scaleInPlace(1.0 / Math.PI);\r\n\r\n // The resultant SH now represents outgoing radiance, so includes the Lambert 1/pi normalisation factor but without albedo (rho) applied\r\n // (The pixel shader must apply albedo after texture fetches, etc).\r\n }\r\n\r\n /**\r\n * Integrates the reconstruction coefficients directly in to the SH preventing further\r\n * required operations at run time.\r\n *\r\n * This is simply done by scaling back the SH with Ylm constants parameter.\r\n * The trigonometric part being applied by the shader at run time.\r\n */\r\n public preScaleForRendering(): void {\r\n this.preScaled = true;\r\n\r\n this.l00.scaleInPlace(SH3ylmBasisConstants[0]);\r\n\r\n this.l1_1.scaleInPlace(SH3ylmBasisConstants[1]);\r\n this.l10.scaleInPlace(SH3ylmBasisConstants[2]);\r\n this.l11.scaleInPlace(SH3ylmBasisConstants[3]);\r\n\r\n this.l2_2.scaleInPlace(SH3ylmBasisConstants[4]);\r\n this.l2_1.scaleInPlace(SH3ylmBasisConstants[5]);\r\n this.l20.scaleInPlace(SH3ylmBasisConstants[6]);\r\n this.l21.scaleInPlace(SH3ylmBasisConstants[7]);\r\n this.l22.scaleInPlace(SH3ylmBasisConstants[8]);\r\n }\r\n\r\n /**\r\n * update the spherical harmonics coefficients from the given array\r\n * @param data defines the 9x3 coefficients (l00, l1-1, l10, l11, l2-2, l2-1, l20, l21, l22)\r\n * @returns the spherical harmonics (this)\r\n */\r\n public updateFromArray(data: ArrayLike>): SphericalHarmonics {\r\n Vector3.FromArrayToRef(data[0], 0, this.l00);\r\n Vector3.FromArrayToRef(data[1], 0, this.l1_1);\r\n Vector3.FromArrayToRef(data[2], 0, this.l10);\r\n Vector3.FromArrayToRef(data[3], 0, this.l11);\r\n Vector3.FromArrayToRef(data[4], 0, this.l2_2);\r\n Vector3.FromArrayToRef(data[5], 0, this.l2_1);\r\n Vector3.FromArrayToRef(data[6], 0, this.l20);\r\n Vector3.FromArrayToRef(data[7], 0, this.l21);\r\n Vector3.FromArrayToRef(data[8], 0, this.l22);\r\n return this;\r\n }\r\n\r\n /**\r\n * update the spherical harmonics coefficients from the given floats array\r\n * @param data defines the 9x3 coefficients (l00, l1-1, l10, l11, l2-2, l2-1, l20, l21, l22)\r\n * @returns the spherical harmonics (this)\r\n */\r\n public updateFromFloatsArray(data: ArrayLike): SphericalHarmonics {\r\n Vector3.FromFloatsToRef(data[0], data[1], data[2], this.l00);\r\n Vector3.FromFloatsToRef(data[3], data[4], data[5], this.l1_1);\r\n Vector3.FromFloatsToRef(data[6], data[7], data[8], this.l10);\r\n Vector3.FromFloatsToRef(data[9], data[10], data[11], this.l11);\r\n Vector3.FromFloatsToRef(data[12], data[13], data[14], this.l2_2);\r\n Vector3.FromFloatsToRef(data[15], data[16], data[17], this.l2_1);\r\n Vector3.FromFloatsToRef(data[18], data[19], data[20], this.l20);\r\n Vector3.FromFloatsToRef(data[21], data[22], data[23], this.l21);\r\n Vector3.FromFloatsToRef(data[24], data[25], data[26], this.l22);\r\n return this;\r\n }\r\n\r\n /**\r\n * Constructs a spherical harmonics from an array.\r\n * @param data defines the 9x3 coefficients (l00, l1-1, l10, l11, l2-2, l2-1, l20, l21, l22)\r\n * @returns the spherical harmonics\r\n */\r\n public static FromArray(data: ArrayLike>): SphericalHarmonics {\r\n const sh = new SphericalHarmonics();\r\n return sh.updateFromArray(data);\r\n }\r\n\r\n // Keep for references.\r\n /**\r\n * Gets the spherical harmonics from polynomial\r\n * @param polynomial the spherical polynomial\r\n * @returns the spherical harmonics\r\n */\r\n public static FromPolynomial(polynomial: SphericalPolynomial): SphericalHarmonics {\r\n const result = new SphericalHarmonics();\r\n\r\n result.l00 = polynomial.xx.scale(0.376127).add(polynomial.yy.scale(0.376127)).add(polynomial.zz.scale(0.376126));\r\n result.l1_1 = polynomial.y.scale(0.977204);\r\n result.l10 = polynomial.z.scale(0.977204);\r\n result.l11 = polynomial.x.scale(0.977204);\r\n result.l2_2 = polynomial.xy.scale(1.16538);\r\n result.l2_1 = polynomial.yz.scale(1.16538);\r\n result.l20 = polynomial.zz.scale(1.34567).subtract(polynomial.xx.scale(0.672834)).subtract(polynomial.yy.scale(0.672834));\r\n result.l21 = polynomial.zx.scale(1.16538);\r\n result.l22 = polynomial.xx.scale(1.16538).subtract(polynomial.yy.scale(1.16538));\r\n\r\n result.l1_1.scaleInPlace(-1);\r\n result.l11.scaleInPlace(-1);\r\n result.l2_1.scaleInPlace(-1);\r\n result.l21.scaleInPlace(-1);\r\n\r\n result.scaleInPlace(Math.PI);\r\n\r\n return result;\r\n }\r\n}\r\n\r\n/**\r\n * Class representing spherical polynomial coefficients to the 3rd degree\r\n */\r\nexport class SphericalPolynomial {\r\n private _harmonics: Nullable;\r\n\r\n /**\r\n * The spherical harmonics used to create the polynomials.\r\n */\r\n public get preScaledHarmonics(): SphericalHarmonics {\r\n if (!this._harmonics) {\r\n this._harmonics = SphericalHarmonics.FromPolynomial(this);\r\n }\r\n if (!this._harmonics.preScaled) {\r\n this._harmonics.preScaleForRendering();\r\n }\r\n return this._harmonics;\r\n }\r\n\r\n /**\r\n * The x coefficients of the spherical polynomial\r\n */\r\n public x: Vector3 = Vector3.Zero();\r\n\r\n /**\r\n * The y coefficients of the spherical polynomial\r\n */\r\n public y: Vector3 = Vector3.Zero();\r\n\r\n /**\r\n * The z coefficients of the spherical polynomial\r\n */\r\n public z: Vector3 = Vector3.Zero();\r\n\r\n /**\r\n * The xx coefficients of the spherical polynomial\r\n */\r\n public xx: Vector3 = Vector3.Zero();\r\n\r\n /**\r\n * The yy coefficients of the spherical polynomial\r\n */\r\n public yy: Vector3 = Vector3.Zero();\r\n\r\n /**\r\n * The zz coefficients of the spherical polynomial\r\n */\r\n public zz: Vector3 = Vector3.Zero();\r\n\r\n /**\r\n * The xy coefficients of the spherical polynomial\r\n */\r\n public xy: Vector3 = Vector3.Zero();\r\n\r\n /**\r\n * The yz coefficients of the spherical polynomial\r\n */\r\n public yz: Vector3 = Vector3.Zero();\r\n\r\n /**\r\n * The zx coefficients of the spherical polynomial\r\n */\r\n public zx: Vector3 = Vector3.Zero();\r\n\r\n /**\r\n * Adds an ambient color to the spherical polynomial\r\n * @param color the color to add\r\n */\r\n public addAmbient(color: Color3): void {\r\n TmpVectors.Vector3[0].copyFromFloats(color.r, color.g, color.b);\r\n const colorVector = TmpVectors.Vector3[0];\r\n this.xx.addInPlace(colorVector);\r\n this.yy.addInPlace(colorVector);\r\n this.zz.addInPlace(colorVector);\r\n }\r\n\r\n /**\r\n * Scales the spherical polynomial by the given amount\r\n * @param scale the amount to scale\r\n */\r\n public scaleInPlace(scale: number) {\r\n this.x.scaleInPlace(scale);\r\n this.y.scaleInPlace(scale);\r\n this.z.scaleInPlace(scale);\r\n this.xx.scaleInPlace(scale);\r\n this.yy.scaleInPlace(scale);\r\n this.zz.scaleInPlace(scale);\r\n this.yz.scaleInPlace(scale);\r\n this.zx.scaleInPlace(scale);\r\n this.xy.scaleInPlace(scale);\r\n }\r\n\r\n /**\r\n * Updates the spherical polynomial from harmonics\r\n * @param harmonics the spherical harmonics\r\n * @returns the spherical polynomial\r\n */\r\n public updateFromHarmonics(harmonics: SphericalHarmonics): SphericalPolynomial {\r\n this._harmonics = harmonics;\r\n\r\n this.x.copyFrom(harmonics.l11);\r\n this.x.scaleInPlace(1.02333).scaleInPlace(-1);\r\n this.y.copyFrom(harmonics.l1_1);\r\n this.y.scaleInPlace(1.02333).scaleInPlace(-1);\r\n this.z.copyFrom(harmonics.l10);\r\n this.z.scaleInPlace(1.02333);\r\n\r\n this.xx.copyFrom(harmonics.l00);\r\n TmpVectors.Vector3[0].copyFrom(harmonics.l20).scaleInPlace(0.247708);\r\n TmpVectors.Vector3[1].copyFrom(harmonics.l22).scaleInPlace(0.429043);\r\n this.xx.scaleInPlace(0.886277).subtractInPlace(TmpVectors.Vector3[0]).addInPlace(TmpVectors.Vector3[1]);\r\n this.yy.copyFrom(harmonics.l00);\r\n this.yy.scaleInPlace(0.886277).subtractInPlace(TmpVectors.Vector3[0]).subtractInPlace(TmpVectors.Vector3[1]);\r\n this.zz.copyFrom(harmonics.l00);\r\n TmpVectors.Vector3[0].copyFrom(harmonics.l20).scaleInPlace(0.495417);\r\n this.zz.scaleInPlace(0.886277).addInPlace(TmpVectors.Vector3[0]);\r\n\r\n this.yz.copyFrom(harmonics.l2_1);\r\n this.yz.scaleInPlace(0.858086).scaleInPlace(-1);\r\n this.zx.copyFrom(harmonics.l21);\r\n this.zx.scaleInPlace(0.858086).scaleInPlace(-1);\r\n this.xy.copyFrom(harmonics.l2_2);\r\n this.xy.scaleInPlace(0.858086);\r\n\r\n this.scaleInPlace(1.0 / Math.PI);\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Gets the spherical polynomial from harmonics\r\n * @param harmonics the spherical harmonics\r\n * @returns the spherical polynomial\r\n */\r\n public static FromHarmonics(harmonics: SphericalHarmonics): SphericalPolynomial {\r\n const result = new SphericalPolynomial();\r\n return result.updateFromHarmonics(harmonics);\r\n }\r\n\r\n /**\r\n * Constructs a spherical polynomial from an array.\r\n * @param data defines the 9x3 coefficients (x, y, z, xx, yy, zz, yz, zx, xy)\r\n * @returns the spherical polynomial\r\n */\r\n public static FromArray(data: ArrayLike>): SphericalPolynomial {\r\n const sp = new SphericalPolynomial();\r\n Vector3.FromArrayToRef(data[0], 0, sp.x);\r\n Vector3.FromArrayToRef(data[1], 0, sp.y);\r\n Vector3.FromArrayToRef(data[2], 0, sp.z);\r\n Vector3.FromArrayToRef(data[3], 0, sp.xx);\r\n Vector3.FromArrayToRef(data[4], 0, sp.yy);\r\n Vector3.FromArrayToRef(data[5], 0, sp.zz);\r\n Vector3.FromArrayToRef(data[6], 0, sp.yz);\r\n Vector3.FromArrayToRef(data[7], 0, sp.zx);\r\n Vector3.FromArrayToRef(data[8], 0, sp.xy);\r\n return sp;\r\n }\r\n}\r\n","import { Vector3 } from \"../../Maths/math.vector\";\r\nimport { Clamp } from \"../../Maths/math.scalar.functions\";\r\nimport { SphericalPolynomial, SphericalHarmonics } from \"../../Maths/sphericalPolynomial\";\r\nimport type { BaseTexture } from \"../../Materials/Textures/baseTexture\";\r\nimport type { Nullable } from \"../../types\";\r\nimport { Constants } from \"../../Engines/constants\";\r\nimport type { CubeMapInfo } from \"./panoramaToCubemap\";\r\nimport { ToLinearSpace } from \"../../Maths/math.constants\";\r\nimport { Color3 } from \"../../Maths/math.color\";\r\n\r\nclass FileFaceOrientation {\r\n public name: string;\r\n public worldAxisForNormal: Vector3; // the world axis corresponding to the normal to the face\r\n public worldAxisForFileX: Vector3; // the world axis corresponding to texture right x-axis in file\r\n public worldAxisForFileY: Vector3; // the world axis corresponding to texture down y-axis in file\r\n\r\n public constructor(name: string, worldAxisForNormal: Vector3, worldAxisForFileX: Vector3, worldAxisForFileY: Vector3) {\r\n this.name = name;\r\n this.worldAxisForNormal = worldAxisForNormal;\r\n this.worldAxisForFileX = worldAxisForFileX;\r\n this.worldAxisForFileY = worldAxisForFileY;\r\n }\r\n}\r\n\r\n/**\r\n * Helper class dealing with the extraction of spherical polynomial dataArray\r\n * from a cube map.\r\n */\r\nexport class CubeMapToSphericalPolynomialTools {\r\n private static _FileFaces: FileFaceOrientation[] = [\r\n new FileFaceOrientation(\"right\", new Vector3(1, 0, 0), new Vector3(0, 0, -1), new Vector3(0, -1, 0)), // +X east\r\n new FileFaceOrientation(\"left\", new Vector3(-1, 0, 0), new Vector3(0, 0, 1), new Vector3(0, -1, 0)), // -X west\r\n new FileFaceOrientation(\"up\", new Vector3(0, 1, 0), new Vector3(1, 0, 0), new Vector3(0, 0, 1)), // +Y north\r\n new FileFaceOrientation(\"down\", new Vector3(0, -1, 0), new Vector3(1, 0, 0), new Vector3(0, 0, -1)), // -Y south\r\n new FileFaceOrientation(\"front\", new Vector3(0, 0, 1), new Vector3(1, 0, 0), new Vector3(0, -1, 0)), // +Z top\r\n new FileFaceOrientation(\"back\", new Vector3(0, 0, -1), new Vector3(-1, 0, 0), new Vector3(0, -1, 0)), // -Z bottom\r\n ];\r\n\r\n /** @internal */\r\n public static MAX_HDRI_VALUE = 4096;\r\n /** @internal */\r\n public static PRESERVE_CLAMPED_COLORS = false;\r\n\r\n /**\r\n * Converts a texture to the according Spherical Polynomial data.\r\n * This extracts the first 3 orders only as they are the only one used in the lighting.\r\n *\r\n * @param texture The texture to extract the information from.\r\n * @returns The Spherical Polynomial data.\r\n */\r\n public static ConvertCubeMapTextureToSphericalPolynomial(texture: BaseTexture): Nullable> {\r\n if (!texture.isCube) {\r\n // Only supports cube Textures currently.\r\n return null;\r\n }\r\n\r\n texture.getScene()?.getEngine().flushFramebuffer();\r\n\r\n const size = texture.getSize().width;\r\n const rightPromise = texture.readPixels(0, undefined, undefined, false);\r\n const leftPromise = texture.readPixels(1, undefined, undefined, false);\r\n\r\n let upPromise: Nullable>;\r\n let downPromise: Nullable>;\r\n if (texture.isRenderTarget) {\r\n upPromise = texture.readPixels(3, undefined, undefined, false);\r\n downPromise = texture.readPixels(2, undefined, undefined, false);\r\n } else {\r\n upPromise = texture.readPixels(2, undefined, undefined, false);\r\n downPromise = texture.readPixels(3, undefined, undefined, false);\r\n }\r\n\r\n const frontPromise = texture.readPixels(4, undefined, undefined, false);\r\n const backPromise = texture.readPixels(5, undefined, undefined, false);\r\n\r\n const gammaSpace = texture.gammaSpace;\r\n // Always read as RGBA.\r\n const format = Constants.TEXTUREFORMAT_RGBA;\r\n let type = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n if (texture.textureType == Constants.TEXTURETYPE_FLOAT || texture.textureType == Constants.TEXTURETYPE_HALF_FLOAT) {\r\n type = Constants.TEXTURETYPE_FLOAT;\r\n }\r\n\r\n return new Promise((resolve) => {\r\n Promise.all([leftPromise, rightPromise, upPromise, downPromise, frontPromise, backPromise]).then(([left, right, up, down, front, back]) => {\r\n const cubeInfo: CubeMapInfo = {\r\n size,\r\n right,\r\n left,\r\n up,\r\n down,\r\n front,\r\n back,\r\n format,\r\n type,\r\n gammaSpace,\r\n };\r\n\r\n resolve(this.ConvertCubeMapToSphericalPolynomial(cubeInfo));\r\n });\r\n });\r\n }\r\n\r\n /**\r\n * Compute the area on the unit sphere of the rectangle defined by (x,y) and the origin\r\n * See https://www.rorydriscoll.com/2012/01/15/cubemap-texel-solid-angle/\r\n * @param x\r\n * @param y\r\n * @returns the area\r\n */\r\n private static _AreaElement(x: number, y: number): number {\r\n return Math.atan2(x * y, Math.sqrt(x * x + y * y + 1));\r\n }\r\n\r\n /**\r\n * Converts a cubemap to the according Spherical Polynomial data.\r\n * This extracts the first 3 orders only as they are the only one used in the lighting.\r\n *\r\n * @param cubeInfo The Cube map to extract the information from.\r\n * @returns The Spherical Polynomial data.\r\n */\r\n public static ConvertCubeMapToSphericalPolynomial(cubeInfo: CubeMapInfo): SphericalPolynomial {\r\n const sphericalHarmonics = new SphericalHarmonics();\r\n let totalSolidAngle = 0.0;\r\n\r\n // The (u,v) range is [-1,+1], so the distance between each texel is 2/Size.\r\n const du = 2.0 / cubeInfo.size;\r\n const dv = du;\r\n\r\n const halfTexel = 0.5 * du;\r\n\r\n // The (u,v) of the first texel is half a texel from the corner (-1,-1).\r\n const minUV = halfTexel - 1.0;\r\n\r\n for (let faceIndex = 0; faceIndex < 6; faceIndex++) {\r\n const fileFace = this._FileFaces[faceIndex];\r\n const dataArray = (cubeInfo)[fileFace.name];\r\n let v = minUV;\r\n\r\n // TODO: we could perform the summation directly into a SphericalPolynomial (SP), which is more efficient than SphericalHarmonic (SH).\r\n // This is possible because during the summation we do not need the SH-specific properties, e.g. orthogonality.\r\n // Because SP is still linear, so summation is fine in that basis.\r\n const stride = cubeInfo.format === Constants.TEXTUREFORMAT_RGBA ? 4 : 3;\r\n for (let y = 0; y < cubeInfo.size; y++) {\r\n let u = minUV;\r\n\r\n for (let x = 0; x < cubeInfo.size; x++) {\r\n // World direction (not normalised)\r\n const worldDirection = fileFace.worldAxisForFileX.scale(u).add(fileFace.worldAxisForFileY.scale(v)).add(fileFace.worldAxisForNormal);\r\n worldDirection.normalize();\r\n\r\n const deltaSolidAngle =\r\n this._AreaElement(u - halfTexel, v - halfTexel) -\r\n this._AreaElement(u - halfTexel, v + halfTexel) -\r\n this._AreaElement(u + halfTexel, v - halfTexel) +\r\n this._AreaElement(u + halfTexel, v + halfTexel);\r\n\r\n let r = dataArray[y * cubeInfo.size * stride + x * stride + 0];\r\n let g = dataArray[y * cubeInfo.size * stride + x * stride + 1];\r\n let b = dataArray[y * cubeInfo.size * stride + x * stride + 2];\r\n\r\n // Prevent NaN harmonics with extreme HDRI data.\r\n if (isNaN(r)) {\r\n r = 0;\r\n }\r\n if (isNaN(g)) {\r\n g = 0;\r\n }\r\n if (isNaN(b)) {\r\n b = 0;\r\n }\r\n\r\n // Handle Integer types.\r\n if (cubeInfo.type === Constants.TEXTURETYPE_UNSIGNED_BYTE) {\r\n r /= 255;\r\n g /= 255;\r\n b /= 255;\r\n }\r\n\r\n // Handle Gamma space textures.\r\n if (cubeInfo.gammaSpace) {\r\n r = Math.pow(Clamp(r), ToLinearSpace);\r\n g = Math.pow(Clamp(g), ToLinearSpace);\r\n b = Math.pow(Clamp(b), ToLinearSpace);\r\n }\r\n\r\n // Prevent to explode in case of really high dynamic ranges.\r\n // sh 3 would not be enough to accurately represent it.\r\n const max = this.MAX_HDRI_VALUE;\r\n if (this.PRESERVE_CLAMPED_COLORS) {\r\n const currentMax = Math.max(r, g, b);\r\n if (currentMax > max) {\r\n const factor = max / currentMax;\r\n r *= factor;\r\n g *= factor;\r\n b *= factor;\r\n }\r\n } else {\r\n r = Clamp(r, 0, max);\r\n g = Clamp(g, 0, max);\r\n b = Clamp(b, 0, max);\r\n }\r\n\r\n const color = new Color3(r, g, b);\r\n\r\n sphericalHarmonics.addLight(worldDirection, color, deltaSolidAngle);\r\n\r\n totalSolidAngle += deltaSolidAngle;\r\n\r\n u += du;\r\n }\r\n\r\n v += dv;\r\n }\r\n }\r\n\r\n // Solid angle for entire sphere is 4*pi\r\n const sphereSolidAngle = 4.0 * Math.PI;\r\n\r\n // Adjust the solid angle to allow for how many faces we processed.\r\n const facesProcessed = 6.0;\r\n const expectedSolidAngle = (sphereSolidAngle * facesProcessed) / 6.0;\r\n\r\n // Adjust the harmonics so that the accumulated solid angle matches the expected solid angle.\r\n // This is needed because the numerical integration over the cube uses a\r\n // small angle approximation of solid angle for each texel (see deltaSolidAngle),\r\n // and also to compensate for accumulative error due to float precision in the summation.\r\n const correctionFactor = expectedSolidAngle / totalSolidAngle;\r\n sphericalHarmonics.scaleInPlace(correctionFactor);\r\n\r\n sphericalHarmonics.convertIncidentRadianceToIrradiance();\r\n sphericalHarmonics.convertIrradianceToLambertianRadiance();\r\n\r\n return SphericalPolynomial.FromHarmonics(sphericalHarmonics);\r\n }\r\n}\r\n","/* eslint-disable @typescript-eslint/naming-convention */\r\n\r\nimport type { Nullable, Tuple } from \"../types\";\r\n\r\n/**\r\n * Returns an array of the given size filled with elements built from the given constructor and the parameters.\r\n * @param size the number of element to construct and put in the array.\r\n * @param itemBuilder a callback responsible for creating new instance of item. Called once per array entry.\r\n * @returns a new array filled with new objects.\r\n */\r\nexport function BuildArray(size: number, itemBuilder: () => T): Array {\r\n const a: T[] = [];\r\n for (let i = 0; i < size; ++i) {\r\n a.push(itemBuilder());\r\n }\r\n return a;\r\n}\r\n\r\n/**\r\n * Returns a tuple of the given size filled with elements built from the given constructor and the parameters.\r\n * @param size he number of element to construct and put in the tuple.\r\n * @param itemBuilder a callback responsible for creating new instance of item. Called once per tuple entry.\r\n * @returns a new tuple filled with new objects.\r\n */\r\nexport function BuildTuple(size: N, itemBuilder: () => T): Tuple {\r\n return BuildArray(size, itemBuilder) as any;\r\n}\r\n\r\n/**\r\n * Defines the callback type used when an observed array function is triggered.\r\n * @internal\r\n */\r\nexport type _ObserveCallback = (functionName: string, previousLength: number) => void;\r\n\r\n/**\r\n * Observes a function and calls the given callback when it is called.\r\n * @param object Defines the object the function to observe belongs to.\r\n * @param functionName Defines the name of the function to observe.\r\n * @param callback Defines the callback to call when the function is called.\r\n * @returns A function to call to stop observing\r\n */\r\nfunction _observeArrayfunction(object: { [key: string]: any }, functionName: string, callback: _ObserveCallback): Nullable<() => void> {\r\n // Finds the function to observe\r\n const oldFunction = object[functionName];\r\n if (typeof oldFunction !== \"function\") {\r\n return null;\r\n }\r\n\r\n // Creates a new function that calls the callback and the old function\r\n const newFunction = function () {\r\n const previousLength = object.length;\r\n const returnValue = newFunction.previous.apply(object, arguments);\r\n callback(functionName, previousLength);\r\n return returnValue;\r\n } as any;\r\n\r\n // Doublishly links the new function and the old function\r\n oldFunction.next = newFunction;\r\n newFunction.previous = oldFunction;\r\n\r\n // Replaces the old function with the new function\r\n object[functionName] = newFunction;\r\n\r\n // Returns a function to disable the hook\r\n return () => {\r\n // Only unhook if the function is still hooked\r\n const previous = newFunction.previous;\r\n if (!previous) {\r\n return;\r\n }\r\n\r\n // Finds the ref to the next function in the chain\r\n const next = newFunction.next;\r\n\r\n // If in the middle of the chain, link the previous and next functions\r\n if (next) {\r\n previous.next = next;\r\n next.previous = previous;\r\n }\r\n // If at the end of the chain, remove the reference to the previous function\r\n // and restore the previous function\r\n else {\r\n previous.next = undefined;\r\n object[functionName] = previous;\r\n }\r\n\r\n // Lose reference to the previous and next functions\r\n newFunction.next = undefined;\r\n newFunction.previous = undefined;\r\n };\r\n}\r\n\r\n/**\r\n * Defines the list of functions to proxy when observing an array.\r\n * The scope is currently reduced to the common functions used in the render target render list and the scene cameras.\r\n */\r\nconst observedArrayFunctions = [\"push\", \"splice\", \"pop\", \"shift\", \"unshift\"];\r\n\r\n/**\r\n * Observes an array and notifies the given observer when the array is modified.\r\n * @param array Defines the array to observe\r\n * @param callback Defines the function to call when the array is modified (in the limit of the observed array functions)\r\n * @returns A function to call to stop observing the array\r\n * @internal\r\n */\r\nexport function _ObserveArray(array: T[], callback: _ObserveCallback) {\r\n // Observes all the required array functions and stores the unhook functions\r\n const unObserveFunctions = observedArrayFunctions.map((name) => {\r\n return _observeArrayfunction(array, name, callback);\r\n });\r\n\r\n // Returns a function that unhook all the observed functions\r\n return () => {\r\n unObserveFunctions.forEach((unObserveFunction) => {\r\n unObserveFunction?.();\r\n });\r\n };\r\n}\r\n","import { InternalTexture, InternalTextureSource } from \"../../Materials/Textures/internalTexture\";\r\nimport { Logger } from \"../../Misc/logger\";\r\nimport type { Nullable } from \"../../types\";\r\nimport type { Scene } from \"../../scene\";\r\nimport { LoadImage } from \"../../Misc/fileTools\";\r\nimport { RandomGUID } from \"../../Misc/guid\";\r\nimport type { IWebRequest } from \"../../Misc/interfaces/iWebRequest\";\r\nimport { AbstractEngine } from \"../abstractEngine\";\r\nimport { _GetCompatibleTextureLoader } from \"core/Materials/Textures/Loaders/textureLoaderManager\";\r\n\r\ndeclare module \"../../Engines/abstractEngine\" {\r\n export interface AbstractEngine {\r\n /** @internal */\r\n createCubeTextureBase(\r\n rootUrl: string,\r\n scene: Nullable,\r\n files: Nullable,\r\n noMipmap: boolean,\r\n onLoad: Nullable<(data?: any) => void>,\r\n onError: Nullable<(message?: string, exception?: any) => void>,\r\n format: number | undefined,\r\n forcedExtension: any,\r\n createPolynomials: boolean,\r\n lodScale: number,\r\n lodOffset: number,\r\n fallback: Nullable,\r\n beforeLoadCubeDataCallback: Nullable<(texture: InternalTexture, data: ArrayBufferView | ArrayBufferView[]) => void>,\r\n imageHandler: Nullable<(texture: InternalTexture, imgs: HTMLImageElement[] | ImageBitmap[]) => void>,\r\n useSRGBBuffer: boolean,\r\n buffer: Nullable\r\n ): InternalTexture;\r\n\r\n /** @internal */\r\n _partialLoadFile(\r\n url: string,\r\n index: number,\r\n loadedFiles: ArrayBuffer[],\r\n onfinish: (files: ArrayBuffer[]) => void,\r\n onErrorCallBack: Nullable<(message?: string, exception?: any) => void>\r\n ): void;\r\n\r\n /** @internal */\r\n _cascadeLoadFiles(scene: Nullable, onfinish: (images: ArrayBuffer[]) => void, files: string[], onError: Nullable<(message?: string, exception?: any) => void>): void;\r\n\r\n /** @internal */\r\n _cascadeLoadImgs(\r\n scene: Nullable,\r\n texture: InternalTexture,\r\n onfinish: Nullable<(texture: InternalTexture, images: HTMLImageElement[] | ImageBitmap[]) => void>,\r\n files: string[],\r\n onError: Nullable<(message?: string, exception?: any) => void>,\r\n mimeType?: string\r\n ): void;\r\n\r\n /** @internal */\r\n _partialLoadImg(\r\n url: string,\r\n index: number,\r\n loadedImages: HTMLImageElement[] | ImageBitmap[],\r\n scene: Nullable,\r\n texture: InternalTexture,\r\n onfinish: Nullable<(texture: InternalTexture, images: HTMLImageElement[] | ImageBitmap[]) => void>,\r\n onErrorCallBack: Nullable<(message?: string, exception?: any) => void>,\r\n mimeType?: string\r\n ): void;\r\n }\r\n}\r\n\r\nAbstractEngine.prototype._partialLoadFile = function (\r\n url: string,\r\n index: number,\r\n loadedFiles: ArrayBuffer[],\r\n onfinish: (files: ArrayBuffer[]) => void,\r\n onErrorCallBack: Nullable<(message?: string, exception?: any) => void> = null\r\n): void {\r\n const onload = (data: ArrayBuffer) => {\r\n loadedFiles[index] = data;\r\n (loadedFiles)._internalCount++;\r\n\r\n if ((loadedFiles)._internalCount === 6) {\r\n onfinish(loadedFiles);\r\n }\r\n };\r\n\r\n const onerror = (request?: IWebRequest, exception?: any) => {\r\n if (onErrorCallBack && request) {\r\n onErrorCallBack(request.status + \" \" + request.statusText, exception);\r\n }\r\n };\r\n\r\n this._loadFile(url, onload as (data: string | ArrayBuffer) => void, undefined, undefined, true, onerror);\r\n};\r\n\r\nAbstractEngine.prototype._cascadeLoadFiles = function (\r\n scene: Nullable,\r\n onfinish: (images: ArrayBuffer[]) => void,\r\n files: string[],\r\n onError: Nullable<(message?: string, exception?: any) => void> = null\r\n): void {\r\n const loadedFiles: ArrayBuffer[] = [];\r\n (loadedFiles)._internalCount = 0;\r\n\r\n for (let index = 0; index < 6; index++) {\r\n this._partialLoadFile(files[index], index, loadedFiles, onfinish, onError);\r\n }\r\n};\r\n\r\nAbstractEngine.prototype._cascadeLoadImgs = function (\r\n scene: Nullable,\r\n texture: InternalTexture,\r\n onfinish: Nullable<(texture: InternalTexture, images: HTMLImageElement[] | ImageBitmap[]) => void>,\r\n files: string[],\r\n onError: Nullable<(message?: string, exception?: any) => void> = null,\r\n mimeType?: string\r\n) {\r\n const loadedImages: HTMLImageElement[] | ImageBitmap[] = [];\r\n (loadedImages)._internalCount = 0;\r\n\r\n for (let index = 0; index < 6; index++) {\r\n this._partialLoadImg(files[index], index, loadedImages, scene, texture, onfinish, onError, mimeType);\r\n }\r\n};\r\n\r\nAbstractEngine.prototype._partialLoadImg = function (\r\n url: string,\r\n index: number,\r\n loadedImages: HTMLImageElement[] | ImageBitmap[],\r\n scene: Nullable,\r\n texture: InternalTexture,\r\n onfinish: Nullable<(texture: InternalTexture, images: HTMLImageElement[] | ImageBitmap[]) => void>,\r\n onErrorCallBack: Nullable<(message?: string, exception?: any) => void> = null,\r\n mimeType?: string\r\n) {\r\n const tokenPendingData = RandomGUID();\r\n\r\n const onload = (img: HTMLImageElement | ImageBitmap) => {\r\n loadedImages[index] = img;\r\n (loadedImages)._internalCount++;\r\n\r\n if (scene) {\r\n scene.removePendingData(tokenPendingData);\r\n }\r\n\r\n if ((loadedImages)._internalCount === 6 && onfinish) {\r\n onfinish(texture, loadedImages);\r\n }\r\n };\r\n\r\n const onerror = (message?: string, exception?: any) => {\r\n if (scene) {\r\n scene.removePendingData(tokenPendingData);\r\n }\r\n\r\n if (onErrorCallBack) {\r\n onErrorCallBack(message, exception);\r\n }\r\n };\r\n\r\n LoadImage(url, onload, onerror, scene ? scene.offlineProvider : null, mimeType);\r\n if (scene) {\r\n scene.addPendingData(tokenPendingData);\r\n }\r\n};\r\n\r\nAbstractEngine.prototype.createCubeTextureBase = function (\r\n rootUrl: string,\r\n scene: Nullable,\r\n files: Nullable,\r\n noMipmap?: boolean,\r\n onLoad: Nullable<(data?: any) => void> = null,\r\n onError: Nullable<(message?: string, exception?: any) => void> = null,\r\n format?: number,\r\n forcedExtension: any = null,\r\n createPolynomials: boolean = false,\r\n lodScale: number = 0,\r\n lodOffset: number = 0,\r\n fallback: Nullable = null,\r\n beforeLoadCubeDataCallback: Nullable<(texture: InternalTexture, data: ArrayBufferView | ArrayBufferView[]) => void> = null,\r\n imageHandler: Nullable<(texture: InternalTexture, imgs: HTMLImageElement[] | ImageBitmap[]) => void> = null,\r\n useSRGBBuffer = false,\r\n buffer: Nullable = null\r\n): InternalTexture {\r\n const texture = fallback ? fallback : new InternalTexture(this, InternalTextureSource.Cube);\r\n texture.isCube = true;\r\n texture.url = rootUrl;\r\n texture.generateMipMaps = !noMipmap;\r\n texture._lodGenerationScale = lodScale;\r\n texture._lodGenerationOffset = lodOffset;\r\n texture._useSRGBBuffer = !!useSRGBBuffer && this._caps.supportSRGBBuffers && (this.version > 1 || this.isWebGPU || !!noMipmap);\r\n if (texture !== fallback) {\r\n texture.label = rootUrl.substring(0, 60); // default label, can be overriden by the caller\r\n }\r\n\r\n if (!this._doNotHandleContextLost) {\r\n texture._extension = forcedExtension;\r\n texture._files = files;\r\n texture._buffer = buffer;\r\n }\r\n\r\n const originalRootUrl = rootUrl;\r\n if (this._transformTextureUrl && !fallback) {\r\n rootUrl = this._transformTextureUrl(rootUrl);\r\n }\r\n\r\n const rootUrlWithoutUriParams = rootUrl.split(\"?\")[0];\r\n const lastDot = rootUrlWithoutUriParams.lastIndexOf(\".\");\r\n const extension = forcedExtension ? forcedExtension : lastDot > -1 ? rootUrlWithoutUriParams.substring(lastDot).toLowerCase() : \"\";\r\n\r\n const loaderPromise = _GetCompatibleTextureLoader(extension);\r\n\r\n const onInternalError = (request?: IWebRequest, exception?: any) => {\r\n if (rootUrl === originalRootUrl) {\r\n if (onError && request) {\r\n onError(request.status + \" \" + request.statusText, exception);\r\n }\r\n } else {\r\n // fall back to the original url if the transformed url fails to load\r\n Logger.Warn(`Failed to load ${rootUrl}, falling back to the ${originalRootUrl}`);\r\n this.createCubeTextureBase(\r\n originalRootUrl,\r\n scene,\r\n files,\r\n !!noMipmap,\r\n onLoad,\r\n onError,\r\n format,\r\n forcedExtension,\r\n createPolynomials,\r\n lodScale,\r\n lodOffset,\r\n texture,\r\n beforeLoadCubeDataCallback,\r\n imageHandler,\r\n useSRGBBuffer,\r\n buffer\r\n );\r\n }\r\n };\r\n\r\n if (loaderPromise) {\r\n loaderPromise.then((loader) => {\r\n const onloaddata = (data: ArrayBufferView | ArrayBufferView[]) => {\r\n if (beforeLoadCubeDataCallback) {\r\n beforeLoadCubeDataCallback(texture, data);\r\n }\r\n loader.loadCubeData(data, texture, createPolynomials, onLoad, onError);\r\n };\r\n if (buffer) {\r\n onloaddata(buffer);\r\n } else if (files && files.length === 6) {\r\n if (loader.supportCascades) {\r\n this._cascadeLoadFiles(scene, (images) => onloaddata(images.map((image) => new Uint8Array(image))), files, onError);\r\n } else {\r\n if (onError) {\r\n onError(\"Textures type does not support cascades.\");\r\n } else {\r\n Logger.Warn(\"Texture loader does not support cascades.\");\r\n }\r\n }\r\n } else {\r\n this._loadFile(rootUrl, (data) => onloaddata(new Uint8Array(data as ArrayBuffer)), undefined, undefined, true, onInternalError);\r\n }\r\n });\r\n } else {\r\n if (!files || files.length === 0) {\r\n throw new Error(\"Cannot load cubemap because files were not defined, or the correct loader was not found.\");\r\n }\r\n\r\n this._cascadeLoadImgs(\r\n scene,\r\n texture,\r\n (texture: InternalTexture, imgs: HTMLImageElement[] | ImageBitmap[]) => {\r\n if (imageHandler) {\r\n imageHandler(texture, imgs);\r\n }\r\n },\r\n files,\r\n onError\r\n );\r\n }\r\n\r\n this._internalTexturesCache.push(texture);\r\n\r\n return texture;\r\n};\r\n","/* eslint-disable @typescript-eslint/naming-convention */\r\nimport { Clamp } from \"../Maths/math.scalar.functions\";\r\nimport type { SphericalPolynomial } from \"../Maths/sphericalPolynomial\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport type { InternalTexture } from \"../Materials/Textures/internalTexture\";\r\nimport type { Nullable } from \"../types\";\r\nimport { Logger } from \"../Misc/logger\";\r\nimport { CubeMapToSphericalPolynomialTools } from \"../Misc/HighDynamicRange/cubemapToSphericalPolynomial\";\r\nimport type { AbstractEngine } from \"../Engines/abstractEngine\";\r\nimport { FromHalfFloat, ToHalfFloat } from \"./textureTools\";\r\n\r\nimport \"../Engines/AbstractEngine/abstractEngine.cubeTexture\";\r\n\r\n// Based on demo done by Brandon Jones - http://media.tojicode.com/webgl-samples/dds.html\r\n// All values and structures referenced from:\r\n// http://msdn.microsoft.com/en-us/library/bb943991.aspx/\r\nconst DDS_MAGIC = 0x20534444;\r\n\r\nconst //DDSD_CAPS = 0x1,\r\n //DDSD_HEIGHT = 0x2,\r\n //DDSD_WIDTH = 0x4,\r\n //DDSD_PITCH = 0x8,\r\n //DDSD_PIXELFORMAT = 0x1000,\r\n DDSD_MIPMAPCOUNT = 0x20000;\r\n//DDSD_LINEARSIZE = 0x80000,\r\n//DDSD_DEPTH = 0x800000;\r\n\r\n// var DDSCAPS_COMPLEX = 0x8,\r\n// DDSCAPS_MIPMAP = 0x400000,\r\n// DDSCAPS_TEXTURE = 0x1000;\r\n\r\nconst DDSCAPS2_CUBEMAP = 0x200;\r\n// DDSCAPS2_CUBEMAP_POSITIVEX = 0x400,\r\n// DDSCAPS2_CUBEMAP_NEGATIVEX = 0x800,\r\n// DDSCAPS2_CUBEMAP_POSITIVEY = 0x1000,\r\n// DDSCAPS2_CUBEMAP_NEGATIVEY = 0x2000,\r\n// DDSCAPS2_CUBEMAP_POSITIVEZ = 0x4000,\r\n// DDSCAPS2_CUBEMAP_NEGATIVEZ = 0x8000,\r\n// DDSCAPS2_VOLUME = 0x200000;\r\n\r\nconst //DDPF_ALPHAPIXELS = 0x1,\r\n //DDPF_ALPHA = 0x2,\r\n DDPF_FOURCC = 0x4,\r\n DDPF_RGB = 0x40,\r\n //DDPF_YUV = 0x200,\r\n DDPF_LUMINANCE = 0x20000;\r\n\r\nfunction FourCCToInt32(value: string) {\r\n return value.charCodeAt(0) + (value.charCodeAt(1) << 8) + (value.charCodeAt(2) << 16) + (value.charCodeAt(3) << 24);\r\n}\r\n\r\nfunction Int32ToFourCC(value: number) {\r\n return String.fromCharCode(value & 0xff, (value >> 8) & 0xff, (value >> 16) & 0xff, (value >> 24) & 0xff);\r\n}\r\n\r\nconst FOURCC_DXT1 = FourCCToInt32(\"DXT1\");\r\nconst FOURCC_DXT3 = FourCCToInt32(\"DXT3\");\r\nconst FOURCC_DXT5 = FourCCToInt32(\"DXT5\");\r\nconst FOURCC_DX10 = FourCCToInt32(\"DX10\");\r\nconst FOURCC_D3DFMT_R16G16B16A16F = 113;\r\nconst FOURCC_D3DFMT_R32G32B32A32F = 116;\r\n\r\nconst DXGI_FORMAT_R32G32B32A32_FLOAT = 2;\r\nconst DXGI_FORMAT_R16G16B16A16_FLOAT = 10;\r\nconst DXGI_FORMAT_B8G8R8X8_UNORM = 88;\r\n\r\nconst headerLengthInt = 31; // The header length in 32 bit ints\r\n\r\n// Offsets into the header array\r\nconst off_magic = 0;\r\n\r\nconst off_size = 1;\r\nconst off_flags = 2;\r\nconst off_height = 3;\r\nconst off_width = 4;\r\n\r\nconst off_mipmapCount = 7;\r\n\r\nconst off_pfFlags = 20;\r\nconst off_pfFourCC = 21;\r\nconst off_RGBbpp = 22;\r\nconst off_RMask = 23;\r\nconst off_GMask = 24;\r\nconst off_BMask = 25;\r\nconst off_AMask = 26;\r\n// var off_caps1 = 27;\r\nconst off_caps2 = 28;\r\n// var off_caps3 = 29;\r\n// var off_caps4 = 30;\r\nconst off_dxgiFormat = 32;\r\n\r\n/**\r\n * Direct draw surface info\r\n * @see https://docs.microsoft.com/en-us/windows/desktop/direct3ddds/dx-graphics-dds-pguide\r\n */\r\nexport interface DDSInfo {\r\n /**\r\n * Width of the texture\r\n */\r\n width: number;\r\n /**\r\n * Width of the texture\r\n */\r\n height: number;\r\n /**\r\n * Number of Mipmaps for the texture\r\n * @see https://en.wikipedia.org/wiki/Mipmap\r\n */\r\n mipmapCount: number;\r\n /**\r\n * If the textures format is a known fourCC format\r\n * @see https://www.fourcc.org/\r\n */\r\n isFourCC: boolean;\r\n /**\r\n * If the texture is an RGB format eg. DXGI_FORMAT_B8G8R8X8_UNORM format\r\n */\r\n isRGB: boolean;\r\n /**\r\n * If the texture is a lumincance format\r\n */\r\n isLuminance: boolean;\r\n /**\r\n * If this is a cube texture\r\n * @see https://docs.microsoft.com/en-us/windows/desktop/direct3ddds/dds-file-layout-for-cubic-environment-maps\r\n */\r\n isCube: boolean;\r\n /**\r\n * If the texture is a compressed format eg. FOURCC_DXT1\r\n */\r\n isCompressed: boolean;\r\n /**\r\n * The dxgiFormat of the texture\r\n * @see https://docs.microsoft.com/en-us/windows/desktop/api/dxgiformat/ne-dxgiformat-dxgi_format\r\n */\r\n dxgiFormat: number;\r\n /**\r\n * Texture type eg. Engine.TEXTURETYPE_UNSIGNED_BYTE, Engine.TEXTURETYPE_FLOAT\r\n */\r\n textureType: number;\r\n /**\r\n * Sphericle polynomial created for the dds texture\r\n */\r\n sphericalPolynomial?: SphericalPolynomial;\r\n}\r\n\r\n/**\r\n * Class used to provide DDS decompression tools\r\n */\r\nexport class DDSTools {\r\n /**\r\n * Gets or sets a boolean indicating that LOD info is stored in alpha channel (false by default)\r\n */\r\n public static StoreLODInAlphaChannel = false;\r\n\r\n /**\r\n * Gets DDS information from an array buffer\r\n * @param data defines the array buffer view to read data from\r\n * @returns the DDS information\r\n */\r\n public static GetDDSInfo(data: ArrayBufferView): DDSInfo {\r\n const header = new Int32Array(data.buffer, data.byteOffset, headerLengthInt);\r\n const extendedHeader = new Int32Array(data.buffer, data.byteOffset, headerLengthInt + 4);\r\n\r\n let mipmapCount = 1;\r\n if (header[off_flags] & DDSD_MIPMAPCOUNT) {\r\n mipmapCount = Math.max(1, header[off_mipmapCount]);\r\n }\r\n\r\n const fourCC = header[off_pfFourCC];\r\n const dxgiFormat = fourCC === FOURCC_DX10 ? extendedHeader[off_dxgiFormat] : 0;\r\n let textureType = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n\r\n switch (fourCC) {\r\n case FOURCC_D3DFMT_R16G16B16A16F:\r\n textureType = Constants.TEXTURETYPE_HALF_FLOAT;\r\n break;\r\n case FOURCC_D3DFMT_R32G32B32A32F:\r\n textureType = Constants.TEXTURETYPE_FLOAT;\r\n break;\r\n case FOURCC_DX10:\r\n if (dxgiFormat === DXGI_FORMAT_R16G16B16A16_FLOAT) {\r\n textureType = Constants.TEXTURETYPE_HALF_FLOAT;\r\n break;\r\n }\r\n if (dxgiFormat === DXGI_FORMAT_R32G32B32A32_FLOAT) {\r\n textureType = Constants.TEXTURETYPE_FLOAT;\r\n break;\r\n }\r\n }\r\n\r\n return {\r\n width: header[off_width],\r\n height: header[off_height],\r\n mipmapCount: mipmapCount,\r\n isFourCC: (header[off_pfFlags] & DDPF_FOURCC) === DDPF_FOURCC,\r\n isRGB: (header[off_pfFlags] & DDPF_RGB) === DDPF_RGB,\r\n isLuminance: (header[off_pfFlags] & DDPF_LUMINANCE) === DDPF_LUMINANCE,\r\n isCube: (header[off_caps2] & DDSCAPS2_CUBEMAP) === DDSCAPS2_CUBEMAP,\r\n isCompressed: fourCC === FOURCC_DXT1 || fourCC === FOURCC_DXT3 || fourCC === FOURCC_DXT5,\r\n dxgiFormat: dxgiFormat,\r\n textureType: textureType,\r\n };\r\n }\r\n\r\n private static _GetHalfFloatAsFloatRGBAArrayBuffer(width: number, height: number, dataOffset: number, dataLength: number, arrayBuffer: ArrayBuffer, lod: number): Float32Array {\r\n const destArray = new Float32Array(dataLength);\r\n const srcData = new Uint16Array(arrayBuffer, dataOffset);\r\n let index = 0;\r\n for (let y = 0; y < height; y++) {\r\n for (let x = 0; x < width; x++) {\r\n const srcPos = (x + y * width) * 4;\r\n destArray[index] = FromHalfFloat(srcData[srcPos]);\r\n destArray[index + 1] = FromHalfFloat(srcData[srcPos + 1]);\r\n destArray[index + 2] = FromHalfFloat(srcData[srcPos + 2]);\r\n if (DDSTools.StoreLODInAlphaChannel) {\r\n destArray[index + 3] = lod;\r\n } else {\r\n destArray[index + 3] = FromHalfFloat(srcData[srcPos + 3]);\r\n }\r\n index += 4;\r\n }\r\n }\r\n\r\n return destArray;\r\n }\r\n\r\n private static _GetHalfFloatRGBAArrayBuffer(width: number, height: number, dataOffset: number, dataLength: number, arrayBuffer: ArrayBuffer, lod: number): Uint16Array {\r\n if (DDSTools.StoreLODInAlphaChannel) {\r\n const destArray = new Uint16Array(dataLength);\r\n const srcData = new Uint16Array(arrayBuffer, dataOffset);\r\n let index = 0;\r\n for (let y = 0; y < height; y++) {\r\n for (let x = 0; x < width; x++) {\r\n const srcPos = (x + y * width) * 4;\r\n destArray[index] = srcData[srcPos];\r\n destArray[index + 1] = srcData[srcPos + 1];\r\n destArray[index + 2] = srcData[srcPos + 2];\r\n destArray[index + 3] = ToHalfFloat(lod);\r\n index += 4;\r\n }\r\n }\r\n\r\n return destArray;\r\n }\r\n\r\n return new Uint16Array(arrayBuffer, dataOffset, dataLength);\r\n }\r\n\r\n private static _GetFloatRGBAArrayBuffer(width: number, height: number, dataOffset: number, dataLength: number, arrayBuffer: ArrayBuffer, lod: number): Float32Array {\r\n if (DDSTools.StoreLODInAlphaChannel) {\r\n const destArray = new Float32Array(dataLength);\r\n const srcData = new Float32Array(arrayBuffer, dataOffset);\r\n let index = 0;\r\n for (let y = 0; y < height; y++) {\r\n for (let x = 0; x < width; x++) {\r\n const srcPos = (x + y * width) * 4;\r\n destArray[index] = srcData[srcPos];\r\n destArray[index + 1] = srcData[srcPos + 1];\r\n destArray[index + 2] = srcData[srcPos + 2];\r\n destArray[index + 3] = lod;\r\n index += 4;\r\n }\r\n }\r\n\r\n return destArray;\r\n }\r\n return new Float32Array(arrayBuffer, dataOffset, dataLength);\r\n }\r\n\r\n private static _GetFloatAsHalfFloatRGBAArrayBuffer(width: number, height: number, dataOffset: number, dataLength: number, arrayBuffer: ArrayBuffer, lod: number): Uint16Array {\r\n const destArray = new Uint16Array(dataLength);\r\n const srcData = new Float32Array(arrayBuffer, dataOffset);\r\n let index = 0;\r\n for (let y = 0; y < height; y++) {\r\n for (let x = 0; x < width; x++) {\r\n destArray[index] = ToHalfFloat(srcData[index]);\r\n destArray[index + 1] = ToHalfFloat(srcData[index + 1]);\r\n destArray[index + 2] = ToHalfFloat(srcData[index + 2]);\r\n if (DDSTools.StoreLODInAlphaChannel) {\r\n destArray[index + 3] = ToHalfFloat(lod);\r\n } else {\r\n destArray[index + 3] = ToHalfFloat(srcData[index + 3]);\r\n }\r\n index += 4;\r\n }\r\n }\r\n\r\n return destArray;\r\n }\r\n\r\n private static _GetFloatAsUIntRGBAArrayBuffer(width: number, height: number, dataOffset: number, dataLength: number, arrayBuffer: ArrayBuffer, lod: number): Uint8Array {\r\n const destArray = new Uint8Array(dataLength);\r\n const srcData = new Float32Array(arrayBuffer, dataOffset);\r\n let index = 0;\r\n for (let y = 0; y < height; y++) {\r\n for (let x = 0; x < width; x++) {\r\n const srcPos = (x + y * width) * 4;\r\n destArray[index] = Clamp(srcData[srcPos]) * 255;\r\n destArray[index + 1] = Clamp(srcData[srcPos + 1]) * 255;\r\n destArray[index + 2] = Clamp(srcData[srcPos + 2]) * 255;\r\n if (DDSTools.StoreLODInAlphaChannel) {\r\n destArray[index + 3] = lod;\r\n } else {\r\n destArray[index + 3] = Clamp(srcData[srcPos + 3]) * 255;\r\n }\r\n index += 4;\r\n }\r\n }\r\n\r\n return destArray;\r\n }\r\n\r\n private static _GetHalfFloatAsUIntRGBAArrayBuffer(width: number, height: number, dataOffset: number, dataLength: number, arrayBuffer: ArrayBuffer, lod: number): Uint8Array {\r\n const destArray = new Uint8Array(dataLength);\r\n const srcData = new Uint16Array(arrayBuffer, dataOffset);\r\n let index = 0;\r\n for (let y = 0; y < height; y++) {\r\n for (let x = 0; x < width; x++) {\r\n const srcPos = (x + y * width) * 4;\r\n destArray[index] = Clamp(FromHalfFloat(srcData[srcPos])) * 255;\r\n destArray[index + 1] = Clamp(FromHalfFloat(srcData[srcPos + 1])) * 255;\r\n destArray[index + 2] = Clamp(FromHalfFloat(srcData[srcPos + 2])) * 255;\r\n if (DDSTools.StoreLODInAlphaChannel) {\r\n destArray[index + 3] = lod;\r\n } else {\r\n destArray[index + 3] = Clamp(FromHalfFloat(srcData[srcPos + 3])) * 255;\r\n }\r\n index += 4;\r\n }\r\n }\r\n\r\n return destArray;\r\n }\r\n\r\n private static _GetRGBAArrayBuffer(\r\n width: number,\r\n height: number,\r\n dataOffset: number,\r\n dataLength: number,\r\n arrayBuffer: ArrayBuffer,\r\n rOffset: number,\r\n gOffset: number,\r\n bOffset: number,\r\n aOffset: number\r\n ): Uint8Array {\r\n const byteArray = new Uint8Array(dataLength);\r\n const srcData = new Uint8Array(arrayBuffer, dataOffset);\r\n let index = 0;\r\n for (let y = 0; y < height; y++) {\r\n for (let x = 0; x < width; x++) {\r\n const srcPos = (x + y * width) * 4;\r\n\r\n byteArray[index] = srcData[srcPos + rOffset];\r\n byteArray[index + 1] = srcData[srcPos + gOffset];\r\n byteArray[index + 2] = srcData[srcPos + bOffset];\r\n byteArray[index + 3] = srcData[srcPos + aOffset];\r\n index += 4;\r\n }\r\n }\r\n\r\n return byteArray;\r\n }\r\n\r\n private static _ExtractLongWordOrder(value: number): number {\r\n if (value === 0 || value === 255 || value === -16777216) {\r\n return 0;\r\n }\r\n\r\n return 1 + DDSTools._ExtractLongWordOrder(value >> 8);\r\n }\r\n\r\n private static _GetRGBArrayBuffer(\r\n width: number,\r\n height: number,\r\n dataOffset: number,\r\n dataLength: number,\r\n arrayBuffer: ArrayBuffer,\r\n rOffset: number,\r\n gOffset: number,\r\n bOffset: number\r\n ): Uint8Array {\r\n const byteArray = new Uint8Array(dataLength);\r\n const srcData = new Uint8Array(arrayBuffer, dataOffset);\r\n let index = 0;\r\n for (let y = 0; y < height; y++) {\r\n for (let x = 0; x < width; x++) {\r\n const srcPos = (x + y * width) * 3;\r\n\r\n byteArray[index] = srcData[srcPos + rOffset];\r\n byteArray[index + 1] = srcData[srcPos + gOffset];\r\n byteArray[index + 2] = srcData[srcPos + bOffset];\r\n index += 3;\r\n }\r\n }\r\n\r\n return byteArray;\r\n }\r\n\r\n private static _GetLuminanceArrayBuffer(width: number, height: number, dataOffset: number, dataLength: number, arrayBuffer: ArrayBuffer): Uint8Array {\r\n const byteArray = new Uint8Array(dataLength);\r\n const srcData = new Uint8Array(arrayBuffer, dataOffset);\r\n let index = 0;\r\n for (let y = 0; y < height; y++) {\r\n for (let x = 0; x < width; x++) {\r\n const srcPos = x + y * width;\r\n byteArray[index] = srcData[srcPos];\r\n index++;\r\n }\r\n }\r\n\r\n return byteArray;\r\n }\r\n\r\n /**\r\n * Uploads DDS Levels to a Babylon Texture\r\n * @internal\r\n */\r\n public static UploadDDSLevels(\r\n engine: AbstractEngine,\r\n texture: InternalTexture,\r\n data: ArrayBufferView,\r\n info: DDSInfo,\r\n loadMipmaps: boolean,\r\n faces: number,\r\n lodIndex = -1,\r\n currentFace?: number,\r\n destTypeMustBeFilterable = true\r\n ) {\r\n let sphericalPolynomialFaces: Nullable> = null;\r\n if (info.sphericalPolynomial) {\r\n sphericalPolynomialFaces = [] as ArrayBufferView[];\r\n }\r\n const ext = !!engine.getCaps().s3tc;\r\n\r\n // TODO WEBGPU Once generateMipMaps is split into generateMipMaps + hasMipMaps in InternalTexture this line can be removed\r\n texture.generateMipMaps = loadMipmaps;\r\n\r\n const header = new Int32Array(data.buffer, data.byteOffset, headerLengthInt);\r\n let fourCC: number,\r\n width: number,\r\n height: number,\r\n dataLength: number = 0,\r\n dataOffset: number;\r\n let byteArray: Uint8Array, mipmapCount: number, mip: number;\r\n let internalCompressedFormat = 0;\r\n let blockBytes = 1;\r\n\r\n if (header[off_magic] !== DDS_MAGIC) {\r\n Logger.Error(\"Invalid magic number in DDS header\");\r\n return;\r\n }\r\n\r\n if (!info.isFourCC && !info.isRGB && !info.isLuminance) {\r\n Logger.Error(\"Unsupported format, must contain a FourCC, RGB or LUMINANCE code\");\r\n return;\r\n }\r\n\r\n if (info.isCompressed && !ext) {\r\n Logger.Error(\"Compressed textures are not supported on this platform.\");\r\n return;\r\n }\r\n\r\n let bpp = header[off_RGBbpp];\r\n dataOffset = header[off_size] + 4;\r\n\r\n let computeFormats = false;\r\n\r\n if (info.isFourCC) {\r\n fourCC = header[off_pfFourCC];\r\n switch (fourCC) {\r\n case FOURCC_DXT1:\r\n blockBytes = 8;\r\n internalCompressedFormat = Constants.TEXTUREFORMAT_COMPRESSED_RGBA_S3TC_DXT1;\r\n break;\r\n case FOURCC_DXT3:\r\n blockBytes = 16;\r\n internalCompressedFormat = Constants.TEXTUREFORMAT_COMPRESSED_RGBA_S3TC_DXT3;\r\n break;\r\n case FOURCC_DXT5:\r\n blockBytes = 16;\r\n internalCompressedFormat = Constants.TEXTUREFORMAT_COMPRESSED_RGBA_S3TC_DXT5;\r\n break;\r\n case FOURCC_D3DFMT_R16G16B16A16F:\r\n computeFormats = true;\r\n bpp = 64;\r\n break;\r\n case FOURCC_D3DFMT_R32G32B32A32F:\r\n computeFormats = true;\r\n bpp = 128;\r\n break;\r\n case FOURCC_DX10: {\r\n // There is an additionnal header so dataOffset need to be changed\r\n dataOffset += 5 * 4; // 5 uints\r\n\r\n let supported = false;\r\n switch (info.dxgiFormat) {\r\n case DXGI_FORMAT_R16G16B16A16_FLOAT:\r\n computeFormats = true;\r\n bpp = 64;\r\n supported = true;\r\n break;\r\n case DXGI_FORMAT_R32G32B32A32_FLOAT:\r\n computeFormats = true;\r\n bpp = 128;\r\n supported = true;\r\n break;\r\n case DXGI_FORMAT_B8G8R8X8_UNORM:\r\n info.isRGB = true;\r\n info.isFourCC = false;\r\n bpp = 32;\r\n supported = true;\r\n break;\r\n }\r\n\r\n if (supported) {\r\n break;\r\n }\r\n }\r\n // eslint-disable-next-line no-fallthrough\r\n default:\r\n Logger.Error([\"Unsupported FourCC code:\", Int32ToFourCC(fourCC)]);\r\n return;\r\n }\r\n }\r\n\r\n const rOffset = DDSTools._ExtractLongWordOrder(header[off_RMask]);\r\n const gOffset = DDSTools._ExtractLongWordOrder(header[off_GMask]);\r\n const bOffset = DDSTools._ExtractLongWordOrder(header[off_BMask]);\r\n const aOffset = DDSTools._ExtractLongWordOrder(header[off_AMask]);\r\n\r\n if (computeFormats) {\r\n internalCompressedFormat = engine._getRGBABufferInternalSizedFormat(info.textureType);\r\n }\r\n\r\n mipmapCount = 1;\r\n if (header[off_flags] & DDSD_MIPMAPCOUNT && loadMipmaps !== false) {\r\n mipmapCount = Math.max(1, header[off_mipmapCount]);\r\n }\r\n\r\n const startFace = currentFace || 0;\r\n const caps = engine.getCaps();\r\n for (let face = startFace; face < faces; face++) {\r\n width = header[off_width];\r\n height = header[off_height];\r\n\r\n for (mip = 0; mip < mipmapCount; ++mip) {\r\n if (lodIndex === -1 || lodIndex === mip) {\r\n // In case of fixed LOD, if the lod has just been uploaded, early exit.\r\n const i = lodIndex === -1 ? mip : 0;\r\n\r\n if (!info.isCompressed && info.isFourCC) {\r\n texture.format = Constants.TEXTUREFORMAT_RGBA;\r\n dataLength = width * height * 4;\r\n let floatArray: Nullable = null;\r\n\r\n if (engine._badOS || engine._badDesktopOS || (!caps.textureHalfFloat && !caps.textureFloat)) {\r\n // Required because iOS has many issues with float and half float generation\r\n if (bpp === 128) {\r\n floatArray = DDSTools._GetFloatAsUIntRGBAArrayBuffer(width, height, data.byteOffset + dataOffset, dataLength, data.buffer, i);\r\n if (sphericalPolynomialFaces && i == 0) {\r\n sphericalPolynomialFaces.push(DDSTools._GetFloatRGBAArrayBuffer(width, height, data.byteOffset + dataOffset, dataLength, data.buffer, i));\r\n }\r\n } else if (bpp === 64) {\r\n floatArray = DDSTools._GetHalfFloatAsUIntRGBAArrayBuffer(width, height, data.byteOffset + dataOffset, dataLength, data.buffer, i);\r\n if (sphericalPolynomialFaces && i == 0) {\r\n sphericalPolynomialFaces.push(\r\n DDSTools._GetHalfFloatAsFloatRGBAArrayBuffer(width, height, data.byteOffset + dataOffset, dataLength, data.buffer, i)\r\n );\r\n }\r\n }\r\n\r\n texture.type = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n } else {\r\n const floatAvailable = caps.textureFloat && ((destTypeMustBeFilterable && caps.textureFloatLinearFiltering) || !destTypeMustBeFilterable);\r\n const halfFloatAvailable = caps.textureHalfFloat && ((destTypeMustBeFilterable && caps.textureHalfFloatLinearFiltering) || !destTypeMustBeFilterable);\r\n\r\n const destType =\r\n (bpp === 128 || (bpp === 64 && !halfFloatAvailable)) && floatAvailable\r\n ? Constants.TEXTURETYPE_FLOAT\r\n : (bpp === 64 || (bpp === 128 && !floatAvailable)) && halfFloatAvailable\r\n ? Constants.TEXTURETYPE_HALF_FLOAT\r\n : Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n\r\n let dataGetter: (width: number, height: number, dataOffset: number, dataLength: number, arrayBuffer: ArrayBuffer, lod: number) => ArrayBufferView;\r\n let dataGetterPolynomial: Nullable<\r\n (width: number, height: number, dataOffset: number, dataLength: number, arrayBuffer: ArrayBuffer, lod: number) => ArrayBufferView\r\n > = null;\r\n\r\n switch (bpp) {\r\n case 128: {\r\n switch (destType) {\r\n case Constants.TEXTURETYPE_FLOAT:\r\n dataGetter = DDSTools._GetFloatRGBAArrayBuffer;\r\n dataGetterPolynomial = null;\r\n break;\r\n case Constants.TEXTURETYPE_HALF_FLOAT:\r\n dataGetter = DDSTools._GetFloatAsHalfFloatRGBAArrayBuffer;\r\n dataGetterPolynomial = DDSTools._GetFloatRGBAArrayBuffer;\r\n break;\r\n case Constants.TEXTURETYPE_UNSIGNED_BYTE:\r\n dataGetter = DDSTools._GetFloatAsUIntRGBAArrayBuffer;\r\n dataGetterPolynomial = DDSTools._GetFloatRGBAArrayBuffer;\r\n break;\r\n }\r\n break;\r\n }\r\n default: {\r\n // 64 bpp\r\n switch (destType) {\r\n case Constants.TEXTURETYPE_FLOAT:\r\n dataGetter = DDSTools._GetHalfFloatAsFloatRGBAArrayBuffer;\r\n dataGetterPolynomial = null;\r\n break;\r\n case Constants.TEXTURETYPE_HALF_FLOAT:\r\n dataGetter = DDSTools._GetHalfFloatRGBAArrayBuffer;\r\n dataGetterPolynomial = DDSTools._GetHalfFloatAsFloatRGBAArrayBuffer;\r\n break;\r\n case Constants.TEXTURETYPE_UNSIGNED_BYTE:\r\n dataGetter = DDSTools._GetHalfFloatAsUIntRGBAArrayBuffer;\r\n dataGetterPolynomial = DDSTools._GetHalfFloatAsFloatRGBAArrayBuffer;\r\n break;\r\n }\r\n break;\r\n }\r\n }\r\n\r\n texture.type = destType;\r\n\r\n floatArray = dataGetter(width, height, data.byteOffset + dataOffset, dataLength, data.buffer, i);\r\n\r\n if (sphericalPolynomialFaces && i == 0) {\r\n sphericalPolynomialFaces.push(\r\n dataGetterPolynomial ? dataGetterPolynomial(width, height, data.byteOffset + dataOffset, dataLength, data.buffer, i) : floatArray\r\n );\r\n }\r\n }\r\n\r\n if (floatArray) {\r\n engine._uploadDataToTextureDirectly(texture, floatArray, face, i);\r\n }\r\n } else if (info.isRGB) {\r\n texture.type = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n if (bpp === 24) {\r\n texture.format = Constants.TEXTUREFORMAT_RGB;\r\n dataLength = width * height * 3;\r\n byteArray = DDSTools._GetRGBArrayBuffer(width, height, data.byteOffset + dataOffset, dataLength, data.buffer, rOffset, gOffset, bOffset);\r\n engine._uploadDataToTextureDirectly(texture, byteArray, face, i);\r\n } else {\r\n // 32\r\n texture.format = Constants.TEXTUREFORMAT_RGBA;\r\n dataLength = width * height * 4;\r\n byteArray = DDSTools._GetRGBAArrayBuffer(width, height, data.byteOffset + dataOffset, dataLength, data.buffer, rOffset, gOffset, bOffset, aOffset);\r\n engine._uploadDataToTextureDirectly(texture, byteArray, face, i);\r\n }\r\n } else if (info.isLuminance) {\r\n const unpackAlignment = engine._getUnpackAlignement();\r\n const unpaddedRowSize = width;\r\n const paddedRowSize = Math.floor((width + unpackAlignment - 1) / unpackAlignment) * unpackAlignment;\r\n dataLength = paddedRowSize * (height - 1) + unpaddedRowSize;\r\n\r\n byteArray = DDSTools._GetLuminanceArrayBuffer(width, height, data.byteOffset + dataOffset, dataLength, data.buffer);\r\n texture.format = Constants.TEXTUREFORMAT_LUMINANCE;\r\n texture.type = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n\r\n engine._uploadDataToTextureDirectly(texture, byteArray, face, i);\r\n } else {\r\n dataLength = (((Math.max(4, width) / 4) * Math.max(4, height)) / 4) * blockBytes;\r\n byteArray = new Uint8Array(data.buffer, data.byteOffset + dataOffset, dataLength);\r\n\r\n texture.type = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n engine._uploadCompressedDataToTextureDirectly(texture, internalCompressedFormat, width, height, byteArray, face, i);\r\n }\r\n }\r\n dataOffset += bpp ? width * height * (bpp / 8) : dataLength;\r\n width *= 0.5;\r\n height *= 0.5;\r\n\r\n width = Math.max(1.0, width);\r\n height = Math.max(1.0, height);\r\n }\r\n\r\n if (currentFace !== undefined) {\r\n // Loading a single face\r\n break;\r\n }\r\n }\r\n if (sphericalPolynomialFaces && sphericalPolynomialFaces.length > 0) {\r\n info.sphericalPolynomial = CubeMapToSphericalPolynomialTools.ConvertCubeMapToSphericalPolynomial({\r\n size: header[off_width],\r\n right: sphericalPolynomialFaces[0],\r\n left: sphericalPolynomialFaces[1],\r\n up: sphericalPolynomialFaces[2],\r\n down: sphericalPolynomialFaces[3],\r\n front: sphericalPolynomialFaces[4],\r\n back: sphericalPolynomialFaces[5],\r\n format: Constants.TEXTUREFORMAT_RGBA,\r\n type: Constants.TEXTURETYPE_FLOAT,\r\n gammaSpace: false,\r\n });\r\n } else {\r\n info.sphericalPolynomial = undefined;\r\n }\r\n }\r\n}\r\n","// eslint-disable-next-line @typescript-eslint/naming-convention\r\nconst __mergedStore = {};\r\n\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nconst __decoratorInitialStore = {};\r\n\r\n/** @internal */\r\nexport function GetDirectStore(target: any): any {\r\n const classKey = target.getClassName();\r\n\r\n if (!(__decoratorInitialStore)[classKey]) {\r\n (__decoratorInitialStore)[classKey] = {};\r\n }\r\n\r\n return (__decoratorInitialStore)[classKey];\r\n}\r\n\r\n/**\r\n * @returns the list of properties flagged as serializable\r\n * @param target host object\r\n */\r\nexport function GetMergedStore(target: any): any {\r\n const classKey = target.getClassName();\r\n\r\n if ((__mergedStore)[classKey]) {\r\n return (__mergedStore)[classKey];\r\n }\r\n\r\n (__mergedStore)[classKey] = {};\r\n\r\n const store = (__mergedStore)[classKey];\r\n let currentTarget = target;\r\n let currentKey = classKey;\r\n while (currentKey) {\r\n const initialStore = (__decoratorInitialStore)[currentKey];\r\n for (const property in initialStore) {\r\n store[property] = initialStore[property];\r\n }\r\n\r\n let parent: any;\r\n let done = false;\r\n\r\n do {\r\n parent = Object.getPrototypeOf(currentTarget);\r\n if (!parent.getClassName) {\r\n done = true;\r\n break;\r\n }\r\n\r\n if (parent.getClassName() !== currentKey) {\r\n break;\r\n }\r\n\r\n currentTarget = parent;\r\n } while (parent);\r\n\r\n if (done) {\r\n break;\r\n }\r\n\r\n currentKey = parent.getClassName();\r\n currentTarget = parent;\r\n }\r\n\r\n return store;\r\n}\r\n","/* eslint-disable @typescript-eslint/no-unused-vars */\r\n/* eslint-disable @typescript-eslint/naming-convention */\r\nimport type { Nullable } from \"../types\";\r\nimport { GetDirectStore } from \"./decorators.functions\";\r\nimport { _WarnImport } from \"./devTools\";\r\n\r\nfunction generateSerializableMember(type: number, sourceName?: string) {\r\n return (target: any, propertyKey: string | symbol) => {\r\n const classStore = GetDirectStore(target);\r\n\r\n if (!classStore[propertyKey]) {\r\n classStore[propertyKey] = { type: type, sourceName: sourceName };\r\n }\r\n };\r\n}\r\n\r\nfunction generateExpandMember(setCallback: string, targetKey: Nullable = null) {\r\n return (target: any, propertyKey: string) => {\r\n const key = targetKey || \"_\" + propertyKey;\r\n Object.defineProperty(target, propertyKey, {\r\n get: function (this: any) {\r\n return this[key];\r\n },\r\n set: function (this: any, value) {\r\n // does this object (i.e. vector3) has an equals function? use it!\r\n // Note - not using \"with epsilon\" here, it is expected te behave like the internal cache does.\r\n if (typeof this.equals === \"function\") {\r\n if (this.equals(value)) {\r\n return;\r\n }\r\n }\r\n if (this[key] === value) {\r\n return;\r\n }\r\n this[key] = value;\r\n\r\n target[setCallback].apply(this);\r\n },\r\n enumerable: true,\r\n configurable: true,\r\n });\r\n };\r\n}\r\n\r\nexport function expandToProperty(callback: string, targetKey: Nullable = null) {\r\n return generateExpandMember(callback, targetKey);\r\n}\r\n\r\nexport function serialize(sourceName?: string) {\r\n return generateSerializableMember(0, sourceName); // value member\r\n}\r\n\r\nexport function serializeAsTexture(sourceName?: string) {\r\n return generateSerializableMember(1, sourceName); // texture member\r\n}\r\n\r\nexport function serializeAsColor3(sourceName?: string) {\r\n return generateSerializableMember(2, sourceName); // color3 member\r\n}\r\n\r\nexport function serializeAsFresnelParameters(sourceName?: string) {\r\n return generateSerializableMember(3, sourceName); // fresnel parameters member\r\n}\r\n\r\nexport function serializeAsVector2(sourceName?: string) {\r\n return generateSerializableMember(4, sourceName); // vector2 member\r\n}\r\n\r\nexport function serializeAsVector3(sourceName?: string) {\r\n return generateSerializableMember(5, sourceName); // vector3 member\r\n}\r\n\r\nexport function serializeAsMeshReference(sourceName?: string) {\r\n return generateSerializableMember(6, sourceName); // mesh reference member\r\n}\r\n\r\nexport function serializeAsColorCurves(sourceName?: string) {\r\n return generateSerializableMember(7, sourceName); // color curves\r\n}\r\n\r\nexport function serializeAsColor4(sourceName?: string) {\r\n return generateSerializableMember(8, sourceName); // color 4\r\n}\r\n\r\nexport function serializeAsImageProcessingConfiguration(sourceName?: string) {\r\n return generateSerializableMember(9, sourceName); // image processing\r\n}\r\n\r\nexport function serializeAsQuaternion(sourceName?: string) {\r\n return generateSerializableMember(10, sourceName); // quaternion member\r\n}\r\n\r\nexport function serializeAsMatrix(sourceName?: string) {\r\n return generateSerializableMember(12, sourceName); // matrix member\r\n}\r\n\r\n/**\r\n * Decorator used to define property that can be serialized as reference to a camera\r\n * @param sourceName defines the name of the property to decorate\r\n * @returns Property Decorator\r\n */\r\nexport function serializeAsCameraReference(sourceName?: string) {\r\n return generateSerializableMember(11, sourceName); // camera reference member\r\n}\r\n\r\n/** @internal */\r\ndeclare const _native: any;\r\n\r\n/**\r\n * Decorator used to redirect a function to a native implementation if available.\r\n * @internal\r\n */\r\nexport function nativeOverride boolean>(\r\n target: any,\r\n propertyKey: string,\r\n descriptor: TypedPropertyDescriptor<(...params: Parameters) => unknown>,\r\n predicate?: T\r\n) {\r\n // Cache the original JS function for later.\r\n const jsFunc = descriptor.value!;\r\n\r\n // Override the JS function to check for a native override on first invocation. Setting descriptor.value overrides the function at the early stage of code being loaded/imported.\r\n descriptor.value = (...params: Parameters): unknown => {\r\n // Assume the resolved function will be the original JS function, then we will check for the Babylon Native context.\r\n let func = jsFunc;\r\n\r\n // Check if we are executing in a Babylon Native context (e.g. check the presence of the _native global property) and if so also check if a function override is available.\r\n if (typeof _native !== \"undefined\" && _native[propertyKey]) {\r\n const nativeFunc = _native[propertyKey] as (...params: Parameters) => unknown;\r\n // If a predicate was provided, then we'll need to invoke the predicate on each invocation of the underlying function to determine whether to call the native function or the JS function.\r\n if (predicate) {\r\n // The resolved function will execute the predicate and then either execute the native function or the JS function.\r\n func = (...params: Parameters) => (predicate(...params) ? nativeFunc(...params) : jsFunc(...params));\r\n } else {\r\n // The resolved function will directly execute the native function.\r\n func = nativeFunc;\r\n }\r\n }\r\n\r\n // Override the JS function again with the final resolved target function.\r\n target[propertyKey] = func;\r\n\r\n // The JS function has now been overridden based on whether we're executing in the context of Babylon Native, but we still need to invoke that function.\r\n // Future invocations of the function will just directly invoke the final overridden function, not any of the decorator setup logic above.\r\n return func(...params);\r\n };\r\n}\r\n\r\n/**\r\n * Decorator factory that applies the nativeOverride decorator, but determines whether to redirect to the native implementation based on a filter function that evaluates the function arguments.\r\n * @param predicate\r\n * @example @nativeOverride.filter((...[arg1]: Parameters) => arg1.length > 20)\r\n * public someMethod(arg1: string, arg2: number): string {\r\n * @internal\r\n */\r\nnativeOverride.filter = function boolean>(predicate: T) {\r\n return (target: any, propertyKey: string, descriptor: TypedPropertyDescriptor<(...params: Parameters) => unknown>) =>\r\n nativeOverride(target, propertyKey, descriptor, predicate);\r\n};\r\n","import type { FresnelParameters } from \"../Materials/fresnelParameters\";\r\nimport type { ImageProcessingConfiguration } from \"../Materials/imageProcessingConfiguration\";\r\nimport { _WarnImport } from \"./devTools\";\r\nimport type { ColorCurves } from \"../Materials/colorCurves\";\r\nimport type { Scene } from \"../scene\";\r\nimport type { Nullable } from \"../types\";\r\nimport type { BaseTexture } from \"../Materials/Textures/baseTexture\";\r\nimport type { IAnimatable } from \"../Animations/animatable.interface\";\r\nimport { Tags } from \"./tags\";\r\nimport { Color3, Color4 } from \"../Maths/math.color\";\r\nimport { Matrix, Quaternion, Vector2, Vector3 } from \"../Maths/math.vector\";\r\nimport type { Camera } from \"../Cameras/camera\";\r\nimport { GetMergedStore } from \"./decorators.functions\";\r\n\r\n/** @internal */\r\nexport interface CopySourceOptions {\r\n /*\r\n * if a texture is used in more than one channel (e.g diffuse and opacity),\r\n * only clone it once and reuse it on the other channels. Default false\r\n */\r\n cloneTexturesOnlyOnce?: boolean;\r\n}\r\n\r\nconst _copySource = function (creationFunction: () => T, source: T, instanciate: boolean, options: CopySourceOptions = {}): T {\r\n const destination = creationFunction();\r\n\r\n // Tags\r\n if (Tags && Tags.HasTags(source)) {\r\n Tags.AddTagsTo(destination, Tags.GetTags(source, true));\r\n }\r\n\r\n const classStore = GetMergedStore(destination);\r\n\r\n // Map from source texture uniqueId to destination texture\r\n const textureMap: Record = {};\r\n\r\n // Properties\r\n for (const property in classStore) {\r\n const propertyDescriptor = classStore[property];\r\n const sourceProperty = (source)[property];\r\n const propertyType = propertyDescriptor.type;\r\n\r\n if (sourceProperty !== undefined && sourceProperty !== null && (property !== \"uniqueId\" || SerializationHelper.AllowLoadingUniqueId)) {\r\n switch (propertyType) {\r\n case 0: // Value\r\n case 6: // Mesh reference\r\n case 9: // Image processing configuration reference\r\n case 11: // Camera reference\r\n (destination)[property] = sourceProperty;\r\n break;\r\n case 1: // Texture\r\n if (options.cloneTexturesOnlyOnce && textureMap[sourceProperty.uniqueId]) {\r\n (destination)[property] = textureMap[sourceProperty.uniqueId];\r\n } else {\r\n (destination)[property] = instanciate || sourceProperty.isRenderTarget ? sourceProperty : sourceProperty.clone();\r\n textureMap[sourceProperty.uniqueId] = (destination)[property];\r\n }\r\n break;\r\n case 2: // Color3\r\n case 3: // FresnelParameters\r\n case 4: // Vector2\r\n case 5: // Vector3\r\n case 7: // Color Curves\r\n case 8: // Color 4\r\n case 10: // Quaternion\r\n case 12: // Matrix\r\n (destination)[property] = instanciate ? sourceProperty : sourceProperty.clone();\r\n break;\r\n }\r\n }\r\n }\r\n\r\n return destination;\r\n};\r\n\r\n/**\r\n * Class used to help serialization objects\r\n */\r\nexport class SerializationHelper {\r\n /**\r\n * Gets or sets a boolean to indicate if the UniqueId property should be serialized\r\n */\r\n public static AllowLoadingUniqueId = false;\r\n\r\n /**\r\n * @internal\r\n */\r\n public static _ImageProcessingConfigurationParser = (sourceProperty: any): ImageProcessingConfiguration => {\r\n throw _WarnImport(\"ImageProcessingConfiguration\");\r\n };\r\n\r\n /**\r\n * @internal\r\n */\r\n public static _FresnelParametersParser = (sourceProperty: any): FresnelParameters => {\r\n throw _WarnImport(\"FresnelParameters\");\r\n };\r\n\r\n /**\r\n * @internal\r\n */\r\n public static _ColorCurvesParser = (sourceProperty: any): ColorCurves => {\r\n throw _WarnImport(\"ColorCurves\");\r\n };\r\n\r\n /**\r\n * @internal\r\n */\r\n public static _TextureParser = (sourceProperty: any, scene: Scene, rootUrl: string): Nullable => {\r\n throw _WarnImport(\"Texture\");\r\n };\r\n\r\n /**\r\n * Appends the serialized animations from the source animations\r\n * @param source Source containing the animations\r\n * @param destination Target to store the animations\r\n */\r\n public static AppendSerializedAnimations(source: IAnimatable, destination: any): void {\r\n if (source.animations) {\r\n destination.animations = [];\r\n for (let animationIndex = 0; animationIndex < source.animations.length; animationIndex++) {\r\n const animation = source.animations[animationIndex];\r\n\r\n destination.animations.push(animation.serialize());\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Static function used to serialized a specific entity\r\n * @param entity defines the entity to serialize\r\n * @param serializationObject defines the optional target object where serialization data will be stored\r\n * @returns a JSON compatible object representing the serialization of the entity\r\n */\r\n public static Serialize(entity: T, serializationObject?: any): any {\r\n if (!serializationObject) {\r\n serializationObject = {};\r\n }\r\n\r\n // Tags\r\n if (Tags) {\r\n serializationObject.tags = Tags.GetTags(entity);\r\n }\r\n\r\n const serializedProperties = GetMergedStore(entity);\r\n\r\n // Properties\r\n for (const property in serializedProperties) {\r\n const propertyDescriptor = serializedProperties[property];\r\n const targetPropertyName = propertyDescriptor.sourceName || property;\r\n const propertyType = propertyDescriptor.type;\r\n const sourceProperty = (entity)[property];\r\n\r\n if (sourceProperty !== undefined && sourceProperty !== null && (property !== \"uniqueId\" || SerializationHelper.AllowLoadingUniqueId)) {\r\n switch (propertyType) {\r\n case 0: // Value\r\n serializationObject[targetPropertyName] = sourceProperty;\r\n break;\r\n case 1: // Texture\r\n serializationObject[targetPropertyName] = sourceProperty.serialize();\r\n break;\r\n case 2: // Color3\r\n serializationObject[targetPropertyName] = sourceProperty.asArray();\r\n break;\r\n case 3: // FresnelParameters\r\n serializationObject[targetPropertyName] = sourceProperty.serialize();\r\n break;\r\n case 4: // Vector2\r\n serializationObject[targetPropertyName] = sourceProperty.asArray();\r\n break;\r\n case 5: // Vector3\r\n serializationObject[targetPropertyName] = sourceProperty.asArray();\r\n break;\r\n case 6: // Mesh reference\r\n serializationObject[targetPropertyName] = sourceProperty.id;\r\n break;\r\n case 7: // Color Curves\r\n serializationObject[targetPropertyName] = sourceProperty.serialize();\r\n break;\r\n case 8: // Color 4\r\n serializationObject[targetPropertyName] = (sourceProperty).asArray();\r\n break;\r\n case 9: // Image Processing\r\n serializationObject[targetPropertyName] = (sourceProperty).serialize();\r\n break;\r\n case 10: // Quaternion\r\n serializationObject[targetPropertyName] = (sourceProperty).asArray();\r\n break;\r\n case 11: // Camera reference\r\n serializationObject[targetPropertyName] = (sourceProperty).id;\r\n break;\r\n case 12: // Matrix\r\n serializationObject[targetPropertyName] = (sourceProperty).asArray();\r\n break;\r\n }\r\n }\r\n }\r\n\r\n return serializationObject;\r\n }\r\n\r\n /**\r\n * Given a source json and a destination object in a scene, this function will parse the source and will try to apply its content to the destination object\r\n * @param source the source json data\r\n * @param destination the destination object\r\n * @param scene the scene where the object is\r\n * @param rootUrl root url to use to load assets\r\n */\r\n public static ParseProperties(source: any, destination: any, scene: Nullable, rootUrl: Nullable) {\r\n if (!rootUrl) {\r\n rootUrl = \"\";\r\n }\r\n\r\n const classStore = GetMergedStore(destination);\r\n\r\n // Properties\r\n for (const property in classStore) {\r\n const propertyDescriptor = classStore[property];\r\n const sourceProperty = source[propertyDescriptor.sourceName || property];\r\n const propertyType = propertyDescriptor.type;\r\n\r\n if (sourceProperty !== undefined && sourceProperty !== null && (property !== \"uniqueId\" || SerializationHelper.AllowLoadingUniqueId)) {\r\n const dest = destination;\r\n switch (propertyType) {\r\n case 0: // Value\r\n dest[property] = sourceProperty;\r\n break;\r\n case 1: // Texture\r\n if (scene) {\r\n dest[property] = SerializationHelper._TextureParser(sourceProperty, scene, rootUrl);\r\n }\r\n break;\r\n case 2: // Color3\r\n dest[property] = Color3.FromArray(sourceProperty);\r\n break;\r\n case 3: // FresnelParameters\r\n dest[property] = SerializationHelper._FresnelParametersParser(sourceProperty);\r\n break;\r\n case 4: // Vector2\r\n dest[property] = Vector2.FromArray(sourceProperty);\r\n break;\r\n case 5: // Vector3\r\n dest[property] = Vector3.FromArray(sourceProperty);\r\n break;\r\n case 6: // Mesh reference\r\n if (scene) {\r\n dest[property] = scene.getLastMeshById(sourceProperty);\r\n }\r\n break;\r\n case 7: // Color Curves\r\n dest[property] = SerializationHelper._ColorCurvesParser(sourceProperty);\r\n break;\r\n case 8: // Color 4\r\n dest[property] = Color4.FromArray(sourceProperty);\r\n break;\r\n case 9: // Image Processing\r\n dest[property] = SerializationHelper._ImageProcessingConfigurationParser(sourceProperty);\r\n break;\r\n case 10: // Quaternion\r\n dest[property] = Quaternion.FromArray(sourceProperty);\r\n break;\r\n case 11: // Camera reference\r\n if (scene) {\r\n dest[property] = scene.getCameraById(sourceProperty);\r\n }\r\n break;\r\n case 12: // Matrix\r\n dest[property] = Matrix.FromArray(sourceProperty);\r\n break;\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Creates a new entity from a serialization data object\r\n * @param creationFunction defines a function used to instanciated the new entity\r\n * @param source defines the source serialization data\r\n * @param scene defines the hosting scene\r\n * @param rootUrl defines the root url for resources\r\n * @returns a new entity\r\n */\r\n public static Parse(creationFunction: () => T, source: any, scene: Nullable, rootUrl: Nullable = null): T {\r\n const destination = creationFunction();\r\n\r\n // Tags\r\n if (Tags) {\r\n Tags.AddTagsTo(destination, source.tags);\r\n }\r\n\r\n SerializationHelper.ParseProperties(source, destination, scene, rootUrl);\r\n\r\n return destination;\r\n }\r\n\r\n /**\r\n * Clones an object\r\n * @param creationFunction defines the function used to instanciate the new object\r\n * @param source defines the source object\r\n * @param options defines the options to use\r\n * @returns the cloned object\r\n */\r\n public static Clone(creationFunction: () => T, source: T, options: CopySourceOptions = {}): T {\r\n return _copySource(creationFunction, source, false, options);\r\n }\r\n\r\n /**\r\n * Instanciates a new object based on a source one (some data will be shared between both object)\r\n * @param creationFunction defines the function used to instanciate the new object\r\n * @param source defines the source object\r\n * @returns the new object\r\n */\r\n public static Instanciate(creationFunction: () => T, source: T): T {\r\n return _copySource(creationFunction, source, true);\r\n }\r\n}\r\n","/* eslint-disable @typescript-eslint/no-unused-vars */\r\nimport { _WarnImport } from \"./devTools\";\r\n\r\nimport type { ThinEngine } from \"../Engines/thinEngine\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { EffectRenderer, EffectWrapper } from \"../Materials/effectRenderer\";\r\nimport { Tools } from \"./tools\";\r\nimport type { Nullable } from \"../types\";\r\nimport { Clamp } from \"../Maths/math.scalar.functions\";\r\nimport type { AbstractEngine } from \"../Engines/abstractEngine\";\r\nimport { EngineStore } from \"../Engines/engineStore\";\r\n\r\ntype DumpToolsEngine = {\r\n canvas: HTMLCanvasElement | OffscreenCanvas;\r\n engine: ThinEngine;\r\n renderer: EffectRenderer;\r\n wrapper: EffectWrapper;\r\n};\r\n\r\nlet _dumpToolsEngine: Nullable;\r\n\r\nlet _enginePromise: Promise | null = null;\r\n\r\nasync function _CreateDumpRenderer(): Promise {\r\n if (!_enginePromise) {\r\n _enginePromise = new Promise((resolve, reject) => {\r\n let canvas: HTMLCanvasElement | OffscreenCanvas;\r\n let engine: Nullable = null;\r\n const options = {\r\n preserveDrawingBuffer: true,\r\n depth: false,\r\n stencil: false,\r\n alpha: true,\r\n premultipliedAlpha: false,\r\n antialias: false,\r\n failIfMajorPerformanceCaveat: false,\r\n };\r\n import(\"../Engines/thinEngine\")\r\n .then(({ ThinEngine: thinEngineClass }) => {\r\n try {\r\n canvas = new OffscreenCanvas(100, 100); // will be resized later\r\n engine = new thinEngineClass(canvas, false, options);\r\n } catch (e) {\r\n // The browser either does not support OffscreenCanvas or WebGL context in OffscreenCanvas, fallback on a regular canvas\r\n canvas = document.createElement(\"canvas\");\r\n engine = new thinEngineClass(canvas, false, options);\r\n }\r\n // remove this engine from the list of instances to avoid using it for other purposes\r\n EngineStore.Instances.pop();\r\n // However, make sure to dispose it when no other engines are left\r\n EngineStore.OnEnginesDisposedObservable.add((e) => {\r\n // guaranteed to run when no other instances are left\r\n // only dispose if it's not the current engine\r\n if (engine && e !== engine && !engine.isDisposed && EngineStore.Instances.length === 0) {\r\n // Dump the engine and the associated resources\r\n Dispose();\r\n }\r\n });\r\n engine.getCaps().parallelShaderCompile = undefined;\r\n const renderer = new EffectRenderer(engine);\r\n import(\"../Shaders/pass.fragment\").then(({ passPixelShader }) => {\r\n if (!engine) {\r\n reject(\"Engine is not defined\");\r\n return;\r\n }\r\n const wrapper = new EffectWrapper({\r\n engine,\r\n name: passPixelShader.name,\r\n fragmentShader: passPixelShader.shader,\r\n samplerNames: [\"textureSampler\"],\r\n });\r\n _dumpToolsEngine = {\r\n canvas,\r\n engine,\r\n renderer,\r\n wrapper,\r\n };\r\n resolve(_dumpToolsEngine);\r\n });\r\n })\r\n .catch(reject);\r\n });\r\n }\r\n return await _enginePromise;\r\n}\r\n\r\n/**\r\n * Dumps the current bound framebuffer\r\n * @param width defines the rendering width\r\n * @param height defines the rendering height\r\n * @param engine defines the hosting engine\r\n * @param successCallback defines the callback triggered once the data are available\r\n * @param mimeType defines the mime type of the result\r\n * @param fileName defines the filename to download. If present, the result will automatically be downloaded\r\n * @param quality The quality of the image if lossy mimeType is used (e.g. image/jpeg, image/webp). See {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob | HTMLCanvasElement.toBlob()}'s `quality` parameter.\r\n * @returns a void promise\r\n */\r\nexport async function DumpFramebuffer(\r\n width: number,\r\n height: number,\r\n engine: AbstractEngine,\r\n successCallback?: (data: string) => void,\r\n mimeType = \"image/png\",\r\n fileName?: string,\r\n quality?: number\r\n) {\r\n // Read the contents of the framebuffer\r\n const bufferView = await engine.readPixels(0, 0, width, height);\r\n\r\n const data = new Uint8Array(bufferView.buffer);\r\n\r\n DumpData(width, height, data, successCallback as (data: string | ArrayBuffer) => void, mimeType, fileName, true, undefined, quality);\r\n}\r\n\r\n/**\r\n * Dumps an array buffer\r\n * @param width defines the rendering width\r\n * @param height defines the rendering height\r\n * @param data the data array\r\n * @param mimeType defines the mime type of the result\r\n * @param fileName defines the filename to download. If present, the result will automatically be downloaded\r\n * @param invertY true to invert the picture in the Y dimension\r\n * @param toArrayBuffer true to convert the data to an ArrayBuffer (encoded as `mimeType`) instead of a base64 string\r\n * @param quality The quality of the image if lossy mimeType is used (e.g. image/jpeg, image/webp). See {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob | HTMLCanvasElement.toBlob()}'s `quality` parameter.\r\n * @returns a promise that resolve to the final data\r\n */\r\nexport function DumpDataAsync(\r\n width: number,\r\n height: number,\r\n data: ArrayBufferView,\r\n mimeType = \"image/png\",\r\n fileName?: string,\r\n invertY = false,\r\n toArrayBuffer = false,\r\n quality?: number\r\n): Promise {\r\n return new Promise((resolve) => {\r\n DumpData(width, height, data, (result) => resolve(result), mimeType, fileName, invertY, toArrayBuffer, quality);\r\n });\r\n}\r\n\r\n/**\r\n * Dumps an array buffer\r\n * @param width defines the rendering width\r\n * @param height defines the rendering height\r\n * @param data the data array\r\n * @param successCallback defines the callback triggered once the data are available\r\n * @param mimeType defines the mime type of the result\r\n * @param fileName defines the filename to download. If present, the result will automatically be downloaded\r\n * @param invertY true to invert the picture in the Y dimension\r\n * @param toArrayBuffer true to convert the data to an ArrayBuffer (encoded as `mimeType`) instead of a base64 string\r\n * @param quality The quality of the image if lossy mimeType is used (e.g. image/jpeg, image/webp). See {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob | HTMLCanvasElement.toBlob()}'s `quality` parameter.\r\n */\r\nexport function DumpData(\r\n width: number,\r\n height: number,\r\n data: ArrayBufferView,\r\n successCallback?: (data: string | ArrayBuffer) => void,\r\n mimeType = \"image/png\",\r\n fileName?: string,\r\n invertY = false,\r\n toArrayBuffer = false,\r\n quality?: number\r\n): void {\r\n _CreateDumpRenderer().then((renderer) => {\r\n renderer.engine.setSize(width, height, true);\r\n\r\n // Convert if data are float32\r\n if (data instanceof Float32Array) {\r\n const data2 = new Uint8Array(data.length);\r\n let n = data.length;\r\n while (n--) {\r\n const v = data[n];\r\n data2[n] = Math.round(Clamp(v) * 255);\r\n }\r\n data = data2;\r\n }\r\n\r\n // Create the image\r\n const texture = renderer.engine.createRawTexture(data, width, height, Constants.TEXTUREFORMAT_RGBA, false, !invertY, Constants.TEXTURE_NEAREST_NEAREST);\r\n\r\n renderer.renderer.setViewport();\r\n renderer.renderer.applyEffectWrapper(renderer.wrapper);\r\n renderer.wrapper.effect._bindTexture(\"textureSampler\", texture);\r\n renderer.renderer.draw();\r\n\r\n if (toArrayBuffer) {\r\n Tools.ToBlob(\r\n renderer.canvas,\r\n (blob) => {\r\n const fileReader = new FileReader();\r\n fileReader.onload = (event: any) => {\r\n const arrayBuffer = event.target!.result as ArrayBuffer;\r\n if (successCallback) {\r\n successCallback(arrayBuffer);\r\n }\r\n };\r\n fileReader.readAsArrayBuffer(blob!);\r\n },\r\n mimeType,\r\n quality\r\n );\r\n } else {\r\n Tools.EncodeScreenshotCanvasData(renderer.canvas, successCallback, mimeType, fileName, quality);\r\n }\r\n\r\n texture.dispose();\r\n });\r\n}\r\n\r\n/**\r\n * Dispose the dump tools associated resources\r\n */\r\nexport function Dispose() {\r\n if (_dumpToolsEngine) {\r\n _dumpToolsEngine.wrapper.dispose();\r\n _dumpToolsEngine.renderer.dispose();\r\n _dumpToolsEngine.engine.dispose();\r\n } else {\r\n // in cases where the engine is not yet created, we need to wait for it to dispose it\r\n _enginePromise?.then((dumpToolsEngine) => {\r\n dumpToolsEngine.wrapper.dispose();\r\n dumpToolsEngine.renderer.dispose();\r\n dumpToolsEngine.engine.dispose();\r\n });\r\n }\r\n _enginePromise = null;\r\n _dumpToolsEngine = null;\r\n}\r\n\r\n/**\r\n * Object containing a set of static utilities functions to dump data from a canvas\r\n * @deprecated use functions\r\n */\r\nexport const DumpTools = {\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n DumpData,\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n DumpDataAsync,\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n DumpFramebuffer,\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n Dispose,\r\n};\r\n\r\n/**\r\n * This will be executed automatically for UMD and es5.\r\n * If esm dev wants the side effects to execute they will have to run it manually\r\n * Once we build native modules those need to be exported.\r\n * @internal\r\n */\r\nconst initSideEffects = () => {\r\n // References the dependencies.\r\n Tools.DumpData = DumpData;\r\n Tools.DumpDataAsync = DumpDataAsync;\r\n Tools.DumpFramebuffer = DumpFramebuffer;\r\n};\r\n\r\ninitSideEffects();\r\n","import { PrecisionDate } from \"./precisionDate\";\r\n\r\n/**\r\n * This class is used to track a performance counter which is number based.\r\n * The user has access to many properties which give statistics of different nature.\r\n *\r\n * The implementer can track two kinds of Performance Counter: time and count.\r\n * For time you can optionally call fetchNewFrame() to notify the start of a new frame to monitor, then call beginMonitoring() to start and endMonitoring() to record the lapsed time. endMonitoring takes a newFrame parameter for you to specify if the monitored time should be set for a new frame or accumulated to the current frame being monitored.\r\n * For count you first have to call fetchNewFrame() to notify the start of a new frame to monitor, then call addCount() how many time required to increment the count value you monitor.\r\n */\r\nexport class PerfCounter {\r\n /**\r\n * Gets or sets a global boolean to turn on and off all the counters\r\n */\r\n public static Enabled = true;\r\n\r\n /**\r\n * Returns the smallest value ever\r\n */\r\n public get min(): number {\r\n return this._min;\r\n }\r\n\r\n /**\r\n * Returns the biggest value ever\r\n */\r\n public get max(): number {\r\n return this._max;\r\n }\r\n\r\n /**\r\n * Returns the average value since the performance counter is running\r\n */\r\n public get average(): number {\r\n return this._average;\r\n }\r\n\r\n /**\r\n * Returns the average value of the last second the counter was monitored\r\n */\r\n public get lastSecAverage(): number {\r\n return this._lastSecAverage;\r\n }\r\n\r\n /**\r\n * Returns the current value\r\n */\r\n public get current(): number {\r\n return this._current;\r\n }\r\n\r\n /**\r\n * Gets the accumulated total\r\n */\r\n public get total(): number {\r\n return this._totalAccumulated;\r\n }\r\n\r\n /**\r\n * Gets the total value count\r\n */\r\n public get count(): number {\r\n return this._totalValueCount;\r\n }\r\n\r\n /**\r\n * Creates a new counter\r\n */\r\n constructor() {\r\n this._startMonitoringTime = 0;\r\n this._min = 0;\r\n this._max = 0;\r\n this._average = 0;\r\n this._lastSecAverage = 0;\r\n this._current = 0;\r\n this._totalValueCount = 0;\r\n this._totalAccumulated = 0;\r\n this._lastSecAccumulated = 0;\r\n this._lastSecTime = 0;\r\n this._lastSecValueCount = 0;\r\n }\r\n\r\n /**\r\n * Call this method to start monitoring a new frame.\r\n * This scenario is typically used when you accumulate monitoring time many times for a single frame, you call this method at the start of the frame, then beginMonitoring to start recording and endMonitoring(false) to accumulated the recorded time to the PerfCounter or addCount() to accumulate a monitored count.\r\n */\r\n public fetchNewFrame() {\r\n this._totalValueCount++;\r\n this._current = 0;\r\n this._lastSecValueCount++;\r\n }\r\n\r\n /**\r\n * Call this method to monitor a count of something (e.g. mesh drawn in viewport count)\r\n * @param newCount the count value to add to the monitored count\r\n * @param fetchResult true when it's the last time in the frame you add to the counter and you wish to update the statistics properties (min/max/average), false if you only want to update statistics.\r\n */\r\n public addCount(newCount: number, fetchResult: boolean) {\r\n if (!PerfCounter.Enabled) {\r\n return;\r\n }\r\n this._current += newCount;\r\n if (fetchResult) {\r\n this._fetchResult();\r\n }\r\n }\r\n\r\n /**\r\n * Start monitoring this performance counter\r\n */\r\n public beginMonitoring() {\r\n if (!PerfCounter.Enabled) {\r\n return;\r\n }\r\n this._startMonitoringTime = PrecisionDate.Now;\r\n }\r\n\r\n /**\r\n * Compute the time lapsed since the previous beginMonitoring() call.\r\n * @param newFrame true by default to fetch the result and monitor a new frame, if false the time monitored will be added to the current frame counter\r\n */\r\n public endMonitoring(newFrame: boolean = true) {\r\n if (!PerfCounter.Enabled) {\r\n return;\r\n }\r\n\r\n if (newFrame) {\r\n this.fetchNewFrame();\r\n }\r\n\r\n const currentTime = PrecisionDate.Now;\r\n this._current = currentTime - this._startMonitoringTime;\r\n\r\n if (newFrame) {\r\n this._fetchResult();\r\n }\r\n }\r\n\r\n /**\r\n * Call this method to end the monitoring of a frame.\r\n * This scenario is typically used when you accumulate monitoring time many times for a single frame, you call this method at the end of the frame, after beginMonitoring to start recording and endMonitoring(false) to accumulated the recorded time to the PerfCounter or addCount() to accumulate a monitored count.\r\n */\r\n public endFrame() {\r\n this._fetchResult();\r\n }\r\n\r\n /** @internal */\r\n public _fetchResult() {\r\n this._totalAccumulated += this._current;\r\n this._lastSecAccumulated += this._current;\r\n\r\n // Min/Max update\r\n this._min = Math.min(this._min, this._current);\r\n this._max = Math.max(this._max, this._current);\r\n this._average = this._totalAccumulated / this._totalValueCount;\r\n\r\n // Reset last sec?\r\n const now = PrecisionDate.Now;\r\n if (now - this._lastSecTime > 1000) {\r\n this._lastSecAverage = this._lastSecAccumulated / this._lastSecValueCount;\r\n this._lastSecTime = now;\r\n this._lastSecAccumulated = 0;\r\n this._lastSecValueCount = 0;\r\n }\r\n }\r\n\r\n private _startMonitoringTime: number;\r\n private _min: number;\r\n private _max: number;\r\n private _average: number;\r\n private _current: number;\r\n private _totalValueCount: number;\r\n private _totalAccumulated: number;\r\n private _lastSecAverage: number;\r\n private _lastSecAccumulated: number;\r\n private _lastSecTime: number;\r\n private _lastSecValueCount: number;\r\n}\r\n","/**\r\n * Defines an array and its length.\r\n * It can be helpful to group result from both Arrays and smart arrays in one structure.\r\n */\r\nexport interface ISmartArrayLike {\r\n /**\r\n * The data of the array.\r\n */\r\n data: Array;\r\n /**\r\n * The active length of the array.\r\n */\r\n length: number;\r\n}\r\n\r\n/**\r\n * Defines an GC Friendly array where the backfield array do not shrink to prevent over allocations.\r\n */\r\nexport class SmartArray implements ISmartArrayLike {\r\n /**\r\n * The full set of data from the array.\r\n */\r\n public data: Array;\r\n\r\n /**\r\n * The active length of the array.\r\n */\r\n public length: number = 0;\r\n\r\n protected _id: number;\r\n\r\n /**\r\n * Instantiates a Smart Array.\r\n * @param capacity defines the default capacity of the array.\r\n */\r\n constructor(capacity: number) {\r\n this.data = new Array(capacity);\r\n this._id = SmartArray._GlobalId++;\r\n }\r\n\r\n /**\r\n * Pushes a value at the end of the active data.\r\n * @param value defines the object to push in the array.\r\n */\r\n public push(value: T): void {\r\n this.data[this.length++] = value;\r\n\r\n if (this.length > this.data.length) {\r\n this.data.length *= 2;\r\n }\r\n }\r\n\r\n /**\r\n * Iterates over the active data and apply the lambda to them.\r\n * @param func defines the action to apply on each value.\r\n */\r\n public forEach(func: (content: T) => void): void {\r\n for (let index = 0; index < this.length; index++) {\r\n func(this.data[index]);\r\n }\r\n }\r\n\r\n /**\r\n * Sorts the full sets of data.\r\n * @param compareFn defines the comparison function to apply.\r\n */\r\n public sort(compareFn: (a: T, b: T) => number): void {\r\n this.data.sort(compareFn);\r\n }\r\n\r\n /**\r\n * Resets the active data to an empty array.\r\n */\r\n public reset(): void {\r\n this.length = 0;\r\n }\r\n\r\n /**\r\n * Releases all the data from the array as well as the array.\r\n */\r\n public dispose(): void {\r\n this.reset();\r\n\r\n if (this.data) {\r\n this.data.length = 0;\r\n }\r\n }\r\n\r\n /**\r\n * Concats the active data with a given array.\r\n * @param array defines the data to concatenate with.\r\n */\r\n public concat(array: any): void {\r\n if (array.length === 0) {\r\n return;\r\n }\r\n if (this.length + array.length > this.data.length) {\r\n this.data.length = (this.length + array.length) * 2;\r\n }\r\n\r\n for (let index = 0; index < array.length; index++) {\r\n this.data[this.length++] = (array.data || array)[index];\r\n }\r\n }\r\n\r\n /**\r\n * Returns the position of a value in the active data.\r\n * @param value defines the value to find the index for\r\n * @returns the index if found in the active data otherwise -1\r\n */\r\n public indexOf(value: T): number {\r\n const position = this.data.indexOf(value);\r\n\r\n if (position >= this.length) {\r\n return -1;\r\n }\r\n\r\n return position;\r\n }\r\n\r\n /**\r\n * Returns whether an element is part of the active data.\r\n * @param value defines the value to look for\r\n * @returns true if found in the active data otherwise false\r\n */\r\n public contains(value: T): boolean {\r\n return this.indexOf(value) !== -1;\r\n }\r\n\r\n // Statics\r\n private static _GlobalId = 0;\r\n}\r\n\r\n/**\r\n * Defines an GC Friendly array where the backfield array do not shrink to prevent over allocations.\r\n * The data in this array can only be present once\r\n */\r\nexport class SmartArrayNoDuplicate extends SmartArray {\r\n private _duplicateId = 0;\r\n\r\n /**\r\n * Pushes a value at the end of the active data.\r\n * THIS DOES NOT PREVENT DUPPLICATE DATA\r\n * @param value defines the object to push in the array.\r\n */\r\n public override push(value: T): void {\r\n super.push(value);\r\n\r\n if (!(value).__smartArrayFlags) {\r\n (value).__smartArrayFlags = {};\r\n }\r\n\r\n (value).__smartArrayFlags[this._id] = this._duplicateId;\r\n }\r\n\r\n /**\r\n * Pushes a value at the end of the active data.\r\n * If the data is already present, it won t be added again\r\n * @param value defines the object to push in the array.\r\n * @returns true if added false if it was already present\r\n */\r\n public pushNoDuplicate(value: T): boolean {\r\n if ((value).__smartArrayFlags && (value).__smartArrayFlags[this._id] === this._duplicateId) {\r\n return false;\r\n }\r\n this.push(value);\r\n return true;\r\n }\r\n\r\n /**\r\n * Resets the active data to an empty array.\r\n */\r\n public override reset(): void {\r\n super.reset();\r\n this._duplicateId++;\r\n }\r\n\r\n /**\r\n * Concats the active data with a given array.\r\n * This ensures no duplicate will be present in the result.\r\n * @param array defines the data to concatenate with.\r\n */\r\n public concatWithNoDuplicate(array: any): void {\r\n if (array.length === 0) {\r\n return;\r\n }\r\n if (this.length + array.length > this.data.length) {\r\n this.data.length = (this.length + array.length) * 2;\r\n }\r\n\r\n for (let index = 0; index < array.length; index++) {\r\n const item = (array.data || array)[index];\r\n this.pushNoDuplicate(item);\r\n }\r\n }\r\n}\r\n","/**\r\n * Class used to evaluate queries containing `and` and `or` operators\r\n */\r\nexport class AndOrNotEvaluator {\r\n /**\r\n * Evaluate a query\r\n * @param query defines the query to evaluate\r\n * @param evaluateCallback defines the callback used to filter result\r\n * @returns true if the query matches\r\n */\r\n public static Eval(query: string, evaluateCallback: (val: any) => boolean): boolean {\r\n if (!query.match(/\\([^()]*\\)/g)) {\r\n query = AndOrNotEvaluator._HandleParenthesisContent(query, evaluateCallback);\r\n } else {\r\n query = query.replace(/\\([^()]*\\)/g, (r) => {\r\n // remove parenthesis\r\n r = r.slice(1, r.length - 1);\r\n return AndOrNotEvaluator._HandleParenthesisContent(r, evaluateCallback);\r\n });\r\n }\r\n\r\n if (query === \"true\") {\r\n return true;\r\n }\r\n\r\n if (query === \"false\") {\r\n return false;\r\n }\r\n\r\n return AndOrNotEvaluator.Eval(query, evaluateCallback);\r\n }\r\n\r\n private static _HandleParenthesisContent(parenthesisContent: string, evaluateCallback: (val: string) => boolean): string {\r\n evaluateCallback =\r\n evaluateCallback ||\r\n ((r) => {\r\n return r === \"true\" ? true : false;\r\n });\r\n\r\n let result;\r\n const or = parenthesisContent.split(\"||\");\r\n\r\n for (const i in or) {\r\n if (Object.prototype.hasOwnProperty.call(or, i)) {\r\n let ori = AndOrNotEvaluator._SimplifyNegation(or[i].trim());\r\n const and = ori.split(\"&&\");\r\n\r\n if (and.length > 1) {\r\n for (let j = 0; j < and.length; ++j) {\r\n const andj = AndOrNotEvaluator._SimplifyNegation(and[j].trim());\r\n if (andj !== \"true\" && andj !== \"false\") {\r\n if (andj[0] === \"!\") {\r\n result = !evaluateCallback(andj.substring(1));\r\n } else {\r\n result = evaluateCallback(andj);\r\n }\r\n } else {\r\n result = andj === \"true\" ? true : false;\r\n }\r\n if (!result) {\r\n // no need to continue since 'false && ... && ...' will always return false\r\n ori = \"false\";\r\n break;\r\n }\r\n }\r\n }\r\n\r\n if (result || ori === \"true\") {\r\n // no need to continue since 'true || ... || ...' will always return true\r\n result = true;\r\n break;\r\n }\r\n\r\n // result equals false (or undefined)\r\n\r\n if (ori !== \"true\" && ori !== \"false\") {\r\n if (ori[0] === \"!\") {\r\n result = !evaluateCallback(ori.substring(1));\r\n } else {\r\n result = evaluateCallback(ori);\r\n }\r\n } else {\r\n result = ori === \"true\" ? true : false;\r\n }\r\n }\r\n }\r\n\r\n // the whole parenthesis scope is replaced by 'true' or 'false'\r\n return result ? \"true\" : \"false\";\r\n }\r\n\r\n private static _SimplifyNegation(booleanString: string): string {\r\n booleanString = booleanString.replace(/^[\\s!]+/, (r) => {\r\n // remove whitespaces\r\n r = r.replace(/[\\s]/g, () => \"\");\r\n return r.length % 2 ? \"!\" : \"\";\r\n });\r\n\r\n booleanString = booleanString.trim();\r\n\r\n if (booleanString === \"!true\") {\r\n booleanString = \"false\";\r\n } else if (booleanString === \"!false\") {\r\n booleanString = \"true\";\r\n }\r\n\r\n return booleanString;\r\n }\r\n}\r\n","import { AndOrNotEvaluator } from \"./andOrNotEvaluator\";\r\n\r\n/**\r\n * Class used to store custom tags\r\n */\r\nexport class Tags {\r\n /**\r\n * Adds support for tags on the given object\r\n * @param obj defines the object to use\r\n */\r\n public static EnableFor(obj: any): void {\r\n obj._tags = obj._tags || {};\r\n\r\n obj.hasTags = () => {\r\n return Tags.HasTags(obj);\r\n };\r\n\r\n obj.addTags = (tagsString: string) => {\r\n return Tags.AddTagsTo(obj, tagsString);\r\n };\r\n\r\n obj.removeTags = (tagsString: string) => {\r\n return Tags.RemoveTagsFrom(obj, tagsString);\r\n };\r\n\r\n obj.matchesTagsQuery = (tagsQuery: string) => {\r\n return Tags.MatchesQuery(obj, tagsQuery);\r\n };\r\n }\r\n\r\n /**\r\n * Removes tags support\r\n * @param obj defines the object to use\r\n */\r\n public static DisableFor(obj: any): void {\r\n delete obj._tags;\r\n delete obj.hasTags;\r\n delete obj.addTags;\r\n delete obj.removeTags;\r\n delete obj.matchesTagsQuery;\r\n }\r\n\r\n /**\r\n * Gets a boolean indicating if the given object has tags\r\n * @param obj defines the object to use\r\n * @returns a boolean\r\n */\r\n public static HasTags(obj: any): boolean {\r\n if (!obj._tags) {\r\n return false;\r\n }\r\n\r\n const tags = obj._tags;\r\n for (const i in tags) {\r\n if (Object.prototype.hasOwnProperty.call(tags, i)) {\r\n return true;\r\n }\r\n }\r\n return false;\r\n }\r\n\r\n /**\r\n * Gets the tags available on a given object\r\n * @param obj defines the object to use\r\n * @param asString defines if the tags must be returned as a string instead of an array of strings\r\n * @returns the tags\r\n */\r\n public static GetTags(obj: any, asString: boolean = true): any {\r\n if (!obj._tags) {\r\n return null;\r\n }\r\n if (asString) {\r\n const tagsArray = [];\r\n for (const tag in obj._tags) {\r\n if (Object.prototype.hasOwnProperty.call(obj._tags, tag) && obj._tags[tag] === true) {\r\n tagsArray.push(tag);\r\n }\r\n }\r\n return tagsArray.join(\" \");\r\n } else {\r\n return obj._tags;\r\n }\r\n }\r\n\r\n /**\r\n * Adds tags to an object\r\n * @param obj defines the object to use\r\n * @param tagsString defines the tag string. The tags 'true' and 'false' are reserved and cannot be used as tags.\r\n * A tag cannot start with '||', '&&', and '!'. It cannot contain whitespaces\r\n */\r\n public static AddTagsTo(obj: any, tagsString: string): void {\r\n if (!tagsString) {\r\n return;\r\n }\r\n\r\n if (typeof tagsString !== \"string\") {\r\n return;\r\n }\r\n\r\n const tags = tagsString.split(\" \");\r\n tags.forEach(function (tag) {\r\n Tags._AddTagTo(obj, tag);\r\n });\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n public static _AddTagTo(obj: any, tag: string): void {\r\n tag = tag.trim();\r\n\r\n if (tag === \"\" || tag === \"true\" || tag === \"false\") {\r\n return;\r\n }\r\n\r\n if (tag.match(/[\\s]/) || tag.match(/^([!]|([|]|[&]){2})/)) {\r\n return;\r\n }\r\n\r\n Tags.EnableFor(obj);\r\n obj._tags[tag] = true;\r\n }\r\n\r\n /**\r\n * Removes specific tags from a specific object\r\n * @param obj defines the object to use\r\n * @param tagsString defines the tags to remove\r\n */\r\n public static RemoveTagsFrom(obj: any, tagsString: string) {\r\n if (!Tags.HasTags(obj)) {\r\n return;\r\n }\r\n const tags = tagsString.split(\" \");\r\n for (const t in tags) {\r\n Tags._RemoveTagFrom(obj, tags[t]);\r\n }\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n public static _RemoveTagFrom(obj: any, tag: string): void {\r\n delete obj._tags[tag];\r\n }\r\n\r\n /**\r\n * Defines if tags hosted on an object match a given query\r\n * @param obj defines the object to use\r\n * @param tagsQuery defines the tag query\r\n * @returns a boolean\r\n */\r\n public static MatchesQuery(obj: any, tagsQuery: string): boolean {\r\n if (tagsQuery === undefined) {\r\n return true;\r\n }\r\n\r\n if (tagsQuery === \"\") {\r\n return Tags.HasTags(obj);\r\n }\r\n\r\n return AndOrNotEvaluator.Eval(tagsQuery, (r) => Tags.HasTags(obj) && obj._tags[r]);\r\n }\r\n}\r\n","// eslint-disable-next-line import/no-internal-modules\r\nimport type { SmartArray, Nullable, Immutable, Camera, Scene, AbstractMesh, SubMesh, Material, IParticleSystem } from \"core/index\";\r\nimport { Observable } from \"../Misc/observable\";\r\nimport { RenderingManager } from \"../Rendering/renderingManager\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport { _ObserveArray } from \"../Misc/arrayTools\";\r\n\r\n/**\r\n * Defines the options of the object renderer\r\n */\r\nexport interface ObjectRendererOptions {\r\n /** The number of passes the renderer will support (1 by default) */\r\n numPasses?: number;\r\n\r\n /** True (default) to not change the aspect ratio of the scene in the RTT */\r\n doNotChangeAspectRatio?: boolean;\r\n}\r\n\r\n/**\r\n * A class that renders objects to the currently bound render target.\r\n * This class only renders objects, and is not concerned with the output texture or post-processing.\r\n */\r\nexport class ObjectRenderer {\r\n /**\r\n * Objects will only be rendered once which can be useful to improve performance if everything in your render is static for instance.\r\n */\r\n public static readonly REFRESHRATE_RENDER_ONCE: number = 0;\r\n /**\r\n * Objects will be rendered every frame and is recommended for dynamic contents.\r\n */\r\n public static readonly REFRESHRATE_RENDER_ONEVERYFRAME: number = 1;\r\n /**\r\n * Objects will be rendered every 2 frames which could be enough if your dynamic objects are not\r\n * the central point of your effect and can save a lot of performances.\r\n */\r\n public static readonly REFRESHRATE_RENDER_ONEVERYTWOFRAMES: number = 2;\r\n\r\n /**\r\n * Use this predicate to dynamically define the list of mesh you want to render.\r\n * If set, the renderList property will be overwritten.\r\n */\r\n public renderListPredicate: (AbstractMesh: AbstractMesh) => boolean;\r\n\r\n private _renderList: Nullable>;\r\n private _unObserveRenderList: Nullable<() => void> = null;\r\n\r\n /**\r\n * Use this list to define the list of mesh you want to render.\r\n */\r\n public get renderList(): Nullable> {\r\n return this._renderList;\r\n }\r\n\r\n public set renderList(value: Nullable>) {\r\n if (this._renderList === value) {\r\n return;\r\n }\r\n if (this._unObserveRenderList) {\r\n this._unObserveRenderList();\r\n this._unObserveRenderList = null;\r\n }\r\n\r\n if (value) {\r\n this._unObserveRenderList = _ObserveArray(value, this._renderListHasChanged);\r\n }\r\n\r\n this._renderList = value;\r\n }\r\n\r\n private _renderListHasChanged = (_functionName: String, previousLength: number) => {\r\n const newLength = this._renderList ? this._renderList.length : 0;\r\n if ((previousLength === 0 && newLength > 0) || newLength === 0) {\r\n this._scene.meshes.forEach((mesh) => {\r\n mesh._markSubMeshesAsLightDirty();\r\n });\r\n }\r\n };\r\n\r\n /**\r\n * Define the list of particle systems to render. If not provided, will render all the particle systems of the scene.\r\n * Note that the particle systems are rendered only if renderParticles is set to true.\r\n */\r\n public particleSystemList: Nullable> = null;\r\n\r\n /**\r\n * Use this function to overload the renderList array at rendering time.\r\n * Return null to render with the current renderList, else return the list of meshes to use for rendering.\r\n * For 2DArray, layerOrFace is the index of the layer that is going to be rendered, else it is the faceIndex of\r\n * the cube (if the RTT is a cube, else layerOrFace=0).\r\n * The renderList passed to the function is the current render list (the one that will be used if the function returns null).\r\n * The length of this list is passed through renderListLength: don't use renderList.length directly because the array can\r\n * hold dummy elements!\r\n */\r\n public getCustomRenderList: Nullable<(layerOrFace: number, renderList: Nullable>>, renderListLength: number) => Nullable>> =\r\n null;\r\n\r\n /**\r\n * Define if particles should be rendered.\r\n */\r\n public renderParticles = true;\r\n\r\n /**\r\n * Define if sprites should be rendered.\r\n */\r\n public renderSprites = false;\r\n\r\n /**\r\n * Force checking the layerMask property even if a custom list of meshes is provided (ie. if renderList is not undefined)\r\n */\r\n public forceLayerMaskCheck = false;\r\n\r\n /**\r\n * Define the camera used to render the objects.\r\n */\r\n public activeCamera: Nullable;\r\n\r\n /**\r\n * Define the camera used to calculate the LOD of the objects.\r\n * If not defined, activeCamera will be used. If not defined nor activeCamera, scene's active camera will be used.\r\n */\r\n public cameraForLOD: Nullable;\r\n\r\n /**\r\n * Override the mesh isReady function with your own one.\r\n */\r\n public customIsReadyFunction: (mesh: AbstractMesh, refreshRate: number, preWarm?: boolean) => boolean;\r\n\r\n /**\r\n * Override the render function with your own one.\r\n */\r\n public customRenderFunction: (\r\n opaqueSubMeshes: SmartArray,\r\n alphaTestSubMeshes: SmartArray,\r\n transparentSubMeshes: SmartArray,\r\n depthOnlySubMeshes: SmartArray,\r\n beforeTransparents?: () => void\r\n ) => void;\r\n\r\n /**\r\n * An event triggered before rendering the objects\r\n */\r\n public readonly onBeforeRenderObservable = new Observable();\r\n\r\n /**\r\n * An event triggered after rendering the objects\r\n */\r\n public readonly onAfterRenderObservable = new Observable();\r\n\r\n /**\r\n * An event triggered before the rendering group is processed\r\n */\r\n public readonly onBeforeRenderingManagerRenderObservable = new Observable();\r\n\r\n /**\r\n * An event triggered after the rendering group is processed\r\n */\r\n public readonly onAfterRenderingManagerRenderObservable = new Observable();\r\n\r\n /**\r\n * An event triggered when fast path rendering is used\r\n */\r\n public readonly onFastPathRenderObservable = new Observable();\r\n\r\n protected _scene: Scene;\r\n /** @internal */\r\n public _renderingManager: RenderingManager;\r\n /** @internal */\r\n public _waitingRenderList?: string[];\r\n protected _currentRefreshId = -1;\r\n protected _refreshRate = 1;\r\n\r\n /**\r\n * The options used by the object renderer\r\n */\r\n public options: Required;\r\n\r\n private _name: string;\r\n /**\r\n * Friendly name of the object renderer\r\n */\r\n public get name() {\r\n return this._name;\r\n }\r\n\r\n public set name(value: string) {\r\n if (this._name === value) {\r\n return;\r\n }\r\n\r\n this._name = value;\r\n\r\n if (!this._scene) {\r\n return;\r\n }\r\n\r\n const engine = this._scene.getEngine();\r\n\r\n for (let i = 0; i < this._renderPassIds.length; ++i) {\r\n const renderPassId = this._renderPassIds[i];\r\n engine._renderPassNames[renderPassId] = `${this._name}#${i}`;\r\n }\r\n }\r\n\r\n /**\r\n * Current render pass id. Note it can change over the rendering as there's a separate id for each face of a cube / each layer of an array layer!\r\n */\r\n public renderPassId: number;\r\n private readonly _renderPassIds: number[];\r\n /**\r\n * Gets the render pass ids used by the object renderer.\r\n */\r\n public get renderPassIds(): readonly number[] {\r\n return this._renderPassIds;\r\n }\r\n\r\n /**\r\n * Gets the current value of the refreshId counter\r\n */\r\n public get currentRefreshId() {\r\n return this._currentRefreshId;\r\n }\r\n\r\n /**\r\n * Sets a specific material to be used to render a mesh/a list of meshes with this object renderer\r\n * @param mesh mesh or array of meshes\r\n * @param material material or array of materials to use for this render pass. If undefined is passed, no specific material will be used but the regular material instead (mesh.material). It's possible to provide an array of materials to use a different material for each rendering pass.\r\n */\r\n public setMaterialForRendering(mesh: AbstractMesh | AbstractMesh[], material?: Material | Material[]): void {\r\n let meshes;\r\n if (!Array.isArray(mesh)) {\r\n meshes = [mesh];\r\n } else {\r\n meshes = mesh;\r\n }\r\n for (let j = 0; j < meshes.length; ++j) {\r\n for (let i = 0; i < this.options.numPasses; ++i) {\r\n meshes[j].setMaterialForRenderPass(this._renderPassIds[i], material !== undefined ? (Array.isArray(material) ? material[i] : material) : undefined);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Instantiates an object renderer.\r\n * @param name The friendly name of the object renderer\r\n * @param scene The scene the renderer belongs to\r\n * @param options The options used to create the renderer (optional)\r\n */\r\n constructor(name: string, scene: Scene, options?: ObjectRendererOptions) {\r\n this.name = name;\r\n this._scene = scene;\r\n\r\n this.renderList = [] as AbstractMesh[];\r\n this._renderPassIds = [];\r\n\r\n this.options = {\r\n numPasses: 1,\r\n doNotChangeAspectRatio: true,\r\n ...options,\r\n };\r\n\r\n this._createRenderPassId();\r\n\r\n this.renderPassId = this._renderPassIds[0];\r\n\r\n // Rendering groups\r\n this._renderingManager = new RenderingManager(scene);\r\n this._renderingManager._useSceneAutoClearSetup = true;\r\n }\r\n\r\n private _releaseRenderPassId(): void {\r\n const engine = this._scene.getEngine();\r\n for (let i = 0; i < this.options.numPasses; ++i) {\r\n engine.releaseRenderPassId(this._renderPassIds[i]);\r\n }\r\n this._renderPassIds.length = 0;\r\n }\r\n\r\n private _createRenderPassId(): void {\r\n this._releaseRenderPassId();\r\n\r\n const engine = this._scene.getEngine();\r\n\r\n for (let i = 0; i < this.options.numPasses; ++i) {\r\n this._renderPassIds[i] = engine.createRenderPassId(`${this.name}#${i}`);\r\n }\r\n }\r\n\r\n /**\r\n * Resets the refresh counter of the renderer and start back from scratch.\r\n * Could be useful to re-render if it is setup to render only once.\r\n */\r\n public resetRefreshCounter(): void {\r\n this._currentRefreshId = -1;\r\n }\r\n\r\n /**\r\n * Defines the refresh rate of the rendering or the rendering frequency.\r\n * Use 0 to render just once, 1 to render on every frame, 2 to render every two frames and so on...\r\n */\r\n public get refreshRate(): number {\r\n return this._refreshRate;\r\n }\r\n public set refreshRate(value: number) {\r\n this._refreshRate = value;\r\n this.resetRefreshCounter();\r\n }\r\n\r\n /**\r\n * Indicates if the renderer should render the current frame.\r\n * The output is based on the specified refresh rate.\r\n * @returns true if the renderer should render the current frame\r\n */\r\n public shouldRender(): boolean {\r\n if (this._currentRefreshId === -1) {\r\n // At least render once\r\n this._currentRefreshId = 1;\r\n return true;\r\n }\r\n\r\n if (this.refreshRate === this._currentRefreshId) {\r\n this._currentRefreshId = 1;\r\n return true;\r\n }\r\n\r\n this._currentRefreshId++;\r\n return false;\r\n }\r\n\r\n /**\r\n * This function will check if the renderer is ready to render (textures are loaded, shaders are compiled)\r\n * @param viewportWidth defines the width of the viewport\r\n * @param viewportHeight defines the height of the viewport\r\n * @returns true if all required resources are ready\r\n */\r\n public isReadyForRendering(viewportWidth: number, viewportHeight: number): boolean {\r\n this.prepareRenderList();\r\n this.initRender(viewportWidth, viewportHeight);\r\n\r\n const isReady = this._checkReadiness();\r\n\r\n this.finishRender();\r\n\r\n return isReady;\r\n }\r\n\r\n /**\r\n * Makes sure the list of meshes is ready to be rendered\r\n * You should call this function before \"initRender\", but if you know the render list is ok, you may call \"initRender\" directly\r\n */\r\n public prepareRenderList(): void {\r\n const scene = this._scene;\r\n\r\n if (this._waitingRenderList) {\r\n if (!this.renderListPredicate) {\r\n this.renderList = [];\r\n for (let index = 0; index < this._waitingRenderList.length; index++) {\r\n const id = this._waitingRenderList[index];\r\n const mesh = scene.getMeshById(id);\r\n if (mesh) {\r\n this.renderList.push(mesh);\r\n }\r\n }\r\n }\r\n this._waitingRenderList = undefined;\r\n }\r\n\r\n // Is predicate defined?\r\n if (this.renderListPredicate) {\r\n if (this.renderList) {\r\n this.renderList.length = 0; // Clear previous renderList\r\n } else {\r\n this.renderList = [];\r\n }\r\n\r\n const sceneMeshes = this._scene.meshes;\r\n\r\n for (let index = 0; index < sceneMeshes.length; index++) {\r\n const mesh = sceneMeshes[index];\r\n if (this.renderListPredicate(mesh)) {\r\n this.renderList.push(mesh);\r\n }\r\n }\r\n }\r\n }\r\n\r\n private _defaultRenderListPrepared: boolean;\r\n private _currentSceneCamera: Nullable = null;\r\n\r\n /**\r\n * This method makes sure everything is setup before \"render\" can be called\r\n * @param viewportWidth Width of the viewport to render to\r\n * @param viewportHeight Height of the viewport to render to\r\n */\r\n public initRender(viewportWidth: number, viewportHeight: number): void {\r\n const engine = this._scene.getEngine();\r\n const camera: Nullable = this.activeCamera ?? this._scene.activeCamera;\r\n\r\n this._currentSceneCamera = this._scene.activeCamera;\r\n\r\n if (camera) {\r\n if (camera !== this._scene.activeCamera) {\r\n this._scene.setTransformMatrix(camera.getViewMatrix(), camera.getProjectionMatrix(true));\r\n this._scene.activeCamera = camera;\r\n }\r\n engine.setViewport(camera.rigParent ? camera.rigParent.viewport : camera.viewport, viewportWidth, viewportHeight);\r\n }\r\n\r\n this._defaultRenderListPrepared = false;\r\n }\r\n\r\n /**\r\n * This method must be called after the \"render\" call(s), to complete the rendering process.\r\n */\r\n public finishRender() {\r\n const scene = this._scene;\r\n\r\n scene.activeCamera = this._currentSceneCamera;\r\n if (this._currentSceneCamera) {\r\n if (this.activeCamera && this.activeCamera !== scene.activeCamera) {\r\n scene.setTransformMatrix(this._currentSceneCamera.getViewMatrix(), this._currentSceneCamera.getProjectionMatrix(true));\r\n }\r\n scene.getEngine().setViewport(this._currentSceneCamera.viewport);\r\n }\r\n\r\n scene.resetCachedMaterial();\r\n }\r\n\r\n /**\r\n * Renders all the objects (meshes, particles systems, sprites) to the currently bound render target texture.\r\n * @param passIndex defines the pass index to use (default: 0)\r\n * @param skipOnAfterRenderObservable defines a flag to skip raising the onAfterRenderObservable\r\n */\r\n public render(passIndex = 0, skipOnAfterRenderObservable = false): void {\r\n const scene = this._scene;\r\n const engine = scene.getEngine();\r\n\r\n const currentRenderPassId = engine.currentRenderPassId;\r\n\r\n engine.currentRenderPassId = this._renderPassIds[passIndex];\r\n\r\n this.onBeforeRenderObservable.notifyObservers(passIndex);\r\n\r\n const fastPath = engine.snapshotRendering && engine.snapshotRenderingMode === Constants.SNAPSHOTRENDERING_FAST;\r\n\r\n if (!fastPath) {\r\n // Get the list of meshes to render\r\n let currentRenderList: Nullable> = null;\r\n const defaultRenderList = this.renderList ? this.renderList : scene.getActiveMeshes().data;\r\n const defaultRenderListLength = this.renderList ? this.renderList.length : scene.getActiveMeshes().length;\r\n\r\n if (this.getCustomRenderList) {\r\n currentRenderList = this.getCustomRenderList(passIndex, defaultRenderList, defaultRenderListLength);\r\n }\r\n\r\n if (!currentRenderList) {\r\n // No custom render list provided, we prepare the rendering for the default list, but check\r\n // first if we did not already performed the preparation before so as to avoid re-doing it several times\r\n if (!this._defaultRenderListPrepared) {\r\n this._prepareRenderingManager(defaultRenderList, defaultRenderListLength, !this.renderList || this.forceLayerMaskCheck);\r\n this._defaultRenderListPrepared = true;\r\n }\r\n currentRenderList = defaultRenderList;\r\n } else {\r\n // Prepare the rendering for the custom render list provided\r\n this._prepareRenderingManager(currentRenderList, currentRenderList.length, this.forceLayerMaskCheck);\r\n }\r\n\r\n this.onBeforeRenderingManagerRenderObservable.notifyObservers(passIndex);\r\n\r\n this._renderingManager.render(this.customRenderFunction, currentRenderList, this.renderParticles, this.renderSprites);\r\n\r\n this.onAfterRenderingManagerRenderObservable.notifyObservers(passIndex);\r\n } else {\r\n this.onFastPathRenderObservable.notifyObservers(passIndex);\r\n }\r\n\r\n if (!skipOnAfterRenderObservable) {\r\n this.onAfterRenderObservable.notifyObservers(passIndex);\r\n }\r\n\r\n engine.currentRenderPassId = currentRenderPassId;\r\n }\r\n\r\n /** @internal */\r\n public _checkReadiness(): boolean {\r\n const scene = this._scene;\r\n const engine = scene.getEngine();\r\n const currentRenderPassId = engine.currentRenderPassId;\r\n\r\n let returnValue = true;\r\n\r\n if (!scene.getViewMatrix()) {\r\n // We probably didn't execute scene.render() yet, so make sure we have a view/projection matrix setup for the scene\r\n scene.updateTransformMatrix();\r\n }\r\n\r\n const numPasses = this.options.numPasses;\r\n for (let passIndex = 0; passIndex < numPasses && returnValue; passIndex++) {\r\n let currentRenderList: Nullable> = null;\r\n const defaultRenderList = this.renderList ? this.renderList : scene.getActiveMeshes().data;\r\n const defaultRenderListLength = this.renderList ? this.renderList.length : scene.getActiveMeshes().length;\r\n\r\n engine.currentRenderPassId = this._renderPassIds[passIndex];\r\n\r\n this.onBeforeRenderObservable.notifyObservers(passIndex);\r\n\r\n if (this.getCustomRenderList) {\r\n currentRenderList = this.getCustomRenderList(passIndex, defaultRenderList, defaultRenderListLength);\r\n }\r\n\r\n if (!currentRenderList) {\r\n currentRenderList = defaultRenderList;\r\n }\r\n\r\n if (!this.options.doNotChangeAspectRatio) {\r\n scene.updateTransformMatrix(true);\r\n }\r\n\r\n for (let i = 0; i < currentRenderList.length && returnValue; ++i) {\r\n const mesh = currentRenderList[i];\r\n\r\n if (!mesh.isEnabled() || mesh.isBlocked || !mesh.isVisible || !mesh.subMeshes) {\r\n continue;\r\n }\r\n\r\n if (this.customIsReadyFunction) {\r\n if (!this.customIsReadyFunction(mesh, this.refreshRate, true)) {\r\n returnValue = false;\r\n continue;\r\n }\r\n } else if (!mesh.isReady(true)) {\r\n returnValue = false;\r\n continue;\r\n }\r\n }\r\n\r\n this.onAfterRenderObservable.notifyObservers(passIndex);\r\n\r\n if (numPasses > 1) {\r\n scene.incrementRenderId();\r\n scene.resetCachedMaterial();\r\n }\r\n }\r\n\r\n const particleSystems = this.particleSystemList || scene.particleSystems;\r\n for (const particleSystem of particleSystems) {\r\n if (!particleSystem.isReady()) {\r\n returnValue = false;\r\n }\r\n }\r\n\r\n engine.currentRenderPassId = currentRenderPassId;\r\n\r\n return returnValue;\r\n }\r\n\r\n private _prepareRenderingManager(currentRenderList: Array, currentRenderListLength: number, checkLayerMask: boolean): void {\r\n const scene = this._scene;\r\n const camera = scene.activeCamera; // note that at this point, scene.activeCamera == this.activeCamera if defined, because initRender() has been called before\r\n const cameraForLOD = this.cameraForLOD ?? camera;\r\n\r\n this._renderingManager.reset();\r\n\r\n const sceneRenderId = scene.getRenderId();\r\n const currentFrameId = scene.getFrameId();\r\n for (let meshIndex = 0; meshIndex < currentRenderListLength; meshIndex++) {\r\n const mesh = currentRenderList[meshIndex];\r\n\r\n if (mesh && !mesh.isBlocked) {\r\n if (this.customIsReadyFunction) {\r\n if (!this.customIsReadyFunction(mesh, this.refreshRate, false)) {\r\n this.resetRefreshCounter();\r\n continue;\r\n }\r\n } else if (!mesh.isReady(this.refreshRate === 0)) {\r\n this.resetRefreshCounter();\r\n continue;\r\n }\r\n\r\n let meshToRender: Nullable = null;\r\n\r\n if (cameraForLOD) {\r\n const meshToRenderAndFrameId = mesh._internalAbstractMeshDataInfo._currentLOD.get(cameraForLOD);\r\n if (!meshToRenderAndFrameId || meshToRenderAndFrameId[1] !== currentFrameId) {\r\n meshToRender = scene.customLODSelector ? scene.customLODSelector(mesh, cameraForLOD) : mesh.getLOD(cameraForLOD);\r\n if (!meshToRenderAndFrameId) {\r\n mesh._internalAbstractMeshDataInfo._currentLOD.set(cameraForLOD, [meshToRender, currentFrameId]);\r\n } else {\r\n meshToRenderAndFrameId[0] = meshToRender;\r\n meshToRenderAndFrameId[1] = currentFrameId;\r\n }\r\n } else {\r\n meshToRender = meshToRenderAndFrameId[0];\r\n }\r\n } else {\r\n meshToRender = mesh;\r\n }\r\n\r\n if (!meshToRender) {\r\n continue;\r\n }\r\n\r\n if (meshToRender !== mesh && meshToRender.billboardMode !== 0) {\r\n meshToRender.computeWorldMatrix(); // Compute world matrix if LOD is billboard\r\n }\r\n\r\n meshToRender._preActivateForIntermediateRendering(sceneRenderId);\r\n\r\n let isMasked;\r\n if (checkLayerMask && camera) {\r\n isMasked = (mesh.layerMask & camera.layerMask) === 0;\r\n } else {\r\n isMasked = false;\r\n }\r\n\r\n if (mesh.isEnabled() && mesh.isVisible && mesh.subMeshes && !isMasked) {\r\n if (meshToRender !== mesh) {\r\n meshToRender._activate(sceneRenderId, true);\r\n }\r\n if (mesh._activate(sceneRenderId, true) && mesh.subMeshes.length) {\r\n if (!mesh.isAnInstance) {\r\n meshToRender._internalAbstractMeshDataInfo._onlyForInstancesIntermediate = false;\r\n } else {\r\n if (mesh._internalAbstractMeshDataInfo._actAsRegularMesh) {\r\n meshToRender = mesh;\r\n }\r\n }\r\n meshToRender._internalAbstractMeshDataInfo._isActiveIntermediate = true;\r\n\r\n scene._prepareSkeleton(meshToRender);\r\n\r\n for (let subIndex = 0; subIndex < meshToRender.subMeshes.length; subIndex++) {\r\n const subMesh = meshToRender.subMeshes[subIndex];\r\n this._renderingManager.dispatch(subMesh, meshToRender);\r\n }\r\n }\r\n\r\n mesh._postActivate();\r\n }\r\n }\r\n }\r\n\r\n const particleSystems = this.particleSystemList || scene.particleSystems;\r\n for (let particleIndex = 0; particleIndex < particleSystems.length; particleIndex++) {\r\n const particleSystem = particleSystems[particleIndex];\r\n\r\n const emitter: any = particleSystem.emitter;\r\n\r\n if (!particleSystem.isStarted() || !emitter || (emitter.position && !emitter.isEnabled())) {\r\n continue;\r\n }\r\n\r\n this._renderingManager.dispatchParticles(particleSystem);\r\n }\r\n }\r\n\r\n /**\r\n * Overrides the default sort function applied in the rendering group to prepare the meshes.\r\n * This allowed control for front to back rendering or reversely depending of the special needs.\r\n *\r\n * @param renderingGroupId The rendering group id corresponding to its index\r\n * @param opaqueSortCompareFn The opaque queue comparison function use to sort.\r\n * @param alphaTestSortCompareFn The alpha test queue comparison function use to sort.\r\n * @param transparentSortCompareFn The transparent queue comparison function use to sort.\r\n */\r\n public setRenderingOrder(\r\n renderingGroupId: number,\r\n opaqueSortCompareFn: Nullable<(a: SubMesh, b: SubMesh) => number> = null,\r\n alphaTestSortCompareFn: Nullable<(a: SubMesh, b: SubMesh) => number> = null,\r\n transparentSortCompareFn: Nullable<(a: SubMesh, b: SubMesh) => number> = null\r\n ): void {\r\n this._renderingManager.setRenderingOrder(renderingGroupId, opaqueSortCompareFn, alphaTestSortCompareFn, transparentSortCompareFn);\r\n }\r\n\r\n /**\r\n * Specifies whether or not the stencil and depth buffer are cleared between two rendering groups.\r\n *\r\n * @param renderingGroupId The rendering group id corresponding to its index\r\n * @param autoClearDepthStencil Automatically clears depth and stencil between groups if true.\r\n * @param depth Automatically clears depth between groups if true and autoClear is true.\r\n * @param stencil Automatically clears stencil between groups if true and autoClear is true.\r\n */\r\n public setRenderingAutoClearDepthStencil(renderingGroupId: number, autoClearDepthStencil: boolean, depth = true, stencil = true): void {\r\n this._renderingManager.setRenderingAutoClearDepthStencil(renderingGroupId, autoClearDepthStencil, depth, stencil);\r\n this._renderingManager._useSceneAutoClearSetup = false;\r\n }\r\n\r\n /**\r\n * Clones the renderer.\r\n * @returns the cloned renderer\r\n */\r\n public clone(): ObjectRenderer {\r\n const newRenderer = new ObjectRenderer(this.name, this._scene, this.options);\r\n\r\n if (this.renderList) {\r\n newRenderer.renderList = this.renderList.slice(0);\r\n }\r\n\r\n return newRenderer;\r\n }\r\n\r\n /**\r\n * Dispose the renderer and release its associated resources.\r\n */\r\n public dispose(): void {\r\n const renderList = this.renderList ? this.renderList : this._scene.getActiveMeshes().data;\r\n const renderListLength = this.renderList ? this.renderList.length : this._scene.getActiveMeshes().length;\r\n for (let i = 0; i < renderListLength; i++) {\r\n const mesh = renderList[i];\r\n if (mesh.getMaterialForRenderPass(this.renderPassId) !== undefined) {\r\n mesh.setMaterialForRenderPass(this.renderPassId, undefined);\r\n }\r\n }\r\n\r\n this.onBeforeRenderObservable.clear();\r\n this.onAfterRenderObservable.clear();\r\n this.onBeforeRenderingManagerRenderObservable.clear();\r\n this.onAfterRenderingManagerRenderObservable.clear();\r\n this.onFastPathRenderObservable.clear();\r\n\r\n this._releaseRenderPassId();\r\n\r\n this.renderList = null;\r\n }\r\n\r\n /** @internal */\r\n public _rebuild(): void {\r\n if (this.refreshRate === ObjectRenderer.REFRESHRATE_RENDER_ONCE) {\r\n this.refreshRate = ObjectRenderer.REFRESHRATE_RENDER_ONCE;\r\n }\r\n }\r\n\r\n /**\r\n * Clear the info related to rendering groups preventing retention point in material dispose.\r\n */\r\n public freeRenderingGroups(): void {\r\n if (this._renderingManager) {\r\n this._renderingManager.freeRenderingGroups();\r\n }\r\n }\r\n}\r\n","import type { Observer } from \"../../Misc/observable\";\r\nimport { Observable } from \"../../Misc/observable\";\r\nimport type { SmartArray } from \"../../Misc/smartArray\";\r\nimport type { Nullable, Immutable } from \"../../types\";\r\nimport type { Camera } from \"../../Cameras/camera\";\r\nimport type { Scene } from \"../../scene\";\r\nimport { Matrix, Vector3 } from \"../../Maths/math.vector\";\r\nimport type { Color4 } from \"../../Maths/math.color\";\r\nimport type { RenderTargetCreationOptions, TextureSize } from \"../../Materials/Textures/textureCreationOptions\";\r\nimport type { AbstractMesh } from \"../../Meshes/abstractMesh\";\r\nimport type { SubMesh } from \"../../Meshes/subMesh\";\r\nimport type { InternalTexture } from \"../../Materials/Textures/internalTexture\";\r\nimport { Texture } from \"../../Materials/Textures/texture\";\r\nimport { PostProcessManager } from \"../../PostProcesses/postProcessManager\";\r\nimport type { PostProcess } from \"../../PostProcesses/postProcess\";\r\nimport { Constants } from \"../../Engines/constants\";\r\nimport type { IRenderTargetTexture, RenderTargetWrapper } from \"../../Engines/renderTargetWrapper\";\r\n\r\nimport type { Material } from \"../material\";\r\nimport { FloorPOT, NearestPOT } from \"../../Misc/tools.functions\";\r\nimport { Effect } from \"../effect\";\r\nimport type { AbstractEngine } from \"../../Engines/abstractEngine\";\r\nimport type { IParticleSystem } from \"core/Particles/IParticleSystem\";\r\nimport { Logger } from \"../../Misc/logger\";\r\nimport { ObjectRenderer } from \"core/Rendering/objectRenderer\";\r\n\r\ndeclare module \"../effect\" {\r\n export interface Effect {\r\n /**\r\n * Sets a depth stencil texture from a render target on the engine to be used in the shader.\r\n * @param channel Name of the sampler variable.\r\n * @param texture Texture to set.\r\n */\r\n setDepthStencilTexture(channel: string, texture: Nullable): void;\r\n }\r\n}\r\n\r\n/**\r\n * Sets a depth stencil texture from a render target on the engine to be used in the shader.\r\n * @param channel Name of the sampler variable.\r\n * @param texture Texture to set.\r\n */\r\nEffect.prototype.setDepthStencilTexture = function (channel: string, texture: Nullable): void {\r\n this._engine.setDepthStencilTexture(this._samplers[channel], this._uniforms[channel], texture, channel);\r\n};\r\n\r\n/**\r\n * Options for the RenderTargetTexture constructor\r\n */\r\nexport interface RenderTargetTextureOptions {\r\n /** True (default: false) if mipmaps need to be generated after render */\r\n generateMipMaps?: boolean;\r\n\r\n /** True (default) to not change the aspect ratio of the scene in the RTT */\r\n doNotChangeAspectRatio?: boolean;\r\n\r\n /** The type of the buffer in the RTT (byte (default), half float, float...) */\r\n type?: number;\r\n\r\n /** True (default: false) if a cube texture needs to be created */\r\n isCube?: boolean;\r\n\r\n /** The sampling mode to be used with the render target (Trilinear (default), Linear, Nearest...) */\r\n samplingMode?: number;\r\n\r\n /** True (default) to generate a depth buffer */\r\n generateDepthBuffer?: boolean;\r\n\r\n /** True (default: false) to generate a stencil buffer */\r\n generateStencilBuffer?: boolean;\r\n\r\n /** True (default: false) if multiple textures need to be created (Draw Buffers) */\r\n isMulti?: boolean;\r\n\r\n /** The internal format of the buffer in the RTT (RED, RG, RGB, RGBA (default), ALPHA...) */\r\n format?: number;\r\n\r\n /** True (default: false) if the texture allocation should be delayed */\r\n delayAllocation?: boolean;\r\n\r\n /** Sample count to use when creating the RTT */\r\n samples?: number;\r\n\r\n /** specific flags to use when creating the texture (e.g., Constants.TEXTURE_CREATIONFLAG_STORAGE for storage textures) */\r\n creationFlags?: number;\r\n\r\n /** True (default: false) to indicate that no color target should be created. (e.g., if you only want to write to the depth buffer) */\r\n noColorAttachment?: boolean;\r\n\r\n /** Specifies the internal texture to use directly instead of creating one (ignores `noColorAttachment` flag when set) **/\r\n colorAttachment?: InternalTexture;\r\n\r\n /** True (default: false) to create a SRGB texture */\r\n useSRGBBuffer?: boolean;\r\n\r\n /** Defines the underlying texture texture space */\r\n gammaSpace?: boolean;\r\n\r\n /** If not provided (default), a new object renderer instance will be created */\r\n existingObjectRenderer?: ObjectRenderer;\r\n}\r\n\r\n/**\r\n * This Helps creating a texture that will be created from a camera in your scene.\r\n * It is basically a dynamic texture that could be used to create special effects for instance.\r\n * Actually, It is the base of lot of effects in the framework like post process, shadows, effect layers and rendering pipelines...\r\n */\r\nexport class RenderTargetTexture extends Texture implements IRenderTargetTexture {\r\n /**\r\n * The texture will only be rendered once which can be useful to improve performance if everything in your render is static for instance.\r\n */\r\n public static readonly REFRESHRATE_RENDER_ONCE: number = ObjectRenderer.REFRESHRATE_RENDER_ONCE;\r\n /**\r\n * The texture will be rendered every frame and is recommended for dynamic contents.\r\n */\r\n public static readonly REFRESHRATE_RENDER_ONEVERYFRAME: number = ObjectRenderer.REFRESHRATE_RENDER_ONEVERYFRAME;\r\n /**\r\n * The texture will be rendered every 2 frames which could be enough if your dynamic objects are not\r\n * the central point of your effect and can save a lot of performances.\r\n */\r\n public static readonly REFRESHRATE_RENDER_ONEVERYTWOFRAMES: number = ObjectRenderer.REFRESHRATE_RENDER_ONEVERYTWOFRAMES;\r\n\r\n /**\r\n * Use this predicate to dynamically define the list of mesh you want to render.\r\n * If set, the renderList property will be overwritten.\r\n */\r\n public get renderListPredicate(): (AbstractMesh: AbstractMesh) => boolean {\r\n return this._objectRenderer.renderListPredicate;\r\n }\r\n\r\n public set renderListPredicate(value: (AbstractMesh: AbstractMesh) => boolean) {\r\n this._objectRenderer.renderListPredicate = value;\r\n }\r\n\r\n /**\r\n * Use this list to define the list of mesh you want to render.\r\n */\r\n public get renderList(): Nullable> {\r\n return this._objectRenderer.renderList;\r\n }\r\n\r\n public set renderList(value: Nullable>) {\r\n this._objectRenderer.renderList = value;\r\n }\r\n\r\n /**\r\n * Define the list of particle systems to render in the texture. If not provided, will render all the particle systems of the scene.\r\n * Note that the particle systems are rendered only if renderParticles is set to true.\r\n */\r\n public get particleSystemList(): Nullable> {\r\n return this._objectRenderer.particleSystemList;\r\n }\r\n\r\n public set particleSystemList(value: Nullable>) {\r\n this._objectRenderer.particleSystemList = value;\r\n }\r\n\r\n /**\r\n * Use this function to overload the renderList array at rendering time.\r\n * Return null to render with the current renderList, else return the list of meshes to use for rendering.\r\n * For 2DArray RTT, layerOrFace is the index of the layer that is going to be rendered, else it is the faceIndex of\r\n * the cube (if the RTT is a cube, else layerOrFace=0).\r\n * The renderList passed to the function is the current render list (the one that will be used if the function returns null).\r\n * The length of this list is passed through renderListLength: don't use renderList.length directly because the array can\r\n * hold dummy elements!\r\n */\r\n public get getCustomRenderList(): Nullable<\r\n (layerOrFace: number, renderList: Nullable>>, renderListLength: number) => Nullable>\r\n > {\r\n return this._objectRenderer.getCustomRenderList;\r\n }\r\n\r\n public set getCustomRenderList(\r\n value: Nullable<(layerOrFace: number, renderList: Nullable>>, renderListLength: number) => Nullable>>\r\n ) {\r\n this._objectRenderer.getCustomRenderList = value;\r\n }\r\n\r\n /**\r\n * Define if particles should be rendered in your texture (default: true).\r\n */\r\n public get renderParticles() {\r\n return this._objectRenderer.renderParticles;\r\n }\r\n\r\n public set renderParticles(value: boolean) {\r\n this._objectRenderer.renderParticles = value;\r\n }\r\n\r\n /**\r\n * Define if sprites should be rendered in your texture (default: false).\r\n */\r\n public get renderSprites() {\r\n return this._objectRenderer.renderSprites;\r\n }\r\n\r\n public set renderSprites(value: boolean) {\r\n this._objectRenderer.renderSprites = value;\r\n }\r\n\r\n /**\r\n * Force checking the layerMask property even if a custom list of meshes is provided (ie. if renderList is not undefined) (default: false).\r\n */\r\n public get forceLayerMaskCheck() {\r\n return this._objectRenderer.forceLayerMaskCheck;\r\n }\r\n\r\n public set forceLayerMaskCheck(value: boolean) {\r\n this._objectRenderer.forceLayerMaskCheck = value;\r\n }\r\n\r\n /**\r\n * Define the camera used to render the texture.\r\n */\r\n public get activeCamera(): Nullable {\r\n return this._objectRenderer.activeCamera;\r\n }\r\n\r\n public set activeCamera(value: Nullable) {\r\n this._objectRenderer.activeCamera = value;\r\n }\r\n\r\n /**\r\n * Define the camera used to calculate the LOD of the objects.\r\n * If not defined, activeCamera will be used. If not defined nor activeCamera, scene's active camera will be used.\r\n */\r\n public get cameraForLOD(): Nullable {\r\n return this._objectRenderer.cameraForLOD;\r\n }\r\n\r\n public set cameraForLOD(value: Nullable) {\r\n this._objectRenderer.cameraForLOD = value;\r\n }\r\n\r\n /**\r\n * Override the mesh isReady function with your own one.\r\n */\r\n public get customIsReadyFunction(): (mesh: AbstractMesh, refreshRate: number, preWarm?: boolean) => boolean {\r\n return this._objectRenderer.customIsReadyFunction;\r\n }\r\n\r\n public set customIsReadyFunction(value: (mesh: AbstractMesh, refreshRate: number, preWarm?: boolean) => boolean) {\r\n this._objectRenderer.customIsReadyFunction = value;\r\n }\r\n\r\n /**\r\n * Override the render function of the texture with your own one.\r\n */\r\n public get customRenderFunction(): (\r\n opaqueSubMeshes: SmartArray,\r\n alphaTestSubMeshes: SmartArray,\r\n transparentSubMeshes: SmartArray,\r\n depthOnlySubMeshes: SmartArray,\r\n beforeTransparents?: () => void\r\n ) => void {\r\n return this._objectRenderer.customRenderFunction;\r\n }\r\n\r\n public set customRenderFunction(\r\n value: (\r\n opaqueSubMeshes: SmartArray,\r\n alphaTestSubMeshes: SmartArray,\r\n transparentSubMeshes: SmartArray,\r\n depthOnlySubMeshes: SmartArray,\r\n beforeTransparents?: () => void\r\n ) => void\r\n ) {\r\n this._objectRenderer.customRenderFunction = value;\r\n }\r\n\r\n /**\r\n * Define if camera post processes should be use while rendering the texture.\r\n */\r\n public useCameraPostProcesses: boolean;\r\n /**\r\n * Define if the camera viewport should be respected while rendering the texture or if the render should be done to the entire texture.\r\n */\r\n public ignoreCameraViewport: boolean = false;\r\n\r\n private _postProcessManager: Nullable;\r\n\r\n /**\r\n * Post-processes for this render target\r\n */\r\n public get postProcesses() {\r\n return this._postProcesses;\r\n }\r\n private _postProcesses: PostProcess[];\r\n private _resizeObserver: Nullable>;\r\n\r\n private get _prePassEnabled() {\r\n return !!this._prePassRenderTarget && this._prePassRenderTarget.enabled;\r\n }\r\n\r\n /**\r\n * An event triggered when the texture is unbind.\r\n */\r\n public onBeforeBindObservable = new Observable();\r\n\r\n /**\r\n * An event triggered when the texture is unbind.\r\n */\r\n public onAfterUnbindObservable = new Observable();\r\n\r\n private _onAfterUnbindObserver: Nullable>;\r\n /**\r\n * Set a after unbind callback in the texture.\r\n * This has been kept for backward compatibility and use of onAfterUnbindObservable is recommended.\r\n */\r\n public set onAfterUnbind(callback: () => void) {\r\n if (this._onAfterUnbindObserver) {\r\n this.onAfterUnbindObservable.remove(this._onAfterUnbindObserver);\r\n }\r\n this._onAfterUnbindObserver = this.onAfterUnbindObservable.add(callback);\r\n }\r\n\r\n /**\r\n * An event triggered before rendering the texture\r\n */\r\n public get onBeforeRenderObservable() {\r\n return this._objectRenderer.onBeforeRenderObservable;\r\n }\r\n\r\n private _onBeforeRenderObserver: Nullable>;\r\n /**\r\n * Set a before render callback in the texture.\r\n * This has been kept for backward compatibility and use of onBeforeRenderObservable is recommended.\r\n */\r\n public set onBeforeRender(callback: (faceIndex: number) => void) {\r\n if (this._onBeforeRenderObserver) {\r\n this.onBeforeRenderObservable.remove(this._onBeforeRenderObserver);\r\n }\r\n this._onBeforeRenderObserver = this.onBeforeRenderObservable.add(callback);\r\n }\r\n\r\n /**\r\n * An event triggered after rendering the texture\r\n */\r\n public get onAfterRenderObservable() {\r\n return this._objectRenderer.onAfterRenderObservable;\r\n }\r\n\r\n private _onAfterRenderObserver: Nullable>;\r\n /**\r\n * Set a after render callback in the texture.\r\n * This has been kept for backward compatibility and use of onAfterRenderObservable is recommended.\r\n */\r\n public set onAfterRender(callback: (faceIndex: number) => void) {\r\n if (this._onAfterRenderObserver) {\r\n this.onAfterRenderObservable.remove(this._onAfterRenderObserver);\r\n }\r\n this._onAfterRenderObserver = this.onAfterRenderObservable.add(callback);\r\n }\r\n\r\n /**\r\n * An event triggered after the texture clear\r\n */\r\n public onClearObservable = new Observable();\r\n\r\n private _onClearObserver: Nullable>;\r\n /**\r\n * Set a clear callback in the texture.\r\n * This has been kept for backward compatibility and use of onClearObservable is recommended.\r\n */\r\n public set onClear(callback: (Engine: AbstractEngine) => void) {\r\n if (this._onClearObserver) {\r\n this.onClearObservable.remove(this._onClearObserver);\r\n }\r\n this._onClearObserver = this.onClearObservable.add(callback);\r\n }\r\n\r\n /**\r\n * An event triggered when the texture is resized.\r\n */\r\n public onResizeObservable = new Observable();\r\n\r\n /**\r\n * Define the clear color of the Render Target if it should be different from the scene.\r\n */\r\n public clearColor: Color4;\r\n /** @internal */\r\n public _size: TextureSize;\r\n protected _initialSizeParameter: TextureSize | { ratio: number };\r\n protected _sizeRatio: Nullable;\r\n /** @internal */\r\n public _generateMipMaps: boolean;\r\n /** @internal */\r\n public _cleared = false;\r\n /**\r\n * Skip the initial clear of the rtt at the beginning of the frame render loop\r\n */\r\n public skipInitialClear = false;\r\n /** @internal */\r\n public get _waitingRenderList() {\r\n return this._objectRenderer._waitingRenderList;\r\n }\r\n\r\n /** @internal */\r\n public set _waitingRenderList(value: string[] | undefined) {\r\n this._objectRenderer._waitingRenderList = value;\r\n }\r\n\r\n protected _objectRenderer: ObjectRenderer;\r\n protected _doNotChangeAspectRatio: boolean;\r\n protected _textureMatrix: Matrix;\r\n protected _samples = 1;\r\n protected _renderTargetOptions: RenderTargetCreationOptions;\r\n private _canRescale = true;\r\n protected _renderTarget: Nullable = null;\r\n private _currentFaceIndex: number;\r\n private _currentLayer: number;\r\n private _currentUseCameraPostProcess: boolean;\r\n private _currentDumpForDebug: boolean;\r\n private _dontDisposeObjectRenderer = false;\r\n\r\n /**\r\n * Current render pass id of the render target texture. Note it can change over the rendering as there's a separate id for each face of a cube / each layer of an array layer!\r\n */\r\n public get renderPassId(): number {\r\n return this._objectRenderer.renderPassId;\r\n }\r\n\r\n /**\r\n * Gets the render pass ids used by the render target texture. For a single render target the array length will be 1, for a cube texture it will be 6 and for\r\n * a 2D texture array it will return an array of ids the size of the 2D texture array\r\n */\r\n public get renderPassIds(): readonly number[] {\r\n return this._objectRenderer.renderPassIds;\r\n }\r\n\r\n /**\r\n * Gets the current value of the refreshId counter\r\n */\r\n public get currentRefreshId() {\r\n return this._objectRenderer.currentRefreshId;\r\n }\r\n\r\n /**\r\n * Sets a specific material to be used to render a mesh/a list of meshes in this render target texture\r\n * @param mesh mesh or array of meshes\r\n * @param material material or array of materials to use for this render pass. If undefined is passed, no specific material will be used but the regular material instead (mesh.material). It's possible to provide an array of materials to use a different material for each rendering in the case of a cube texture (6 rendering) and a 2D texture array (as many rendering as the length of the array)\r\n */\r\n public setMaterialForRendering(mesh: AbstractMesh | AbstractMesh[], material?: Material | Material[]): void {\r\n this._objectRenderer.setMaterialForRendering(mesh, material);\r\n }\r\n\r\n /**\r\n * Define if the texture has multiple draw buffers or if false a single draw buffer.\r\n */\r\n public get isMulti(): boolean {\r\n return this._renderTarget?.isMulti ?? false;\r\n }\r\n\r\n /**\r\n * Gets render target creation options that were used.\r\n */\r\n public get renderTargetOptions(): RenderTargetCreationOptions {\r\n return this._renderTargetOptions;\r\n }\r\n\r\n /**\r\n * Gets the render target wrapper associated with this render target\r\n */\r\n public get renderTarget(): Nullable {\r\n return this._renderTarget;\r\n }\r\n\r\n protected _onRatioRescale(): void {\r\n if (this._sizeRatio) {\r\n this.resize(this._initialSizeParameter);\r\n }\r\n }\r\n\r\n /**\r\n * Gets or sets the center of the bounding box associated with the texture (when in cube mode)\r\n * It must define where the camera used to render the texture is set\r\n */\r\n public boundingBoxPosition = Vector3.Zero();\r\n\r\n private _boundingBoxSize: Vector3;\r\n\r\n /**\r\n * Gets or sets the size of the bounding box associated with the texture (when in cube mode)\r\n * When defined, the cubemap will switch to local mode\r\n * @see https://community.arm.com/graphics/b/blog/posts/reflections-based-on-local-cubemaps-in-unity\r\n * @example https://www.babylonjs-playground.com/#RNASML\r\n */\r\n public set boundingBoxSize(value: Vector3) {\r\n if (this._boundingBoxSize && this._boundingBoxSize.equals(value)) {\r\n return;\r\n }\r\n this._boundingBoxSize = value;\r\n const scene = this.getScene();\r\n if (scene) {\r\n scene.markAllMaterialsAsDirty(Constants.MATERIAL_TextureDirtyFlag);\r\n }\r\n }\r\n public get boundingBoxSize(): Vector3 {\r\n return this._boundingBoxSize;\r\n }\r\n\r\n /**\r\n * In case the RTT has been created with a depth texture, get the associated\r\n * depth texture.\r\n * Otherwise, return null.\r\n */\r\n public get depthStencilTexture(): Nullable {\r\n return this._renderTarget?._depthStencilTexture ?? null;\r\n }\r\n\r\n /** @internal */\r\n public _disableEngineStages = false; // TODO: remove this when the shadow generator task (frame graph) is reworked (see https://github.com/BabylonJS/Babylon.js/pull/15962#discussion_r1874417607)\r\n\r\n private readonly _onBeforeRenderingManagerRenderObserver: Nullable>;\r\n private readonly _onAfterRenderingManagerRenderObserver: Nullable>;\r\n private readonly _onFastPathRenderObserver: Nullable>;\r\n\r\n /**\r\n * Instantiate a render target texture. This is mainly used to render of screen the scene to for instance apply post process\r\n * or used a shadow, depth texture...\r\n * @param name The friendly name of the texture\r\n * @param size The size of the RTT (number if square, or {width: number, height:number} or {ratio:} to define a ratio from the main scene)\r\n * @param scene The scene the RTT belongs to. Default is the last created scene.\r\n * @param options The options for creating the render target texture.\r\n */\r\n constructor(name: string, size: TextureSize | { ratio: number }, scene?: Nullable, options?: RenderTargetTextureOptions);\r\n\r\n /**\r\n * Instantiate a render target texture. This is mainly used to render of screen the scene to for instance apply post process\r\n * or used a shadow, depth texture...\r\n * @param name The friendly name of the texture\r\n * @param size The size of the RTT (number if square, or {width: number, height:number} or {ratio:} to define a ratio from the main scene)\r\n * @param scene The scene the RTT belongs to. Default is the last created scene\r\n * @param generateMipMaps True (default: false) if mipmaps need to be generated after render\r\n * @param doNotChangeAspectRatio True (default) to not change the aspect ratio of the scene in the RTT\r\n * @param type The type of the buffer in the RTT (byte (default), half float, float...)\r\n * @param isCube True (default: false) if a cube texture needs to be created\r\n * @param samplingMode The sampling mode to be used with the render target (Trilinear (default), Linear, Nearest...)\r\n * @param generateDepthBuffer True (default) to generate a depth buffer\r\n * @param generateStencilBuffer True (default: false) to generate a stencil buffer\r\n * @param isMulti True (default: false) if multiple textures need to be created (Draw Buffers)\r\n * @param format The internal format of the buffer in the RTT (RED, RG, RGB, RGBA (default), ALPHA...)\r\n * @param delayAllocation True (default: false) if the texture allocation should be delayed\r\n * @param samples Sample count to use when creating the RTT\r\n * @param creationFlags specific flags to use when creating the texture (e.g., Constants.TEXTURE_CREATIONFLAG_STORAGE for storage textures)\r\n * @param noColorAttachment True (default: false) to indicate that no color target should be created. (e.g., if you only want to write to the depth buffer)\r\n * @param useSRGBBuffer True (default: false) to create a SRGB texture\r\n */\r\n constructor(\r\n name: string,\r\n size: TextureSize | { ratio: number },\r\n scene?: Nullable,\r\n generateMipMaps?: boolean,\r\n doNotChangeAspectRatio?: boolean,\r\n type?: number,\r\n isCube?: boolean,\r\n samplingMode?: number,\r\n generateDepthBuffer?: boolean,\r\n generateStencilBuffer?: boolean,\r\n isMulti?: boolean,\r\n format?: number,\r\n delayAllocation?: boolean,\r\n samples?: number,\r\n creationFlags?: number,\r\n noColorAttachment?: boolean,\r\n useSRGBBuffer?: boolean\r\n );\r\n\r\n /** @internal */\r\n constructor(\r\n name: string,\r\n size: TextureSize | { ratio: number },\r\n scene?: Nullable,\r\n generateMipMaps: boolean | RenderTargetTextureOptions = false,\r\n doNotChangeAspectRatio: boolean = true,\r\n type: number = Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n isCube = false,\r\n samplingMode = Texture.TRILINEAR_SAMPLINGMODE,\r\n generateDepthBuffer = true,\r\n generateStencilBuffer = false,\r\n isMulti = false,\r\n format = Constants.TEXTUREFORMAT_RGBA,\r\n delayAllocation = false,\r\n samples?: number,\r\n creationFlags?: number,\r\n noColorAttachment = false,\r\n useSRGBBuffer = false\r\n ) {\r\n let colorAttachment: InternalTexture | undefined = undefined;\r\n let gammaSpace = true;\r\n let existingObjectRenderer: ObjectRenderer | undefined = undefined;\r\n if (typeof generateMipMaps === \"object\") {\r\n const options = generateMipMaps;\r\n generateMipMaps = !!options.generateMipMaps;\r\n doNotChangeAspectRatio = options.doNotChangeAspectRatio ?? true;\r\n type = options.type ?? Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n isCube = !!options.isCube;\r\n samplingMode = options.samplingMode ?? Texture.TRILINEAR_SAMPLINGMODE;\r\n generateDepthBuffer = options.generateDepthBuffer ?? true;\r\n generateStencilBuffer = !!options.generateStencilBuffer;\r\n isMulti = !!options.isMulti;\r\n format = options.format ?? Constants.TEXTUREFORMAT_RGBA;\r\n delayAllocation = !!options.delayAllocation;\r\n samples = options.samples;\r\n creationFlags = options.creationFlags;\r\n noColorAttachment = !!options.noColorAttachment;\r\n useSRGBBuffer = !!options.useSRGBBuffer;\r\n colorAttachment = options.colorAttachment;\r\n gammaSpace = options.gammaSpace ?? gammaSpace;\r\n existingObjectRenderer = options.existingObjectRenderer;\r\n }\r\n\r\n super(null, scene, !generateMipMaps, undefined, samplingMode, undefined, undefined, undefined, undefined, format);\r\n\r\n scene = this.getScene();\r\n if (!scene) {\r\n return;\r\n }\r\n\r\n const engine = this.getScene()!.getEngine();\r\n\r\n this._gammaSpace = gammaSpace;\r\n this._coordinatesMode = Texture.PROJECTION_MODE;\r\n this.name = name;\r\n this.isRenderTarget = true;\r\n this._initialSizeParameter = size;\r\n this._dontDisposeObjectRenderer = !!existingObjectRenderer;\r\n\r\n this._processSizeParameter(size);\r\n\r\n this._objectRenderer =\r\n existingObjectRenderer ??\r\n new ObjectRenderer(name, scene, {\r\n numPasses: isCube ? 6 : this.getRenderLayers() || 1,\r\n doNotChangeAspectRatio,\r\n });\r\n\r\n this._onBeforeRenderingManagerRenderObserver = this._objectRenderer.onBeforeRenderingManagerRenderObservable.add(() => {\r\n // Before clear\r\n if (!this._disableEngineStages) {\r\n for (const step of this._scene!._beforeRenderTargetClearStage) {\r\n step.action(this, this._currentFaceIndex, this._currentLayer);\r\n }\r\n }\r\n\r\n // Clear\r\n if (this.onClearObservable.hasObservers()) {\r\n this.onClearObservable.notifyObservers(engine);\r\n } else if (!this.skipInitialClear) {\r\n engine.clear(this.clearColor || this._scene!.clearColor, true, true, true);\r\n }\r\n\r\n if (!this._doNotChangeAspectRatio) {\r\n this._scene!.updateTransformMatrix(true);\r\n }\r\n\r\n // Before Camera Draw\r\n if (!this._disableEngineStages) {\r\n for (const step of this._scene!._beforeRenderTargetDrawStage) {\r\n step.action(this, this._currentFaceIndex, this._currentLayer);\r\n }\r\n }\r\n });\r\n\r\n this._onAfterRenderingManagerRenderObserver = this._objectRenderer.onAfterRenderingManagerRenderObservable.add(() => {\r\n // After Camera Draw\r\n if (!this._disableEngineStages) {\r\n for (const step of this._scene!._afterRenderTargetDrawStage) {\r\n step.action(this, this._currentFaceIndex, this._currentLayer);\r\n }\r\n }\r\n\r\n const saveGenerateMipMaps = this._texture?.generateMipMaps ?? false;\r\n\r\n if (this._texture) {\r\n this._texture.generateMipMaps = false; // if left true, the mipmaps will be generated (if this._texture.generateMipMaps = true) when the first post process binds its own RTT: by doing so it will unbind the current RTT,\r\n // which will trigger a mipmap generation. We don't want this because it's a wasted work, we will do an unbind of the current RTT at the end of the process (see unbindFrameBuffer) which will\r\n // trigger the generation of the final mipmaps\r\n }\r\n\r\n if (this._postProcessManager) {\r\n this._postProcessManager._finalizeFrame(false, this._renderTarget ?? undefined, this._currentFaceIndex, this._postProcesses, this.ignoreCameraViewport);\r\n } else if (this._currentUseCameraPostProcess) {\r\n this._scene!.postProcessManager._finalizeFrame(false, this._renderTarget ?? undefined, this._currentFaceIndex);\r\n }\r\n\r\n if (!this._disableEngineStages) {\r\n for (const step of this._scene!._afterRenderTargetPostProcessStage) {\r\n step.action(this, this._currentFaceIndex, this._currentLayer);\r\n }\r\n }\r\n\r\n if (this._texture) {\r\n this._texture.generateMipMaps = saveGenerateMipMaps;\r\n }\r\n\r\n if (!this._doNotChangeAspectRatio) {\r\n this._scene!.updateTransformMatrix(true);\r\n }\r\n\r\n // Dump ?\r\n if (this._currentDumpForDebug) {\r\n if (!this._dumpTools) {\r\n Logger.Error(\"dumpTools module is still being loaded. To speed up the process import dump tools directly in your project\");\r\n } else {\r\n this._dumpTools.DumpFramebuffer(this.getRenderWidth(), this.getRenderHeight(), engine);\r\n }\r\n }\r\n });\r\n\r\n this._onFastPathRenderObserver = this._objectRenderer.onFastPathRenderObservable.add(() => {\r\n if (this.onClearObservable.hasObservers()) {\r\n this.onClearObservable.notifyObservers(engine);\r\n } else {\r\n if (!this.skipInitialClear) {\r\n engine.clear(this.clearColor || this._scene!.clearColor, true, true, true);\r\n }\r\n }\r\n });\r\n\r\n this._resizeObserver = engine.onResizeObservable.add(() => {});\r\n\r\n this._generateMipMaps = generateMipMaps ? true : false;\r\n this._doNotChangeAspectRatio = doNotChangeAspectRatio;\r\n\r\n if (isMulti) {\r\n return;\r\n }\r\n\r\n this._renderTargetOptions = {\r\n generateMipMaps: generateMipMaps,\r\n type: type,\r\n format: this._format ?? undefined,\r\n samplingMode: this.samplingMode,\r\n generateDepthBuffer: generateDepthBuffer,\r\n generateStencilBuffer: generateStencilBuffer,\r\n samples,\r\n creationFlags,\r\n noColorAttachment: noColorAttachment,\r\n useSRGBBuffer,\r\n colorAttachment: colorAttachment,\r\n label: this.name,\r\n };\r\n\r\n if (this.samplingMode === Texture.NEAREST_SAMPLINGMODE) {\r\n this.wrapU = Texture.CLAMP_ADDRESSMODE;\r\n this.wrapV = Texture.CLAMP_ADDRESSMODE;\r\n }\r\n\r\n if (!delayAllocation) {\r\n if (isCube) {\r\n this._renderTarget = scene.getEngine().createRenderTargetCubeTexture(this.getRenderSize(), this._renderTargetOptions);\r\n this.coordinatesMode = Texture.INVCUBIC_MODE;\r\n this._textureMatrix = Matrix.Identity();\r\n } else {\r\n this._renderTarget = scene.getEngine().createRenderTargetTexture(this._size, this._renderTargetOptions);\r\n }\r\n this._texture = this._renderTarget.texture;\r\n if (samples !== undefined) {\r\n this.samples = samples;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Creates a depth stencil texture.\r\n * This is only available in WebGL 2 or with the depth texture extension available.\r\n * @param comparisonFunction Specifies the comparison function to set on the texture. If 0 or undefined, the texture is not in comparison mode (default: 0)\r\n * @param bilinearFiltering Specifies whether or not bilinear filtering is enable on the texture (default: true)\r\n * @param generateStencil Specifies whether or not a stencil should be allocated in the texture (default: false)\r\n * @param samples sample count of the depth/stencil texture (default: 1)\r\n * @param format format of the depth texture (default: Constants.TEXTUREFORMAT_DEPTH32_FLOAT)\r\n * @param label defines the label of the texture (for debugging purpose)\r\n */\r\n public createDepthStencilTexture(\r\n comparisonFunction: number = 0,\r\n bilinearFiltering: boolean = true,\r\n generateStencil: boolean = false,\r\n samples: number = 1,\r\n format: number = Constants.TEXTUREFORMAT_DEPTH32_FLOAT,\r\n label?: string\r\n ): void {\r\n this._renderTarget?.createDepthStencilTexture(comparisonFunction, bilinearFiltering, generateStencil, samples, format, label);\r\n }\r\n\r\n protected _processSizeParameter(size: TextureSize | { ratio: number }): void {\r\n if ((<{ ratio: number }>size).ratio) {\r\n this._sizeRatio = (<{ ratio: number }>size).ratio;\r\n const engine = this._getEngine()!;\r\n this._size = {\r\n width: this._bestReflectionRenderTargetDimension(engine.getRenderWidth(), this._sizeRatio),\r\n height: this._bestReflectionRenderTargetDimension(engine.getRenderHeight(), this._sizeRatio),\r\n };\r\n } else {\r\n this._size = size;\r\n }\r\n }\r\n\r\n /**\r\n * Define the number of samples to use in case of MSAA.\r\n * It defaults to one meaning no MSAA has been enabled.\r\n */\r\n public get samples(): number {\r\n return this._renderTarget?.samples ?? this._samples;\r\n }\r\n\r\n public set samples(value: number) {\r\n if (this._renderTarget) {\r\n this._samples = this._renderTarget.setSamples(value);\r\n }\r\n }\r\n\r\n /**\r\n * Adds a post process to the render target rendering passes.\r\n * @param postProcess define the post process to add\r\n */\r\n public addPostProcess(postProcess: PostProcess): void {\r\n if (!this._postProcessManager) {\r\n const scene = this.getScene();\r\n\r\n if (!scene) {\r\n return;\r\n }\r\n this._postProcessManager = new PostProcessManager(scene);\r\n this._postProcesses = new Array();\r\n }\r\n\r\n this._postProcesses.push(postProcess);\r\n this._postProcesses[0].autoClear = false;\r\n }\r\n\r\n /**\r\n * Clear all the post processes attached to the render target\r\n * @param dispose define if the cleared post processes should also be disposed (false by default)\r\n */\r\n public clearPostProcesses(dispose: boolean = false): void {\r\n if (!this._postProcesses) {\r\n return;\r\n }\r\n\r\n if (dispose) {\r\n for (const postProcess of this._postProcesses) {\r\n postProcess.dispose();\r\n }\r\n }\r\n\r\n this._postProcesses = [];\r\n }\r\n\r\n /**\r\n * Remove one of the post process from the list of attached post processes to the texture\r\n * @param postProcess define the post process to remove from the list\r\n */\r\n public removePostProcess(postProcess: PostProcess): void {\r\n if (!this._postProcesses) {\r\n return;\r\n }\r\n\r\n const index = this._postProcesses.indexOf(postProcess);\r\n\r\n if (index === -1) {\r\n return;\r\n }\r\n\r\n this._postProcesses.splice(index, 1);\r\n\r\n if (this._postProcesses.length > 0) {\r\n this._postProcesses[0].autoClear = false;\r\n }\r\n }\r\n\r\n /**\r\n * Resets the refresh counter of the texture and start bak from scratch.\r\n * Could be useful to regenerate the texture if it is setup to render only once.\r\n */\r\n public resetRefreshCounter(): void {\r\n this._objectRenderer.resetRefreshCounter();\r\n }\r\n\r\n /**\r\n * Define the refresh rate of the texture or the rendering frequency.\r\n * Use 0 to render just once, 1 to render on every frame, 2 to render every two frames and so on...\r\n */\r\n public get refreshRate(): number {\r\n return this._objectRenderer.refreshRate;\r\n }\r\n public set refreshRate(value: number) {\r\n this._objectRenderer.refreshRate = value;\r\n }\r\n\r\n /** @internal */\r\n public _shouldRender(): boolean {\r\n return this._objectRenderer.shouldRender();\r\n }\r\n\r\n /**\r\n * Gets the actual render size of the texture.\r\n * @returns the width of the render size\r\n */\r\n public getRenderSize(): number {\r\n return this.getRenderWidth();\r\n }\r\n\r\n /**\r\n * Gets the actual render width of the texture.\r\n * @returns the width of the render size\r\n */\r\n public getRenderWidth(): number {\r\n if ((<{ width: number; height: number }>this._size).width) {\r\n return (<{ width: number; height: number }>this._size).width;\r\n }\r\n\r\n return this._size;\r\n }\r\n\r\n /**\r\n * Gets the actual render height of the texture.\r\n * @returns the height of the render size\r\n */\r\n public getRenderHeight(): number {\r\n if ((<{ width: number; height: number }>this._size).width) {\r\n return (<{ width: number; height: number }>this._size).height;\r\n }\r\n\r\n return this._size;\r\n }\r\n\r\n /**\r\n * Gets the actual number of layers of the texture or, in the case of a 3D texture, return the depth.\r\n * @returns the number of layers\r\n */\r\n public getRenderLayers(): number {\r\n const layers = (<{ width: number; height: number; depth?: number; layers?: number }>this._size).layers;\r\n if (layers) {\r\n return layers;\r\n }\r\n const depth = (<{ width: number; height: number; depth?: number; layers?: number }>this._size).depth;\r\n if (depth) {\r\n return depth;\r\n }\r\n\r\n return 0;\r\n }\r\n\r\n /**\r\n * Don't allow this render target texture to rescale. Mainly used to prevent rescaling by the scene optimizer.\r\n */\r\n public disableRescaling() {\r\n this._canRescale = false;\r\n }\r\n\r\n /**\r\n * Get if the texture can be rescaled or not.\r\n */\r\n public override get canRescale(): boolean {\r\n return this._canRescale;\r\n }\r\n\r\n /**\r\n * Resize the texture using a ratio.\r\n * @param ratio the ratio to apply to the texture size in order to compute the new target size\r\n */\r\n public override scale(ratio: number): void {\r\n const newSize = Math.max(1, this.getRenderSize() * ratio);\r\n\r\n this.resize(newSize);\r\n }\r\n\r\n /**\r\n * Get the texture reflection matrix used to rotate/transform the reflection.\r\n * @returns the reflection matrix\r\n */\r\n public override getReflectionTextureMatrix(): Matrix {\r\n if (this.isCube) {\r\n return this._textureMatrix;\r\n }\r\n\r\n return super.getReflectionTextureMatrix();\r\n }\r\n\r\n /**\r\n * Resize the texture to a new desired size.\r\n * Be careful as it will recreate all the data in the new texture.\r\n * @param size Define the new size. It can be:\r\n * - a number for squared texture,\r\n * - an object containing { width: number, height: number }\r\n * - or an object containing a ratio { ratio: number }\r\n */\r\n public resize(size: TextureSize | { ratio: number }): void {\r\n const wasCube = this.isCube;\r\n\r\n this._renderTarget?.dispose();\r\n this._renderTarget = null;\r\n\r\n const scene = this.getScene();\r\n\r\n if (!scene) {\r\n return;\r\n }\r\n\r\n this._processSizeParameter(size);\r\n\r\n if (wasCube) {\r\n this._renderTarget = scene.getEngine().createRenderTargetCubeTexture(this.getRenderSize(), this._renderTargetOptions);\r\n } else {\r\n this._renderTarget = scene.getEngine().createRenderTargetTexture(this._size, this._renderTargetOptions);\r\n }\r\n this._texture = this._renderTarget.texture;\r\n\r\n if (this._renderTargetOptions.samples !== undefined) {\r\n this.samples = this._renderTargetOptions.samples;\r\n }\r\n\r\n if (this.onResizeObservable.hasObservers()) {\r\n this.onResizeObservable.notifyObservers(this);\r\n }\r\n }\r\n\r\n /**\r\n * Renders all the objects from the render list into the texture.\r\n * @param useCameraPostProcess Define if camera post processes should be used during the rendering\r\n * @param dumpForDebug Define if the rendering result should be dumped (copied) for debugging purpose\r\n */\r\n public render(useCameraPostProcess: boolean = false, dumpForDebug: boolean = false): void {\r\n this._render(useCameraPostProcess, dumpForDebug);\r\n }\r\n\r\n private _dumpToolsLoading = false;\r\n private _dumpTools: typeof import(\"../../Misc/dumpTools\");\r\n\r\n /**\r\n * This function will check if the render target texture can be rendered (textures are loaded, shaders are compiled)\r\n * @returns true if all required resources are ready\r\n */\r\n public isReadyForRendering(): boolean {\r\n if (!this._dumpToolsLoading) {\r\n this._dumpToolsLoading = true;\r\n // avoid a static import to allow ignoring the import in some cases\r\n import(\"../../Misc/dumpTools\").then((module) => (this._dumpTools = module));\r\n }\r\n\r\n this._objectRenderer.prepareRenderList();\r\n\r\n this.onBeforeBindObservable.notifyObservers(this);\r\n\r\n this._objectRenderer.initRender(this.getRenderWidth(), this.getRenderHeight());\r\n\r\n const isReady = this._objectRenderer._checkReadiness();\r\n\r\n this.onAfterUnbindObservable.notifyObservers(this);\r\n\r\n this._objectRenderer.finishRender();\r\n\r\n return isReady;\r\n }\r\n\r\n private _render(useCameraPostProcess: boolean = false, dumpForDebug: boolean = false): void {\r\n const scene = this.getScene();\r\n\r\n if (!scene) {\r\n return;\r\n }\r\n\r\n if (this.useCameraPostProcesses !== undefined) {\r\n useCameraPostProcess = this.useCameraPostProcesses;\r\n }\r\n\r\n this._objectRenderer.prepareRenderList();\r\n\r\n this.onBeforeBindObservable.notifyObservers(this);\r\n\r\n this._objectRenderer.initRender(this.getRenderWidth(), this.getRenderHeight());\r\n\r\n if ((this.is2DArray || this.is3D) && !this.isMulti) {\r\n for (let layer = 0; layer < this.getRenderLayers(); layer++) {\r\n this._renderToTarget(0, useCameraPostProcess, dumpForDebug, layer);\r\n scene.incrementRenderId();\r\n scene.resetCachedMaterial();\r\n }\r\n } else if (this.isCube && !this.isMulti) {\r\n for (let face = 0; face < 6; face++) {\r\n this._renderToTarget(face, useCameraPostProcess, dumpForDebug);\r\n scene.incrementRenderId();\r\n scene.resetCachedMaterial();\r\n }\r\n } else {\r\n this._renderToTarget(0, useCameraPostProcess, dumpForDebug);\r\n }\r\n\r\n this.onAfterUnbindObservable.notifyObservers(this);\r\n\r\n this._objectRenderer.finishRender();\r\n }\r\n\r\n private _bestReflectionRenderTargetDimension(renderDimension: number, scale: number): number {\r\n const minimum = 128;\r\n const x = renderDimension * scale;\r\n const curved = NearestPOT(x + (minimum * minimum) / (minimum + x));\r\n\r\n // Ensure we don't exceed the render dimension (while staying POT)\r\n return Math.min(FloorPOT(renderDimension), curved);\r\n }\r\n\r\n /**\r\n * @internal\r\n * @param faceIndex face index to bind to if this is a cubetexture\r\n * @param layer defines the index of the texture to bind in the array\r\n */\r\n public _bindFrameBuffer(faceIndex: number = 0, layer = 0) {\r\n const scene = this.getScene();\r\n if (!scene) {\r\n return;\r\n }\r\n\r\n const engine = scene.getEngine();\r\n if (this._renderTarget) {\r\n engine.bindFramebuffer(this._renderTarget, this.isCube ? faceIndex : undefined, undefined, undefined, this.ignoreCameraViewport, 0, layer);\r\n }\r\n }\r\n\r\n protected _unbindFrameBuffer(engine: AbstractEngine, faceIndex: number): void {\r\n if (!this._renderTarget) {\r\n return;\r\n }\r\n engine.unBindFramebuffer(this._renderTarget, this.isCube, () => {\r\n this.onAfterRenderObservable.notifyObservers(faceIndex);\r\n });\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n public _prepareFrame(scene: Scene, faceIndex?: number, layer?: number, useCameraPostProcess?: boolean) {\r\n if (this._postProcessManager) {\r\n if (!this._prePassEnabled) {\r\n this._postProcessManager._prepareFrame(this._texture, this._postProcesses);\r\n }\r\n } else if (!useCameraPostProcess || !scene.postProcessManager._prepareFrame(this._texture)) {\r\n this._bindFrameBuffer(faceIndex, layer);\r\n }\r\n }\r\n\r\n private _renderToTarget(faceIndex: number, useCameraPostProcess: boolean, dumpForDebug: boolean, layer = 0): void {\r\n const scene = this.getScene();\r\n\r\n if (!scene) {\r\n return;\r\n }\r\n\r\n const engine = scene.getEngine();\r\n\r\n this._currentFaceIndex = faceIndex;\r\n this._currentLayer = layer;\r\n this._currentUseCameraPostProcess = useCameraPostProcess;\r\n this._currentDumpForDebug = dumpForDebug;\r\n\r\n this._prepareFrame(scene, faceIndex, layer, useCameraPostProcess);\r\n\r\n engine._debugPushGroup?.(`render to face #${faceIndex} layer #${layer}`, 2);\r\n\r\n this._objectRenderer.render(faceIndex + layer, true); // only faceIndex or layer (if any) will be different from 0 (we don't support array of cubes), so it's safe to add them to get the pass index\r\n\r\n engine._debugPopGroup?.(2);\r\n\r\n this._unbindFrameBuffer(engine, faceIndex);\r\n\r\n if (this._texture && this.isCube && faceIndex === 5) {\r\n engine.generateMipMapsForCubemap(this._texture, true);\r\n }\r\n }\r\n\r\n /**\r\n * Overrides the default sort function applied in the rendering group to prepare the meshes.\r\n * This allowed control for front to back rendering or reversely depending of the special needs.\r\n *\r\n * @param renderingGroupId The rendering group id corresponding to its index\r\n * @param opaqueSortCompareFn The opaque queue comparison function use to sort.\r\n * @param alphaTestSortCompareFn The alpha test queue comparison function use to sort.\r\n * @param transparentSortCompareFn The transparent queue comparison function use to sort.\r\n */\r\n public setRenderingOrder(\r\n renderingGroupId: number,\r\n opaqueSortCompareFn: Nullable<(a: SubMesh, b: SubMesh) => number> = null,\r\n alphaTestSortCompareFn: Nullable<(a: SubMesh, b: SubMesh) => number> = null,\r\n transparentSortCompareFn: Nullable<(a: SubMesh, b: SubMesh) => number> = null\r\n ): void {\r\n this._objectRenderer.setRenderingOrder(renderingGroupId, opaqueSortCompareFn, alphaTestSortCompareFn, transparentSortCompareFn);\r\n }\r\n\r\n /**\r\n * Specifies whether or not the stencil and depth buffer are cleared between two rendering groups.\r\n *\r\n * @param renderingGroupId The rendering group id corresponding to its index\r\n * @param autoClearDepthStencil Automatically clears depth and stencil between groups if true.\r\n */\r\n public setRenderingAutoClearDepthStencil(renderingGroupId: number, autoClearDepthStencil: boolean): void {\r\n this._objectRenderer.setRenderingAutoClearDepthStencil(renderingGroupId, autoClearDepthStencil);\r\n }\r\n\r\n /**\r\n * Clones the texture.\r\n * @returns the cloned texture\r\n */\r\n public override clone(): RenderTargetTexture {\r\n const textureSize = this.getSize();\r\n const newTexture = new RenderTargetTexture(\r\n this.name,\r\n textureSize,\r\n this.getScene(),\r\n this._renderTargetOptions.generateMipMaps,\r\n this._doNotChangeAspectRatio,\r\n this._renderTargetOptions.type,\r\n this.isCube,\r\n this._renderTargetOptions.samplingMode,\r\n this._renderTargetOptions.generateDepthBuffer,\r\n this._renderTargetOptions.generateStencilBuffer,\r\n undefined,\r\n this._renderTargetOptions.format,\r\n undefined,\r\n this._renderTargetOptions.samples\r\n );\r\n\r\n // Base texture\r\n newTexture.hasAlpha = this.hasAlpha;\r\n newTexture.level = this.level;\r\n\r\n // RenderTarget Texture\r\n newTexture.coordinatesMode = this.coordinatesMode;\r\n if (this.renderList) {\r\n newTexture.renderList = this.renderList.slice(0);\r\n }\r\n\r\n return newTexture;\r\n }\r\n\r\n /**\r\n * Serialize the texture to a JSON representation we can easily use in the respective Parse function.\r\n * @returns The JSON representation of the texture\r\n */\r\n public override serialize(): any {\r\n if (!this.name) {\r\n return null;\r\n }\r\n\r\n const serializationObject = super.serialize();\r\n\r\n serializationObject.renderTargetSize = this.getRenderSize();\r\n serializationObject.renderList = [];\r\n\r\n if (this.renderList) {\r\n for (let index = 0; index < this.renderList.length; index++) {\r\n serializationObject.renderList.push(this.renderList[index].id);\r\n }\r\n }\r\n\r\n return serializationObject;\r\n }\r\n\r\n /**\r\n * This will remove the attached framebuffer objects. The texture will not be able to be used as render target anymore\r\n */\r\n public disposeFramebufferObjects(): void {\r\n this._renderTarget?.dispose(true);\r\n }\r\n\r\n /**\r\n * Release and destroy the underlying lower level texture aka internalTexture.\r\n */\r\n public override releaseInternalTexture(): void {\r\n this._renderTarget?.releaseTextures();\r\n this._texture = null;\r\n }\r\n\r\n /**\r\n * Dispose the texture and release its associated resources.\r\n */\r\n public override dispose(): void {\r\n this.onResizeObservable.clear();\r\n this.onClearObservable.clear();\r\n this.onAfterUnbindObservable.clear();\r\n this.onBeforeBindObservable.clear();\r\n\r\n if (this._postProcessManager) {\r\n this._postProcessManager.dispose();\r\n this._postProcessManager = null;\r\n }\r\n\r\n if (this._prePassRenderTarget) {\r\n this._prePassRenderTarget.dispose();\r\n }\r\n\r\n this._objectRenderer.onBeforeRenderingManagerRenderObservable.remove(this._onBeforeRenderingManagerRenderObserver);\r\n this._objectRenderer.onAfterRenderingManagerRenderObservable.remove(this._onAfterRenderingManagerRenderObserver);\r\n this._objectRenderer.onFastPathRenderObservable.remove(this._onFastPathRenderObserver);\r\n\r\n if (!this._dontDisposeObjectRenderer) {\r\n this._objectRenderer.dispose();\r\n }\r\n\r\n this.clearPostProcesses(true);\r\n\r\n if (this._resizeObserver) {\r\n this.getScene()!.getEngine().onResizeObservable.remove(this._resizeObserver);\r\n this._resizeObserver = null;\r\n }\r\n\r\n // Remove from custom render targets\r\n const scene = this.getScene();\r\n\r\n if (!scene) {\r\n return;\r\n }\r\n\r\n let index = scene.customRenderTargets.indexOf(this);\r\n\r\n if (index >= 0) {\r\n scene.customRenderTargets.splice(index, 1);\r\n }\r\n\r\n for (const camera of scene.cameras) {\r\n index = camera.customRenderTargets.indexOf(this);\r\n\r\n if (index >= 0) {\r\n camera.customRenderTargets.splice(index, 1);\r\n }\r\n }\r\n\r\n this._renderTarget?.dispose();\r\n this._renderTarget = null;\r\n this._texture = null;\r\n\r\n super.dispose();\r\n }\r\n\r\n /** @internal */\r\n public override _rebuild(): void {\r\n this._objectRenderer._rebuild();\r\n\r\n if (this._postProcessManager) {\r\n this._postProcessManager._rebuild();\r\n }\r\n }\r\n\r\n /**\r\n * Clear the info related to rendering groups preventing retention point in material dispose.\r\n */\r\n public freeRenderingGroups(): void {\r\n this._objectRenderer.freeRenderingGroups();\r\n }\r\n\r\n /**\r\n * Gets the number of views the corresponding to the texture (eg. a MultiviewRenderTarget will have > 1)\r\n * @returns the view count\r\n */\r\n public getViewCount() {\r\n return 1;\r\n }\r\n}\r\n\r\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\r\nTexture._CreateRenderTargetTexture = (name: string, renderTargetSize: number, scene: Scene, generateMipMaps: boolean, creationFlags?: number) => {\r\n return new RenderTargetTexture(name, renderTargetSize, scene, generateMipMaps);\r\n};\r\n","import type { Nullable } from \"../types\";\r\nimport { PrecisionDate } from \"./precisionDate\";\r\n\r\n/**\r\n * Performance monitor tracks rolling average frame-time and frame-time variance over a user defined sliding-window\r\n */\r\nexport class PerformanceMonitor {\r\n private _enabled: boolean = true;\r\n private _rollingFrameTime: RollingAverage;\r\n private _lastFrameTimeMs: Nullable;\r\n\r\n /**\r\n * constructor\r\n * @param frameSampleSize The number of samples required to saturate the sliding window\r\n */\r\n constructor(frameSampleSize: number = 30) {\r\n this._rollingFrameTime = new RollingAverage(frameSampleSize);\r\n }\r\n\r\n /**\r\n * Samples current frame\r\n * @param timeMs A timestamp in milliseconds of the current frame to compare with other frames\r\n */\r\n public sampleFrame(timeMs: number = PrecisionDate.Now) {\r\n if (!this._enabled) {\r\n return;\r\n }\r\n\r\n if (this._lastFrameTimeMs != null) {\r\n const dt = timeMs - this._lastFrameTimeMs;\r\n this._rollingFrameTime.add(dt);\r\n }\r\n\r\n this._lastFrameTimeMs = timeMs;\r\n }\r\n\r\n /**\r\n * Returns the average frame time in milliseconds over the sliding window (or the subset of frames sampled so far)\r\n */\r\n public get averageFrameTime(): number {\r\n return this._rollingFrameTime.average;\r\n }\r\n\r\n /**\r\n * Returns the variance frame time in milliseconds over the sliding window (or the subset of frames sampled so far)\r\n */\r\n public get averageFrameTimeVariance(): number {\r\n return this._rollingFrameTime.variance;\r\n }\r\n\r\n /**\r\n * Returns the frame time of the most recent frame\r\n */\r\n public get instantaneousFrameTime(): number {\r\n return this._rollingFrameTime.history(0);\r\n }\r\n\r\n /**\r\n * Returns the average framerate in frames per second over the sliding window (or the subset of frames sampled so far)\r\n */\r\n public get averageFPS(): number {\r\n return 1000.0 / this._rollingFrameTime.average;\r\n }\r\n\r\n /**\r\n * Returns the average framerate in frames per second using the most recent frame time\r\n */\r\n public get instantaneousFPS(): number {\r\n const history = this._rollingFrameTime.history(0);\r\n\r\n if (history === 0) {\r\n return 0;\r\n }\r\n\r\n return 1000.0 / history;\r\n }\r\n\r\n /**\r\n * Returns true if enough samples have been taken to completely fill the sliding window\r\n */\r\n public get isSaturated(): boolean {\r\n return this._rollingFrameTime.isSaturated();\r\n }\r\n\r\n /**\r\n * Enables contributions to the sliding window sample set\r\n */\r\n public enable() {\r\n this._enabled = true;\r\n }\r\n\r\n /**\r\n * Disables contributions to the sliding window sample set\r\n * Samples will not be interpolated over the disabled period\r\n */\r\n public disable() {\r\n this._enabled = false;\r\n //clear last sample to avoid interpolating over the disabled period when next enabled\r\n this._lastFrameTimeMs = null;\r\n }\r\n\r\n /**\r\n * Returns true if sampling is enabled\r\n */\r\n public get isEnabled(): boolean {\r\n return this._enabled;\r\n }\r\n\r\n /**\r\n * Resets performance monitor\r\n */\r\n public reset() {\r\n //clear last sample to avoid interpolating over the disabled period when next enabled\r\n this._lastFrameTimeMs = null;\r\n //wipe record\r\n this._rollingFrameTime.reset();\r\n }\r\n}\r\n\r\n/**\r\n * RollingAverage\r\n *\r\n * Utility to efficiently compute the rolling average and variance over a sliding window of samples\r\n */\r\nexport class RollingAverage {\r\n /**\r\n * Current average\r\n */\r\n public average: number;\r\n /**\r\n * Current variance\r\n */\r\n public variance: number;\r\n\r\n protected _samples: Array;\r\n protected _sampleCount: number;\r\n protected _pos: number;\r\n protected _m2: number; //sum of squares of differences from the (current) mean\r\n\r\n /**\r\n * constructor\r\n * @param length The number of samples required to saturate the sliding window\r\n */\r\n constructor(length: number) {\r\n this._samples = new Array(length);\r\n this.reset();\r\n }\r\n\r\n /**\r\n * Adds a sample to the sample set\r\n * @param v The sample value\r\n */\r\n public add(v: number) {\r\n //http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance\r\n let delta: number;\r\n\r\n //we need to check if we've already wrapped round\r\n if (this.isSaturated()) {\r\n //remove bottom of stack from mean\r\n const bottomValue = this._samples[this._pos];\r\n delta = bottomValue - this.average;\r\n this.average -= delta / (this._sampleCount - 1);\r\n this._m2 -= delta * (bottomValue - this.average);\r\n } else {\r\n this._sampleCount++;\r\n }\r\n\r\n //add new value to mean\r\n delta = v - this.average;\r\n this.average += delta / this._sampleCount;\r\n this._m2 += delta * (v - this.average);\r\n\r\n //set the new variance\r\n this.variance = this._m2 / (this._sampleCount - 1);\r\n\r\n this._samples[this._pos] = v;\r\n this._pos++;\r\n\r\n this._pos %= this._samples.length; //positive wrap around\r\n }\r\n\r\n /**\r\n * Returns previously added values or null if outside of history or outside the sliding window domain\r\n * @param i Index in history. For example, pass 0 for the most recent value and 1 for the value before that\r\n * @returns Value previously recorded with add() or null if outside of range\r\n */\r\n public history(i: number): number {\r\n if (i >= this._sampleCount || i >= this._samples.length) {\r\n return 0;\r\n }\r\n\r\n const i0 = this._wrapPosition(this._pos - 1.0);\r\n return this._samples[this._wrapPosition(i0 - i)];\r\n }\r\n\r\n /**\r\n * Returns true if enough samples have been taken to completely fill the sliding window\r\n * @returns true if sample-set saturated\r\n */\r\n public isSaturated(): boolean {\r\n return this._sampleCount >= this._samples.length;\r\n }\r\n\r\n /**\r\n * Resets the rolling average (equivalent to 0 samples taken so far)\r\n */\r\n public reset() {\r\n this.average = 0;\r\n this.variance = 0;\r\n this._sampleCount = 0;\r\n this._pos = 0;\r\n this._m2 = 0;\r\n }\r\n\r\n /**\r\n * Wraps a value around the sample range boundaries\r\n * @param i Position in sample range, for example if the sample length is 5, and i is -3, then 2 will be returned.\r\n * @returns Wrapped position in sample range\r\n */\r\n protected _wrapPosition(i: number): number {\r\n const max = this._samples.length;\r\n return ((i % max) + max) % max;\r\n }\r\n}\r\n","import { ThinEngine } from \"../../Engines/thinEngine\";\r\nimport type { InternalTexture } from \"../../Materials/Textures/internalTexture\";\r\nimport type { Nullable } from \"../../types\";\r\n\r\ndeclare module \"../../Engines/abstractEngine\" {\r\n export interface AbstractEngine {\r\n /** @internal */\r\n _readTexturePixels(\r\n texture: InternalTexture,\r\n width: number,\r\n height: number,\r\n faceIndex?: number,\r\n level?: number,\r\n buffer?: Nullable,\r\n flushRenderer?: boolean,\r\n noDataConversion?: boolean,\r\n x?: number,\r\n y?: number\r\n ): Promise;\r\n\r\n /** @internal */\r\n _readTexturePixelsSync(\r\n texture: InternalTexture,\r\n width: number,\r\n height: number,\r\n faceIndex?: number,\r\n level?: number,\r\n buffer?: Nullable,\r\n flushRenderer?: boolean,\r\n noDataConversion?: boolean,\r\n x?: number,\r\n y?: number\r\n ): ArrayBufferView;\r\n }\r\n}\r\n\r\n// back-compat\r\nimport { allocateAndCopyTypedBuffer } from \"../../Engines/abstractEngine.functions\";\r\nexport { allocateAndCopyTypedBuffer };\r\n\r\nThinEngine.prototype._readTexturePixelsSync = function (\r\n texture: InternalTexture,\r\n width: number,\r\n height: number,\r\n faceIndex = -1,\r\n level = 0,\r\n buffer: Nullable = null,\r\n flushRenderer = true,\r\n noDataConversion = false,\r\n x = 0,\r\n y = 0\r\n): ArrayBufferView {\r\n const gl = this._gl;\r\n if (!gl) {\r\n throw new Error(\"Engine does not have gl rendering context.\");\r\n }\r\n if (!this._dummyFramebuffer) {\r\n const dummy = gl.createFramebuffer();\r\n\r\n if (!dummy) {\r\n throw new Error(\"Unable to create dummy framebuffer\");\r\n }\r\n\r\n this._dummyFramebuffer = dummy;\r\n }\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, this._dummyFramebuffer);\r\n\r\n if (faceIndex > -1) {\r\n gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, texture._hardwareTexture?.underlyingResource, level);\r\n } else {\r\n gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture._hardwareTexture?.underlyingResource, level);\r\n }\r\n\r\n let readType = texture.type !== undefined ? this._getWebGLTextureType(texture.type) : gl.UNSIGNED_BYTE;\r\n\r\n if (!noDataConversion) {\r\n switch (readType) {\r\n case gl.UNSIGNED_BYTE:\r\n if (!buffer) {\r\n buffer = new Uint8Array(4 * width * height);\r\n }\r\n readType = gl.UNSIGNED_BYTE;\r\n break;\r\n default:\r\n if (!buffer) {\r\n buffer = new Float32Array(4 * width * height);\r\n }\r\n readType = gl.FLOAT;\r\n break;\r\n }\r\n } else if (!buffer) {\r\n buffer = allocateAndCopyTypedBuffer(texture.type, 4 * width * height);\r\n }\r\n\r\n if (flushRenderer) {\r\n this.flushFramebuffer();\r\n }\r\n\r\n gl.readPixels(x, y, width, height, gl.RGBA, readType, buffer);\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, this._currentFramebuffer);\r\n\r\n return buffer;\r\n};\r\n\r\nThinEngine.prototype._readTexturePixels = function (\r\n texture: InternalTexture,\r\n width: number,\r\n height: number,\r\n faceIndex = -1,\r\n level = 0,\r\n buffer: Nullable = null,\r\n flushRenderer = true,\r\n noDataConversion = false,\r\n x = 0,\r\n y = 0\r\n): Promise {\r\n return Promise.resolve(this._readTexturePixelsSync(texture, width, height, faceIndex, level, buffer, flushRenderer, noDataConversion, x, y));\r\n};\r\n","import { ThinEngine } from \"../../Engines/thinEngine\";\r\nimport type { DataBuffer } from \"../../Buffers/dataBuffer\";\r\nimport type { IndicesArray, DataArray } from \"../../types\";\r\n\r\ndeclare module \"../../Engines/abstractEngine\" {\r\n export interface AbstractEngine {\r\n /**\r\n * Update a dynamic index buffer\r\n * @param indexBuffer defines the target index buffer\r\n * @param indices defines the data to update\r\n * @param offset defines the offset in the target index buffer where update should start\r\n */\r\n updateDynamicIndexBuffer(indexBuffer: DataBuffer, indices: IndicesArray, offset?: number): void;\r\n\r\n /**\r\n * Updates a dynamic vertex buffer.\r\n * @param vertexBuffer the vertex buffer to update\r\n * @param data the data used to update the vertex buffer\r\n * @param byteOffset the byte offset of the data\r\n * @param byteLength the byte length of the data\r\n */\r\n updateDynamicVertexBuffer(vertexBuffer: DataBuffer, data: DataArray, byteOffset?: number, byteLength?: number): void;\r\n }\r\n}\r\n\r\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\r\nThinEngine.prototype.updateDynamicIndexBuffer = function (this: ThinEngine, indexBuffer: DataBuffer, indices: IndicesArray, offset: number = 0): void {\r\n // Force cache update\r\n this._currentBoundBuffer[this._gl.ELEMENT_ARRAY_BUFFER] = null;\r\n this.bindIndexBuffer(indexBuffer);\r\n\r\n let view: ArrayBufferView;\r\n if (indexBuffer.is32Bits) {\r\n // anything else than Uint32Array needs to be converted to Uint32Array\r\n view = indices instanceof Uint32Array ? indices : new Uint32Array(indices);\r\n } else {\r\n // anything else than Uint16Array needs to be converted to Uint16Array\r\n view = indices instanceof Uint16Array ? indices : new Uint16Array(indices);\r\n }\r\n\r\n this._gl.bufferData(this._gl.ELEMENT_ARRAY_BUFFER, view, this._gl.DYNAMIC_DRAW);\r\n\r\n this._resetIndexBufferBinding();\r\n};\r\n\r\nThinEngine.prototype.updateDynamicVertexBuffer = function (this: ThinEngine, vertexBuffer: DataBuffer, data: DataArray, byteOffset?: number, byteLength?: number): void {\r\n this.bindArrayBuffer(vertexBuffer);\r\n\r\n if (byteOffset === undefined) {\r\n byteOffset = 0;\r\n }\r\n\r\n const dataLength = (data as ArrayBuffer).byteLength || (data as number[]).length;\r\n\r\n if (byteLength === undefined || (byteLength >= dataLength && byteOffset === 0)) {\r\n if (data instanceof Array) {\r\n this._gl.bufferSubData(this._gl.ARRAY_BUFFER, byteOffset, new Float32Array(data));\r\n } else {\r\n this._gl.bufferSubData(this._gl.ARRAY_BUFFER, byteOffset, data);\r\n }\r\n } else {\r\n if (data instanceof Array) {\r\n this._gl.bufferSubData(this._gl.ARRAY_BUFFER, 0, new Float32Array(data).subarray(byteOffset, byteOffset + byteLength));\r\n } else {\r\n if (data instanceof ArrayBuffer) {\r\n data = new Uint8Array(data, byteOffset, byteLength);\r\n } else {\r\n data = new Uint8Array(data.buffer, data.byteOffset + byteOffset, byteLength);\r\n }\r\n\r\n this._gl.bufferSubData(this._gl.ARRAY_BUFFER, 0, data);\r\n }\r\n }\r\n\r\n this._resetVertexBufferBinding();\r\n};\r\n","import { ThinEngine } from \"../../Engines/thinEngine\";\r\nimport { InternalTexture, InternalTextureSource } from \"../../Materials/Textures/internalTexture\";\r\nimport { Logger } from \"../../Misc/logger\";\r\nimport type { Nullable } from \"../../types\";\r\nimport type { Scene } from \"../../scene\";\r\nimport { Constants } from \"../constants\";\r\nimport type { DepthTextureCreationOptions } from \"../../Materials/Textures/textureCreationOptions\";\r\nimport { GetExponentOfTwo } from \"../../Misc/tools.functions\";\r\n\r\ndeclare module \"../../Engines/abstractEngine\" {\r\n export interface AbstractEngine {\r\n /**\r\n * @internal\r\n */\r\n _setCubeMapTextureParams(texture: InternalTexture, loadMipmap: boolean, maxLevel?: number): void;\r\n /**\r\n * Creates a depth stencil cube texture.\r\n * This is only available in WebGL 2.\r\n * @param size The size of face edge in the cube texture.\r\n * @param options The options defining the cube texture.\r\n * @returns The cube texture\r\n */\r\n _createDepthStencilCubeTexture(size: number, options: DepthTextureCreationOptions): InternalTexture;\r\n\r\n /**\r\n * Creates a cube texture\r\n * @param rootUrl defines the url where the files to load is located\r\n * @param scene defines the current scene\r\n * @param files defines the list of files to load (1 per face)\r\n * @param noMipmap defines a boolean indicating that no mipmaps shall be generated (false by default)\r\n * @param onLoad defines an optional callback raised when the texture is loaded\r\n * @param onError defines an optional callback raised if there is an issue to load the texture\r\n * @param format defines the format of the data\r\n * @param forcedExtension defines the extension to use to pick the right loader\r\n * @param createPolynomials if a polynomial sphere should be created for the cube texture\r\n * @param lodScale defines the scale applied to environment texture. This manages the range of LOD level used for IBL according to the roughness\r\n * @param lodOffset defines the offset applied to environment texture. This manages first LOD level used for IBL according to the roughness\r\n * @param fallback defines texture to use while falling back when (compressed) texture file not found.\r\n * @param loaderOptions options to be passed to the loader\r\n * @param useSRGBBuffer defines if the texture must be loaded in a sRGB GPU buffer (if supported by the GPU).\r\n * @param buffer defines the data buffer to load instead of loading the rootUrl\r\n * @returns the cube texture as an InternalTexture\r\n */\r\n createCubeTexture(\r\n rootUrl: string,\r\n scene: Nullable,\r\n files: Nullable,\r\n noMipmap: boolean | undefined,\r\n onLoad: Nullable<(data?: any) => void>,\r\n onError: Nullable<(message?: string, exception?: any) => void>,\r\n format: number | undefined,\r\n forcedExtension: any,\r\n createPolynomials: boolean,\r\n lodScale: number,\r\n lodOffset: number,\r\n fallback: Nullable,\r\n loaderOptions: any,\r\n useSRGBBuffer: boolean,\r\n buffer: Nullable\r\n ): InternalTexture;\r\n\r\n /**\r\n * Creates a cube texture\r\n * @param rootUrl defines the url where the files to load is located\r\n * @param scene defines the current scene\r\n * @param files defines the list of files to load (1 per face)\r\n * @param noMipmap defines a boolean indicating that no mipmaps shall be generated (false by default)\r\n * @param onLoad defines an optional callback raised when the texture is loaded\r\n * @param onError defines an optional callback raised if there is an issue to load the texture\r\n * @param format defines the format of the data\r\n * @param forcedExtension defines the extension to use to pick the right loader\r\n * @returns the cube texture as an InternalTexture\r\n */\r\n createCubeTexture(\r\n rootUrl: string,\r\n scene: Nullable,\r\n files: Nullable,\r\n noMipmap: boolean,\r\n onLoad: Nullable<(data?: any) => void>,\r\n onError: Nullable<(message?: string, exception?: any) => void>,\r\n format: number | undefined,\r\n forcedExtension: any\r\n ): InternalTexture;\r\n\r\n /**\r\n * Creates a cube texture\r\n * @param rootUrl defines the url where the files to load is located\r\n * @param scene defines the current scene\r\n * @param files defines the list of files to load (1 per face)\r\n * @param noMipmap defines a boolean indicating that no mipmaps shall be generated (false by default)\r\n * @param onLoad defines an optional callback raised when the texture is loaded\r\n * @param onError defines an optional callback raised if there is an issue to load the texture\r\n * @param format defines the format of the data\r\n * @param forcedExtension defines the extension to use to pick the right loader\r\n * @param createPolynomials if a polynomial sphere should be created for the cube texture\r\n * @param lodScale defines the scale applied to environment texture. This manages the range of LOD level used for IBL according to the roughness\r\n * @param lodOffset defines the offset applied to environment texture. This manages first LOD level used for IBL according to the roughness\r\n * @returns the cube texture as an InternalTexture\r\n */\r\n createCubeTexture(\r\n rootUrl: string,\r\n scene: Nullable,\r\n files: Nullable,\r\n noMipmap: boolean,\r\n onLoad: Nullable<(data?: any) => void>,\r\n onError: Nullable<(message?: string, exception?: any) => void>,\r\n format: number | undefined,\r\n forcedExtension: any,\r\n createPolynomials: boolean,\r\n lodScale: number,\r\n lodOffset: number\r\n ): InternalTexture;\r\n\r\n /** @internal */\r\n createCubeTextureBase(\r\n rootUrl: string,\r\n scene: Nullable,\r\n files: Nullable,\r\n noMipmap: boolean,\r\n onLoad: Nullable<(data?: any) => void>,\r\n onError: Nullable<(message?: string, exception?: any) => void>,\r\n format: number | undefined,\r\n forcedExtension: any,\r\n createPolynomials: boolean,\r\n lodScale: number,\r\n lodOffset: number,\r\n fallback: Nullable,\r\n beforeLoadCubeDataCallback: Nullable<(texture: InternalTexture, data: ArrayBufferView | ArrayBufferView[]) => void>,\r\n imageHandler: Nullable<(texture: InternalTexture, imgs: HTMLImageElement[] | ImageBitmap[]) => void>,\r\n useSRGBBuffer: boolean,\r\n buffer: ArrayBufferView\r\n ): InternalTexture;\r\n\r\n /**\r\n * Force the mipmap generation for the given render target texture\r\n * @param texture defines the render target texture to use\r\n * @param unbind defines whether or not to unbind the texture after generation. Defaults to true.\r\n */\r\n generateMipMapsForCubemap(texture: InternalTexture, unbind?: boolean): void;\r\n }\r\n}\r\n\r\nThinEngine.prototype._createDepthStencilCubeTexture = function (size: number, options: DepthTextureCreationOptions): InternalTexture {\r\n const internalTexture = new InternalTexture(this, InternalTextureSource.DepthStencil);\r\n internalTexture.isCube = true;\r\n\r\n if (this.webGLVersion === 1) {\r\n Logger.Error(\"Depth cube texture is not supported by WebGL 1.\");\r\n return internalTexture;\r\n }\r\n\r\n const internalOptions = {\r\n bilinearFiltering: false,\r\n comparisonFunction: 0,\r\n generateStencil: false,\r\n ...options,\r\n };\r\n\r\n const gl = this._gl;\r\n this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, internalTexture, true);\r\n\r\n this._setupDepthStencilTexture(internalTexture, size, internalOptions.bilinearFiltering, internalOptions.comparisonFunction);\r\n\r\n // Create the depth/stencil buffer\r\n for (let face = 0; face < 6; face++) {\r\n if (internalOptions.generateStencil) {\r\n gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + face, 0, gl.DEPTH24_STENCIL8, size, size, 0, gl.DEPTH_STENCIL, gl.UNSIGNED_INT_24_8, null);\r\n } else {\r\n gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + face, 0, gl.DEPTH_COMPONENT24, size, size, 0, gl.DEPTH_COMPONENT, gl.UNSIGNED_INT, null);\r\n }\r\n }\r\n\r\n this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, null);\r\n\r\n this._internalTexturesCache.push(internalTexture);\r\n\r\n return internalTexture;\r\n};\r\n\r\nThinEngine.prototype._setCubeMapTextureParams = function (texture: InternalTexture, loadMipmap: boolean, maxLevel?: number): void {\r\n const gl = this._gl;\r\n gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\r\n gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, loadMipmap ? gl.LINEAR_MIPMAP_LINEAR : gl.LINEAR);\r\n gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n texture.samplingMode = loadMipmap ? Constants.TEXTURE_TRILINEAR_SAMPLINGMODE : Constants.TEXTURE_LINEAR_LINEAR;\r\n\r\n if (loadMipmap && this.getCaps().textureMaxLevel && maxLevel !== undefined && maxLevel > 0) {\r\n gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAX_LEVEL, maxLevel);\r\n texture._maxLodLevel = maxLevel;\r\n }\r\n\r\n this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, null);\r\n};\r\n\r\nThinEngine.prototype.createCubeTexture = function (\r\n rootUrl: string,\r\n scene: Nullable,\r\n files: Nullable,\r\n noMipmap?: boolean,\r\n onLoad: Nullable<(data?: any) => void> = null,\r\n onError: Nullable<(message?: string, exception?: any) => void> = null,\r\n format?: number,\r\n forcedExtension: any = null,\r\n createPolynomials: boolean = false,\r\n lodScale: number = 0,\r\n lodOffset: number = 0,\r\n fallback: Nullable = null,\r\n loaderOptions?: any,\r\n useSRGBBuffer = false,\r\n buffer: Nullable = null\r\n): InternalTexture {\r\n const gl = this._gl;\r\n\r\n return this.createCubeTextureBase(\r\n rootUrl,\r\n scene,\r\n files,\r\n !!noMipmap,\r\n onLoad,\r\n onError,\r\n format,\r\n forcedExtension,\r\n createPolynomials,\r\n lodScale,\r\n lodOffset,\r\n fallback,\r\n (texture: InternalTexture) => this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, texture, true),\r\n (texture: InternalTexture, imgs: HTMLImageElement[] | ImageBitmap[]) => {\r\n const width = this.needPOTTextures ? GetExponentOfTwo(imgs[0].width, this._caps.maxCubemapTextureSize) : imgs[0].width;\r\n const height = width;\r\n\r\n const faces = [\r\n gl.TEXTURE_CUBE_MAP_POSITIVE_X,\r\n gl.TEXTURE_CUBE_MAP_POSITIVE_Y,\r\n gl.TEXTURE_CUBE_MAP_POSITIVE_Z,\r\n gl.TEXTURE_CUBE_MAP_NEGATIVE_X,\r\n gl.TEXTURE_CUBE_MAP_NEGATIVE_Y,\r\n gl.TEXTURE_CUBE_MAP_NEGATIVE_Z,\r\n ];\r\n\r\n this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, texture, true);\r\n this._unpackFlipY(false);\r\n\r\n const internalFormat = format ? this._getInternalFormat(format, texture._useSRGBBuffer) : texture._useSRGBBuffer ? this._glSRGBExtensionValues.SRGB8_ALPHA8 : gl.RGBA;\r\n let texelFormat = format ? this._getInternalFormat(format) : gl.RGBA;\r\n\r\n if (texture._useSRGBBuffer && this.webGLVersion === 1) {\r\n texelFormat = internalFormat;\r\n }\r\n\r\n for (let index = 0; index < faces.length; index++) {\r\n if (imgs[index].width !== width || imgs[index].height !== height) {\r\n this._prepareWorkingCanvas();\r\n\r\n if (!this._workingCanvas || !this._workingContext) {\r\n Logger.Warn(\"Cannot create canvas to resize texture.\");\r\n return;\r\n }\r\n this._workingCanvas.width = width;\r\n this._workingCanvas.height = height;\r\n\r\n this._workingContext.drawImage(imgs[index], 0, 0, imgs[index].width, imgs[index].height, 0, 0, width, height);\r\n gl.texImage2D(faces[index], 0, internalFormat, texelFormat, gl.UNSIGNED_BYTE, this._workingCanvas as TexImageSource);\r\n } else {\r\n gl.texImage2D(faces[index], 0, internalFormat, texelFormat, gl.UNSIGNED_BYTE, imgs[index]);\r\n }\r\n }\r\n\r\n if (!noMipmap) {\r\n gl.generateMipmap(gl.TEXTURE_CUBE_MAP);\r\n }\r\n\r\n this._setCubeMapTextureParams(texture, !noMipmap);\r\n\r\n texture.width = width;\r\n texture.height = height;\r\n texture.isReady = true;\r\n if (format) {\r\n texture.format = format;\r\n }\r\n\r\n texture.onLoadedObservable.notifyObservers(texture);\r\n texture.onLoadedObservable.clear();\r\n\r\n if (onLoad) {\r\n onLoad();\r\n }\r\n },\r\n !!useSRGBBuffer,\r\n buffer\r\n );\r\n};\r\n\r\nThinEngine.prototype.generateMipMapsForCubemap = function (texture: InternalTexture, unbind = true) {\r\n if (texture.generateMipMaps) {\r\n const gl = this._gl;\r\n this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, texture, true);\r\n gl.generateMipmap(gl.TEXTURE_CUBE_MAP);\r\n if (unbind) {\r\n this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, null);\r\n }\r\n }\r\n};\r\n","import type { Nullable } from \"../../types\";\r\nimport { ThinEngine } from \"../../Engines/thinEngine\";\r\nimport type { RenderTargetTexture } from \"../../Materials/Textures/renderTargetTexture\";\r\n\r\ndeclare module \"../../Engines/abstractEngine\" {\r\n export interface AbstractEngine {\r\n /**\r\n * Sets a depth stencil texture from a render target to the according uniform.\r\n * @param channel The texture channel\r\n * @param uniform The uniform to set\r\n * @param texture The render target texture containing the depth stencil texture to apply\r\n * @param name The texture name\r\n */\r\n setDepthStencilTexture(channel: number, uniform: Nullable, texture: Nullable, name?: string): void;\r\n }\r\n}\r\n\r\nThinEngine.prototype.setDepthStencilTexture = function (channel: number, uniform: Nullable, texture: Nullable, name?: string): void {\r\n if (channel === undefined) {\r\n return;\r\n }\r\n\r\n if (uniform) {\r\n this._boundUniforms[channel] = uniform;\r\n }\r\n\r\n if (!texture || !texture.depthStencilTexture) {\r\n this._setTexture(channel, null, undefined, undefined, name);\r\n } else {\r\n this._setTexture(channel, texture, false, true, name);\r\n }\r\n};\r\n","import { InternalTexture, InternalTextureSource } from \"../../Materials/Textures/internalTexture\";\r\nimport { Logger } from \"../../Misc/logger\";\r\nimport { Constants } from \"../constants\";\r\nimport { ThinEngine } from \"../thinEngine\";\r\nimport type { RenderTargetWrapper } from \"../renderTargetWrapper\";\r\nimport type { WebGLRenderTargetWrapper } from \"../WebGL/webGLRenderTargetWrapper\";\r\nimport type { RenderTargetCreationOptions } from \"../../Materials/Textures/textureCreationOptions\";\r\n\r\ndeclare module \"../../Engines/abstractEngine\" {\r\n export interface AbstractEngine {\r\n /**\r\n * Creates a new render target cube wrapper\r\n * @param size defines the size of the texture\r\n * @param options defines the options used to create the texture\r\n * @returns a new render target cube wrapper\r\n */\r\n createRenderTargetCubeTexture(size: number, options?: RenderTargetCreationOptions): RenderTargetWrapper;\r\n }\r\n}\r\n\r\nThinEngine.prototype.createRenderTargetCubeTexture = function (size: number, options?: RenderTargetCreationOptions): RenderTargetWrapper {\r\n const rtWrapper = this._createHardwareRenderTargetWrapper(false, true, size) as WebGLRenderTargetWrapper;\r\n\r\n const fullOptions = {\r\n generateMipMaps: true,\r\n generateDepthBuffer: true,\r\n generateStencilBuffer: false,\r\n type: Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n samplingMode: Constants.TEXTURE_TRILINEAR_SAMPLINGMODE,\r\n format: Constants.TEXTUREFORMAT_RGBA,\r\n ...options,\r\n };\r\n fullOptions.generateStencilBuffer = fullOptions.generateDepthBuffer && fullOptions.generateStencilBuffer;\r\n\r\n if (fullOptions.type === Constants.TEXTURETYPE_FLOAT && !this._caps.textureFloatLinearFiltering) {\r\n // if floating point linear (gl.FLOAT) then force to NEAREST_SAMPLINGMODE\r\n fullOptions.samplingMode = Constants.TEXTURE_NEAREST_SAMPLINGMODE;\r\n } else if (fullOptions.type === Constants.TEXTURETYPE_HALF_FLOAT && !this._caps.textureHalfFloatLinearFiltering) {\r\n // if floating point linear (HALF_FLOAT) then force to NEAREST_SAMPLINGMODE\r\n fullOptions.samplingMode = Constants.TEXTURE_NEAREST_SAMPLINGMODE;\r\n }\r\n const gl = this._gl;\r\n\r\n const texture = new InternalTexture(this, InternalTextureSource.RenderTarget);\r\n this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, texture, true);\r\n\r\n const filters = this._getSamplingParameters(fullOptions.samplingMode, fullOptions.generateMipMaps);\r\n\r\n if (fullOptions.type === Constants.TEXTURETYPE_FLOAT && !this._caps.textureFloat) {\r\n fullOptions.type = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n Logger.Warn(\"Float textures are not supported. Cube render target forced to TEXTURETYPE_UNESIGNED_BYTE type\");\r\n }\r\n\r\n gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, filters.mag);\r\n gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, filters.min);\r\n gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n\r\n for (let face = 0; face < 6; face++) {\r\n gl.texImage2D(\r\n gl.TEXTURE_CUBE_MAP_POSITIVE_X + face,\r\n 0,\r\n this._getRGBABufferInternalSizedFormat(fullOptions.type, fullOptions.format),\r\n size,\r\n size,\r\n 0,\r\n this._getInternalFormat(fullOptions.format),\r\n this._getWebGLTextureType(fullOptions.type),\r\n null\r\n );\r\n }\r\n\r\n // Create the framebuffer\r\n const framebuffer = gl.createFramebuffer();\r\n this._bindUnboundFramebuffer(framebuffer);\r\n\r\n rtWrapper._depthStencilBuffer = this._setupFramebufferDepthAttachments(fullOptions.generateStencilBuffer, fullOptions.generateDepthBuffer, size, size);\r\n\r\n // MipMaps\r\n if (fullOptions.generateMipMaps) {\r\n gl.generateMipmap(gl.TEXTURE_CUBE_MAP);\r\n }\r\n\r\n // Unbind\r\n this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, null);\r\n this._bindUnboundFramebuffer(null);\r\n\r\n rtWrapper._framebuffer = framebuffer;\r\n rtWrapper._generateDepthBuffer = fullOptions.generateDepthBuffer;\r\n rtWrapper._generateStencilBuffer = fullOptions.generateStencilBuffer;\r\n\r\n texture.width = size;\r\n texture.height = size;\r\n texture.isReady = true;\r\n texture.isCube = true;\r\n texture.samples = 1;\r\n texture.generateMipMaps = fullOptions.generateMipMaps;\r\n texture.samplingMode = fullOptions.samplingMode;\r\n texture.type = fullOptions.type;\r\n texture.format = fullOptions.format;\r\n\r\n this._internalTexturesCache.push(texture);\r\n rtWrapper.setTextures(texture);\r\n\r\n return rtWrapper;\r\n};\r\n","import { ThinEngine } from \"../../Engines/thinEngine\";\r\nimport { InternalTexture, InternalTextureSource } from \"../../Materials/Textures/internalTexture\";\r\nimport { Logger } from \"../../Misc/logger\";\r\nimport type { Nullable } from \"../../types\";\r\nimport type { Scene } from \"../../scene\";\r\nimport { Constants } from \"../constants\";\r\nimport { SphericalPolynomial } from \"core/Maths/sphericalPolynomial\";\r\nimport { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\nimport type { DDSInfo } from \"core/Misc/dds\";\r\n\r\ndeclare module \"../../Engines/abstractEngine\" {\r\n export interface AbstractEngine {\r\n /**\r\n * Create a cube texture from prefiltered data (ie. the mipmaps contain ready to use data for PBR reflection)\r\n * @param rootUrl defines the url where the file to load is located\r\n * @param scene defines the current scene\r\n * @param lodScale defines scale to apply to the mip map selection\r\n * @param lodOffset defines offset to apply to the mip map selection\r\n * @param onLoad defines an optional callback raised when the texture is loaded\r\n * @param onError defines an optional callback raised if there is an issue to load the texture\r\n * @param format defines the format of the data\r\n * @param forcedExtension defines the extension to use to pick the right loader\r\n * @param createPolynomials defines wheter or not to create polynomails harmonics for the texture\r\n * @returns the cube texture as an InternalTexture\r\n */\r\n createPrefilteredCubeTexture(\r\n rootUrl: string,\r\n scene: Nullable,\r\n lodScale: number,\r\n lodOffset: number,\r\n onLoad?: Nullable<(internalTexture: Nullable) => void>,\r\n onError?: Nullable<(message?: string, exception?: any) => void>,\r\n format?: number,\r\n forcedExtension?: any,\r\n createPolynomials?: boolean\r\n ): InternalTexture;\r\n }\r\n}\r\n\r\nThinEngine.prototype.createPrefilteredCubeTexture = function (\r\n rootUrl: string,\r\n scene: Nullable,\r\n lodScale: number,\r\n lodOffset: number,\r\n onLoad: Nullable<(internalTexture: Nullable) => void> = null,\r\n onError: Nullable<(message?: string, exception?: any) => void> = null,\r\n format?: number,\r\n forcedExtension: any = null,\r\n createPolynomials: boolean = true\r\n): InternalTexture {\r\n const callback = async (loadData: any) => {\r\n if (!loadData) {\r\n if (onLoad) {\r\n onLoad(null);\r\n }\r\n return;\r\n }\r\n\r\n const texture = loadData.texture as InternalTexture;\r\n if (!createPolynomials) {\r\n texture._sphericalPolynomial = new SphericalPolynomial();\r\n } else if (loadData.info.sphericalPolynomial) {\r\n texture._sphericalPolynomial = loadData.info.sphericalPolynomial;\r\n }\r\n texture._source = InternalTextureSource.CubePrefiltered;\r\n\r\n if (this.getCaps().textureLOD) {\r\n // Do not add extra process if texture lod is supported.\r\n if (onLoad) {\r\n onLoad(texture);\r\n }\r\n return;\r\n }\r\n\r\n const mipSlices = 3;\r\n\r\n const gl = this._gl;\r\n const width = loadData.width;\r\n if (!width) {\r\n return;\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n const { DDSTools } = await import(\"core/Misc/dds\");\r\n\r\n const textures: BaseTexture[] = [];\r\n for (let i = 0; i < mipSlices; i++) {\r\n //compute LOD from even spacing in smoothness (matching shader calculation)\r\n const smoothness = i / (mipSlices - 1);\r\n const roughness = 1 - smoothness;\r\n\r\n const minLODIndex = lodOffset; // roughness = 0\r\n const maxLODIndex = Math.log2(width) * lodScale + lodOffset; // roughness = 1\r\n\r\n const lodIndex = minLODIndex + (maxLODIndex - minLODIndex) * roughness;\r\n const mipmapIndex = Math.round(Math.min(Math.max(lodIndex, 0), maxLODIndex));\r\n\r\n const glTextureFromLod = new InternalTexture(this, InternalTextureSource.Temp);\r\n glTextureFromLod.type = texture.type;\r\n glTextureFromLod.format = texture.format;\r\n glTextureFromLod.width = Math.pow(2, Math.max(Math.log2(width) - mipmapIndex, 0));\r\n glTextureFromLod.height = glTextureFromLod.width;\r\n glTextureFromLod.isCube = true;\r\n glTextureFromLod._cachedWrapU = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n glTextureFromLod._cachedWrapV = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, glTextureFromLod, true);\r\n\r\n glTextureFromLod.samplingMode = Constants.TEXTURE_LINEAR_LINEAR;\r\n gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\r\n gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\r\n gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n\r\n if (loadData.isDDS) {\r\n const info: DDSInfo = loadData.info;\r\n const data: any = loadData.data;\r\n this._unpackFlipY(info.isCompressed);\r\n\r\n DDSTools.UploadDDSLevels(this, glTextureFromLod, data, info, true, 6, mipmapIndex);\r\n } else {\r\n Logger.Warn(\"DDS is the only prefiltered cube map supported so far.\");\r\n }\r\n\r\n this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, null);\r\n\r\n // Wrap in a base texture for easy binding.\r\n const lodTexture = new BaseTexture(scene);\r\n lodTexture._isCube = true;\r\n lodTexture._texture = glTextureFromLod;\r\n\r\n glTextureFromLod.isReady = true;\r\n textures.push(lodTexture);\r\n }\r\n\r\n texture._lodTextureHigh = textures[2];\r\n texture._lodTextureMid = textures[1];\r\n texture._lodTextureLow = textures[0];\r\n\r\n if (onLoad) {\r\n onLoad(texture);\r\n }\r\n };\r\n\r\n return this.createCubeTexture(rootUrl, scene, null, false, callback, onError, format, forcedExtension, createPolynomials, lodScale, lodOffset);\r\n};\r\n","import { ThinEngine } from \"../../Engines/thinEngine\";\r\nimport type { FloatArray, Nullable } from \"../../types\";\r\nimport type { DataBuffer } from \"../../Buffers/dataBuffer\";\r\nimport { WebGLDataBuffer } from \"../../Meshes/WebGL/webGLDataBuffer\";\r\nimport type { IPipelineContext } from \"../IPipelineContext\";\r\nimport type { WebGLPipelineContext } from \"../WebGL/webGLPipelineContext\";\r\n\r\ndeclare module \"../../Engines/thinEngine\" {\r\n export interface ThinEngine {\r\n /**\r\n * Create an uniform buffer\r\n * @see https://doc.babylonjs.com/setup/support/webGL2#uniform-buffer-objets\r\n * @param elements defines the content of the uniform buffer\r\n * @param label defines a name for the buffer (for debugging purpose)\r\n * @returns the webGL uniform buffer\r\n */\r\n createUniformBuffer(elements: FloatArray, label?: string): DataBuffer;\r\n\r\n /**\r\n * Create a dynamic uniform buffer\r\n * @see https://doc.babylonjs.com/setup/support/webGL2#uniform-buffer-objets\r\n * @param elements defines the content of the uniform buffer\r\n * @param label defines a name for the buffer (for debugging purpose)\r\n * @returns the webGL uniform buffer\r\n */\r\n createDynamicUniformBuffer(elements: FloatArray, label?: string): DataBuffer;\r\n\r\n /**\r\n * Update an existing uniform buffer\r\n * @see https://doc.babylonjs.com/setup/support/webGL2#uniform-buffer-objets\r\n * @param uniformBuffer defines the target uniform buffer\r\n * @param elements defines the content to update\r\n * @param offset defines the offset in the uniform buffer where update should start\r\n * @param count defines the size of the data to update\r\n */\r\n updateUniformBuffer(uniformBuffer: DataBuffer, elements: FloatArray, offset?: number, count?: number): void;\r\n\r\n /**\r\n * Bind an uniform buffer to the current webGL context\r\n * @param buffer defines the buffer to bind\r\n */\r\n bindUniformBuffer(buffer: Nullable): void;\r\n\r\n /**\r\n * Bind a buffer to the current webGL context at a given location\r\n * @param buffer defines the buffer to bind\r\n * @param location defines the index where to bind the buffer\r\n * @param name Name of the uniform variable to bind\r\n */\r\n bindUniformBufferBase(buffer: DataBuffer, location: number, name: string): void;\r\n\r\n /**\r\n * Bind a specific block at a given index in a specific shader program\r\n * @param pipelineContext defines the pipeline context to use\r\n * @param blockName defines the block name\r\n * @param index defines the index where to bind the block\r\n */\r\n bindUniformBlock(pipelineContext: IPipelineContext, blockName: string, index: number): void;\r\n }\r\n}\r\n\r\nThinEngine.prototype.createUniformBuffer = function (elements: FloatArray, _label?: string): DataBuffer {\r\n const ubo = this._gl.createBuffer();\r\n\r\n if (!ubo) {\r\n throw new Error(\"Unable to create uniform buffer\");\r\n }\r\n const result = new WebGLDataBuffer(ubo);\r\n\r\n this.bindUniformBuffer(result);\r\n\r\n if (elements instanceof Float32Array) {\r\n this._gl.bufferData(this._gl.UNIFORM_BUFFER, elements, this._gl.STATIC_DRAW);\r\n } else {\r\n this._gl.bufferData(this._gl.UNIFORM_BUFFER, new Float32Array(elements), this._gl.STATIC_DRAW);\r\n }\r\n\r\n this.bindUniformBuffer(null);\r\n\r\n result.references = 1;\r\n return result;\r\n};\r\n\r\nThinEngine.prototype.createDynamicUniformBuffer = function (elements: FloatArray, _label?: string): DataBuffer {\r\n const ubo = this._gl.createBuffer();\r\n\r\n if (!ubo) {\r\n throw new Error(\"Unable to create dynamic uniform buffer\");\r\n }\r\n\r\n const result = new WebGLDataBuffer(ubo);\r\n this.bindUniformBuffer(result);\r\n\r\n if (elements instanceof Float32Array) {\r\n this._gl.bufferData(this._gl.UNIFORM_BUFFER, elements, this._gl.DYNAMIC_DRAW);\r\n } else {\r\n this._gl.bufferData(this._gl.UNIFORM_BUFFER, new Float32Array(elements), this._gl.DYNAMIC_DRAW);\r\n }\r\n\r\n this.bindUniformBuffer(null);\r\n\r\n result.references = 1;\r\n return result;\r\n};\r\n\r\nThinEngine.prototype.updateUniformBuffer = function (uniformBuffer: DataBuffer, elements: FloatArray, offset?: number, count?: number): void {\r\n this.bindUniformBuffer(uniformBuffer);\r\n\r\n if (offset === undefined) {\r\n offset = 0;\r\n }\r\n\r\n if (count === undefined) {\r\n if (elements instanceof Float32Array) {\r\n this._gl.bufferSubData(this._gl.UNIFORM_BUFFER, offset, elements);\r\n } else {\r\n this._gl.bufferSubData(this._gl.UNIFORM_BUFFER, offset, new Float32Array(elements));\r\n }\r\n } else {\r\n if (elements instanceof Float32Array) {\r\n this._gl.bufferSubData(this._gl.UNIFORM_BUFFER, 0, elements.subarray(offset, offset + count));\r\n } else {\r\n this._gl.bufferSubData(this._gl.UNIFORM_BUFFER, 0, new Float32Array(elements).subarray(offset, offset + count));\r\n }\r\n }\r\n\r\n this.bindUniformBuffer(null);\r\n};\r\n\r\nThinEngine.prototype.bindUniformBuffer = function (buffer: Nullable): void {\r\n this._gl.bindBuffer(this._gl.UNIFORM_BUFFER, buffer ? buffer.underlyingResource : null);\r\n};\r\n\r\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\r\nThinEngine.prototype.bindUniformBufferBase = function (buffer: DataBuffer, location: number, name: string): void {\r\n this._gl.bindBufferBase(this._gl.UNIFORM_BUFFER, location, buffer ? buffer.underlyingResource : null);\r\n};\r\n\r\nThinEngine.prototype.bindUniformBlock = function (pipelineContext: IPipelineContext, blockName: string, index: number): void {\r\n const program = (pipelineContext as WebGLPipelineContext).program!;\r\n\r\n const uniformLocation = this._gl.getUniformBlockIndex(program, blockName);\r\n\r\n if (uniformLocation !== 0xffffffff) {\r\n this._gl.uniformBlockBinding(program, uniformLocation, index);\r\n }\r\n};\r\n","import { IsWindowObjectExist } from \"../../Misc/domManagement\";\r\nimport type { ILoadingScreen } from \"../../Loading/loadingScreen\";\r\nimport { AbstractEngine } from \"../abstractEngine\";\r\n\r\ndeclare module \"../../Engines/abstractEngine\" {\r\n export interface AbstractEngine {\r\n /**\r\n * Display the loading screen\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/customLoadingScreen\r\n */\r\n displayLoadingUI(): void;\r\n\r\n /**\r\n * Hide the loading screen\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/customLoadingScreen\r\n */\r\n hideLoadingUI(): void;\r\n\r\n /**\r\n * Gets or sets the current loading screen object\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/customLoadingScreen\r\n */\r\n loadingScreen: ILoadingScreen;\r\n\r\n /**\r\n * Sets the current loading screen text\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/customLoadingScreen\r\n */\r\n loadingUIText: string;\r\n\r\n /**\r\n * Sets the current loading screen background color\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/customLoadingScreen\r\n */\r\n loadingUIBackgroundColor: string;\r\n }\r\n}\r\n\r\nAbstractEngine.prototype.displayLoadingUI = function (): void {\r\n if (!IsWindowObjectExist()) {\r\n return;\r\n }\r\n const loadingScreen = this.loadingScreen;\r\n if (loadingScreen) {\r\n loadingScreen.displayLoadingUI();\r\n }\r\n};\r\n\r\nAbstractEngine.prototype.hideLoadingUI = function (): void {\r\n if (!IsWindowObjectExist()) {\r\n return;\r\n }\r\n const loadingScreen = this._loadingScreen;\r\n if (loadingScreen) {\r\n loadingScreen.hideLoadingUI();\r\n }\r\n};\r\n\r\nObject.defineProperty(AbstractEngine.prototype, \"loadingScreen\", {\r\n get: function (this: AbstractEngine) {\r\n if (!this._loadingScreen && this._renderingCanvas) {\r\n this._loadingScreen = AbstractEngine.DefaultLoadingScreenFactory(this._renderingCanvas);\r\n }\r\n return this._loadingScreen;\r\n },\r\n set: function (this: AbstractEngine, value: ILoadingScreen) {\r\n this._loadingScreen = value;\r\n },\r\n enumerable: true,\r\n configurable: true,\r\n});\r\n\r\nObject.defineProperty(AbstractEngine.prototype, \"loadingUIText\", {\r\n set: function (this: AbstractEngine, value: string) {\r\n this.loadingScreen.loadingUIText = value;\r\n },\r\n enumerable: true,\r\n configurable: true,\r\n});\r\n\r\nObject.defineProperty(AbstractEngine.prototype, \"loadingUIBackgroundColor\", {\r\n set: function (this: AbstractEngine, value: string) {\r\n this.loadingScreen.loadingUIBackgroundColor = value;\r\n },\r\n enumerable: true,\r\n configurable: true,\r\n});\r\n","import type { IViewportLike } from \"../../Maths/math.like\";\r\nimport type { Nullable } from \"../../types\";\r\nimport { AbstractEngine } from \"../abstractEngine\";\r\n\r\n/**\r\n * Defines the interface used by objects containing a viewport (like a camera)\r\n */\r\ninterface IViewportOwnerLike {\r\n /**\r\n * Gets or sets the viewport\r\n */\r\n viewport: IViewportLike;\r\n}\r\n\r\ndeclare module \"../../Engines/abstractEngine\" {\r\n export interface AbstractEngine {\r\n /**\r\n * Gets the HTML element used to attach event listeners\r\n * @returns a HTML element\r\n */\r\n getInputElement(): Nullable;\r\n\r\n /**\r\n * Gets the client rect of the HTML canvas attached with the current webGL context\r\n * @returns a client rectangle\r\n */\r\n getRenderingCanvasClientRect(): Nullable;\r\n\r\n /**\r\n * Gets the client rect of the HTML element used for events\r\n * @returns a client rectangle\r\n */\r\n getInputElementClientRect(): Nullable;\r\n\r\n /**\r\n * Gets current aspect ratio\r\n * @param viewportOwner defines the camera to use to get the aspect ratio\r\n * @param useScreen defines if screen size must be used (or the current render target if any)\r\n * @returns a number defining the aspect ratio\r\n */\r\n getAspectRatio(viewportOwner: IViewportOwnerLike, useScreen?: boolean): number;\r\n\r\n /**\r\n * Gets current screen aspect ratio\r\n * @returns a number defining the aspect ratio\r\n */\r\n getScreenAspectRatio(): number;\r\n\r\n /**\r\n * Toggle full screen mode\r\n * @param requestPointerLock defines if a pointer lock should be requested from the user\r\n */\r\n switchFullscreen(requestPointerLock: boolean): void;\r\n\r\n /**\r\n * Enters full screen mode\r\n * @param requestPointerLock defines if a pointer lock should be requested from the user\r\n */\r\n enterFullscreen(requestPointerLock: boolean): void;\r\n\r\n /**\r\n * Exits full screen mode\r\n */\r\n exitFullscreen(): void;\r\n\r\n /** @internal */\r\n _onPointerLockChange: () => void;\r\n\r\n /** @internal */\r\n _verifyPointerLock(): void;\r\n }\r\n}\r\n\r\nAbstractEngine.prototype.getInputElement = function (): Nullable {\r\n return this._renderingCanvas;\r\n};\r\n\r\nAbstractEngine.prototype.getRenderingCanvasClientRect = function (): Nullable {\r\n if (!this._renderingCanvas) {\r\n return null;\r\n }\r\n return this._renderingCanvas.getBoundingClientRect();\r\n};\r\n\r\nAbstractEngine.prototype.getInputElementClientRect = function (): Nullable {\r\n if (!this._renderingCanvas) {\r\n return null;\r\n }\r\n return this.getInputElement()!.getBoundingClientRect();\r\n};\r\n\r\nAbstractEngine.prototype.getAspectRatio = function (viewportOwner: IViewportOwnerLike, useScreen = false): number {\r\n const viewport = viewportOwner.viewport;\r\n return (this.getRenderWidth(useScreen) * viewport.width) / (this.getRenderHeight(useScreen) * viewport.height);\r\n};\r\n\r\nAbstractEngine.prototype.getScreenAspectRatio = function (): number {\r\n return this.getRenderWidth(true) / this.getRenderHeight(true);\r\n};\r\n\r\nAbstractEngine.prototype._verifyPointerLock = function (): void {\r\n this._onPointerLockChange?.();\r\n};\r\n","import { AbstractEngine } from \"../abstractEngine\";\r\nimport { Constants } from \"../constants\";\r\n\r\ndeclare module \"../abstractEngine\" {\r\n export interface AbstractEngine {\r\n /**\r\n * Sets the current alpha equation\r\n * @param equation defines the equation to use (one of the Engine.ALPHA_EQUATION_XXX)\r\n */\r\n setAlphaEquation(equation: number): void;\r\n }\r\n}\r\n\r\nAbstractEngine.prototype.setAlphaEquation = function (equation: number): void {\r\n if (this._alphaEquation === equation) {\r\n return;\r\n }\r\n\r\n switch (equation) {\r\n case Constants.ALPHA_EQUATION_ADD:\r\n this._alphaState.setAlphaEquationParameters(Constants.GL_ALPHA_EQUATION_ADD, Constants.GL_ALPHA_EQUATION_ADD);\r\n break;\r\n case Constants.ALPHA_EQUATION_SUBSTRACT:\r\n this._alphaState.setAlphaEquationParameters(Constants.GL_ALPHA_EQUATION_SUBTRACT, Constants.GL_ALPHA_EQUATION_SUBTRACT);\r\n break;\r\n case Constants.ALPHA_EQUATION_REVERSE_SUBTRACT:\r\n this._alphaState.setAlphaEquationParameters(Constants.GL_ALPHA_EQUATION_REVERSE_SUBTRACT, Constants.GL_ALPHA_EQUATION_REVERSE_SUBTRACT);\r\n break;\r\n case Constants.ALPHA_EQUATION_MAX:\r\n this._alphaState.setAlphaEquationParameters(Constants.GL_ALPHA_EQUATION_MAX, Constants.GL_ALPHA_EQUATION_MAX);\r\n break;\r\n case Constants.ALPHA_EQUATION_MIN:\r\n this._alphaState.setAlphaEquationParameters(Constants.GL_ALPHA_EQUATION_MIN, Constants.GL_ALPHA_EQUATION_MIN);\r\n break;\r\n case Constants.ALPHA_EQUATION_DARKEN:\r\n this._alphaState.setAlphaEquationParameters(Constants.GL_ALPHA_EQUATION_MIN, Constants.GL_ALPHA_EQUATION_ADD);\r\n break;\r\n }\r\n this._alphaEquation = equation;\r\n};\r\n","import type { Nullable } from \"../../types\";\r\nimport { AbstractEngine } from \"../abstractEngine\";\r\nimport { Constants } from \"../constants\";\r\n\r\nimport \"./abstractEngine.alpha\";\r\n\r\ndeclare module \"../../Engines/abstractEngine\" {\r\n export interface AbstractEngine {\r\n /** @internal */\r\n _cachedStencilBuffer: boolean;\r\n /** @internal */\r\n _cachedStencilFunction: number;\r\n /** @internal */\r\n _cachedStencilMask: number;\r\n /** @internal */\r\n _cachedStencilOperationPass: number;\r\n /** @internal */\r\n _cachedStencilOperationFail: number;\r\n /** @internal */\r\n _cachedStencilOperationDepthFail: number;\r\n /** @internal */\r\n _cachedStencilReference: number;\r\n\r\n /**\r\n * Gets the current depth function\r\n * @returns a number defining the depth function\r\n */\r\n getDepthFunction(): Nullable;\r\n\r\n /**\r\n * Sets the current depth function\r\n * @param depthFunc defines the function to use\r\n */\r\n setDepthFunction(depthFunc: number): void;\r\n\r\n /**\r\n * Sets the current depth function to GREATER\r\n */\r\n setDepthFunctionToGreater(): void;\r\n\r\n /**\r\n * Sets the current depth function to GEQUAL\r\n */\r\n setDepthFunctionToGreaterOrEqual(): void;\r\n\r\n /**\r\n * Sets the current depth function to LESS\r\n */\r\n setDepthFunctionToLess(): void;\r\n\r\n /**\r\n * Sets the current depth function to LEQUAL\r\n */\r\n setDepthFunctionToLessOrEqual(): void;\r\n\r\n /**\r\n * Gets a boolean indicating if depth writing is enabled\r\n * @returns the current depth writing state\r\n */\r\n getDepthWrite(): boolean;\r\n\r\n /**\r\n * Enable or disable depth writing\r\n * @param enable defines the state to set\r\n */\r\n setDepthWrite(enable: boolean): void;\r\n\r\n /**\r\n * Gets the current stencil operation when stencil passes\r\n * @returns a number defining stencil operation to use when stencil passes\r\n */\r\n getStencilOperationPass(): number;\r\n\r\n /**\r\n * Gets a boolean indicating if stencil buffer is enabled\r\n * @returns the current stencil buffer state\r\n */\r\n getStencilBuffer(): boolean;\r\n\r\n /**\r\n * Enable or disable the stencil buffer\r\n * @param enable defines if the stencil buffer must be enabled or disabled\r\n */\r\n setStencilBuffer(enable: boolean): void;\r\n\r\n /**\r\n * Gets the current stencil mask\r\n * @returns a number defining the new stencil mask to use\r\n */\r\n getStencilMask(): number;\r\n /**\r\n * Sets the current stencil mask\r\n * @param mask defines the new stencil mask to use\r\n */\r\n setStencilMask(mask: number): void;\r\n\r\n /**\r\n * Gets the current stencil function\r\n * @returns a number defining the stencil function to use\r\n */\r\n getStencilFunction(): number;\r\n\r\n /**\r\n * Gets the current stencil reference value\r\n * @returns a number defining the stencil reference value to use\r\n */\r\n getStencilFunctionReference(): number;\r\n\r\n /**\r\n * Gets the current stencil mask\r\n * @returns a number defining the stencil mask to use\r\n */\r\n getStencilFunctionMask(): number;\r\n\r\n /**\r\n * Sets the current stencil function\r\n * @param stencilFunc defines the new stencil function to use\r\n */\r\n setStencilFunction(stencilFunc: number): void;\r\n\r\n /**\r\n * Sets the current stencil reference\r\n * @param reference defines the new stencil reference to use\r\n */\r\n setStencilFunctionReference(reference: number): void;\r\n\r\n /**\r\n * Sets the current stencil mask\r\n * @param mask defines the new stencil mask to use\r\n */\r\n setStencilFunctionMask(mask: number): void;\r\n\r\n /**\r\n * Gets the current stencil operation when stencil fails\r\n * @returns a number defining stencil operation to use when stencil fails\r\n */\r\n getStencilOperationFail(): number;\r\n\r\n /**\r\n * Gets the current stencil operation when depth fails\r\n * @returns a number defining stencil operation to use when depth fails\r\n */\r\n getStencilOperationDepthFail(): number;\r\n\r\n /**\r\n * Sets the stencil operation to use when stencil fails\r\n * @param operation defines the stencil operation to use when stencil fails\r\n */\r\n setStencilOperationFail(operation: number): void;\r\n\r\n /**\r\n * Sets the stencil operation to use when depth fails\r\n * @param operation defines the stencil operation to use when depth fails\r\n */\r\n setStencilOperationDepthFail(operation: number): void;\r\n\r\n /**\r\n * Sets the stencil operation to use when stencil passes\r\n * @param operation defines the stencil operation to use when stencil passes\r\n */\r\n setStencilOperationPass(operation: number): void;\r\n\r\n /**\r\n * Caches the state of the stencil buffer\r\n */\r\n cacheStencilState(): void;\r\n\r\n /**\r\n * Restores the state of the stencil buffer\r\n */\r\n restoreStencilState(): void;\r\n\r\n /**\r\n * Sets alpha constants used by some alpha blending modes\r\n * @param r defines the red component\r\n * @param g defines the green component\r\n * @param b defines the blue component\r\n * @param a defines the alpha component\r\n */\r\n setAlphaConstants(r: number, g: number, b: number, a: number): void;\r\n\r\n /**\r\n * Gets the current alpha mode\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/materials/advanced/transparent_rendering\r\n * @returns the current alpha mode\r\n */\r\n getAlphaMode(): number;\r\n\r\n /**\r\n * Gets the current alpha equation.\r\n * @returns the current alpha equation\r\n */\r\n getAlphaEquation(): number;\r\n }\r\n}\r\n\r\nAbstractEngine.prototype.getInputElement = function (): Nullable {\r\n return this._renderingCanvas;\r\n};\r\n\r\nAbstractEngine.prototype.getDepthFunction = function (): Nullable {\r\n return this._depthCullingState.depthFunc;\r\n};\r\n\r\nAbstractEngine.prototype.setDepthFunction = function (depthFunc: number) {\r\n this._depthCullingState.depthFunc = depthFunc;\r\n};\r\n\r\nAbstractEngine.prototype.setDepthFunctionToGreater = function (): void {\r\n this.setDepthFunction(Constants.GREATER);\r\n};\r\n\r\nAbstractEngine.prototype.setDepthFunctionToGreaterOrEqual = function (): void {\r\n this.setDepthFunction(Constants.GEQUAL);\r\n};\r\n\r\nAbstractEngine.prototype.setDepthFunctionToLess = function (): void {\r\n this.setDepthFunction(Constants.LESS);\r\n};\r\nAbstractEngine.prototype.setDepthFunctionToLessOrEqual = function (): void {\r\n this.setDepthFunction(Constants.LEQUAL);\r\n};\r\n\r\nAbstractEngine.prototype.getDepthWrite = function (): boolean {\r\n return this._depthCullingState.depthMask;\r\n};\r\n\r\nAbstractEngine.prototype.setDepthWrite = function (enable: boolean): void {\r\n this._depthCullingState.depthMask = enable;\r\n};\r\n\r\nAbstractEngine.prototype.getStencilBuffer = function (): boolean {\r\n return this._stencilState.stencilTest;\r\n};\r\n\r\nAbstractEngine.prototype.setStencilBuffer = function (enable: boolean): void {\r\n this._stencilState.stencilTest = enable;\r\n};\r\n\r\nAbstractEngine.prototype.getStencilMask = function (): number {\r\n return this._stencilState.stencilMask;\r\n};\r\n\r\nAbstractEngine.prototype.setStencilMask = function (mask: number): void {\r\n this._stencilState.stencilMask = mask;\r\n};\r\n\r\nAbstractEngine.prototype.getStencilFunction = function (): number {\r\n return this._stencilState.stencilFunc;\r\n};\r\n\r\nAbstractEngine.prototype.getStencilFunctionReference = function (): number {\r\n return this._stencilState.stencilFuncRef;\r\n};\r\n\r\nAbstractEngine.prototype.getStencilFunctionMask = function (): number {\r\n return this._stencilState.stencilFuncMask;\r\n};\r\n\r\nAbstractEngine.prototype.setStencilFunction = function (stencilFunc: number) {\r\n this._stencilState.stencilFunc = stencilFunc;\r\n};\r\n\r\nAbstractEngine.prototype.setStencilFunctionReference = function (reference: number): void {\r\n this._stencilState.stencilFuncRef = reference;\r\n};\r\n\r\nAbstractEngine.prototype.setStencilFunctionMask = function (mask: number): void {\r\n this._stencilState.stencilFuncMask = mask;\r\n};\r\n\r\nAbstractEngine.prototype.getStencilOperationFail = function (): number {\r\n return this._stencilState.stencilOpStencilFail;\r\n};\r\n\r\nAbstractEngine.prototype.getStencilOperationDepthFail = function (): number {\r\n return this._stencilState.stencilOpDepthFail;\r\n};\r\n\r\nAbstractEngine.prototype.getStencilOperationPass = function (): number {\r\n return this._stencilState.stencilOpStencilDepthPass;\r\n};\r\n\r\nAbstractEngine.prototype.setStencilOperationFail = function (operation: number): void {\r\n this._stencilState.stencilOpStencilFail = operation;\r\n};\r\n\r\nAbstractEngine.prototype.setStencilOperationDepthFail = function (operation: number): void {\r\n this._stencilState.stencilOpDepthFail = operation;\r\n};\r\n\r\nAbstractEngine.prototype.setStencilOperationPass = function (operation: number): void {\r\n this._stencilState.stencilOpStencilDepthPass = operation;\r\n};\r\n\r\nAbstractEngine.prototype.cacheStencilState = function (): void {\r\n this._cachedStencilBuffer = this.getStencilBuffer();\r\n this._cachedStencilFunction = this.getStencilFunction();\r\n this._cachedStencilMask = this.getStencilMask();\r\n this._cachedStencilOperationPass = this.getStencilOperationPass();\r\n this._cachedStencilOperationFail = this.getStencilOperationFail();\r\n this._cachedStencilOperationDepthFail = this.getStencilOperationDepthFail();\r\n this._cachedStencilReference = this.getStencilFunctionReference();\r\n};\r\n\r\nAbstractEngine.prototype.restoreStencilState = function (): void {\r\n this.setStencilFunction(this._cachedStencilFunction);\r\n this.setStencilMask(this._cachedStencilMask);\r\n this.setStencilBuffer(this._cachedStencilBuffer);\r\n this.setStencilOperationPass(this._cachedStencilOperationPass);\r\n this.setStencilOperationFail(this._cachedStencilOperationFail);\r\n this.setStencilOperationDepthFail(this._cachedStencilOperationDepthFail);\r\n this.setStencilFunctionReference(this._cachedStencilReference);\r\n};\r\n\r\nAbstractEngine.prototype.setAlphaConstants = function (r: number, g: number, b: number, a: number): void {\r\n this._alphaState.setAlphaBlendConstants(r, g, b, a);\r\n};\r\n\r\nAbstractEngine.prototype.getAlphaMode = function (): number {\r\n return this._alphaMode;\r\n};\r\n\r\nAbstractEngine.prototype.getAlphaEquation = function (): number {\r\n return this._alphaEquation;\r\n};\r\n","import { AbstractEngine } from \"../abstractEngine\";\r\n\r\ndeclare module \"../../Engines/abstractEngine\" {\r\n export interface AbstractEngine {\r\n /**\r\n * Gets the names of the render passes that are currently created\r\n * @returns list of the render pass names\r\n */\r\n getRenderPassNames(): string[];\r\n\r\n /**\r\n * Gets the name of the current render pass\r\n * @returns name of the current render pass\r\n */\r\n getCurrentRenderPassName(): string;\r\n\r\n /**\r\n * Creates a render pass id\r\n * @param name Name of the render pass (for debug purpose only)\r\n * @returns the id of the new render pass\r\n */\r\n createRenderPassId(name?: string): number;\r\n\r\n /**\r\n * Releases a render pass id\r\n * @param id id of the render pass to release\r\n */\r\n releaseRenderPassId(id: number): void;\r\n }\r\n}\r\n\r\nAbstractEngine.prototype.getRenderPassNames = function (): string[] {\r\n return this._renderPassNames;\r\n};\r\n\r\nAbstractEngine.prototype.getCurrentRenderPassName = function (): string {\r\n return this._renderPassNames[this.currentRenderPassId];\r\n};\r\n\r\nAbstractEngine.prototype.createRenderPassId = function (name?: string): number {\r\n // Note: render pass id == 0 is always for the main render pass\r\n const id = ++AbstractEngine._RenderPassIdCounter;\r\n this._renderPassNames[id] = name ?? \"NONAME\";\r\n return id;\r\n};\r\n\r\nAbstractEngine.prototype.releaseRenderPassId = function (id: number): void {\r\n this._renderPassNames[id] = undefined as any;\r\n\r\n for (let s = 0; s < this.scenes.length; ++s) {\r\n const scene = this.scenes[s];\r\n for (let m = 0; m < scene.meshes.length; ++m) {\r\n const mesh = scene.meshes[m];\r\n if (mesh.subMeshes) {\r\n for (let b = 0; b < mesh.subMeshes.length; ++b) {\r\n const subMesh = mesh.subMeshes[b];\r\n subMesh._removeDrawWrapper(id);\r\n }\r\n }\r\n }\r\n }\r\n};\r\n","import { IsDocumentAvailable } from \"../Misc/domManagement\";\r\nimport type { Nullable } from \"../types\";\r\nimport { AbstractEngine } from \"./abstractEngine\";\r\nimport type { AbstractEngineOptions } from \"./abstractEngine\";\r\nimport { EngineStore } from \"./engineStore\";\r\n\r\n/** @internal */\r\nfunction _DisableTouchAction(canvas: Nullable): void {\r\n if (!canvas || !canvas.setAttribute) {\r\n return;\r\n }\r\n\r\n canvas.setAttribute(\"touch-action\", \"none\");\r\n canvas.style.touchAction = \"none\";\r\n (canvas.style as any).webkitTapHighlightColor = \"transparent\";\r\n}\r\n\r\n/** @internal */\r\nexport function _CommonInit(commonEngine: AbstractEngine, canvas: HTMLCanvasElement, creationOptions: AbstractEngineOptions) {\r\n commonEngine._onCanvasFocus = () => {\r\n commonEngine.onCanvasFocusObservable.notifyObservers(commonEngine);\r\n };\r\n\r\n commonEngine._onCanvasBlur = () => {\r\n commonEngine.onCanvasBlurObservable.notifyObservers(commonEngine);\r\n };\r\n\r\n commonEngine._onCanvasContextMenu = (evt: Event) => {\r\n if (commonEngine.disableContextMenu) {\r\n evt.preventDefault();\r\n }\r\n };\r\n\r\n canvas.addEventListener(\"focus\", commonEngine._onCanvasFocus);\r\n canvas.addEventListener(\"blur\", commonEngine._onCanvasBlur);\r\n canvas.addEventListener(\"contextmenu\", commonEngine._onCanvasContextMenu);\r\n\r\n commonEngine._onBlur = () => {\r\n if (commonEngine.disablePerformanceMonitorInBackground) {\r\n commonEngine.performanceMonitor.disable();\r\n }\r\n commonEngine._windowIsBackground = true;\r\n };\r\n\r\n commonEngine._onFocus = () => {\r\n if (commonEngine.disablePerformanceMonitorInBackground) {\r\n commonEngine.performanceMonitor.enable();\r\n }\r\n commonEngine._windowIsBackground = false;\r\n };\r\n\r\n commonEngine._onCanvasPointerOut = (ev) => {\r\n // Check that the element at the point of the pointer out isn't the canvas and if it isn't, notify observers\r\n // Note: This is a workaround for a bug with Safari\r\n if (document.elementFromPoint(ev.clientX, ev.clientY) !== canvas) {\r\n commonEngine.onCanvasPointerOutObservable.notifyObservers(ev);\r\n }\r\n };\r\n\r\n const hostWindow = commonEngine.getHostWindow(); // it calls IsWindowObjectExist()\r\n if (hostWindow && typeof hostWindow.addEventListener === \"function\") {\r\n hostWindow.addEventListener(\"blur\", commonEngine._onBlur);\r\n hostWindow.addEventListener(\"focus\", commonEngine._onFocus);\r\n }\r\n\r\n canvas.addEventListener(\"pointerout\", commonEngine._onCanvasPointerOut);\r\n\r\n if (!creationOptions.doNotHandleTouchAction) {\r\n _DisableTouchAction(canvas);\r\n }\r\n\r\n // Create Audio Engine if needed.\r\n if (!AbstractEngine.audioEngine && creationOptions.audioEngine && AbstractEngine.AudioEngineFactory) {\r\n AbstractEngine.audioEngine = AbstractEngine.AudioEngineFactory(commonEngine.getRenderingCanvas(), commonEngine.getAudioContext(), commonEngine.getAudioDestination());\r\n }\r\n if (IsDocumentAvailable()) {\r\n // Fullscreen\r\n commonEngine._onFullscreenChange = () => {\r\n commonEngine.isFullscreen = !!document.fullscreenElement;\r\n\r\n // Pointer lock\r\n if (commonEngine.isFullscreen && commonEngine._pointerLockRequested && canvas) {\r\n RequestPointerlock(canvas);\r\n }\r\n };\r\n\r\n document.addEventListener(\"fullscreenchange\", commonEngine._onFullscreenChange, false);\r\n document.addEventListener(\"webkitfullscreenchange\", commonEngine._onFullscreenChange, false);\r\n\r\n // Pointer lock\r\n commonEngine._onPointerLockChange = () => {\r\n commonEngine.isPointerLock = document.pointerLockElement === canvas;\r\n };\r\n\r\n document.addEventListener(\"pointerlockchange\", commonEngine._onPointerLockChange, false);\r\n document.addEventListener(\"webkitpointerlockchange\", commonEngine._onPointerLockChange, false);\r\n }\r\n\r\n commonEngine.enableOfflineSupport = AbstractEngine.OfflineProviderFactory !== undefined;\r\n\r\n commonEngine._deterministicLockstep = !!creationOptions.deterministicLockstep;\r\n commonEngine._lockstepMaxSteps = creationOptions.lockstepMaxSteps || 0;\r\n commonEngine._timeStep = creationOptions.timeStep || 1 / 60;\r\n}\r\n\r\n/** @internal */\r\nexport function _CommonDispose(commonEngine: AbstractEngine, canvas: Nullable) {\r\n // Release audio engine\r\n if (EngineStore.Instances.length === 1 && AbstractEngine.audioEngine) {\r\n AbstractEngine.audioEngine.dispose();\r\n AbstractEngine.audioEngine = null;\r\n }\r\n\r\n // Events\r\n const hostWindow = commonEngine.getHostWindow(); // it calls IsWindowObjectExist()\r\n if (hostWindow && typeof hostWindow.removeEventListener === \"function\") {\r\n hostWindow.removeEventListener(\"blur\", commonEngine._onBlur);\r\n hostWindow.removeEventListener(\"focus\", commonEngine._onFocus);\r\n }\r\n\r\n if (canvas) {\r\n canvas.removeEventListener(\"focus\", commonEngine._onCanvasFocus);\r\n canvas.removeEventListener(\"blur\", commonEngine._onCanvasBlur);\r\n canvas.removeEventListener(\"pointerout\", commonEngine._onCanvasPointerOut);\r\n canvas.removeEventListener(\"contextmenu\", commonEngine._onCanvasContextMenu);\r\n }\r\n\r\n if (IsDocumentAvailable()) {\r\n document.removeEventListener(\"fullscreenchange\", commonEngine._onFullscreenChange);\r\n document.removeEventListener(\"mozfullscreenchange\", commonEngine._onFullscreenChange);\r\n document.removeEventListener(\"webkitfullscreenchange\", commonEngine._onFullscreenChange);\r\n document.removeEventListener(\"msfullscreenchange\", commonEngine._onFullscreenChange);\r\n document.removeEventListener(\"pointerlockchange\", commonEngine._onPointerLockChange);\r\n document.removeEventListener(\"mspointerlockchange\", commonEngine._onPointerLockChange);\r\n document.removeEventListener(\"mozpointerlockchange\", commonEngine._onPointerLockChange);\r\n document.removeEventListener(\"webkitpointerlockchange\", commonEngine._onPointerLockChange);\r\n }\r\n}\r\n\r\n/**\r\n * Get Font size information\r\n * @param font font name\r\n * @returns an object containing ascent, height and descent\r\n */\r\nexport function GetFontOffset(font: string): { ascent: number; height: number; descent: number } {\r\n const text = document.createElement(\"span\");\r\n text.textContent = \"Hg\";\r\n text.style.font = font;\r\n\r\n const block = document.createElement(\"div\");\r\n block.style.display = \"inline-block\";\r\n block.style.width = \"1px\";\r\n block.style.height = \"0px\";\r\n block.style.verticalAlign = \"bottom\";\r\n\r\n const div = document.createElement(\"div\");\r\n div.style.whiteSpace = \"nowrap\";\r\n div.appendChild(text);\r\n div.appendChild(block);\r\n\r\n document.body.appendChild(div);\r\n\r\n let fontAscent = 0;\r\n let fontHeight = 0;\r\n try {\r\n fontHeight = block.getBoundingClientRect().top - text.getBoundingClientRect().top;\r\n block.style.verticalAlign = \"baseline\";\r\n fontAscent = block.getBoundingClientRect().top - text.getBoundingClientRect().top;\r\n } finally {\r\n document.body.removeChild(div);\r\n }\r\n return { ascent: fontAscent, height: fontHeight, descent: fontHeight - fontAscent };\r\n}\r\n\r\n/** @internal */\r\nexport function CreateImageBitmapFromSource(engine: AbstractEngine, imageSource: string, options?: ImageBitmapOptions): Promise {\r\n const promise = new Promise((resolve, reject) => {\r\n const image = new Image();\r\n image.onload = () => {\r\n image.decode().then(() => {\r\n engine.createImageBitmap(image, options).then((imageBitmap) => {\r\n resolve(imageBitmap);\r\n });\r\n });\r\n };\r\n image.onerror = () => {\r\n reject(`Error loading image ${image.src}`);\r\n };\r\n\r\n image.src = imageSource;\r\n });\r\n\r\n return promise;\r\n}\r\n\r\n/** @internal */\r\nexport function ResizeImageBitmap(engine: AbstractEngine, image: HTMLImageElement | ImageBitmap, bufferWidth: number, bufferHeight: number): Uint8Array {\r\n const canvas = engine.createCanvas(bufferWidth, bufferHeight);\r\n const context = canvas.getContext(\"2d\");\r\n\r\n if (!context) {\r\n throw new Error(\"Unable to get 2d context for resizeImageBitmap\");\r\n }\r\n\r\n context.drawImage(image, 0, 0);\r\n\r\n // Create VertexData from map data\r\n // Cast is due to wrong definition in lib.d.ts from ts 1.3 - https://github.com/Microsoft/TypeScript/issues/949\r\n const buffer = (context.getImageData(0, 0, bufferWidth, bufferHeight).data);\r\n return buffer;\r\n}\r\n\r\n/**\r\n * Ask the browser to promote the current element to fullscreen rendering mode\r\n * @param element defines the DOM element to promote\r\n */\r\nexport function RequestFullscreen(element: HTMLElement): void {\r\n const requestFunction = element.requestFullscreen || (element).webkitRequestFullscreen;\r\n if (!requestFunction) {\r\n return;\r\n }\r\n requestFunction.call(element);\r\n}\r\n\r\n/**\r\n * Asks the browser to exit fullscreen mode\r\n */\r\nexport function ExitFullscreen(): void {\r\n const anyDoc = document as any;\r\n\r\n if (document.exitFullscreen) {\r\n document.exitFullscreen();\r\n } else if (anyDoc.webkitCancelFullScreen) {\r\n anyDoc.webkitCancelFullScreen();\r\n }\r\n}\r\n\r\n/**\r\n * Ask the browser to promote the current element to pointerlock mode\r\n * @param element defines the DOM element to promote\r\n */\r\nexport function RequestPointerlock(element: HTMLElement): void {\r\n if (element.requestPointerLock) {\r\n // In some browsers, requestPointerLock returns a promise.\r\n // Handle possible rejections to avoid an unhandled top-level exception.\r\n const promise: unknown = element.requestPointerLock();\r\n if (promise instanceof Promise)\r\n promise\r\n .then(() => {\r\n element.focus();\r\n })\r\n .catch(() => {});\r\n else element.focus();\r\n }\r\n}\r\n\r\n/**\r\n * Asks the browser to exit pointerlock mode\r\n */\r\nexport function ExitPointerlock(): void {\r\n if (document.exitPointerLock) {\r\n document.exitPointerLock();\r\n }\r\n}\r\n","import type { Analyser } from \"./analyser\";\r\n\r\nimport type { Nullable } from \"../types\";\r\nimport { Observable } from \"../Misc/observable\";\r\nimport { Logger } from \"../Misc/logger\";\r\nimport { AbstractEngine } from \"../Engines/abstractEngine\";\r\nimport type { IAudioEngine } from \"./Interfaces/IAudioEngine\";\r\nimport { IsWindowObjectExist } from \"../Misc/domManagement\";\r\n\r\n// Sets the default audio engine to Babylon.js\r\nAbstractEngine.AudioEngineFactory = (\r\n hostElement: Nullable,\r\n audioContext: Nullable,\r\n audioDestination: Nullable\r\n) => {\r\n return new AudioEngine(hostElement, audioContext, audioDestination);\r\n};\r\n\r\n/**\r\n * This represents the default audio engine used in babylon.\r\n * It is responsible to play, synchronize and analyse sounds throughout the application.\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/audio/playingSoundsMusic\r\n */\r\nexport class AudioEngine implements IAudioEngine {\r\n private _audioContext: Nullable = null;\r\n private _audioContextInitialized = false;\r\n private _muteButton: Nullable = null;\r\n private _hostElement: Nullable;\r\n private _audioDestination: Nullable = null;\r\n\r\n /**\r\n * Gets whether the current host supports Web Audio and thus could create AudioContexts.\r\n */\r\n public canUseWebAudio: boolean = false;\r\n\r\n /**\r\n * The master gain node defines the global audio volume of your audio engine.\r\n */\r\n public masterGain: GainNode;\r\n\r\n /**\r\n * Defines if Babylon should emit a warning if WebAudio is not supported.\r\n * @ignoreNaming\r\n */\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n public WarnedWebAudioUnsupported: boolean = false;\r\n\r\n /**\r\n * Gets whether or not mp3 are supported by your browser.\r\n */\r\n public isMP3supported: boolean = false;\r\n\r\n /**\r\n * Gets whether or not ogg are supported by your browser.\r\n */\r\n public isOGGsupported: boolean = false;\r\n\r\n /**\r\n * Gets whether audio has been unlocked on the device.\r\n * Some Browsers have strong restrictions about Audio and won't autoplay unless\r\n * a user interaction has happened.\r\n */\r\n public unlocked: boolean = false;\r\n\r\n /**\r\n * Defines if the audio engine relies on a custom unlocked button.\r\n * In this case, the embedded button will not be displayed.\r\n */\r\n public useCustomUnlockedButton: boolean = false;\r\n\r\n /**\r\n * Event raised when audio has been unlocked on the browser.\r\n */\r\n public onAudioUnlockedObservable = new Observable();\r\n\r\n /**\r\n * Event raised when audio has been locked on the browser.\r\n */\r\n public onAudioLockedObservable = new Observable();\r\n\r\n /**\r\n * Gets the current AudioContext if available.\r\n */\r\n public get audioContext(): Nullable {\r\n if (!this._audioContextInitialized) {\r\n this._initializeAudioContext();\r\n }\r\n return this._audioContext;\r\n }\r\n\r\n private _connectedAnalyser: Nullable;\r\n\r\n /**\r\n * Instantiates a new audio engine.\r\n *\r\n * There should be only one per page as some browsers restrict the number\r\n * of audio contexts you can create.\r\n * @param hostElement defines the host element where to display the mute icon if necessary\r\n * @param audioContext defines the audio context to be used by the audio engine\r\n * @param audioDestination defines the audio destination node to be used by audio engine\r\n */\r\n constructor(\r\n hostElement: Nullable = null,\r\n audioContext: Nullable = null,\r\n audioDestination: Nullable = null\r\n ) {\r\n if (!IsWindowObjectExist()) {\r\n return;\r\n }\r\n if (typeof window.AudioContext !== \"undefined\") {\r\n this.canUseWebAudio = true;\r\n }\r\n\r\n const audioElem = document.createElement(\"audio\");\r\n this._hostElement = hostElement;\r\n this._audioContext = audioContext;\r\n this._audioDestination = audioDestination;\r\n\r\n try {\r\n if (\r\n audioElem &&\r\n !!audioElem.canPlayType &&\r\n (audioElem.canPlayType('audio/mpeg; codecs=\"mp3\"').replace(/^no$/, \"\") || audioElem.canPlayType(\"audio/mp3\").replace(/^no$/, \"\"))\r\n ) {\r\n this.isMP3supported = true;\r\n }\r\n } catch (e) {\r\n // protect error during capability check.\r\n }\r\n\r\n try {\r\n if (audioElem && !!audioElem.canPlayType && audioElem.canPlayType('audio/ogg; codecs=\"vorbis\"').replace(/^no$/, \"\")) {\r\n this.isOGGsupported = true;\r\n }\r\n } catch (e) {\r\n // protect error during capability check.\r\n }\r\n }\r\n\r\n /**\r\n * Flags the audio engine in Locked state.\r\n * This happens due to new browser policies preventing audio to autoplay.\r\n */\r\n public lock() {\r\n this._triggerSuspendedState();\r\n }\r\n\r\n /**\r\n * Unlocks the audio engine once a user action has been done on the dom.\r\n * This is helpful to resume play once browser policies have been satisfied.\r\n */\r\n public unlock() {\r\n if (this._audioContext?.state === \"running\") {\r\n this._hideMuteButton();\r\n\r\n if (!this.unlocked) {\r\n // Notify users that the audio stack is unlocked/unmuted\r\n this.unlocked = true;\r\n this.onAudioUnlockedObservable.notifyObservers(this);\r\n }\r\n\r\n return;\r\n }\r\n\r\n // On iOS, if the audio context resume request was sent from an event other than a `click` event, then\r\n // the resume promise will never resolve and the only way to get the audio context unstuck is to\r\n // suspend it and make another resume request.\r\n if (this._tryToRun) {\r\n this._audioContext?.suspend().then(() => {\r\n this._tryToRun = false;\r\n this._triggerRunningState();\r\n });\r\n } else {\r\n this._triggerRunningState();\r\n }\r\n }\r\n\r\n /** @internal */\r\n public _resumeAudioContextOnStateChange(): void {\r\n this._audioContext?.addEventListener(\r\n \"statechange\",\r\n () => {\r\n if (this.unlocked && this._audioContext?.state !== \"running\") {\r\n this._resumeAudioContext();\r\n }\r\n },\r\n {\r\n once: true,\r\n passive: true,\r\n signal: AbortSignal.timeout(3000),\r\n }\r\n );\r\n }\r\n\r\n private _resumeAudioContext(): Promise {\r\n if (this._audioContext?.resume) {\r\n return this._audioContext.resume();\r\n }\r\n return Promise.resolve();\r\n }\r\n\r\n private _initializeAudioContext() {\r\n try {\r\n if (this.canUseWebAudio) {\r\n if (!this._audioContext) {\r\n this._audioContext = new AudioContext();\r\n }\r\n // create a global volume gain node\r\n this.masterGain = this._audioContext.createGain();\r\n this.masterGain.gain.value = 1;\r\n if (!this._audioDestination) {\r\n this._audioDestination = this._audioContext.destination;\r\n }\r\n this.masterGain.connect(this._audioDestination);\r\n this._audioContextInitialized = true;\r\n if (this._audioContext.state === \"running\") {\r\n // Do not wait for the promise to unlock.\r\n this._triggerRunningState();\r\n }\r\n }\r\n } catch (e) {\r\n this.canUseWebAudio = false;\r\n Logger.Error(\"Web Audio: \" + e.message);\r\n }\r\n }\r\n\r\n private _tryToRun = false;\r\n private _triggerRunningState() {\r\n if (this._tryToRun) {\r\n return;\r\n }\r\n this._tryToRun = true;\r\n\r\n this._resumeAudioContext()\r\n .then(() => {\r\n this._tryToRun = false;\r\n if (this._muteButton) {\r\n this._hideMuteButton();\r\n }\r\n // Notify users that the audio stack is unlocked/unmuted\r\n this.unlocked = true;\r\n this.onAudioUnlockedObservable.notifyObservers(this);\r\n })\r\n .catch(() => {\r\n this._tryToRun = false;\r\n this.unlocked = false;\r\n });\r\n }\r\n\r\n private _triggerSuspendedState() {\r\n this.unlocked = false;\r\n this.onAudioLockedObservable.notifyObservers(this);\r\n this._displayMuteButton();\r\n }\r\n\r\n private _displayMuteButton() {\r\n if (this.useCustomUnlockedButton || this._muteButton) {\r\n return;\r\n }\r\n\r\n this._muteButton = document.createElement(\"BUTTON\");\r\n this._muteButton.className = \"babylonUnmuteIcon\";\r\n this._muteButton.id = \"babylonUnmuteIconBtn\";\r\n this._muteButton.title = \"Unmute\";\r\n const imageUrl = !window.SVGSVGElement\r\n ? \"https://cdn.babylonjs.com/Assets/audio.png\"\r\n : \"data:image/svg+xml;charset=UTF-8,%3Csvg%20version%3D%221.1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2239%22%20height%3D%2232%22%20viewBox%3D%220%200%2039%2032%22%3E%3Cpath%20fill%3D%22white%22%20d%3D%22M9.625%2018.938l-0.031%200.016h-4.953q-0.016%200-0.031-0.016v-12.453q0-0.016%200.031-0.016h4.953q0.031%200%200.031%200.016v12.453zM12.125%207.688l8.719-8.703v27.453l-8.719-8.719-0.016-0.047v-9.938zM23.359%207.875l1.406-1.406%204.219%204.203%204.203-4.203%201.422%201.406-4.219%204.219%204.219%204.203-1.484%201.359-4.141-4.156-4.219%204.219-1.406-1.422%204.219-4.203z%22%3E%3C%2Fpath%3E%3C%2Fsvg%3E\";\r\n\r\n const css =\r\n \".babylonUnmuteIcon { position: absolute; left: 20px; top: 20px; height: 40px; width: 60px; background-color: rgba(51,51,51,0.7); background-image: url(\" +\r\n imageUrl +\r\n \"); background-size: 80%; background-repeat:no-repeat; background-position: center; background-position-y: 4px; border: none; outline: none; transition: transform 0.125s ease-out; cursor: pointer; z-index: 9999; } .babylonUnmuteIcon:hover { transform: scale(1.05) } .babylonUnmuteIcon:active { background-color: rgba(51,51,51,1) }\";\r\n\r\n const style = document.createElement(\"style\");\r\n style.appendChild(document.createTextNode(css));\r\n document.getElementsByTagName(\"head\")[0].appendChild(style);\r\n\r\n document.body.appendChild(this._muteButton);\r\n\r\n this._moveButtonToTopLeft();\r\n\r\n this._muteButton.addEventListener(\r\n \"touchend\",\r\n () => {\r\n this._triggerRunningState();\r\n },\r\n true\r\n );\r\n this._muteButton.addEventListener(\r\n \"click\",\r\n () => {\r\n this.unlock();\r\n },\r\n true\r\n );\r\n\r\n window.addEventListener(\"resize\", this._onResize);\r\n }\r\n\r\n private _moveButtonToTopLeft() {\r\n if (this._hostElement && this._muteButton) {\r\n this._muteButton.style.top = this._hostElement.offsetTop + 20 + \"px\";\r\n this._muteButton.style.left = this._hostElement.offsetLeft + 20 + \"px\";\r\n }\r\n }\r\n\r\n private _onResize = () => {\r\n this._moveButtonToTopLeft();\r\n };\r\n\r\n private _hideMuteButton() {\r\n if (this._muteButton) {\r\n document.body.removeChild(this._muteButton);\r\n this._muteButton = null;\r\n }\r\n }\r\n\r\n /**\r\n * Destroy and release the resources associated with the audio context.\r\n */\r\n public dispose(): void {\r\n if (this.canUseWebAudio && this._audioContextInitialized) {\r\n if (this._connectedAnalyser && this._audioContext) {\r\n this._connectedAnalyser.stopDebugCanvas();\r\n this._connectedAnalyser.dispose();\r\n this.masterGain.disconnect();\r\n this.masterGain.connect(this._audioContext.destination);\r\n this._connectedAnalyser = null;\r\n }\r\n this.masterGain.gain.value = 1;\r\n }\r\n this.WarnedWebAudioUnsupported = false;\r\n this._hideMuteButton();\r\n window.removeEventListener(\"resize\", this._onResize);\r\n\r\n this.onAudioUnlockedObservable.clear();\r\n this.onAudioLockedObservable.clear();\r\n }\r\n\r\n /**\r\n * Gets the global volume sets on the master gain.\r\n * @returns the global volume if set or -1 otherwise\r\n */\r\n public getGlobalVolume(): number {\r\n if (this.canUseWebAudio && this._audioContextInitialized) {\r\n return this.masterGain.gain.value;\r\n } else {\r\n return -1;\r\n }\r\n }\r\n\r\n /**\r\n * Sets the global volume of your experience (sets on the master gain).\r\n * @param newVolume Defines the new global volume of the application\r\n */\r\n public setGlobalVolume(newVolume: number): void {\r\n if (this.canUseWebAudio && this._audioContextInitialized) {\r\n this.masterGain.gain.value = newVolume;\r\n }\r\n }\r\n\r\n /**\r\n * Connect the audio engine to an audio analyser allowing some amazing\r\n * synchronization between the sounds/music and your visualization (VuMeter for instance).\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/audio/playingSoundsMusic#using-the-analyser\r\n * @param analyser The analyser to connect to the engine\r\n */\r\n public connectToAnalyser(analyser: Analyser): void {\r\n if (this._connectedAnalyser) {\r\n this._connectedAnalyser.stopDebugCanvas();\r\n }\r\n if (this.canUseWebAudio && this._audioContextInitialized && this._audioContext) {\r\n this._connectedAnalyser = analyser;\r\n this.masterGain.disconnect();\r\n this._connectedAnalyser.connectAudioNodes(this.masterGain, this._audioContext.destination);\r\n }\r\n }\r\n}\r\n","import type { Nullable } from \"../types\";\r\nimport type { Scene } from \"../scene\";\r\nimport { InternalTexture, InternalTextureSource } from \"../Materials/Textures/internalTexture\";\r\nimport type { IOfflineProvider } from \"../Offline/IOfflineProvider\";\r\nimport type { ILoadingScreen } from \"../Loading/loadingScreen\";\r\nimport { EngineStore } from \"./engineStore\";\r\nimport type { WebGLPipelineContext } from \"./WebGL/webGLPipelineContext\";\r\nimport type { IPipelineContext } from \"./IPipelineContext\";\r\nimport type { ICustomAnimationFrameRequester } from \"../Misc/customAnimationFrameRequester\";\r\nimport type { EngineOptions } from \"./thinEngine\";\r\nimport { ThinEngine } from \"./thinEngine\";\r\nimport { Constants } from \"./constants\";\r\nimport type { IViewportLike, IColor4Like } from \"../Maths/math.like\";\r\nimport { PerformanceMonitor } from \"../Misc/performanceMonitor\";\r\nimport type { DataBuffer } from \"../Buffers/dataBuffer\";\r\nimport { WebGLDataBuffer } from \"../Meshes/WebGL/webGLDataBuffer\";\r\nimport { Logger } from \"../Misc/logger\";\r\nimport type { RenderTargetWrapper } from \"./renderTargetWrapper\";\r\nimport { WebGLHardwareTexture } from \"./WebGL/webGLHardwareTexture\";\r\n\r\nimport \"./Extensions/engine.alpha\";\r\nimport \"./Extensions/engine.rawTexture\";\r\nimport \"./Extensions/engine.readTexture\";\r\nimport \"./Extensions/engine.dynamicBuffer\";\r\nimport \"./Extensions/engine.cubeTexture\";\r\nimport \"./Extensions/engine.renderTarget\";\r\nimport \"./Extensions/engine.renderTargetTexture\";\r\nimport \"./Extensions/engine.renderTargetCube\";\r\nimport \"./Extensions/engine.prefilteredCubeTexture\";\r\nimport \"./Extensions/engine.uniformBuffer\";\r\nimport \"./AbstractEngine/abstractEngine.loadingScreen\";\r\nimport \"./AbstractEngine/abstractEngine.dom\";\r\nimport \"./AbstractEngine/abstractEngine.states\";\r\nimport \"./AbstractEngine/abstractEngine.renderPass\";\r\nimport \"./AbstractEngine/abstractEngine.texture\";\r\n\r\nimport type { PostProcess } from \"../PostProcesses/postProcess\";\r\nimport { AbstractEngine } from \"./abstractEngine\";\r\nimport {\r\n CreateImageBitmapFromSource,\r\n ExitFullscreen,\r\n ExitPointerlock,\r\n GetFontOffset,\r\n RequestFullscreen,\r\n RequestPointerlock,\r\n ResizeImageBitmap,\r\n _CommonDispose,\r\n _CommonInit,\r\n} from \"./engine.common\";\r\nimport { PerfCounter } from \"../Misc/perfCounter\";\r\nimport \"../Audio/audioEngine\";\r\nimport { _retryWithInterval } from \"core/Misc/timingTools\";\r\n\r\n/**\r\n * The engine class is responsible for interfacing with all lower-level APIs such as WebGL and Audio\r\n */\r\nexport class Engine extends ThinEngine {\r\n // Const statics\r\n\r\n /** Defines that alpha blending is disabled */\r\n public static readonly ALPHA_DISABLE = Constants.ALPHA_DISABLE;\r\n /** Defines that alpha blending to SRC ALPHA * SRC + DEST */\r\n public static readonly ALPHA_ADD = Constants.ALPHA_ADD;\r\n /** Defines that alpha blending to SRC ALPHA * SRC + (1 - SRC ALPHA) * DEST */\r\n public static readonly ALPHA_COMBINE = Constants.ALPHA_COMBINE;\r\n /** Defines that alpha blending to DEST - SRC * DEST */\r\n public static readonly ALPHA_SUBTRACT = Constants.ALPHA_SUBTRACT;\r\n /** Defines that alpha blending to SRC * DEST */\r\n public static readonly ALPHA_MULTIPLY = Constants.ALPHA_MULTIPLY;\r\n /** Defines that alpha blending to SRC ALPHA * SRC + (1 - SRC) * DEST */\r\n public static readonly ALPHA_MAXIMIZED = Constants.ALPHA_MAXIMIZED;\r\n /** Defines that alpha blending to SRC + DEST */\r\n public static readonly ALPHA_ONEONE = Constants.ALPHA_ONEONE;\r\n /** Defines that alpha blending to SRC + (1 - SRC ALPHA) * DEST */\r\n public static readonly ALPHA_PREMULTIPLIED = Constants.ALPHA_PREMULTIPLIED;\r\n /**\r\n * Defines that alpha blending to SRC + (1 - SRC ALPHA) * DEST\r\n * Alpha will be set to (1 - SRC ALPHA) * DEST ALPHA\r\n */\r\n public static readonly ALPHA_PREMULTIPLIED_PORTERDUFF = Constants.ALPHA_PREMULTIPLIED_PORTERDUFF;\r\n /** Defines that alpha blending to CST * SRC + (1 - CST) * DEST */\r\n public static readonly ALPHA_INTERPOLATE = Constants.ALPHA_INTERPOLATE;\r\n /**\r\n * Defines that alpha blending to SRC + (1 - SRC) * DEST\r\n * Alpha will be set to SRC ALPHA + (1 - SRC ALPHA) * DEST ALPHA\r\n */\r\n public static readonly ALPHA_SCREENMODE = Constants.ALPHA_SCREENMODE;\r\n\r\n /** Defines that the resource is not delayed*/\r\n public static readonly DELAYLOADSTATE_NONE = Constants.DELAYLOADSTATE_NONE;\r\n /** Defines that the resource was successfully delay loaded */\r\n public static readonly DELAYLOADSTATE_LOADED = Constants.DELAYLOADSTATE_LOADED;\r\n /** Defines that the resource is currently delay loading */\r\n public static readonly DELAYLOADSTATE_LOADING = Constants.DELAYLOADSTATE_LOADING;\r\n /** Defines that the resource is delayed and has not started loading */\r\n public static readonly DELAYLOADSTATE_NOTLOADED = Constants.DELAYLOADSTATE_NOTLOADED;\r\n\r\n // Depht or Stencil test Constants.\r\n /** Passed to depthFunction or stencilFunction to specify depth or stencil tests will never pass. i.e. Nothing will be drawn */\r\n public static readonly NEVER = Constants.NEVER;\r\n /** Passed to depthFunction or stencilFunction to specify depth or stencil tests will always pass. i.e. Pixels will be drawn in the order they are drawn */\r\n public static readonly ALWAYS = Constants.ALWAYS;\r\n /** Passed to depthFunction or stencilFunction to specify depth or stencil tests will pass if the new depth value is less than the stored value */\r\n public static readonly LESS = Constants.LESS;\r\n /** Passed to depthFunction or stencilFunction to specify depth or stencil tests will pass if the new depth value is equals to the stored value */\r\n public static readonly EQUAL = Constants.EQUAL;\r\n /** Passed to depthFunction or stencilFunction to specify depth or stencil tests will pass if the new depth value is less than or equal to the stored value */\r\n public static readonly LEQUAL = Constants.LEQUAL;\r\n /** Passed to depthFunction or stencilFunction to specify depth or stencil tests will pass if the new depth value is greater than the stored value */\r\n public static readonly GREATER = Constants.GREATER;\r\n /** Passed to depthFunction or stencilFunction to specify depth or stencil tests will pass if the new depth value is greater than or equal to the stored value */\r\n public static readonly GEQUAL = Constants.GEQUAL;\r\n /** Passed to depthFunction or stencilFunction to specify depth or stencil tests will pass if the new depth value is not equal to the stored value */\r\n public static readonly NOTEQUAL = Constants.NOTEQUAL;\r\n\r\n // Stencil Actions Constants.\r\n /** Passed to stencilOperation to specify that stencil value must be kept */\r\n public static readonly KEEP = Constants.KEEP;\r\n /** Passed to stencilOperation to specify that stencil value must be replaced */\r\n public static readonly REPLACE = Constants.REPLACE;\r\n /** Passed to stencilOperation to specify that stencil value must be incremented */\r\n public static readonly INCR = Constants.INCR;\r\n /** Passed to stencilOperation to specify that stencil value must be decremented */\r\n public static readonly DECR = Constants.DECR;\r\n /** Passed to stencilOperation to specify that stencil value must be inverted */\r\n public static readonly INVERT = Constants.INVERT;\r\n /** Passed to stencilOperation to specify that stencil value must be incremented with wrapping */\r\n public static readonly INCR_WRAP = Constants.INCR_WRAP;\r\n /** Passed to stencilOperation to specify that stencil value must be decremented with wrapping */\r\n public static readonly DECR_WRAP = Constants.DECR_WRAP;\r\n\r\n /** Texture is not repeating outside of 0..1 UVs */\r\n public static readonly TEXTURE_CLAMP_ADDRESSMODE = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n /** Texture is repeating outside of 0..1 UVs */\r\n public static readonly TEXTURE_WRAP_ADDRESSMODE = Constants.TEXTURE_WRAP_ADDRESSMODE;\r\n /** Texture is repeating and mirrored */\r\n public static readonly TEXTURE_MIRROR_ADDRESSMODE = Constants.TEXTURE_MIRROR_ADDRESSMODE;\r\n\r\n /** ALPHA */\r\n public static readonly TEXTUREFORMAT_ALPHA = Constants.TEXTUREFORMAT_ALPHA;\r\n /** LUMINANCE */\r\n public static readonly TEXTUREFORMAT_LUMINANCE = Constants.TEXTUREFORMAT_LUMINANCE;\r\n /** LUMINANCE_ALPHA */\r\n public static readonly TEXTUREFORMAT_LUMINANCE_ALPHA = Constants.TEXTUREFORMAT_LUMINANCE_ALPHA;\r\n /** RGB */\r\n public static readonly TEXTUREFORMAT_RGB = Constants.TEXTUREFORMAT_RGB;\r\n /** RGBA */\r\n public static readonly TEXTUREFORMAT_RGBA = Constants.TEXTUREFORMAT_RGBA;\r\n /** RED */\r\n public static readonly TEXTUREFORMAT_RED = Constants.TEXTUREFORMAT_RED;\r\n /** RED (2nd reference) */\r\n public static readonly TEXTUREFORMAT_R = Constants.TEXTUREFORMAT_R;\r\n /** RED unsigned short normed to [0, 1] **/\r\n public static readonly TEXTUREFORMAT_R16_UNORM = Constants.TEXTUREFORMAT_R16_UNORM;\r\n /** RG unsigned short normed to [0, 1] **/\r\n public static readonly TEXTUREFORMAT_RG16_UNORM = Constants.TEXTUREFORMAT_RG16_UNORM;\r\n /** RGB unsigned short normed to [0, 1] **/\r\n public static readonly TEXTUREFORMAT_RGB16_UNORM = Constants.TEXTUREFORMAT_RGB16_UNORM;\r\n /** RGBA unsigned short normed to [0, 1] **/\r\n public static readonly TEXTUREFORMAT_RGBA16_UNORM = Constants.TEXTUREFORMAT_RGBA16_UNORM;\r\n /** RED signed short normed to [-1, 1] **/\r\n public static readonly TEXTUREFORMAT_R16_SNORM = Constants.TEXTUREFORMAT_R16_SNORM;\r\n /** RG signed short normed to [-1, 1] **/\r\n public static readonly TEXTUREFORMAT_RG16_SNORM = Constants.TEXTUREFORMAT_RG16_SNORM;\r\n /** RGB signed short normed to [-1, 1] **/\r\n public static readonly TEXTUREFORMAT_RGB16_SNORM = Constants.TEXTUREFORMAT_RGB16_SNORM;\r\n /** RGBA signed short normed to [-1, 1] **/\r\n public static readonly TEXTUREFORMAT_RGBA16_SNORM = Constants.TEXTUREFORMAT_RGBA16_SNORM;\r\n /** RG */\r\n public static readonly TEXTUREFORMAT_RG = Constants.TEXTUREFORMAT_RG;\r\n /** RED_INTEGER */\r\n public static readonly TEXTUREFORMAT_RED_INTEGER = Constants.TEXTUREFORMAT_RED_INTEGER;\r\n /** RED_INTEGER (2nd reference) */\r\n public static readonly TEXTUREFORMAT_R_INTEGER = Constants.TEXTUREFORMAT_R_INTEGER;\r\n /** RG_INTEGER */\r\n public static readonly TEXTUREFORMAT_RG_INTEGER = Constants.TEXTUREFORMAT_RG_INTEGER;\r\n /** RGB_INTEGER */\r\n public static readonly TEXTUREFORMAT_RGB_INTEGER = Constants.TEXTUREFORMAT_RGB_INTEGER;\r\n /** RGBA_INTEGER */\r\n public static readonly TEXTUREFORMAT_RGBA_INTEGER = Constants.TEXTUREFORMAT_RGBA_INTEGER;\r\n\r\n /** UNSIGNED_BYTE */\r\n public static readonly TEXTURETYPE_UNSIGNED_BYTE = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n /** @deprecated use more explicit TEXTURETYPE_UNSIGNED_BYTE instead. Use TEXTURETYPE_UNSIGNED_INTEGER for 32bits values.*/\r\n public static readonly TEXTURETYPE_UNSIGNED_INT = Constants.TEXTURETYPE_UNSIGNED_INT;\r\n /** FLOAT */\r\n public static readonly TEXTURETYPE_FLOAT = Constants.TEXTURETYPE_FLOAT;\r\n /** HALF_FLOAT */\r\n public static readonly TEXTURETYPE_HALF_FLOAT = Constants.TEXTURETYPE_HALF_FLOAT;\r\n /** BYTE */\r\n public static readonly TEXTURETYPE_BYTE = Constants.TEXTURETYPE_BYTE;\r\n /** SHORT */\r\n public static readonly TEXTURETYPE_SHORT = Constants.TEXTURETYPE_SHORT;\r\n /** UNSIGNED_SHORT */\r\n public static readonly TEXTURETYPE_UNSIGNED_SHORT = Constants.TEXTURETYPE_UNSIGNED_SHORT;\r\n /** INT */\r\n public static readonly TEXTURETYPE_INT = Constants.TEXTURETYPE_INT;\r\n /** UNSIGNED_INT */\r\n public static readonly TEXTURETYPE_UNSIGNED_INTEGER = Constants.TEXTURETYPE_UNSIGNED_INTEGER;\r\n /** UNSIGNED_SHORT_4_4_4_4 */\r\n public static readonly TEXTURETYPE_UNSIGNED_SHORT_4_4_4_4 = Constants.TEXTURETYPE_UNSIGNED_SHORT_4_4_4_4;\r\n /** UNSIGNED_SHORT_5_5_5_1 */\r\n public static readonly TEXTURETYPE_UNSIGNED_SHORT_5_5_5_1 = Constants.TEXTURETYPE_UNSIGNED_SHORT_5_5_5_1;\r\n /** UNSIGNED_SHORT_5_6_5 */\r\n public static readonly TEXTURETYPE_UNSIGNED_SHORT_5_6_5 = Constants.TEXTURETYPE_UNSIGNED_SHORT_5_6_5;\r\n /** UNSIGNED_INT_2_10_10_10_REV */\r\n public static readonly TEXTURETYPE_UNSIGNED_INT_2_10_10_10_REV = Constants.TEXTURETYPE_UNSIGNED_INT_2_10_10_10_REV;\r\n /** UNSIGNED_INT_24_8 */\r\n public static readonly TEXTURETYPE_UNSIGNED_INT_24_8 = Constants.TEXTURETYPE_UNSIGNED_INT_24_8;\r\n /** UNSIGNED_INT_10F_11F_11F_REV */\r\n public static readonly TEXTURETYPE_UNSIGNED_INT_10F_11F_11F_REV = Constants.TEXTURETYPE_UNSIGNED_INT_10F_11F_11F_REV;\r\n /** UNSIGNED_INT_5_9_9_9_REV */\r\n public static readonly TEXTURETYPE_UNSIGNED_INT_5_9_9_9_REV = Constants.TEXTURETYPE_UNSIGNED_INT_5_9_9_9_REV;\r\n /** FLOAT_32_UNSIGNED_INT_24_8_REV */\r\n public static readonly TEXTURETYPE_FLOAT_32_UNSIGNED_INT_24_8_REV = Constants.TEXTURETYPE_FLOAT_32_UNSIGNED_INT_24_8_REV;\r\n\r\n /** nearest is mag = nearest and min = nearest and mip = none */\r\n public static readonly TEXTURE_NEAREST_SAMPLINGMODE = Constants.TEXTURE_NEAREST_SAMPLINGMODE;\r\n /** Bilinear is mag = linear and min = linear and mip = nearest */\r\n public static readonly TEXTURE_BILINEAR_SAMPLINGMODE = Constants.TEXTURE_BILINEAR_SAMPLINGMODE;\r\n /** Trilinear is mag = linear and min = linear and mip = linear */\r\n public static readonly TEXTURE_TRILINEAR_SAMPLINGMODE = Constants.TEXTURE_TRILINEAR_SAMPLINGMODE;\r\n /** nearest is mag = nearest and min = nearest and mip = linear */\r\n public static readonly TEXTURE_NEAREST_NEAREST_MIPLINEAR = Constants.TEXTURE_NEAREST_NEAREST_MIPLINEAR;\r\n /** Bilinear is mag = linear and min = linear and mip = nearest */\r\n public static readonly TEXTURE_LINEAR_LINEAR_MIPNEAREST = Constants.TEXTURE_LINEAR_LINEAR_MIPNEAREST;\r\n /** Trilinear is mag = linear and min = linear and mip = linear */\r\n public static readonly TEXTURE_LINEAR_LINEAR_MIPLINEAR = Constants.TEXTURE_LINEAR_LINEAR_MIPLINEAR;\r\n /** mag = nearest and min = nearest and mip = nearest */\r\n public static readonly TEXTURE_NEAREST_NEAREST_MIPNEAREST = Constants.TEXTURE_NEAREST_NEAREST_MIPNEAREST;\r\n /** mag = nearest and min = linear and mip = nearest */\r\n public static readonly TEXTURE_NEAREST_LINEAR_MIPNEAREST = Constants.TEXTURE_NEAREST_LINEAR_MIPNEAREST;\r\n /** mag = nearest and min = linear and mip = linear */\r\n public static readonly TEXTURE_NEAREST_LINEAR_MIPLINEAR = Constants.TEXTURE_NEAREST_LINEAR_MIPLINEAR;\r\n /** mag = nearest and min = linear and mip = none */\r\n public static readonly TEXTURE_NEAREST_LINEAR = Constants.TEXTURE_NEAREST_LINEAR;\r\n /** mag = nearest and min = nearest and mip = none */\r\n public static readonly TEXTURE_NEAREST_NEAREST = Constants.TEXTURE_NEAREST_NEAREST;\r\n /** mag = linear and min = nearest and mip = nearest */\r\n public static readonly TEXTURE_LINEAR_NEAREST_MIPNEAREST = Constants.TEXTURE_LINEAR_NEAREST_MIPNEAREST;\r\n /** mag = linear and min = nearest and mip = linear */\r\n public static readonly TEXTURE_LINEAR_NEAREST_MIPLINEAR = Constants.TEXTURE_LINEAR_NEAREST_MIPLINEAR;\r\n /** mag = linear and min = linear and mip = none */\r\n public static readonly TEXTURE_LINEAR_LINEAR = Constants.TEXTURE_LINEAR_LINEAR;\r\n /** mag = linear and min = nearest and mip = none */\r\n public static readonly TEXTURE_LINEAR_NEAREST = Constants.TEXTURE_LINEAR_NEAREST;\r\n\r\n /** Explicit coordinates mode */\r\n public static readonly TEXTURE_EXPLICIT_MODE = Constants.TEXTURE_EXPLICIT_MODE;\r\n /** Spherical coordinates mode */\r\n public static readonly TEXTURE_SPHERICAL_MODE = Constants.TEXTURE_SPHERICAL_MODE;\r\n /** Planar coordinates mode */\r\n public static readonly TEXTURE_PLANAR_MODE = Constants.TEXTURE_PLANAR_MODE;\r\n /** Cubic coordinates mode */\r\n public static readonly TEXTURE_CUBIC_MODE = Constants.TEXTURE_CUBIC_MODE;\r\n /** Projection coordinates mode */\r\n public static readonly TEXTURE_PROJECTION_MODE = Constants.TEXTURE_PROJECTION_MODE;\r\n /** Skybox coordinates mode */\r\n public static readonly TEXTURE_SKYBOX_MODE = Constants.TEXTURE_SKYBOX_MODE;\r\n /** Inverse Cubic coordinates mode */\r\n public static readonly TEXTURE_INVCUBIC_MODE = Constants.TEXTURE_INVCUBIC_MODE;\r\n /** Equirectangular coordinates mode */\r\n public static readonly TEXTURE_EQUIRECTANGULAR_MODE = Constants.TEXTURE_EQUIRECTANGULAR_MODE;\r\n /** Equirectangular Fixed coordinates mode */\r\n public static readonly TEXTURE_FIXED_EQUIRECTANGULAR_MODE = Constants.TEXTURE_FIXED_EQUIRECTANGULAR_MODE;\r\n /** Equirectangular Fixed Mirrored coordinates mode */\r\n public static readonly TEXTURE_FIXED_EQUIRECTANGULAR_MIRRORED_MODE = Constants.TEXTURE_FIXED_EQUIRECTANGULAR_MIRRORED_MODE;\r\n\r\n // Texture rescaling mode\r\n /** Defines that texture rescaling will use a floor to find the closer power of 2 size */\r\n public static readonly SCALEMODE_FLOOR = Constants.SCALEMODE_FLOOR;\r\n /** Defines that texture rescaling will look for the nearest power of 2 size */\r\n public static readonly SCALEMODE_NEAREST = Constants.SCALEMODE_NEAREST;\r\n /** Defines that texture rescaling will use a ceil to find the closer power of 2 size */\r\n public static readonly SCALEMODE_CEILING = Constants.SCALEMODE_CEILING;\r\n\r\n /**\r\n * Returns the current npm package of the sdk\r\n */\r\n // Not mixed with Version for tooling purpose.\r\n public static override get NpmPackage(): string {\r\n return AbstractEngine.NpmPackage;\r\n }\r\n\r\n /**\r\n * Returns the current version of the framework\r\n */\r\n public static override get Version(): string {\r\n return AbstractEngine.Version;\r\n }\r\n\r\n /** Gets the list of created engines */\r\n public static get Instances(): AbstractEngine[] {\r\n return EngineStore.Instances;\r\n }\r\n\r\n /**\r\n * Gets the latest created engine\r\n */\r\n public static get LastCreatedEngine(): Nullable {\r\n return EngineStore.LastCreatedEngine;\r\n }\r\n\r\n /**\r\n * Gets the latest created scene\r\n */\r\n public static get LastCreatedScene(): Nullable {\r\n return EngineStore.LastCreatedScene;\r\n }\r\n\r\n /** @internal */\r\n\r\n // eslint-disable-next-line jsdoc/require-returns-check\r\n /**\r\n * Method called to create the default loading screen.\r\n * This can be overridden in your own app.\r\n * @param canvas The rendering canvas element\r\n * @returns The loading screen\r\n */\r\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n public static override DefaultLoadingScreenFactory(canvas: HTMLCanvasElement): ILoadingScreen {\r\n return AbstractEngine.DefaultLoadingScreenFactory(canvas);\r\n }\r\n\r\n // Members\r\n\r\n /**\r\n * If set, will be used to request the next animation frame for the render loop\r\n */\r\n public customAnimationFrameRequester: Nullable = null;\r\n\r\n private _rescalePostProcess: Nullable;\r\n\r\n protected override get _supportsHardwareTextureRescaling() {\r\n return !!Engine._RescalePostProcessFactory;\r\n }\r\n\r\n private _measureFps(): void {\r\n this._performanceMonitor.sampleFrame();\r\n this._fps = this._performanceMonitor.averageFPS;\r\n this._deltaTime = this._performanceMonitor.instantaneousFrameTime || 0;\r\n }\r\n\r\n private _performanceMonitor = new PerformanceMonitor();\r\n /**\r\n * Gets the performance monitor attached to this engine\r\n * @see https://doc.babylonjs.com/features/featuresDeepDive/scene/optimize_your_scene#engineinstrumentation\r\n */\r\n public override get performanceMonitor(): PerformanceMonitor {\r\n return this._performanceMonitor;\r\n }\r\n\r\n // Events\r\n\r\n /**\r\n * Creates a new engine\r\n * @param canvasOrContext defines the canvas or WebGL context to use for rendering. If you provide a WebGL context, Babylon.js will not hook events on the canvas (like pointers, keyboards, etc...) so no event observables will be available. This is mostly used when Babylon.js is used as a plugin on a system which already used the WebGL context\r\n * @param antialias defines enable antialiasing (default: false)\r\n * @param options defines further options to be sent to the getContext() function\r\n * @param adaptToDeviceRatio defines whether to adapt to the device's viewport characteristics (default: false)\r\n */\r\n constructor(\r\n canvasOrContext: Nullable,\r\n antialias?: boolean,\r\n options?: EngineOptions,\r\n adaptToDeviceRatio: boolean = false\r\n ) {\r\n super(canvasOrContext, antialias, options, adaptToDeviceRatio);\r\n\r\n this._drawCalls = new PerfCounter();\r\n\r\n if (!canvasOrContext) {\r\n return;\r\n }\r\n\r\n this._features.supportRenderPasses = true;\r\n\r\n options = this._creationOptions;\r\n }\r\n\r\n protected override _initGLContext(): void {\r\n super._initGLContext();\r\n\r\n this._rescalePostProcess = null;\r\n }\r\n\r\n /**\r\n * Shared initialization across engines types.\r\n * @param canvas The canvas associated with this instance of the engine.\r\n */\r\n protected override _sharedInit(canvas: HTMLCanvasElement) {\r\n super._sharedInit(canvas);\r\n\r\n _CommonInit(this, canvas, this._creationOptions);\r\n }\r\n\r\n /**\r\n * Resize an image and returns the image data as an uint8array\r\n * @param image image to resize\r\n * @param bufferWidth destination buffer width\r\n * @param bufferHeight destination buffer height\r\n * @returns an uint8array containing RGBA values of bufferWidth * bufferHeight size\r\n */\r\n public override resizeImageBitmap(image: HTMLImageElement | ImageBitmap, bufferWidth: number, bufferHeight: number): Uint8Array {\r\n return ResizeImageBitmap(this, image, bufferWidth, bufferHeight);\r\n }\r\n\r\n /**\r\n * Engine abstraction for loading and creating an image bitmap from a given source string.\r\n * @param imageSource source to load the image from.\r\n * @param options An object that sets options for the image's extraction.\r\n * @returns ImageBitmap\r\n */\r\n public override _createImageBitmapFromSource(imageSource: string, options?: ImageBitmapOptions): Promise {\r\n return CreateImageBitmapFromSource(this, imageSource, options);\r\n }\r\n\r\n /**\r\n * Toggle full screen mode\r\n * @param requestPointerLock defines if a pointer lock should be requested from the user\r\n */\r\n public override switchFullscreen(requestPointerLock: boolean): void {\r\n if (this.isFullscreen) {\r\n this.exitFullscreen();\r\n } else {\r\n this.enterFullscreen(requestPointerLock);\r\n }\r\n }\r\n\r\n /**\r\n * Enters full screen mode\r\n * @param requestPointerLock defines if a pointer lock should be requested from the user\r\n */\r\n public override enterFullscreen(requestPointerLock: boolean): void {\r\n if (!this.isFullscreen) {\r\n this._pointerLockRequested = requestPointerLock;\r\n if (this._renderingCanvas) {\r\n RequestFullscreen(this._renderingCanvas);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Exits full screen mode\r\n */\r\n public override exitFullscreen(): void {\r\n if (this.isFullscreen) {\r\n ExitFullscreen();\r\n }\r\n }\r\n\r\n /** States */\r\n\r\n /**\r\n * Sets a boolean indicating if the dithering state is enabled or disabled\r\n * @param value defines the dithering state\r\n */\r\n public setDitheringState(value: boolean): void {\r\n if (value) {\r\n this._gl.enable(this._gl.DITHER);\r\n } else {\r\n this._gl.disable(this._gl.DITHER);\r\n }\r\n }\r\n\r\n /**\r\n * Sets a boolean indicating if the rasterizer state is enabled or disabled\r\n * @param value defines the rasterizer state\r\n */\r\n public setRasterizerState(value: boolean): void {\r\n if (value) {\r\n this._gl.disable(this._gl.RASTERIZER_DISCARD);\r\n } else {\r\n this._gl.enable(this._gl.RASTERIZER_DISCARD);\r\n }\r\n }\r\n\r\n /**\r\n * Directly set the WebGL Viewport\r\n * @param x defines the x coordinate of the viewport (in screen space)\r\n * @param y defines the y coordinate of the viewport (in screen space)\r\n * @param width defines the width of the viewport (in screen space)\r\n * @param height defines the height of the viewport (in screen space)\r\n * @returns the current viewport Object (if any) that is being replaced by this call. You can restore this viewport later on to go back to the original state\r\n */\r\n public setDirectViewport(x: number, y: number, width: number, height: number): Nullable {\r\n const currentViewport = this._cachedViewport;\r\n this._cachedViewport = null;\r\n\r\n this._viewport(x, y, width, height);\r\n\r\n return currentViewport;\r\n }\r\n\r\n /**\r\n * Executes a scissor clear (ie. a clear on a specific portion of the screen)\r\n * @param x defines the x-coordinate of the bottom left corner of the clear rectangle\r\n * @param y defines the y-coordinate of the corner of the clear rectangle\r\n * @param width defines the width of the clear rectangle\r\n * @param height defines the height of the clear rectangle\r\n * @param clearColor defines the clear color\r\n */\r\n public scissorClear(x: number, y: number, width: number, height: number, clearColor: IColor4Like): void {\r\n this.enableScissor(x, y, width, height);\r\n this.clear(clearColor, true, true, true);\r\n this.disableScissor();\r\n }\r\n\r\n /**\r\n * Enable scissor test on a specific rectangle (ie. render will only be executed on a specific portion of the screen)\r\n * @param x defines the x-coordinate of the bottom left corner of the clear rectangle\r\n * @param y defines the y-coordinate of the corner of the clear rectangle\r\n * @param width defines the width of the clear rectangle\r\n * @param height defines the height of the clear rectangle\r\n */\r\n public enableScissor(x: number, y: number, width: number, height: number): void {\r\n const gl = this._gl;\r\n\r\n // Change state\r\n gl.enable(gl.SCISSOR_TEST);\r\n gl.scissor(x, y, width, height);\r\n }\r\n\r\n /**\r\n * Disable previously set scissor test rectangle\r\n */\r\n public disableScissor() {\r\n const gl = this._gl;\r\n\r\n gl.disable(gl.SCISSOR_TEST);\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n public _loadFileAsync(url: string, offlineProvider?: IOfflineProvider, useArrayBuffer?: false): Promise;\r\n public _loadFileAsync(url: string, offlineProvider?: IOfflineProvider, useArrayBuffer?: true): Promise;\r\n\r\n /**\r\n * @internal\r\n */\r\n public _loadFileAsync(url: string, offlineProvider?: IOfflineProvider, useArrayBuffer?: boolean): Promise {\r\n return new Promise((resolve, reject) => {\r\n this._loadFile(\r\n url,\r\n (data) => {\r\n resolve(data);\r\n },\r\n undefined,\r\n offlineProvider,\r\n useArrayBuffer,\r\n (request, exception) => {\r\n reject(exception);\r\n }\r\n );\r\n });\r\n }\r\n\r\n /**\r\n * Gets the source code of the vertex shader associated with a specific webGL program\r\n * @param program defines the program to use\r\n * @returns a string containing the source code of the vertex shader associated with the program\r\n */\r\n public getVertexShaderSource(program: WebGLProgram): Nullable {\r\n const shaders = this._gl.getAttachedShaders(program);\r\n\r\n if (!shaders) {\r\n return null;\r\n }\r\n\r\n return this._gl.getShaderSource(shaders[0]);\r\n }\r\n\r\n /**\r\n * Gets the source code of the fragment shader associated with a specific webGL program\r\n * @param program defines the program to use\r\n * @returns a string containing the source code of the fragment shader associated with the program\r\n */\r\n public getFragmentShaderSource(program: WebGLProgram): Nullable {\r\n const shaders = this._gl.getAttachedShaders(program);\r\n\r\n if (!shaders) {\r\n return null;\r\n }\r\n\r\n return this._gl.getShaderSource(shaders[1]);\r\n }\r\n\r\n /**\r\n * sets the object from which width and height will be taken from when getting render width and height\r\n * Will fallback to the gl object\r\n * @param dimensions the framebuffer width and height that will be used.\r\n */\r\n public override set framebufferDimensionsObject(dimensions: Nullable<{ framebufferWidth: number; framebufferHeight: number }>) {\r\n this._framebufferDimensionsObject = dimensions;\r\n if (this._framebufferDimensionsObject) {\r\n this.onResizeObservable.notifyObservers(this);\r\n }\r\n }\r\n\r\n protected override _rebuildBuffers(): void {\r\n // Index / Vertex\r\n for (const scene of this.scenes) {\r\n scene.resetCachedMaterial();\r\n scene._rebuildGeometries();\r\n }\r\n\r\n for (const scene of this._virtualScenes) {\r\n scene.resetCachedMaterial();\r\n scene._rebuildGeometries();\r\n }\r\n\r\n super._rebuildBuffers();\r\n }\r\n\r\n /**\r\n * Get Font size information\r\n * @param font font name\r\n * @returns an object containing ascent, height and descent\r\n */\r\n public override getFontOffset(font: string): { ascent: number; height: number; descent: number } {\r\n return GetFontOffset(font);\r\n }\r\n\r\n protected override _cancelFrame() {\r\n if (this.customAnimationFrameRequester) {\r\n if (this._frameHandler !== 0) {\r\n this._frameHandler = 0;\r\n const { cancelAnimationFrame } = this.customAnimationFrameRequester;\r\n if (cancelAnimationFrame) {\r\n cancelAnimationFrame(this.customAnimationFrameRequester.requestID);\r\n }\r\n }\r\n } else {\r\n super._cancelFrame();\r\n }\r\n }\r\n\r\n public override _renderLoop(timestamp?: number): void {\r\n this._processFrame(timestamp);\r\n\r\n // The first condition prevents queuing another frame if we no longer have active render loops (e.g., if\r\n // `stopRenderLoop` is called mid frame). The second condition prevents queuing another frame if one has\r\n // already been queued (e.g., if `stopRenderLoop` and `runRenderLoop` is called mid frame).\r\n if (this._activeRenderLoops.length > 0 && this._frameHandler === 0) {\r\n if (this.customAnimationFrameRequester) {\r\n this.customAnimationFrameRequester.requestID = this._queueNewFrame(\r\n this.customAnimationFrameRequester.renderFunction || this._boundRenderFunction,\r\n this.customAnimationFrameRequester\r\n );\r\n this._frameHandler = this.customAnimationFrameRequester.requestID;\r\n } else {\r\n this._frameHandler = this._queueNewFrame(this._boundRenderFunction, this.getHostWindow());\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Enters Pointerlock mode\r\n */\r\n public enterPointerlock(): void {\r\n if (this._renderingCanvas) {\r\n RequestPointerlock(this._renderingCanvas);\r\n }\r\n }\r\n\r\n /**\r\n * Exits Pointerlock mode\r\n */\r\n public exitPointerlock(): void {\r\n ExitPointerlock();\r\n }\r\n\r\n /**\r\n * Begin a new frame\r\n */\r\n public override beginFrame(): void {\r\n this._measureFps();\r\n super.beginFrame();\r\n }\r\n\r\n public override _deletePipelineContext(pipelineContext: IPipelineContext): void {\r\n const webGLPipelineContext = pipelineContext as WebGLPipelineContext;\r\n if (webGLPipelineContext && webGLPipelineContext.program) {\r\n if (webGLPipelineContext.transformFeedback) {\r\n this.deleteTransformFeedback(webGLPipelineContext.transformFeedback);\r\n webGLPipelineContext.transformFeedback = null;\r\n }\r\n }\r\n super._deletePipelineContext(pipelineContext);\r\n }\r\n\r\n public override createShaderProgram(\r\n pipelineContext: IPipelineContext,\r\n vertexCode: string,\r\n fragmentCode: string,\r\n defines: Nullable,\r\n context?: WebGLRenderingContext,\r\n transformFeedbackVaryings: Nullable = null\r\n ): WebGLProgram {\r\n context = context || this._gl;\r\n\r\n this.onBeforeShaderCompilationObservable.notifyObservers(this);\r\n\r\n const program = super.createShaderProgram(pipelineContext, vertexCode, fragmentCode, defines, context, transformFeedbackVaryings);\r\n this.onAfterShaderCompilationObservable.notifyObservers(this);\r\n\r\n return program;\r\n }\r\n\r\n protected override _createShaderProgram(\r\n pipelineContext: WebGLPipelineContext,\r\n vertexShader: WebGLShader,\r\n fragmentShader: WebGLShader,\r\n context: WebGLRenderingContext,\r\n transformFeedbackVaryings: Nullable = null\r\n ): WebGLProgram {\r\n const shaderProgram = context.createProgram();\r\n pipelineContext.program = shaderProgram;\r\n\r\n if (!shaderProgram) {\r\n throw new Error(\"Unable to create program\");\r\n }\r\n\r\n context.attachShader(shaderProgram, vertexShader);\r\n context.attachShader(shaderProgram, fragmentShader);\r\n\r\n if (this.webGLVersion > 1 && transformFeedbackVaryings) {\r\n const transformFeedback = this.createTransformFeedback();\r\n\r\n this.bindTransformFeedback(transformFeedback);\r\n this.setTranformFeedbackVaryings(shaderProgram, transformFeedbackVaryings);\r\n pipelineContext.transformFeedback = transformFeedback;\r\n }\r\n\r\n context.linkProgram(shaderProgram);\r\n\r\n if (this.webGLVersion > 1 && transformFeedbackVaryings) {\r\n this.bindTransformFeedback(null);\r\n }\r\n\r\n pipelineContext.context = context;\r\n pipelineContext.vertexShader = vertexShader;\r\n pipelineContext.fragmentShader = fragmentShader;\r\n\r\n if (!pipelineContext.isParallelCompiled) {\r\n this._finalizePipelineContext(pipelineContext);\r\n }\r\n\r\n return shaderProgram;\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n public override _releaseTexture(texture: InternalTexture): void {\r\n super._releaseTexture(texture);\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n public override _releaseRenderTargetWrapper(rtWrapper: RenderTargetWrapper): void {\r\n super._releaseRenderTargetWrapper(rtWrapper);\r\n\r\n // Set output texture of post process to null if the framebuffer has been released/disposed\r\n this.scenes.forEach((scene) => {\r\n scene.postProcesses.forEach((postProcess) => {\r\n if (postProcess._outputTexture === rtWrapper) {\r\n postProcess._outputTexture = null;\r\n }\r\n });\r\n scene.cameras.forEach((camera) => {\r\n camera._postProcesses.forEach((postProcess) => {\r\n if (postProcess) {\r\n if (postProcess._outputTexture === rtWrapper) {\r\n postProcess._outputTexture = null;\r\n }\r\n }\r\n });\r\n });\r\n });\r\n }\r\n\r\n /**\r\n * @internal\r\n * Rescales a texture\r\n * @param source input texture\r\n * @param destination destination texture\r\n * @param scene scene to use to render the resize\r\n * @param internalFormat format to use when resizing\r\n * @param onComplete callback to be called when resize has completed\r\n */\r\n public override _rescaleTexture(source: InternalTexture, destination: InternalTexture, scene: Nullable, internalFormat: number, onComplete: () => void): void {\r\n this._gl.texParameteri(this._gl.TEXTURE_2D, this._gl.TEXTURE_MAG_FILTER, this._gl.LINEAR);\r\n this._gl.texParameteri(this._gl.TEXTURE_2D, this._gl.TEXTURE_MIN_FILTER, this._gl.LINEAR);\r\n this._gl.texParameteri(this._gl.TEXTURE_2D, this._gl.TEXTURE_WRAP_S, this._gl.CLAMP_TO_EDGE);\r\n this._gl.texParameteri(this._gl.TEXTURE_2D, this._gl.TEXTURE_WRAP_T, this._gl.CLAMP_TO_EDGE);\r\n\r\n const rtt = this.createRenderTargetTexture(\r\n {\r\n width: destination.width,\r\n height: destination.height,\r\n },\r\n {\r\n generateMipMaps: false,\r\n type: Constants.TEXTURETYPE_UNSIGNED_INT,\r\n samplingMode: Constants.TEXTURE_BILINEAR_SAMPLINGMODE,\r\n generateDepthBuffer: false,\r\n generateStencilBuffer: false,\r\n }\r\n );\r\n\r\n if (!this._rescalePostProcess && Engine._RescalePostProcessFactory) {\r\n this._rescalePostProcess = Engine._RescalePostProcessFactory(this);\r\n }\r\n\r\n if (this._rescalePostProcess) {\r\n this._rescalePostProcess.externalTextureSamplerBinding = true;\r\n const onCompiled = () => {\r\n this._rescalePostProcess!.onApply = function (effect) {\r\n effect._bindTexture(\"textureSampler\", source);\r\n };\r\n\r\n let hostingScene: Scene = scene;\r\n\r\n if (!hostingScene) {\r\n hostingScene = this.scenes[this.scenes.length - 1];\r\n }\r\n hostingScene.postProcessManager.directRender([this._rescalePostProcess!], rtt, true);\r\n\r\n this._bindTextureDirectly(this._gl.TEXTURE_2D, destination, true);\r\n this._gl.copyTexImage2D(this._gl.TEXTURE_2D, 0, internalFormat, 0, 0, destination.width, destination.height, 0);\r\n\r\n this.unBindFramebuffer(rtt);\r\n rtt.dispose();\r\n\r\n if (onComplete) {\r\n onComplete();\r\n }\r\n };\r\n const effect = this._rescalePostProcess.getEffect();\r\n if (effect) {\r\n effect.executeWhenCompiled(onCompiled);\r\n } else {\r\n this._rescalePostProcess.onEffectCreatedObservable.addOnce((effect) => {\r\n effect.executeWhenCompiled(onCompiled);\r\n });\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Wraps an external web gl texture in a Babylon texture.\r\n * @param texture defines the external texture\r\n * @param hasMipMaps defines whether the external texture has mip maps (default: false)\r\n * @param samplingMode defines the sampling mode for the external texture (default: Constants.TEXTURE_TRILINEAR_SAMPLINGMODE)\r\n * @param width defines the width for the external texture (default: 0)\r\n * @param height defines the height for the external texture (default: 0)\r\n * @returns the babylon internal texture\r\n */\r\n public wrapWebGLTexture(\r\n texture: WebGLTexture,\r\n hasMipMaps: boolean = false,\r\n samplingMode: number = Constants.TEXTURE_TRILINEAR_SAMPLINGMODE,\r\n width: number = 0,\r\n height: number = 0\r\n ): InternalTexture {\r\n const hardwareTexture = new WebGLHardwareTexture(texture, this._gl);\r\n const internalTexture = new InternalTexture(this, InternalTextureSource.Unknown, true);\r\n internalTexture._hardwareTexture = hardwareTexture;\r\n internalTexture.baseWidth = width;\r\n internalTexture.baseHeight = height;\r\n internalTexture.width = width;\r\n internalTexture.height = height;\r\n internalTexture.isReady = true;\r\n internalTexture.useMipMaps = hasMipMaps;\r\n this.updateTextureSamplingMode(samplingMode, internalTexture);\r\n return internalTexture;\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n public _uploadImageToTexture(texture: InternalTexture, image: HTMLImageElement | ImageBitmap, faceIndex: number = 0, lod: number = 0) {\r\n const gl = this._gl;\r\n\r\n const textureType = this._getWebGLTextureType(texture.type);\r\n const format = this._getInternalFormat(texture.format);\r\n const internalFormat = this._getRGBABufferInternalSizedFormat(texture.type, format);\r\n\r\n const bindTarget = texture.isCube ? gl.TEXTURE_CUBE_MAP : gl.TEXTURE_2D;\r\n\r\n this._bindTextureDirectly(bindTarget, texture, true);\r\n this._unpackFlipY(texture.invertY);\r\n\r\n let target: GLenum = gl.TEXTURE_2D;\r\n if (texture.isCube) {\r\n target = gl.TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex;\r\n }\r\n\r\n gl.texImage2D(target, lod, internalFormat, format, textureType, image);\r\n this._bindTextureDirectly(bindTarget, null, true);\r\n }\r\n\r\n /**\r\n * Updates a depth texture Comparison Mode and Function.\r\n * If the comparison Function is equal to 0, the mode will be set to none.\r\n * Otherwise, this only works in webgl 2 and requires a shadow sampler in the shader.\r\n * @param texture The texture to set the comparison function for\r\n * @param comparisonFunction The comparison function to set, 0 if no comparison required\r\n */\r\n public updateTextureComparisonFunction(texture: InternalTexture, comparisonFunction: number): void {\r\n if (this.webGLVersion === 1) {\r\n Logger.Error(\"WebGL 1 does not support texture comparison.\");\r\n return;\r\n }\r\n\r\n const gl = this._gl;\r\n\r\n if (texture.isCube) {\r\n this._bindTextureDirectly(this._gl.TEXTURE_CUBE_MAP, texture, true);\r\n\r\n if (comparisonFunction === 0) {\r\n gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_COMPARE_FUNC, Constants.LEQUAL);\r\n gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_COMPARE_MODE, gl.NONE);\r\n } else {\r\n gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_COMPARE_FUNC, comparisonFunction);\r\n gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_COMPARE_MODE, gl.COMPARE_REF_TO_TEXTURE);\r\n }\r\n\r\n this._bindTextureDirectly(this._gl.TEXTURE_CUBE_MAP, null);\r\n } else {\r\n this._bindTextureDirectly(this._gl.TEXTURE_2D, texture, true);\r\n\r\n if (comparisonFunction === 0) {\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_COMPARE_FUNC, Constants.LEQUAL);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_COMPARE_MODE, gl.NONE);\r\n } else {\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_COMPARE_FUNC, comparisonFunction);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_COMPARE_MODE, gl.COMPARE_REF_TO_TEXTURE);\r\n }\r\n\r\n this._bindTextureDirectly(this._gl.TEXTURE_2D, null);\r\n }\r\n\r\n texture._comparisonFunction = comparisonFunction;\r\n }\r\n\r\n /**\r\n * Creates a webGL buffer to use with instantiation\r\n * @param capacity defines the size of the buffer\r\n * @returns the webGL buffer\r\n */\r\n public createInstancesBuffer(capacity: number): DataBuffer {\r\n const buffer = this._gl.createBuffer();\r\n\r\n if (!buffer) {\r\n throw new Error(\"Unable to create instance buffer\");\r\n }\r\n\r\n const result = new WebGLDataBuffer(buffer);\r\n result.capacity = capacity;\r\n\r\n this.bindArrayBuffer(result);\r\n this._gl.bufferData(this._gl.ARRAY_BUFFER, capacity, this._gl.DYNAMIC_DRAW);\r\n\r\n result.references = 1;\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Delete a webGL buffer used with instantiation\r\n * @param buffer defines the webGL buffer to delete\r\n */\r\n public deleteInstancesBuffer(buffer: WebGLBuffer): void {\r\n this._gl.deleteBuffer(buffer);\r\n }\r\n\r\n private _clientWaitAsync(sync: WebGLSync, flags = 0, intervalms = 10): Promise {\r\n const gl = (this._gl as any);\r\n return new Promise((resolve, reject) => {\r\n _retryWithInterval(\r\n () => {\r\n const res = gl.clientWaitSync(sync, flags, 0);\r\n if (res == gl.WAIT_FAILED) {\r\n throw new Error(\"clientWaitSync failed\");\r\n }\r\n if (res == gl.TIMEOUT_EXPIRED) {\r\n return false;\r\n }\r\n return true;\r\n },\r\n resolve,\r\n reject,\r\n intervalms\r\n );\r\n });\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n public _readPixelsAsync(x: number, y: number, w: number, h: number, format: number, type: number, outputBuffer: ArrayBufferView): Nullable> {\r\n if (this._webGLVersion < 2) {\r\n throw new Error(\"_readPixelsAsync only work on WebGL2+\");\r\n }\r\n\r\n const gl = (this._gl as any);\r\n const buf = gl.createBuffer();\r\n gl.bindBuffer(gl.PIXEL_PACK_BUFFER, buf);\r\n gl.bufferData(gl.PIXEL_PACK_BUFFER, outputBuffer.byteLength, gl.STREAM_READ);\r\n gl.readPixels(x, y, w, h, format, type, 0);\r\n gl.bindBuffer(gl.PIXEL_PACK_BUFFER, null);\r\n\r\n const sync = gl.fenceSync(gl.SYNC_GPU_COMMANDS_COMPLETE, 0);\r\n if (!sync) {\r\n return null;\r\n }\r\n\r\n gl.flush();\r\n\r\n return this._clientWaitAsync(sync, 0, 10).then(() => {\r\n gl.deleteSync(sync);\r\n\r\n gl.bindBuffer(gl.PIXEL_PACK_BUFFER, buf);\r\n gl.getBufferSubData(gl.PIXEL_PACK_BUFFER, 0, outputBuffer);\r\n gl.bindBuffer(gl.PIXEL_PACK_BUFFER, null);\r\n gl.deleteBuffer(buf);\r\n\r\n return outputBuffer;\r\n });\r\n }\r\n\r\n public override dispose(): void {\r\n this.hideLoadingUI();\r\n\r\n // Rescale PP\r\n if (this._rescalePostProcess) {\r\n this._rescalePostProcess.dispose();\r\n }\r\n\r\n _CommonDispose(this, this._renderingCanvas);\r\n\r\n super.dispose();\r\n }\r\n}\r\n","// eslint-disable-next-line import/no-internal-modules\r\nimport type { Nullable, EffectWrapperCreationOptions, AbstractEngine } from \"core/index\";\r\nimport { EffectWrapper } from \"core/Materials/effectRenderer\";\r\nimport { Engine } from \"../Engines/engine\";\r\n\r\n/**\r\n * PassPostProcess which produces an output the same as it's input\r\n */\r\nexport class ThinPassPostProcess extends EffectWrapper {\r\n /**\r\n * The fragment shader url\r\n */\r\n public static readonly FragmentUrl = \"pass\";\r\n\r\n protected override _gatherImports(useWebGPU: boolean, list: Promise[]) {\r\n if (useWebGPU) {\r\n this._webGPUReady = true;\r\n list.push(Promise.all([import(\"../ShadersWGSL/pass.fragment\")]));\r\n } else {\r\n list.push(Promise.all([import(\"../Shaders/pass.fragment\")]));\r\n }\r\n\r\n super._gatherImports(useWebGPU, list);\r\n }\r\n\r\n /**\r\n * Constructs a new pass post process\r\n * @param name Name of the effect\r\n * @param engine Engine to use to render the effect. If not provided, the last created engine will be used\r\n * @param options Options to configure the effect\r\n */\r\n constructor(name: string, engine: Nullable = null, options?: EffectWrapperCreationOptions) {\r\n super({\r\n ...options,\r\n name,\r\n engine: engine || Engine.LastCreatedEngine!,\r\n useShaderStore: true,\r\n useAsPostProcess: true,\r\n fragmentShader: ThinPassPostProcess.FragmentUrl,\r\n });\r\n }\r\n}\r\n\r\n/**\r\n * PassCubePostProcess which produces an output the same as it's input (which must be a cube texture)\r\n */\r\nexport class ThinPassCubePostProcess extends EffectWrapper {\r\n /**\r\n * The fragment shader url\r\n */\r\n public static readonly FragmentUrl = \"passCube\";\r\n\r\n protected override _gatherImports(useWebGPU: boolean, list: Promise[]) {\r\n if (useWebGPU) {\r\n this._webGPUReady = true;\r\n list.push(Promise.all([import(\"../ShadersWGSL/passCube.fragment\")]));\r\n } else {\r\n list.push(Promise.all([import(\"../Shaders/passCube.fragment\")]));\r\n }\r\n\r\n super._gatherImports(useWebGPU, list);\r\n }\r\n\r\n /**\r\n * Creates the PassCubePostProcess\r\n * @param name Name of the effect\r\n * @param engine Engine to use to render the effect. If not provided, the last created engine will be used\r\n * @param options Options to configure the effect\r\n */\r\n constructor(name: string, engine: Nullable = null, options?: EffectWrapperCreationOptions) {\r\n super({\r\n ...options,\r\n name,\r\n engine: engine || Engine.LastCreatedEngine!,\r\n useShaderStore: true,\r\n useAsPostProcess: true,\r\n fragmentShader: ThinPassCubePostProcess.FragmentUrl,\r\n defines: \"#define POSITIVEX\",\r\n });\r\n }\r\n\r\n private _face = 0;\r\n\r\n /**\r\n * Gets or sets the cube face to display.\r\n * * 0 is +X\r\n * * 1 is -X\r\n * * 2 is +Y\r\n * * 3 is -Y\r\n * * 4 is +Z\r\n * * 5 is -Z\r\n */\r\n public get face(): number {\r\n return this._face;\r\n }\r\n\r\n public set face(value: number) {\r\n if (value < 0 || value > 5) {\r\n return;\r\n }\r\n\r\n this._face = value;\r\n switch (this._face) {\r\n case 0:\r\n this.updateEffect(\"#define POSITIVEX\");\r\n break;\r\n case 1:\r\n this.updateEffect(\"#define NEGATIVEX\");\r\n break;\r\n case 2:\r\n this.updateEffect(\"#define POSITIVEY\");\r\n break;\r\n case 3:\r\n this.updateEffect(\"#define NEGATIVEY\");\r\n break;\r\n case 4:\r\n this.updateEffect(\"#define POSITIVEZ\");\r\n break;\r\n case 5:\r\n this.updateEffect(\"#define NEGATIVEZ\");\r\n break;\r\n }\r\n }\r\n}\r\n","import type { Nullable } from \"../types\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport type { Camera } from \"../Cameras/camera\";\r\nimport type { PostProcessOptions } from \"./postProcess\";\r\nimport { PostProcess } from \"./postProcess\";\r\nimport { AbstractEngine } from \"../Engines/abstractEngine\";\r\n\r\nimport { RegisterClass } from \"../Misc/typeStore\";\r\nimport { SerializationHelper } from \"../Misc/decorators.serialization\";\r\n\r\nimport type { Scene } from \"../scene\";\r\nimport { ThinPassCubePostProcess, ThinPassPostProcess } from \"./thinPassPostProcess\";\r\nimport { serialize } from \"core/Misc/decorators\";\r\n\r\n/**\r\n * PassPostProcess which produces an output the same as it's input\r\n */\r\nexport class PassPostProcess extends PostProcess {\r\n /**\r\n * Gets a string identifying the name of the class\r\n * @returns \"PassPostProcess\" string\r\n */\r\n public override getClassName(): string {\r\n return \"PassPostProcess\";\r\n }\r\n\r\n /**\r\n * Creates the PassPostProcess\r\n * @param name The name of the effect.\r\n * @param options The required width/height ratio to downsize to before computing the render pass.\r\n * @param camera The camera to apply the render pass to.\r\n * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)\r\n * @param engine The engine which the post process will be applied. (default: current engine)\r\n * @param reusable If the post process can be reused on the same frame. (default: false)\r\n * @param textureType The type of texture to be used when performing the post processing.\r\n * @param blockCompilation If compilation of the shader should not be done in the constructor. The updateEffect method can be used to compile the shader at a later time. (default: false)\r\n */\r\n constructor(\r\n name: string,\r\n options: number | PostProcessOptions,\r\n camera: Nullable = null,\r\n samplingMode?: number,\r\n engine?: AbstractEngine,\r\n reusable?: boolean,\r\n textureType: number = Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n blockCompilation = false\r\n ) {\r\n const localOptions = {\r\n size: typeof options === \"number\" ? options : undefined,\r\n camera,\r\n samplingMode,\r\n engine,\r\n reusable,\r\n textureType,\r\n blockCompilation,\r\n ...(options as PostProcessOptions),\r\n };\r\n\r\n super(name, ThinPassPostProcess.FragmentUrl, {\r\n effectWrapper: typeof options === \"number\" || !options.effectWrapper ? new ThinPassPostProcess(name, engine, localOptions) : undefined,\r\n ...localOptions,\r\n });\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n public static override _Parse(parsedPostProcess: any, targetCamera: Camera, scene: Scene, rootUrl: string) {\r\n return SerializationHelper.Parse(\r\n () => {\r\n return new PassPostProcess(\r\n parsedPostProcess.name,\r\n parsedPostProcess.options,\r\n targetCamera,\r\n parsedPostProcess.renderTargetSamplingMode,\r\n parsedPostProcess._engine,\r\n parsedPostProcess.reusable\r\n );\r\n },\r\n parsedPostProcess,\r\n scene,\r\n rootUrl\r\n );\r\n }\r\n}\r\n\r\nRegisterClass(\"BABYLON.PassPostProcess\", PassPostProcess);\r\n\r\n/**\r\n * PassCubePostProcess which produces an output the same as it's input (which must be a cube texture)\r\n */\r\nexport class PassCubePostProcess extends PostProcess {\r\n /**\r\n * Gets or sets the cube face to display.\r\n * * 0 is +X\r\n * * 1 is -X\r\n * * 2 is +Y\r\n * * 3 is -Y\r\n * * 4 is +Z\r\n * * 5 is -Z\r\n */\r\n @serialize()\r\n public get face(): number {\r\n return this._effectWrapper.face;\r\n }\r\n\r\n public set face(value: number) {\r\n this._effectWrapper.face = value;\r\n }\r\n\r\n /**\r\n * Gets a string identifying the name of the class\r\n * @returns \"PassCubePostProcess\" string\r\n */\r\n public override getClassName(): string {\r\n return \"PassCubePostProcess\";\r\n }\r\n\r\n protected override _effectWrapper: ThinPassCubePostProcess;\r\n\r\n /**\r\n * Creates the PassCubePostProcess\r\n * @param name The name of the effect.\r\n * @param options The required width/height ratio to downsize to before computing the render pass.\r\n * @param camera The camera to apply the render pass to.\r\n * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)\r\n * @param engine The engine which the post process will be applied. (default: current engine)\r\n * @param reusable If the post process can be reused on the same frame. (default: false)\r\n * @param textureType The type of texture to be used when performing the post processing.\r\n * @param blockCompilation If compilation of the shader should not be done in the constructor. The updateEffect method can be used to compile the shader at a later time. (default: false)\r\n */\r\n constructor(\r\n name: string,\r\n options: number | PostProcessOptions,\r\n camera: Nullable = null,\r\n samplingMode?: number,\r\n engine?: AbstractEngine,\r\n reusable?: boolean,\r\n textureType: number = Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n blockCompilation = false\r\n ) {\r\n const localOptions = {\r\n size: typeof options === \"number\" ? options : undefined,\r\n camera,\r\n samplingMode,\r\n engine,\r\n reusable,\r\n textureType,\r\n blockCompilation,\r\n ...(options as PostProcessOptions),\r\n };\r\n\r\n super(name, ThinPassPostProcess.FragmentUrl, {\r\n effectWrapper: typeof options === \"number\" || !options.effectWrapper ? new ThinPassCubePostProcess(name, engine, localOptions) : undefined,\r\n ...localOptions,\r\n });\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n public static override _Parse(parsedPostProcess: any, targetCamera: Camera, scene: Scene, rootUrl: string) {\r\n return SerializationHelper.Parse(\r\n () => {\r\n return new PassCubePostProcess(\r\n parsedPostProcess.name,\r\n parsedPostProcess.options,\r\n targetCamera,\r\n parsedPostProcess.renderTargetSamplingMode,\r\n parsedPostProcess._engine,\r\n parsedPostProcess.reusable\r\n );\r\n },\r\n parsedPostProcess,\r\n scene,\r\n rootUrl\r\n );\r\n }\r\n}\r\n\r\nAbstractEngine._RescalePostProcessFactory = (engine: AbstractEngine) => {\r\n return new PassPostProcess(\"rescale\", 1, null, Constants.TEXTURE_BILINEAR_SAMPLINGMODE, engine, false, Constants.TEXTURETYPE_UNSIGNED_BYTE);\r\n};\r\n","/* eslint-disable @typescript-eslint/naming-convention */\r\nimport type { BaseTexture } from \"core/Materials/Textures/baseTexture\";\r\nimport type { InternalTexture } from \"../Materials/Textures/internalTexture\";\r\nimport { Texture } from \"../Materials/Textures/texture\";\r\nimport { RenderTargetTexture } from \"../Materials/Textures/renderTargetTexture\";\r\nimport { PassPostProcess } from \"../PostProcesses/passPostProcess\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport type { Scene } from \"../scene\";\r\nimport { PostProcess } from \"../PostProcesses/postProcess\";\r\nimport type { AbstractEngine } from \"../Engines/abstractEngine\";\r\nimport { ShaderLanguage } from \"core/Materials\";\r\n\r\n/**\r\n * Uses the GPU to create a copy texture rescaled at a given size\r\n * @param texture Texture to copy from\r\n * @param width defines the desired width\r\n * @param height defines the desired height\r\n * @param useBilinearMode defines if bilinear mode has to be used\r\n * @returns the generated texture\r\n */\r\nexport function CreateResizedCopy(texture: Texture, width: number, height: number, useBilinearMode: boolean = true): Texture {\r\n const scene = texture.getScene();\r\n const engine = scene.getEngine();\r\n\r\n const rtt = new RenderTargetTexture(\r\n \"resized\" + texture.name,\r\n { width: width, height: height },\r\n scene,\r\n !texture.noMipmap,\r\n true,\r\n (texture._texture).type,\r\n false,\r\n texture.samplingMode,\r\n false\r\n );\r\n\r\n rtt.wrapU = texture.wrapU;\r\n rtt.wrapV = texture.wrapV;\r\n rtt.uOffset = texture.uOffset;\r\n rtt.vOffset = texture.vOffset;\r\n rtt.uScale = texture.uScale;\r\n rtt.vScale = texture.vScale;\r\n rtt.uAng = texture.uAng;\r\n rtt.vAng = texture.vAng;\r\n rtt.wAng = texture.wAng;\r\n rtt.coordinatesIndex = texture.coordinatesIndex;\r\n rtt.level = texture.level;\r\n rtt.anisotropicFilteringLevel = texture.anisotropicFilteringLevel;\r\n (rtt._texture).isReady = false;\r\n\r\n texture.wrapU = Texture.CLAMP_ADDRESSMODE;\r\n texture.wrapV = Texture.CLAMP_ADDRESSMODE;\r\n\r\n const passPostProcess = new PassPostProcess(\r\n \"pass\",\r\n 1,\r\n null,\r\n useBilinearMode ? Texture.BILINEAR_SAMPLINGMODE : Texture.NEAREST_SAMPLINGMODE,\r\n engine,\r\n false,\r\n Constants.TEXTURETYPE_UNSIGNED_BYTE\r\n );\r\n passPostProcess.externalTextureSamplerBinding = true;\r\n passPostProcess.onEffectCreatedObservable.addOnce((e) => {\r\n e.executeWhenCompiled(() => {\r\n passPostProcess.onApply = function (effect) {\r\n effect.setTexture(\"textureSampler\", texture);\r\n };\r\n\r\n const internalTexture = rtt.renderTarget;\r\n\r\n if (internalTexture) {\r\n scene.postProcessManager.directRender([passPostProcess], internalTexture);\r\n\r\n engine.unBindFramebuffer(internalTexture);\r\n rtt.disposeFramebufferObjects();\r\n passPostProcess.dispose();\r\n\r\n rtt.getInternalTexture()!.isReady = true;\r\n }\r\n });\r\n });\r\n\r\n return rtt;\r\n}\r\n\r\n/**\r\n * Apply a post process to a texture\r\n * @param postProcessName name of the fragment post process\r\n * @param internalTexture the texture to encode\r\n * @param scene the scene hosting the texture\r\n * @param type type of the output texture. If not provided, use the one from internalTexture\r\n * @param samplingMode sampling mode to use to sample the source texture. If not provided, use the one from internalTexture\r\n * @param format format of the output texture. If not provided, use the one from internalTexture\r\n * @param width width of the output texture. If not provided, use the one from internalTexture\r\n * @param height height of the output texture. If not provided, use the one from internalTexture\r\n * @returns a promise with the internalTexture having its texture replaced by the result of the processing\r\n */\r\nexport function ApplyPostProcess(\r\n postProcessName: string,\r\n internalTexture: InternalTexture,\r\n scene: Scene,\r\n type?: number,\r\n samplingMode?: number,\r\n format?: number,\r\n width?: number,\r\n height?: number\r\n): Promise {\r\n // Gets everything ready.\r\n const engine = internalTexture.getEngine() as AbstractEngine;\r\n\r\n internalTexture.isReady = false;\r\n\r\n samplingMode = samplingMode ?? internalTexture.samplingMode;\r\n type = type ?? internalTexture.type;\r\n format = format ?? internalTexture.format;\r\n width = width ?? internalTexture.width;\r\n height = height ?? internalTexture.height;\r\n\r\n if (type === -1) {\r\n type = Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n }\r\n\r\n return new Promise((resolve) => {\r\n // Create the post process\r\n const postProcess = new PostProcess(\"postprocess\", postProcessName, null, null, 1, null, samplingMode, engine, false, undefined, type, undefined, null, false, format);\r\n postProcess.externalTextureSamplerBinding = true;\r\n\r\n // Hold the output of the decoding.\r\n const encodedTexture = engine.createRenderTargetTexture(\r\n { width: width as number, height: height as number },\r\n {\r\n generateDepthBuffer: false,\r\n generateMipMaps: false,\r\n generateStencilBuffer: false,\r\n samplingMode,\r\n type,\r\n format,\r\n }\r\n );\r\n\r\n postProcess.onEffectCreatedObservable.addOnce((e) => {\r\n e.executeWhenCompiled(() => {\r\n // PP Render Pass\r\n postProcess.onApply = (effect) => {\r\n effect._bindTexture(\"textureSampler\", internalTexture);\r\n effect.setFloat2(\"scale\", 1, 1);\r\n };\r\n scene.postProcessManager.directRender([postProcess!], encodedTexture, true);\r\n\r\n // Cleanup\r\n engine.restoreDefaultFramebuffer();\r\n engine._releaseTexture(internalTexture);\r\n if (postProcess) {\r\n postProcess.dispose();\r\n }\r\n\r\n // Internal Swap\r\n encodedTexture._swapAndDie(internalTexture);\r\n\r\n // Ready to get rolling again.\r\n internalTexture.type = type!;\r\n internalTexture.format = Constants.TEXTUREFORMAT_RGBA;\r\n internalTexture.isReady = true;\r\n\r\n resolve(internalTexture);\r\n });\r\n });\r\n });\r\n}\r\n\r\n// ref: http://stackoverflow.com/questions/32633585/how-do-you-convert-to-half-floats-in-javascript\r\nlet floatView: Float32Array;\r\nlet int32View: Int32Array;\r\n/**\r\n * Converts a number to half float\r\n * @param value number to convert\r\n * @returns converted number\r\n */\r\nexport function ToHalfFloat(value: number): number {\r\n if (!floatView) {\r\n floatView = new Float32Array(1);\r\n int32View = new Int32Array(floatView.buffer);\r\n }\r\n\r\n floatView[0] = value;\r\n const x = int32View[0];\r\n\r\n let bits = (x >> 16) & 0x8000; /* Get the sign */\r\n let m = (x >> 12) & 0x07ff; /* Keep one extra bit for rounding */\r\n const e = (x >> 23) & 0xff; /* Using int is faster here */\r\n\r\n /* If zero, or denormal, or exponent underflows too much for a denormal\r\n * half, return signed zero. */\r\n if (e < 103) {\r\n return bits;\r\n }\r\n\r\n /* If NaN, return NaN. If Inf or exponent overflow, return Inf. */\r\n if (e > 142) {\r\n bits |= 0x7c00;\r\n /* If exponent was 0xff and one mantissa bit was set, it means NaN,\r\n * not Inf, so make sure we set one mantissa bit too. */\r\n bits |= (e == 255 ? 0 : 1) && x & 0x007fffff;\r\n return bits;\r\n }\r\n\r\n /* If exponent underflows but not too much, return a denormal */\r\n if (e < 113) {\r\n m |= 0x0800;\r\n /* Extra rounding may overflow and set mantissa to 0 and exponent\r\n * to 1, which is OK. */\r\n bits |= (m >> (114 - e)) + ((m >> (113 - e)) & 1);\r\n return bits;\r\n }\r\n\r\n bits |= ((e - 112) << 10) | (m >> 1);\r\n bits += m & 1;\r\n return bits;\r\n}\r\n\r\n/**\r\n * Converts a half float to a number\r\n * @param value half float to convert\r\n * @returns converted half float\r\n */\r\nexport function FromHalfFloat(value: number): number {\r\n const s = (value & 0x8000) >> 15;\r\n const e = (value & 0x7c00) >> 10;\r\n const f = value & 0x03ff;\r\n\r\n if (e === 0) {\r\n return (s ? -1 : 1) * Math.pow(2, -14) * (f / Math.pow(2, 10));\r\n } else if (e == 0x1f) {\r\n return f ? NaN : (s ? -1 : 1) * Infinity;\r\n }\r\n\r\n return (s ? -1 : 1) * Math.pow(2, e - 15) * (1 + f / Math.pow(2, 10));\r\n}\r\n\r\nconst ProcessAsync = async (texture: BaseTexture, width: number, height: number, face: number, lod: number): Promise => {\r\n const scene = texture.getScene()!;\r\n const engine = scene.getEngine();\r\n\r\n if (!engine.isWebGPU) {\r\n if (texture.isCube) {\r\n await import(\"../Shaders/lodCube.fragment\");\r\n } else {\r\n await import(\"../Shaders/lod.fragment\");\r\n }\r\n } else {\r\n if (texture.isCube) {\r\n await import(\"../ShadersWGSL/lodCube.fragment\");\r\n } else {\r\n await import(\"../ShadersWGSL/lod.fragment\");\r\n }\r\n }\r\n\r\n let lodPostProcess: PostProcess;\r\n\r\n if (!texture.isCube) {\r\n lodPostProcess = new PostProcess(\"lod\", \"lod\", {\r\n uniforms: [\"lod\", \"gamma\"],\r\n samplingMode: Texture.NEAREST_NEAREST_MIPNEAREST,\r\n engine,\r\n shaderLanguage: engine.isWebGPU ? ShaderLanguage.WGSL : ShaderLanguage.GLSL,\r\n });\r\n } else {\r\n const faceDefines = [\"#define POSITIVEX\", \"#define NEGATIVEX\", \"#define POSITIVEY\", \"#define NEGATIVEY\", \"#define POSITIVEZ\", \"#define NEGATIVEZ\"];\r\n lodPostProcess = new PostProcess(\"lodCube\", \"lodCube\", {\r\n uniforms: [\"lod\", \"gamma\"],\r\n samplingMode: Texture.NEAREST_NEAREST_MIPNEAREST,\r\n engine,\r\n defines: faceDefines[face],\r\n shaderLanguage: engine.isWebGPU ? ShaderLanguage.WGSL : ShaderLanguage.GLSL,\r\n });\r\n }\r\n\r\n await new Promise((resolve) => {\r\n lodPostProcess.onEffectCreatedObservable.addOnce((e) => {\r\n e.executeWhenCompiled(() => {\r\n resolve(0);\r\n });\r\n });\r\n });\r\n\r\n const rtt = new RenderTargetTexture(\"temp\", { width: width, height: height }, scene, false);\r\n\r\n lodPostProcess.onApply = function (effect) {\r\n effect.setTexture(\"textureSampler\", texture);\r\n effect.setFloat(\"lod\", lod);\r\n effect.setInt(\"gamma\", texture.gammaSpace ? 1 : 0);\r\n };\r\n\r\n const internalTexture = texture.getInternalTexture();\r\n\r\n try {\r\n if (rtt.renderTarget && internalTexture) {\r\n const samplingMode = internalTexture.samplingMode;\r\n if (lod !== 0) {\r\n texture.updateSamplingMode(Texture.NEAREST_NEAREST_MIPNEAREST);\r\n } else {\r\n texture.updateSamplingMode(Texture.NEAREST_NEAREST);\r\n }\r\n\r\n scene.postProcessManager.directRender([lodPostProcess], rtt.renderTarget, true);\r\n texture.updateSamplingMode(samplingMode);\r\n\r\n //Reading datas from WebGL\r\n const bufferView = await engine.readPixels(0, 0, width, height);\r\n const data = new Uint8Array(bufferView.buffer, 0, bufferView.byteLength);\r\n\r\n // Unbind\r\n engine.unBindFramebuffer(rtt.renderTarget);\r\n\r\n return data;\r\n } else {\r\n throw Error(\"Render to texture failed.\");\r\n }\r\n } finally {\r\n rtt.dispose();\r\n lodPostProcess.dispose();\r\n }\r\n};\r\n\r\n/**\r\n * Gets the data of the specified texture by rendering it to an intermediate RGBA texture and retrieving the bytes from it.\r\n * This is convienent to get 8-bit RGBA values for a texture in a GPU compressed format.\r\n * @param texture the source texture\r\n * @param width the width of the result, which does not have to match the source texture width\r\n * @param height the height of the result, which does not have to match the source texture height\r\n * @param face if the texture has multiple faces, the face index to use for the source\r\n * @param lod if the texture has multiple LODs, the lod index to use for the source\r\n * @returns the 8-bit texture data\r\n */\r\nexport async function GetTextureDataAsync(texture: BaseTexture, width: number, height: number, face: number = 0, lod: number = 0): Promise {\r\n if (!texture.isReady() && texture._texture) {\r\n await new Promise((resolve, reject) => {\r\n if (texture._texture === null) {\r\n reject(0);\r\n return;\r\n }\r\n texture._texture.onLoadedObservable.addOnce(() => {\r\n resolve(0);\r\n });\r\n });\r\n }\r\n return await ProcessAsync(texture, width, height, face, lod);\r\n}\r\n\r\n/**\r\n * Class used to host texture specific utilities\r\n */\r\nexport const TextureTools = {\r\n /**\r\n * Uses the GPU to create a copy texture rescaled at a given size\r\n * @param texture Texture to copy from\r\n * @param width defines the desired width\r\n * @param height defines the desired height\r\n * @param useBilinearMode defines if bilinear mode has to be used\r\n * @returns the generated texture\r\n */\r\n CreateResizedCopy,\r\n\r\n /**\r\n * Apply a post process to a texture\r\n * @param postProcessName name of the fragment post process\r\n * @param internalTexture the texture to encode\r\n * @param scene the scene hosting the texture\r\n * @param type type of the output texture. If not provided, use the one from internalTexture\r\n * @param samplingMode sampling mode to use to sample the source texture. If not provided, use the one from internalTexture\r\n * @param format format of the output texture. If not provided, use the one from internalTexture\r\n * @returns a promise with the internalTexture having its texture replaced by the result of the processing\r\n */\r\n ApplyPostProcess,\r\n /**\r\n * Converts a number to half float\r\n * @param value number to convert\r\n * @returns converted number\r\n */\r\n ToHalfFloat,\r\n\r\n /**\r\n * Converts a half float to a number\r\n * @param value half float to convert\r\n * @returns converted half float\r\n */\r\n FromHalfFloat,\r\n\r\n /**\r\n * Gets the data of the specified texture by rendering it to an intermediate RGBA texture and retrieving the bytes from it.\r\n * This is convienent to get 8-bit RGBA values for a texture in a GPU compressed format.\r\n * @param texture the source texture\r\n * @param width the width of the result, which does not have to match the source texture width\r\n * @param height the height of the result, which does not have to match the source texture height\r\n * @param face if the texture has multiple faces, the face index to use for the source\r\n * @param channels a filter for which of the RGBA channels to return in the result\r\n * @param lod if the texture has multiple LODs, the lod index to use for the source\r\n * @returns the 8-bit texture data\r\n */\r\n GetTextureDataAsync,\r\n};\r\n","import type { Nullable } from \"../types\";\r\nimport { SmartArray } from \"../Misc/smartArray\";\r\nimport type { Observer } from \"../Misc/observable\";\r\nimport { Observable } from \"../Misc/observable\";\r\nimport { Vector2 } from \"../Maths/math.vector\";\r\nimport type { Camera } from \"../Cameras/camera\";\r\nimport { Effect } from \"../Materials/effect\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport type { RenderTargetCreationOptions } from \"../Materials/Textures/textureCreationOptions\";\r\nimport type { IInspectable } from \"../Misc/iInspectable\";\r\nimport type { Color4 } from \"../Maths/math.color\";\r\n\r\nimport type { NodeMaterial } from \"../Materials/Node/nodeMaterial\";\r\nimport { serialize, serializeAsColor4 } from \"../Misc/decorators\";\r\nimport { SerializationHelper } from \"../Misc/decorators.serialization\";\r\nimport { GetClass, RegisterClass } from \"../Misc/typeStore\";\r\nimport type { RenderTargetWrapper } from \"../Engines/renderTargetWrapper\";\r\nimport { ShaderLanguage } from \"../Materials/shaderLanguage\";\r\n\r\nimport type { Scene } from \"../scene\";\r\nimport type { InternalTexture } from \"../Materials/Textures/internalTexture\";\r\nimport type { Animation } from \"../Animations/animation\";\r\nimport type { PrePassRenderer } from \"../Rendering/prePassRenderer\";\r\nimport type { PrePassEffectConfiguration } from \"../Rendering/prePassEffectConfiguration\";\r\nimport { AbstractEngine } from \"../Engines/abstractEngine\";\r\nimport { GetExponentOfTwo } from \"../Misc/tools.functions\";\r\nimport type { IAssetContainer } from \"core/IAssetContainer\";\r\nimport type { EffectWrapperCustomShaderCodeProcessing, EffectWrapperCreationOptions } from \"../Materials/effectRenderer\";\r\nimport { EffectWrapper } from \"../Materials/effectRenderer\";\r\n\r\ndeclare module \"../Engines/abstractEngine\" {\r\n export interface AbstractEngine {\r\n /**\r\n * Sets a texture to the context from a postprocess\r\n * @param channel defines the channel to use\r\n * @param postProcess defines the source postprocess\r\n * @param name name of the channel\r\n */\r\n setTextureFromPostProcess(channel: number, postProcess: Nullable, name: string): void;\r\n\r\n /**\r\n * Binds the output of the passed in post process to the texture channel specified\r\n * @param channel The channel the texture should be bound to\r\n * @param postProcess The post process which's output should be bound\r\n * @param name name of the channel\r\n */\r\n setTextureFromPostProcessOutput(channel: number, postProcess: Nullable, name: string): void;\r\n }\r\n}\r\n\r\nAbstractEngine.prototype.setTextureFromPostProcess = function (channel: number, postProcess: Nullable, name: string): void {\r\n let postProcessInput = null;\r\n if (postProcess) {\r\n if (postProcess._forcedOutputTexture) {\r\n postProcessInput = postProcess._forcedOutputTexture;\r\n } else if (postProcess._textures.data[postProcess._currentRenderTextureInd]) {\r\n postProcessInput = postProcess._textures.data[postProcess._currentRenderTextureInd];\r\n }\r\n }\r\n\r\n this._bindTexture(channel, postProcessInput?.texture ?? null, name);\r\n};\r\n\r\nAbstractEngine.prototype.setTextureFromPostProcessOutput = function (channel: number, postProcess: Nullable, name: string): void {\r\n this._bindTexture(channel, postProcess?._outputTexture?.texture ?? null, name);\r\n};\r\n\r\ndeclare module \"../Materials/effect\" {\r\n export interface Effect {\r\n /**\r\n * Sets a texture to be the input of the specified post process. (To use the output, pass in the next post process in the pipeline)\r\n * @param channel Name of the sampler variable.\r\n * @param postProcess Post process to get the input texture from.\r\n */\r\n setTextureFromPostProcess(channel: string, postProcess: Nullable): void;\r\n\r\n /**\r\n * (Warning! setTextureFromPostProcessOutput may be desired instead)\r\n * Sets the input texture of the passed in post process to be input of this effect. (To use the output of the passed in post process use setTextureFromPostProcessOutput)\r\n * @param channel Name of the sampler variable.\r\n * @param postProcess Post process to get the output texture from.\r\n */\r\n setTextureFromPostProcessOutput(channel: string, postProcess: Nullable): void;\r\n }\r\n}\r\n\r\n/**\r\n * Sets a texture to be the input of the specified post process. (To use the output, pass in the next post process in the pipeline)\r\n * @param channel Name of the sampler variable.\r\n * @param postProcess Post process to get the input texture from.\r\n */\r\nEffect.prototype.setTextureFromPostProcess = function (channel: string, postProcess: Nullable): void {\r\n this._engine.setTextureFromPostProcess(this._samplers[channel], postProcess, channel);\r\n};\r\n\r\n/**\r\n * (Warning! setTextureFromPostProcessOutput may be desired instead)\r\n * Sets the input texture of the passed in post process to be input of this effect. (To use the output of the passed in post process use setTextureFromPostProcessOutput)\r\n * @param channel Name of the sampler variable.\r\n * @param postProcess Post process to get the output texture from.\r\n */\r\nEffect.prototype.setTextureFromPostProcessOutput = function (channel: string, postProcess: Nullable): void {\r\n this._engine.setTextureFromPostProcessOutput(this._samplers[channel], postProcess, channel);\r\n};\r\n\r\n/**\r\n * Options for the PostProcess constructor\r\n */\r\nexport type PostProcessOptions = EffectWrapperCreationOptions & {\r\n /**\r\n * The width of the texture created for this post process.\r\n * This parameter (and height) is only used when passing a value for the 5th parameter (options) to the PostProcess constructor function.\r\n * If you use a PostProcessOptions for the 3rd parameter of the constructor, size is used instead of width and height.\r\n */\r\n width?: number;\r\n /**\r\n * The height of the texture created for this post process.\r\n * This parameter (and width) is only used when passing a value for the 5th parameter (options) to the PostProcess constructor function.\r\n * If you use a PostProcessOptions for the 3rd parameter of the constructor, size is used instead of width and height.\r\n */\r\n height?: number;\r\n\r\n /**\r\n * The size of the post process texture.\r\n * It is either a ratio to downscale or upscale the texture create for this post process, or an object containing width and height values.\r\n * Default: 1\r\n */\r\n size?: number | { width: number; height: number };\r\n /**\r\n * The camera that the post process will be attached to (default: null)\r\n */\r\n camera?: Nullable;\r\n /**\r\n * The sampling mode to be used by the shader (default: Constants.TEXTURE_NEAREST_SAMPLINGMODE)\r\n */\r\n samplingMode?: number;\r\n /**\r\n * The engine to be used to render the post process (default: engine from scene)\r\n */\r\n engine?: AbstractEngine;\r\n /**\r\n * If the post process can be reused on the same frame. (default: false)\r\n */\r\n reusable?: boolean;\r\n /**\r\n * Type of the texture created for this post process (default: Constants.TEXTURETYPE_UNSIGNED_BYTE)\r\n */\r\n textureType?: number;\r\n /**\r\n * Format of the texture created for this post process (default: TEXTUREFORMAT_RGBA)\r\n */\r\n textureFormat?: number;\r\n /**\r\n * The effect wrapper instance used by the post process. If not provided, a new one will be created.\r\n */\r\n effectWrapper?: EffectWrapper;\r\n};\r\n\r\ntype TextureCache = { texture: RenderTargetWrapper; postProcessChannel: number; lastUsedRenderId: number };\r\n\r\n/**\r\n * PostProcess can be used to apply a shader to a texture after it has been rendered\r\n * See https://doc.babylonjs.com/features/featuresDeepDive/postProcesses/usePostProcesses\r\n */\r\nexport class PostProcess {\r\n /**\r\n * Force all the postprocesses to compile to glsl even on WebGPU engines.\r\n * False by default. This is mostly meant for backward compatibility.\r\n */\r\n public static get ForceGLSL(): boolean {\r\n return EffectWrapper.ForceGLSL;\r\n }\r\n\r\n public static set ForceGLSL(force: boolean) {\r\n EffectWrapper.ForceGLSL = force;\r\n }\r\n\r\n /** @internal */\r\n public _parentContainer: Nullable = null;\r\n\r\n /**\r\n * Registers a shader code processing with a post process name.\r\n * @param postProcessName name of the post process. Use null for the fallback shader code processing. This is the shader code processing that will be used in case no specific shader code processing has been associated to a post process name\r\n * @param customShaderCodeProcessing shader code processing to associate to the post process name\r\n */\r\n public static RegisterShaderCodeProcessing(postProcessName: Nullable, customShaderCodeProcessing?: EffectWrapperCustomShaderCodeProcessing) {\r\n EffectWrapper.RegisterShaderCodeProcessing(postProcessName, customShaderCodeProcessing);\r\n }\r\n\r\n /**\r\n * Gets or sets the unique id of the post process\r\n */\r\n @serialize()\r\n public uniqueId: number;\r\n\r\n /** Name of the PostProcess. */\r\n @serialize()\r\n public get name() {\r\n return this._effectWrapper.name;\r\n }\r\n\r\n public set name(value: string) {\r\n this._effectWrapper.name = value;\r\n }\r\n\r\n /**\r\n * Width of the texture to apply the post process on\r\n */\r\n @serialize()\r\n public width = -1;\r\n\r\n /**\r\n * Height of the texture to apply the post process on\r\n */\r\n @serialize()\r\n public height = -1;\r\n\r\n /**\r\n * Gets the node material used to create this postprocess (null if the postprocess was manually created)\r\n */\r\n public nodeMaterialSource: Nullable = null;\r\n\r\n /**\r\n * Internal, reference to the location where this postprocess was output to. (Typically the texture on the next postprocess in the chain)\r\n * @internal\r\n */\r\n public _outputTexture: Nullable = null;\r\n /**\r\n * Sampling mode used by the shader\r\n */\r\n @serialize()\r\n public renderTargetSamplingMode: number;\r\n /**\r\n * Clear color to use when screen clearing\r\n */\r\n @serializeAsColor4()\r\n public clearColor: Color4;\r\n /**\r\n * If the buffer needs to be cleared before applying the post process. (default: true)\r\n * Should be set to false if shader will overwrite all previous pixels.\r\n */\r\n @serialize()\r\n public autoClear = true;\r\n /**\r\n * If clearing the buffer should be forced in autoClear mode, even when alpha mode is enabled (default: false).\r\n * By default, the buffer will only be cleared if alpha mode is disabled (and autoClear is true).\r\n */\r\n @serialize()\r\n public forceAutoClearInAlphaMode = false;\r\n\r\n /**\r\n * Type of alpha mode to use when performing the post process (default: Engine.ALPHA_DISABLE)\r\n */\r\n @serialize()\r\n public get alphaMode() {\r\n return this._effectWrapper.alphaMode;\r\n }\r\n\r\n public set alphaMode(value: number) {\r\n this._effectWrapper.alphaMode = value;\r\n }\r\n\r\n /**\r\n * Sets the setAlphaBlendConstants of the babylon engine\r\n */\r\n @serialize()\r\n public alphaConstants: Color4;\r\n\r\n /**\r\n * Animations to be used for the post processing\r\n */\r\n public animations: Animation[] = [];\r\n\r\n /**\r\n * Enable Pixel Perfect mode where texture is not scaled to be power of 2.\r\n * Can only be used on a single postprocess or on the last one of a chain. (default: false)\r\n */\r\n @serialize()\r\n public enablePixelPerfectMode = false;\r\n\r\n /**\r\n * Force the postprocess to be applied without taking in account viewport\r\n */\r\n @serialize()\r\n public forceFullscreenViewport = true;\r\n\r\n /**\r\n * List of inspectable custom properties (used by the Inspector)\r\n * @see https://doc.babylonjs.com/toolsAndResources/inspector#extensibility\r\n */\r\n public inspectableCustomProperties: IInspectable[];\r\n\r\n /**\r\n * Scale mode for the post process (default: Engine.SCALEMODE_FLOOR)\r\n *\r\n * | Value | Type | Description |\r\n * | ----- | ----------------------------------- | ----------- |\r\n * | 1 | SCALEMODE_FLOOR | [engine.scalemode_floor](https://doc.babylonjs.com/api/classes/babylon.engine#scalemode_floor) |\r\n * | 2 | SCALEMODE_NEAREST | [engine.scalemode_nearest](https://doc.babylonjs.com/api/classes/babylon.engine#scalemode_nearest) |\r\n * | 3 | SCALEMODE_CEILING | [engine.scalemode_ceiling](https://doc.babylonjs.com/api/classes/babylon.engine#scalemode_ceiling) |\r\n *\r\n */\r\n @serialize()\r\n public scaleMode = Constants.SCALEMODE_FLOOR;\r\n /**\r\n * Force textures to be a power of two (default: false)\r\n */\r\n @serialize()\r\n public alwaysForcePOT = false;\r\n\r\n @serialize(\"samples\")\r\n private _samples = 1;\r\n\r\n /**\r\n * Number of sample textures (default: 1)\r\n */\r\n public get samples() {\r\n return this._samples;\r\n }\r\n\r\n public set samples(n: number) {\r\n this._samples = Math.min(n, this._engine.getCaps().maxMSAASamples);\r\n\r\n this._textures.forEach((texture) => {\r\n texture.setSamples(this._samples);\r\n });\r\n }\r\n\r\n /**\r\n * Modify the scale of the post process to be the same as the viewport (default: false)\r\n */\r\n @serialize()\r\n public adaptScaleToCurrentViewport = false;\r\n\r\n private _camera: Camera;\r\n protected _scene: Scene;\r\n private _engine: AbstractEngine;\r\n\r\n protected _webGPUReady = false;\r\n\r\n private _options: number | { width: number; height: number };\r\n private _reusable = false;\r\n private _renderId = 0;\r\n private _textureType: number;\r\n private _textureFormat: number;\r\n /** @internal */\r\n private _shaderLanguage: ShaderLanguage;\r\n\r\n /**\r\n * Gets the shader language type used to generate vertex and fragment source code.\r\n */\r\n public get shaderLanguage(): ShaderLanguage {\r\n return this._shaderLanguage;\r\n }\r\n\r\n /**\r\n * if externalTextureSamplerBinding is true, the \"apply\" method won't bind the textureSampler texture, it is expected to be done by the \"outside\" (by the onApplyObservable observer most probably).\r\n * counter-productive in some cases because if the texture bound by \"apply\" is different from the currently texture bound, (the one set by the onApplyObservable observer, for eg) some\r\n * internal structures (materialContext) will be dirtified, which may impact performances\r\n */\r\n public externalTextureSamplerBinding = false;\r\n\r\n /**\r\n * Smart array of input and output textures for the post process.\r\n * @internal\r\n */\r\n public _textures = new SmartArray(2);\r\n /**\r\n * Smart array of input and output textures for the post process.\r\n * @internal\r\n */\r\n private _textureCache: TextureCache[] = [];\r\n /**\r\n * The index in _textures that corresponds to the output texture.\r\n * @internal\r\n */\r\n public _currentRenderTextureInd = 0;\r\n private _samplers: string[];\r\n private _fragmentUrl: string;\r\n private _vertexUrl: string;\r\n private _parameters: string[];\r\n private _uniformBuffers: string[];\r\n protected _postProcessDefines: Nullable;\r\n private _scaleRatio = new Vector2(1, 1);\r\n protected _indexParameters: any;\r\n private _shareOutputWithPostProcess: Nullable;\r\n private _texelSize = Vector2.Zero();\r\n\r\n /** @internal */\r\n public _forcedOutputTexture: Nullable;\r\n\r\n /**\r\n * Prepass configuration in case this post process needs a texture from prepass\r\n * @internal\r\n */\r\n public _prePassEffectConfiguration: PrePassEffectConfiguration;\r\n\r\n /**\r\n * Returns the fragment url or shader name used in the post process.\r\n * @returns the fragment url or name in the shader store.\r\n */\r\n public getEffectName(): string {\r\n return this._fragmentUrl;\r\n }\r\n\r\n /**\r\n * Executed when the effect was created\r\n * @returns effect that was created for this post process\r\n */\r\n public onEffectCreatedObservable;\r\n\r\n // Events\r\n\r\n /**\r\n * An event triggered when the postprocess is activated.\r\n */\r\n public onActivateObservable = new Observable();\r\n\r\n private _onActivateObserver: Nullable>;\r\n /**\r\n * A function that is added to the onActivateObservable\r\n */\r\n public set onActivate(callback: Nullable<(camera: Camera) => void>) {\r\n if (this._onActivateObserver) {\r\n this.onActivateObservable.remove(this._onActivateObserver);\r\n }\r\n if (callback) {\r\n this._onActivateObserver = this.onActivateObservable.add(callback);\r\n }\r\n }\r\n\r\n /**\r\n * An event triggered when the postprocess changes its size.\r\n */\r\n public onSizeChangedObservable = new Observable();\r\n\r\n private _onSizeChangedObserver: Nullable>;\r\n /**\r\n * A function that is added to the onSizeChangedObservable\r\n */\r\n public set onSizeChanged(callback: (postProcess: PostProcess) => void) {\r\n if (this._onSizeChangedObserver) {\r\n this.onSizeChangedObservable.remove(this._onSizeChangedObserver);\r\n }\r\n this._onSizeChangedObserver = this.onSizeChangedObservable.add(callback);\r\n }\r\n\r\n /**\r\n * An event triggered when the postprocess applies its effect.\r\n */\r\n public onApplyObservable = new Observable();\r\n\r\n private _onApplyObserver: Nullable>;\r\n /**\r\n * A function that is added to the onApplyObservable\r\n */\r\n public set onApply(callback: (effect: Effect) => void) {\r\n if (this._onApplyObserver) {\r\n this.onApplyObservable.remove(this._onApplyObserver);\r\n }\r\n this._onApplyObserver = this.onApplyObservable.add(callback);\r\n }\r\n\r\n /**\r\n * An event triggered before rendering the postprocess\r\n */\r\n public onBeforeRenderObservable = new Observable();\r\n\r\n private _onBeforeRenderObserver: Nullable>;\r\n /**\r\n * A function that is added to the onBeforeRenderObservable\r\n */\r\n public set onBeforeRender(callback: (effect: Effect) => void) {\r\n if (this._onBeforeRenderObserver) {\r\n this.onBeforeRenderObservable.remove(this._onBeforeRenderObserver);\r\n }\r\n this._onBeforeRenderObserver = this.onBeforeRenderObservable.add(callback);\r\n }\r\n\r\n /**\r\n * An event triggered after rendering the postprocess\r\n */\r\n public onAfterRenderObservable = new Observable();\r\n\r\n private _onAfterRenderObserver: Nullable>;\r\n /**\r\n * A function that is added to the onAfterRenderObservable\r\n */\r\n public set onAfterRender(callback: (efect: Effect) => void) {\r\n if (this._onAfterRenderObserver) {\r\n this.onAfterRenderObservable.remove(this._onAfterRenderObserver);\r\n }\r\n this._onAfterRenderObserver = this.onAfterRenderObservable.add(callback);\r\n }\r\n\r\n /**\r\n * The input texture for this post process and the output texture of the previous post process. When added to a pipeline the previous post process will\r\n * render it's output into this texture and this texture will be used as textureSampler in the fragment shader of this post process.\r\n */\r\n public get inputTexture(): RenderTargetWrapper {\r\n return this._textures.data[this._currentRenderTextureInd];\r\n }\r\n\r\n public set inputTexture(value: RenderTargetWrapper) {\r\n this._forcedOutputTexture = value;\r\n }\r\n\r\n /**\r\n * Since inputTexture should always be defined, if we previously manually set `inputTexture`,\r\n * the only way to unset it is to use this function to restore its internal state\r\n */\r\n public restoreDefaultInputTexture() {\r\n if (this._forcedOutputTexture) {\r\n this._forcedOutputTexture = null;\r\n this.markTextureDirty();\r\n }\r\n }\r\n\r\n /**\r\n * Gets the camera which post process is applied to.\r\n * @returns The camera the post process is applied to.\r\n */\r\n public getCamera(): Camera {\r\n return this._camera;\r\n }\r\n\r\n /**\r\n * Gets the texel size of the postprocess.\r\n * See https://en.wikipedia.org/wiki/Texel_(graphics)\r\n */\r\n public get texelSize(): Vector2 {\r\n if (this._shareOutputWithPostProcess) {\r\n return this._shareOutputWithPostProcess.texelSize;\r\n }\r\n\r\n if (this._forcedOutputTexture) {\r\n this._texelSize.copyFromFloats(1.0 / this._forcedOutputTexture.width, 1.0 / this._forcedOutputTexture.height);\r\n }\r\n\r\n return this._texelSize;\r\n }\r\n\r\n protected readonly _effectWrapper: EffectWrapper;\r\n\r\n /**\r\n * Creates a new instance PostProcess\r\n * @param name The name of the PostProcess.\r\n * @param fragmentUrl The url of the fragment shader to be used.\r\n * @param options The options to be used when constructing the post process.\r\n */\r\n constructor(name: string, fragmentUrl: string, options?: PostProcessOptions);\r\n\r\n /**\r\n * Creates a new instance PostProcess\r\n * @param name The name of the PostProcess.\r\n * @param fragmentUrl The url of the fragment shader to be used.\r\n * @param parameters Array of the names of uniform non-sampler2D variables that will be passed to the shader.\r\n * @param samplers Array of the names of uniform sampler2D variables that will be passed to the shader.\r\n * @param options The required width/height ratio to downsize to before computing the render pass. (Use 1.0 for full size)\r\n * @param camera The camera to apply the render pass to.\r\n * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)\r\n * @param engine The engine which the post process will be applied. (default: current engine)\r\n * @param reusable If the post process can be reused on the same frame. (default: false)\r\n * @param defines String of defines that will be set when running the fragment shader. (default: null)\r\n * @param textureType Type of textures used when performing the post process. (default: 0)\r\n * @param vertexUrl The url of the vertex shader to be used. (default: \"postprocess\")\r\n * @param indexParameters The index parameters to be used for babylons include syntax \"#include[0..varyingCount]\". (default: undefined) See usage in babylon.blurPostProcess.ts and kernelBlur.vertex.fx\r\n * @param blockCompilation If the shader should not be compiled immediatly. (default: false)\r\n * @param textureFormat Format of textures used when performing the post process. (default: TEXTUREFORMAT_RGBA)\r\n * @param shaderLanguage The shader language of the shader. (default: GLSL)\r\n * @param extraInitializations Defines additional code to call to prepare the shader code\r\n */\r\n constructor(\r\n name: string,\r\n fragmentUrl: string,\r\n parameters: Nullable,\r\n samplers: Nullable,\r\n options: number | PostProcessOptions,\r\n camera: Nullable,\r\n samplingMode?: number,\r\n engine?: AbstractEngine,\r\n reusable?: boolean,\r\n defines?: Nullable,\r\n textureType?: number,\r\n vertexUrl?: string,\r\n indexParameters?: any,\r\n blockCompilation?: boolean,\r\n textureFormat?: number,\r\n shaderLanguage?: ShaderLanguage,\r\n extraInitializations?: (useWebGPU: boolean, list: Promise[]) => void\r\n );\r\n\r\n /** @internal */\r\n constructor(\r\n name: string,\r\n fragmentUrl: string,\r\n parameters?: Nullable | PostProcessOptions,\r\n samplers?: Nullable,\r\n _size?: number | PostProcessOptions,\r\n camera?: Nullable,\r\n samplingMode: number = Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n engine?: AbstractEngine,\r\n reusable?: boolean,\r\n defines: Nullable = null,\r\n textureType: number = Constants.TEXTURETYPE_UNSIGNED_BYTE,\r\n vertexUrl: string = \"postprocess\",\r\n indexParameters?: any,\r\n blockCompilation = false,\r\n textureFormat = Constants.TEXTUREFORMAT_RGBA,\r\n shaderLanguage?: ShaderLanguage,\r\n extraInitializations?: (useWebGPU: boolean, list: Promise[]) => void\r\n ) {\r\n let size: number | { width: number; height: number } = 1;\r\n let uniformBuffers: Nullable = null;\r\n let effectWrapper: EffectWrapper | undefined;\r\n if (parameters && !Array.isArray(parameters)) {\r\n const options = parameters;\r\n parameters = options.uniforms ?? null;\r\n samplers = options.samplers ?? null;\r\n size = options.size ?? 1;\r\n camera = options.camera ?? null;\r\n samplingMode = options.samplingMode ?? Constants.TEXTURE_NEAREST_SAMPLINGMODE;\r\n engine = options.engine;\r\n reusable = options.reusable;\r\n defines = Array.isArray(options.defines) ? options.defines.join(\"\\n\") : (options.defines ?? null);\r\n textureType = options.textureType ?? Constants.TEXTURETYPE_UNSIGNED_BYTE;\r\n vertexUrl = options.vertexUrl ?? \"postprocess\";\r\n indexParameters = options.indexParameters;\r\n blockCompilation = options.blockCompilation ?? false;\r\n textureFormat = options.textureFormat ?? Constants.TEXTUREFORMAT_RGBA;\r\n shaderLanguage = options.shaderLanguage ?? ShaderLanguage.GLSL;\r\n uniformBuffers = options.uniformBuffers ?? null;\r\n extraInitializations = options.extraInitializations;\r\n effectWrapper = options.effectWrapper;\r\n } else if (_size) {\r\n if (typeof _size === \"number\") {\r\n size = _size;\r\n } else {\r\n size = { width: _size.width!, height: _size.height! };\r\n }\r\n }\r\n\r\n const useExistingThinPostProcess = !!effectWrapper;\r\n\r\n this._effectWrapper =\r\n effectWrapper ??\r\n new EffectWrapper({\r\n name,\r\n useShaderStore: true,\r\n useAsPostProcess: true,\r\n fragmentShader: fragmentUrl,\r\n engine: engine || camera?.getScene().getEngine(),\r\n uniforms: parameters,\r\n samplers,\r\n uniformBuffers,\r\n defines,\r\n vertexUrl,\r\n indexParameters,\r\n blockCompilation: true,\r\n shaderLanguage,\r\n extraInitializations: undefined,\r\n });\r\n\r\n this.name = name;\r\n this.onEffectCreatedObservable = this._effectWrapper.onEffectCreatedObservable;\r\n\r\n if (camera != null) {\r\n this._camera = camera;\r\n this._scene = camera.getScene();\r\n camera.attachPostProcess(this);\r\n this._engine = this._scene.getEngine();\r\n\r\n this._scene.postProcesses.push(this);\r\n this.uniqueId = this._scene.getUniqueId();\r\n } else if (engine) {\r\n this._engine = engine;\r\n this._engine.postProcesses.push(this);\r\n }\r\n\r\n this._options = size;\r\n this.renderTargetSamplingMode = samplingMode ? samplingMode : Constants.TEXTURE_NEAREST_SAMPLINGMODE;\r\n this._reusable = reusable || false;\r\n this._textureType = textureType;\r\n this._textureFormat = textureFormat;\r\n this._shaderLanguage = shaderLanguage || ShaderLanguage.GLSL;\r\n\r\n this._samplers = samplers || [];\r\n if (this._samplers.indexOf(\"textureSampler\") === -1) {\r\n this._samplers.push(\"textureSampler\");\r\n }\r\n\r\n this._fragmentUrl = fragmentUrl;\r\n this._vertexUrl = vertexUrl;\r\n this._parameters = parameters || [];\r\n\r\n if (this._parameters.indexOf(\"scale\") === -1) {\r\n this._parameters.push(\"scale\");\r\n }\r\n this._uniformBuffers = uniformBuffers || [];\r\n\r\n this._indexParameters = indexParameters;\r\n\r\n if (!useExistingThinPostProcess) {\r\n this._webGPUReady = this._shaderLanguage === ShaderLanguage.WGSL;\r\n\r\n const importPromises: Array> = [];\r\n\r\n this._gatherImports(this._engine.isWebGPU && !PostProcess.ForceGLSL, importPromises);\r\n\r\n this._effectWrapper._webGPUReady = this._webGPUReady;\r\n this._effectWrapper._postConstructor(blockCompilation, defines, extraInitializations, importPromises);\r\n }\r\n }\r\n\r\n protected _gatherImports(useWebGPU = false, list: Promise[]) {\r\n // this._webGPUReady is used to detect when a postprocess is intended to be used with WebGPU\r\n if (useWebGPU && this._webGPUReady) {\r\n list.push(Promise.all([import(\"../ShadersWGSL/postprocess.vertex\")]));\r\n } else {\r\n list.push(Promise.all([import(\"../Shaders/postprocess.vertex\")]));\r\n }\r\n }\r\n\r\n /**\r\n * Gets a string identifying the name of the class\r\n * @returns \"PostProcess\" string\r\n */\r\n public getClassName(): string {\r\n return \"PostProcess\";\r\n }\r\n\r\n /**\r\n * Gets the engine which this post process belongs to.\r\n * @returns The engine the post process was enabled with.\r\n */\r\n public getEngine(): AbstractEngine {\r\n return this._engine;\r\n }\r\n\r\n /**\r\n * The effect that is created when initializing the post process.\r\n * @returns The created effect corresponding to the postprocess.\r\n */\r\n public getEffect(): Effect {\r\n return this._effectWrapper.drawWrapper.effect!;\r\n }\r\n\r\n /**\r\n * To avoid multiple redundant textures for multiple post process, the output the output texture for this post process can be shared with another.\r\n * @param postProcess The post process to share the output with.\r\n * @returns This post process.\r\n */\r\n public shareOutputWith(postProcess: PostProcess): PostProcess {\r\n this._disposeTextures();\r\n\r\n this._shareOutputWithPostProcess = postProcess;\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Reverses the effect of calling shareOutputWith and returns the post process back to its original state.\r\n * This should be called if the post process that shares output with this post process is disabled/disposed.\r\n */\r\n public useOwnOutput() {\r\n if (this._textures.length == 0) {\r\n this._textures = new SmartArray(2);\r\n }\r\n\r\n this._shareOutputWithPostProcess = null;\r\n }\r\n\r\n /**\r\n * Updates the effect with the current post process compile time values and recompiles the shader.\r\n * @param defines Define statements that should be added at the beginning of the shader. (default: null)\r\n * @param uniforms Set of uniform variables that will be passed to the shader. (default: null)\r\n * @param samplers Set of Texture2D variables that will be passed to the shader. (default: null)\r\n * @param indexParameters The index parameters to be used for babylons include syntax \"#include[0..varyingCount]\". (default: undefined) See usage in babylon.blurPostProcess.ts and kernelBlur.vertex.fx\r\n * @param onCompiled Called when the shader has been compiled.\r\n * @param onError Called if there is an error when compiling a shader.\r\n * @param vertexUrl The url of the vertex shader to be used (default: the one given at construction time)\r\n * @param fragmentUrl The url of the fragment shader to be used (default: the one given at construction time)\r\n */\r\n public updateEffect(\r\n defines: Nullable = null,\r\n uniforms: Nullable = null,\r\n samplers: Nullable = null,\r\n indexParameters?: any,\r\n onCompiled?: (effect: Effect) => void,\r\n onError?: (effect: Effect, errors: string) => void,\r\n vertexUrl?: string,\r\n fragmentUrl?: string\r\n ) {\r\n this._effectWrapper.updateEffect(defines, uniforms, samplers, indexParameters, onCompiled, onError, vertexUrl, fragmentUrl);\r\n this._postProcessDefines = Array.isArray(this._effectWrapper.options.defines) ? this._effectWrapper.options.defines.join(\"\\n\") : this._effectWrapper.options.defines;\r\n }\r\n\r\n /**\r\n * The post process is reusable if it can be used multiple times within one frame.\r\n * @returns If the post process is reusable\r\n */\r\n public isReusable(): boolean {\r\n return this._reusable;\r\n }\r\n\r\n /** invalidate frameBuffer to hint the postprocess to create a depth buffer */\r\n public markTextureDirty(): void {\r\n this.width = -1;\r\n }\r\n\r\n private _createRenderTargetTexture(textureSize: { width: number; height: number }, textureOptions: RenderTargetCreationOptions, channel = 0) {\r\n for (let i = 0; i < this._textureCache.length; i++) {\r\n if (\r\n this._textureCache[i].texture.width === textureSize.width &&\r\n this._textureCache[i].texture.height === textureSize.height &&\r\n this._textureCache[i].postProcessChannel === channel &&\r\n this._textureCache[i].texture._generateDepthBuffer === textureOptions.generateDepthBuffer &&\r\n this._textureCache[i].texture.samples === textureOptions.samples\r\n ) {\r\n return this._textureCache[i].texture;\r\n }\r\n }\r\n\r\n const tex = this._engine.createRenderTargetTexture(textureSize, textureOptions);\r\n this._textureCache.push({ texture: tex, postProcessChannel: channel, lastUsedRenderId: -1 });\r\n\r\n return tex;\r\n }\r\n\r\n private _flushTextureCache() {\r\n const currentRenderId = this._renderId;\r\n\r\n for (let i = this._textureCache.length - 1; i >= 0; i--) {\r\n if (currentRenderId - this._textureCache[i].lastUsedRenderId > 100) {\r\n let currentlyUsed = false;\r\n for (let j = 0; j < this._textures.length; j++) {\r\n if (this._textures.data[j] === this._textureCache[i].texture) {\r\n currentlyUsed = true;\r\n break;\r\n }\r\n }\r\n\r\n if (!currentlyUsed) {\r\n this._textureCache[i].texture.dispose();\r\n this._textureCache.splice(i, 1);\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Resizes the post-process texture\r\n * @param width Width of the texture\r\n * @param height Height of the texture\r\n * @param camera The camera this post-process is applied to. Pass null if the post-process is used outside the context of a camera post-process chain (default: null)\r\n * @param needMipMaps True if mip maps need to be generated after render (default: false)\r\n * @param forceDepthStencil True to force post-process texture creation with stencil depth and buffer (default: false)\r\n */\r\n public resize(width: number, height: number, camera: Nullable = null, needMipMaps = false, forceDepthStencil = false) {\r\n if (this._textures.length > 0) {\r\n this._textures.reset();\r\n }\r\n\r\n this.width = width;\r\n this.height = height;\r\n\r\n let firstPP = null;\r\n if (camera) {\r\n for (let i = 0; i < camera._postProcesses.length; i++) {\r\n if (camera._postProcesses[i] !== null) {\r\n firstPP = camera._postProcesses[i];\r\n break;\r\n }\r\n }\r\n }\r\n\r\n const textureSize = { width: this.width, height: this.height };\r\n const textureOptions = {\r\n generateMipMaps: needMipMaps,\r\n generateDepthBuffer: forceDepthStencil || firstPP === this,\r\n generateStencilBuffer: (forceDepthStencil || firstPP === this) && this._engine.isStencilEnable,\r\n samplingMode: this.renderTargetSamplingMode,\r\n type: this._textureType,\r\n format: this._textureFormat,\r\n samples: this._samples,\r\n label: \"PostProcessRTT-\" + this.name,\r\n };\r\n\r\n this._textures.push(this._createRenderTargetTexture(textureSize, textureOptions, 0));\r\n\r\n if (this._reusable) {\r\n this._textures.push(this._createRenderTargetTexture(textureSize, textureOptions, 1));\r\n }\r\n\r\n this._texelSize.copyFromFloats(1.0 / this.width, 1.0 / this.height);\r\n\r\n this.onSizeChangedObservable.notifyObservers(this);\r\n }\r\n\r\n private _getTarget() {\r\n let target: RenderTargetWrapper;\r\n\r\n if (this._shareOutputWithPostProcess) {\r\n target = this._shareOutputWithPostProcess.inputTexture;\r\n } else if (this._forcedOutputTexture) {\r\n target = this._forcedOutputTexture;\r\n\r\n this.width = this._forcedOutputTexture.width;\r\n this.height = this._forcedOutputTexture.height;\r\n } else {\r\n target = this.inputTexture;\r\n\r\n let cache;\r\n for (let i = 0; i < this._textureCache.length; i++) {\r\n if (this._textureCache[i].texture === target) {\r\n cache = this._textureCache[i];\r\n break;\r\n }\r\n }\r\n\r\n if (cache) {\r\n cache.lastUsedRenderId = this._renderId;\r\n }\r\n }\r\n\r\n return target;\r\n }\r\n\r\n /**\r\n * Activates the post process by intializing the textures to be used when executed. Notifies onActivateObservable.\r\n * When this post process is used in a pipeline, this is call will bind the input texture of this post process to the output of the previous.\r\n * @param cameraOrScene The camera that will be used in the post process. This camera will be used when calling onActivateObservable. You can also pass the scene if no camera is available.\r\n * @param sourceTexture The source texture to be inspected to get the width and height if not specified in the post process constructor. (default: null)\r\n * @param forceDepthStencil If true, a depth and stencil buffer will be generated. (default: false)\r\n * @returns The render target wrapper that was bound to be written to.\r\n */\r\n public activate(cameraOrScene: Nullable | Scene, sourceTexture: Nullable = null, forceDepthStencil?: boolean): RenderTargetWrapper {\r\n const camera = cameraOrScene === null || (cameraOrScene as Camera).cameraRigMode !== undefined ? (cameraOrScene as Camera) || this._camera : null;\r\n\r\n const scene = camera?.getScene() ?? (cameraOrScene as Scene);\r\n const engine = scene.getEngine();\r\n const maxSize = engine.getCaps().maxTextureSize;\r\n\r\n const requiredWidth = ((sourceTexture ? sourceTexture.width : this._engine.getRenderWidth(true)) * this._options) | 0;\r\n const requiredHeight = ((sourceTexture ? sourceTexture.height : this._engine.getRenderHeight(true)) * this._options) | 0;\r\n\r\n let desiredWidth = (this._options).width || requiredWidth;\r\n let desiredHeight = (this._options).height || requiredHeight;\r\n\r\n const needMipMaps =\r\n this.renderTargetSamplingMode !== Constants.TEXTURE_NEAREST_LINEAR &&\r\n this.renderTargetSamplingMode !== Constants.TEXTURE_NEAREST_NEAREST &&\r\n this.renderTargetSamplingMode !== Constants.TEXTURE_LINEAR_LINEAR;\r\n\r\n let target: Nullable = null;\r\n\r\n if (!this._shareOutputWithPostProcess && !this._forcedOutputTexture) {\r\n if (this.adaptScaleToCurrentViewport) {\r\n const currentViewport = engine.currentViewport;\r\n\r\n if (currentViewport) {\r\n desiredWidth *= currentViewport.width;\r\n desiredHeight *= currentViewport.height;\r\n }\r\n }\r\n\r\n if (needMipMaps || this.alwaysForcePOT) {\r\n if (!(this._options).width) {\r\n desiredWidth = engine.needPOTTextures ? GetExponentOfTwo(desiredWidth, maxSize, this.scaleMode) : desiredWidth;\r\n }\r\n\r\n if (!(this._options).height) {\r\n desiredHeight = engine.needPOTTextures ? GetExponentOfTwo(desiredHeight, maxSize, this.scaleMode) : desiredHeight;\r\n }\r\n }\r\n\r\n if (this.width !== desiredWidth || this.height !== desiredHeight || !(target = this._getTarget())) {\r\n this.resize(desiredWidth, desiredHeight, camera, needMipMaps, forceDepthStencil);\r\n }\r\n\r\n this._textures.forEach((texture) => {\r\n if (texture.samples !== this.samples) {\r\n this._engine.updateRenderTargetTextureSampleCount(texture, this.samples);\r\n }\r\n });\r\n\r\n this._flushTextureCache();\r\n this._renderId++;\r\n }\r\n\r\n if (!target) {\r\n target = this._getTarget();\r\n }\r\n\r\n // Bind the input of this post process to be used as the output of the previous post process.\r\n if (this.enablePixelPerfectMode) {\r\n this._scaleRatio.copyFromFloats(requiredWidth / desiredWidth, requiredHeight / desiredHeight);\r\n this._engine.bindFramebuffer(target, 0, requiredWidth, requiredHeight, this.forceFullscreenViewport);\r\n } else {\r\n this._scaleRatio.copyFromFloats(1, 1);\r\n this._engine.bindFramebuffer(target, 0, undefined, undefined, this.forceFullscreenViewport);\r\n }\r\n\r\n this._engine._debugInsertMarker?.(`post process ${this.name} input`);\r\n\r\n this.onActivateObservable.notifyObservers(camera!);\r\n\r\n // Clear\r\n if (this.autoClear && (this.alphaMode === Constants.ALPHA_DISABLE || this.forceAutoClearInAlphaMode)) {\r\n this._engine.clear(this.clearColor ? this.clearColor : scene.clearColor, scene._allowPostProcessClearColor, true, true);\r\n }\r\n\r\n if (this._reusable) {\r\n this._currentRenderTextureInd = (this._currentRenderTextureInd + 1) % 2;\r\n }\r\n return target;\r\n }\r\n\r\n /**\r\n * If the post process is supported.\r\n */\r\n public get isSupported(): boolean {\r\n return this._effectWrapper.drawWrapper.effect!.isSupported;\r\n }\r\n\r\n /**\r\n * The aspect ratio of the output texture.\r\n */\r\n public get aspectRatio(): number {\r\n if (this._shareOutputWithPostProcess) {\r\n return this._shareOutputWithPostProcess.aspectRatio;\r\n }\r\n\r\n if (this._forcedOutputTexture) {\r\n return this._forcedOutputTexture.width / this._forcedOutputTexture.height;\r\n }\r\n return this.width / this.height;\r\n }\r\n\r\n /**\r\n * Get a value indicating if the post-process is ready to be used\r\n * @returns true if the post-process is ready (shader is compiled)\r\n */\r\n public isReady(): boolean {\r\n return this._effectWrapper.isReady();\r\n }\r\n\r\n /**\r\n * Binds all textures and uniforms to the shader, this will be run on every pass.\r\n * @returns the effect corresponding to this post process. Null if not compiled or not ready.\r\n */\r\n public apply(): Nullable {\r\n // Check\r\n if (!this._effectWrapper.isReady()) {\r\n return null;\r\n }\r\n\r\n // States\r\n this._engine.enableEffect(this._effectWrapper.drawWrapper);\r\n this._engine.setState(false);\r\n this._engine.setDepthBuffer(false);\r\n this._engine.setDepthWrite(false);\r\n\r\n // Alpha\r\n if (this.alphaConstants) {\r\n this.getEngine().setAlphaConstants(this.alphaConstants.r, this.alphaConstants.g, this.alphaConstants.b, this.alphaConstants.a);\r\n }\r\n\r\n // Bind the output texture of the preivous post process as the input to this post process.\r\n let source: RenderTargetWrapper;\r\n if (this._shareOutputWithPostProcess) {\r\n source = this._shareOutputWithPostProcess.inputTexture;\r\n } else if (this._forcedOutputTexture) {\r\n source = this._forcedOutputTexture;\r\n } else {\r\n source = this.inputTexture;\r\n }\r\n\r\n if (!this.externalTextureSamplerBinding) {\r\n this._effectWrapper.drawWrapper.effect!._bindTexture(\"textureSampler\", source?.texture);\r\n }\r\n\r\n // Parameters\r\n this._effectWrapper.drawWrapper.effect!.setVector2(\"scale\", this._scaleRatio);\r\n this.onApplyObservable.notifyObservers(this._effectWrapper.drawWrapper.effect!);\r\n\r\n this._effectWrapper.bind();\r\n\r\n return this._effectWrapper.drawWrapper.effect;\r\n }\r\n\r\n private _disposeTextures() {\r\n if (this._shareOutputWithPostProcess || this._forcedOutputTexture) {\r\n this._disposeTextureCache();\r\n return;\r\n }\r\n\r\n this._disposeTextureCache();\r\n this._textures.dispose();\r\n }\r\n\r\n private _disposeTextureCache() {\r\n for (let i = this._textureCache.length - 1; i >= 0; i--) {\r\n this._textureCache[i].texture.dispose();\r\n }\r\n\r\n this._textureCache.length = 0;\r\n }\r\n\r\n /**\r\n * Sets the required values to the prepass renderer.\r\n * @param prePassRenderer defines the prepass renderer to setup.\r\n * @returns true if the pre pass is needed.\r\n */\r\n public setPrePassRenderer(prePassRenderer: PrePassRenderer): boolean {\r\n if (this._prePassEffectConfiguration) {\r\n this._prePassEffectConfiguration = prePassRenderer.addEffectConfiguration(this._prePassEffectConfiguration);\r\n this._prePassEffectConfiguration.enabled = true;\r\n return true;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n /**\r\n * Disposes the post process.\r\n * @param camera The camera to dispose the post process on.\r\n */\r\n public dispose(camera?: Camera): void {\r\n camera = camera || this._camera;\r\n\r\n this._disposeTextures();\r\n\r\n let index;\r\n if (this._scene) {\r\n index = this._scene.postProcesses.indexOf(this);\r\n if (index !== -1) {\r\n this._scene.postProcesses.splice(index, 1);\r\n }\r\n }\r\n\r\n if (this._parentContainer) {\r\n const index = this._parentContainer.postProcesses.indexOf(this);\r\n if (index > -1) {\r\n this._parentContainer.postProcesses.splice(index, 1);\r\n }\r\n this._parentContainer = null;\r\n }\r\n\r\n index = this._engine.postProcesses.indexOf(this);\r\n if (index !== -1) {\r\n this._engine.postProcesses.splice(index, 1);\r\n }\r\n\r\n if (!camera) {\r\n return;\r\n }\r\n camera.detachPostProcess(this);\r\n\r\n index = camera._postProcesses.indexOf(this);\r\n if (index === 0 && camera._postProcesses.length > 0) {\r\n const firstPostProcess = this._camera._getFirstPostProcess();\r\n if (firstPostProcess) {\r\n firstPostProcess.markTextureDirty();\r\n }\r\n }\r\n\r\n this.onActivateObservable.clear();\r\n this.onAfterRenderObservable.clear();\r\n this.onApplyObservable.clear();\r\n this.onBeforeRenderObservable.clear();\r\n this.onSizeChangedObservable.clear();\r\n this.onEffectCreatedObservable.clear();\r\n }\r\n\r\n /**\r\n * Serializes the post process to a JSON object\r\n * @returns the JSON object\r\n */\r\n public serialize(): any {\r\n const serializationObject = SerializationHelper.Serialize(this);\r\n const camera = this.getCamera() || (this._scene && this._scene.activeCamera);\r\n serializationObject.customType = \"BABYLON.\" + this.getClassName();\r\n serializationObject.cameraId = camera ? camera.id : null;\r\n serializationObject.reusable = this._reusable;\r\n serializationObject.textureType = this._textureType;\r\n serializationObject.fragmentUrl = this._fragmentUrl;\r\n serializationObject.parameters = this._parameters;\r\n serializationObject.samplers = this._samplers;\r\n serializationObject.uniformBuffers = this._uniformBuffers;\r\n serializationObject.options = this._options;\r\n serializationObject.defines = this._postProcessDefines;\r\n serializationObject.textureFormat = this._textureFormat;\r\n serializationObject.vertexUrl = this._vertexUrl;\r\n serializationObject.indexParameters = this._indexParameters;\r\n\r\n return serializationObject;\r\n }\r\n\r\n /**\r\n * Clones this post process\r\n * @returns a new post process similar to this one\r\n */\r\n public clone(): Nullable {\r\n const serializationObject = this.serialize();\r\n serializationObject._engine = this._engine;\r\n serializationObject.cameraId = null;\r\n\r\n const result = PostProcess.Parse(serializationObject, this._scene, \"\");\r\n\r\n if (!result) {\r\n return null;\r\n }\r\n\r\n result.onActivateObservable = this.onActivateObservable.clone();\r\n result.onSizeChangedObservable = this.onSizeChangedObservable.clone();\r\n result.onApplyObservable = this.onApplyObservable.clone();\r\n result.onBeforeRenderObservable = this.onBeforeRenderObservable.clone();\r\n result.onAfterRenderObservable = this.onAfterRenderObservable.clone();\r\n\r\n result._prePassEffectConfiguration = this._prePassEffectConfiguration;\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Creates a material from parsed material data\r\n * @param parsedPostProcess defines parsed post process data\r\n * @param scene defines the hosting scene\r\n * @param rootUrl defines the root URL to use to load textures\r\n * @returns a new post process\r\n */\r\n public static Parse(parsedPostProcess: any, scene: Scene, rootUrl: string): Nullable {\r\n const postProcessType = GetClass(parsedPostProcess.customType);\r\n\r\n if (!postProcessType || !postProcessType._Parse) {\r\n return null;\r\n }\r\n\r\n const camera = scene ? scene.getCameraById(parsedPostProcess.cameraId) : null;\r\n return postProcessType._Parse(parsedPostProcess, camera, scene, rootUrl);\r\n }\r\n\r\n /**\r\n * @internal\r\n */\r\n public static _Parse(parsedPostProcess: any, targetCamera: Nullable, scene: Nullable, rootUrl: string): Nullable {\r\n return SerializationHelper.Parse(\r\n () => {\r\n return new PostProcess(\r\n parsedPostProcess.name,\r\n parsedPostProcess.fragmentUrl,\r\n parsedPostProcess.parameters,\r\n parsedPostProcess.samplers,\r\n parsedPostProcess.options,\r\n targetCamera,\r\n parsedPostProcess.renderTargetSamplingMode,\r\n parsedPostProcess._engine,\r\n parsedPostProcess.reusable,\r\n parsedPostProcess.defines,\r\n parsedPostProcess.textureType,\r\n parsedPostProcess.vertexUrl,\r\n parsedPostProcess.indexParameters,\r\n false,\r\n parsedPostProcess.textureFormat\r\n );\r\n },\r\n parsedPostProcess,\r\n scene,\r\n rootUrl\r\n );\r\n }\r\n}\r\n\r\nRegisterClass(\"BABYLON.PostProcess\", PostProcess);\r\n","import type { Nullable } from \"../types\";\r\nimport type { InternalTexture } from \"../Materials/Textures/internalTexture\";\r\nimport type { PostProcess } from \"./postProcess\";\r\nimport { VertexBuffer } from \"../Buffers/buffer\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport type { DataBuffer } from \"../Buffers/dataBuffer\";\r\nimport type { RenderTargetWrapper } from \"../Engines/renderTargetWrapper\";\r\nimport { Observable } from \"../Misc/observable\";\r\nimport type { Scene } from \"../scene\";\r\n\r\n/**\r\n * PostProcessManager is used to manage one or more post processes or post process pipelines\r\n * See https://doc.babylonjs.com/features/featuresDeepDive/postProcesses/usePostProcesses\r\n */\r\nexport class PostProcessManager {\r\n private _scene: Scene;\r\n private _indexBuffer: Nullable;\r\n private _vertexBuffers: { [key: string]: Nullable } = {};\r\n\r\n /**\r\n * Creates a new instance PostProcess\r\n * @param scene The scene that the post process is associated with.\r\n */\r\n constructor(scene: Scene) {\r\n this._scene = scene;\r\n }\r\n\r\n private _prepareBuffers(): void {\r\n if (this._vertexBuffers[VertexBuffer.PositionKind]) {\r\n return;\r\n }\r\n\r\n // VBO\r\n const vertices = [];\r\n vertices.push(1, 1);\r\n vertices.push(-1, 1);\r\n vertices.push(-1, -1);\r\n vertices.push(1, -1);\r\n\r\n this._vertexBuffers[VertexBuffer.PositionKind] = new VertexBuffer(this._scene.getEngine(), vertices, VertexBuffer.PositionKind, false, false, 2);\r\n\r\n this._buildIndexBuffer();\r\n }\r\n\r\n private _buildIndexBuffer(): void {\r\n // Indices\r\n const indices = [];\r\n indices.push(0);\r\n indices.push(1);\r\n indices.push(2);\r\n\r\n indices.push(0);\r\n indices.push(2);\r\n indices.push(3);\r\n\r\n this._indexBuffer = this._scene.getEngine().createIndexBuffer(indices);\r\n }\r\n\r\n public onBeforeRenderObservable = new Observable();\r\n\r\n /**\r\n * Rebuilds the vertex buffers of the manager.\r\n * @internal\r\n */\r\n public _rebuild(): void {\r\n const vb = this._vertexBuffers[VertexBuffer.PositionKind];\r\n\r\n if (!vb) {\r\n return;\r\n }\r\n vb._rebuild();\r\n this._buildIndexBuffer();\r\n }\r\n\r\n // Methods\r\n /**\r\n * Prepares a frame to be run through a post process.\r\n * @param sourceTexture The input texture to the post processes. (default: null)\r\n * @param postProcesses An array of post processes to be run. (default: null)\r\n * @returns True if the post processes were able to be run.\r\n * @internal\r\n */\r\n public _prepareFrame(sourceTexture: Nullable = null, postProcesses: Nullable = null): boolean {\r\n const camera = this._scene.activeCamera;\r\n if (!camera) {\r\n return false;\r\n }\r\n\r\n postProcesses = postProcesses || >camera._postProcesses.filter((pp) => {\r\n return pp != null;\r\n });\r\n\r\n if (!postProcesses || postProcesses.length === 0 || !this._scene.postProcessesEnabled) {\r\n return false;\r\n }\r\n\r\n postProcesses[0].activate(camera, sourceTexture, postProcesses !== null && postProcesses !== undefined);\r\n return true;\r\n }\r\n\r\n /**\r\n * Manually render a set of post processes to a texture.\r\n * Please note, the frame buffer won't be unbound after the call in case you have more render to do.\r\n * @param postProcesses An array of post processes to be run.\r\n * @param targetTexture The render target wrapper to render to.\r\n * @param forceFullscreenViewport force gl.viewport to be full screen eg. 0,0,textureWidth,textureHeight\r\n * @param faceIndex defines the face to render to if a cubemap is defined as the target\r\n * @param lodLevel defines which lod of the texture to render to\r\n * @param doNotBindFrambuffer If set to true, assumes that the framebuffer has been bound previously\r\n */\r\n public directRender(\r\n postProcesses: PostProcess[],\r\n targetTexture: Nullable = null,\r\n forceFullscreenViewport = false,\r\n faceIndex = 0,\r\n lodLevel = 0,\r\n doNotBindFrambuffer = false\r\n ): void {\r\n const engine = this._scene.getEngine();\r\n\r\n for (let index = 0; index < postProcesses.length; index++) {\r\n if (index < postProcesses.length - 1) {\r\n postProcesses[index + 1].activate(this._scene.activeCamera || this._scene, targetTexture?.texture);\r\n } else {\r\n if (targetTexture) {\r\n engine.bindFramebuffer(targetTexture, faceIndex, undefined, undefined, forceFullscreenViewport, lodLevel);\r\n } else if (!doNotBindFrambuffer) {\r\n engine.restoreDefaultFramebuffer();\r\n }\r\n engine._debugInsertMarker?.(`post process ${postProcesses[index].name} output`);\r\n }\r\n\r\n const pp = postProcesses[index];\r\n const effect = pp.apply();\r\n\r\n if (effect) {\r\n pp.onBeforeRenderObservable.notifyObservers(effect);\r\n\r\n // VBOs\r\n this._prepareBuffers();\r\n engine.bindBuffers(this._vertexBuffers, this._indexBuffer, effect);\r\n\r\n // Draw order\r\n engine.drawElementsType(Constants.MATERIAL_TriangleFillMode, 0, 6);\r\n\r\n pp.onAfterRenderObservable.notifyObservers(effect);\r\n }\r\n }\r\n\r\n // Restore depth buffer\r\n engine.setDepthBuffer(true);\r\n engine.setDepthWrite(true);\r\n }\r\n\r\n /**\r\n * Finalize the result of the output of the postprocesses.\r\n * @param doNotPresent If true the result will not be displayed to the screen.\r\n * @param targetTexture The render target wrapper to render to.\r\n * @param faceIndex The index of the face to bind the target texture to.\r\n * @param postProcesses The array of post processes to render.\r\n * @param forceFullscreenViewport force gl.viewport to be full screen eg. 0,0,textureWidth,textureHeight (default: false)\r\n * @internal\r\n */\r\n public _finalizeFrame(\r\n doNotPresent?: boolean,\r\n targetTexture?: RenderTargetWrapper,\r\n faceIndex?: number,\r\n postProcesses?: Array,\r\n forceFullscreenViewport = false\r\n ): void {\r\n const camera = this._scene.activeCamera;\r\n\r\n if (!camera) {\r\n return;\r\n }\r\n\r\n this.onBeforeRenderObservable.notifyObservers(this);\r\n\r\n postProcesses = postProcesses || >camera._postProcesses.filter((pp) => {\r\n return pp != null;\r\n });\r\n if (postProcesses.length === 0 || !this._scene.postProcessesEnabled) {\r\n return;\r\n }\r\n const engine = this._scene.getEngine();\r\n\r\n for (let index = 0, len = postProcesses.length; index < len; index++) {\r\n const pp = postProcesses[index];\r\n\r\n if (index < len - 1) {\r\n pp._outputTexture = postProcesses[index + 1].activate(camera, targetTexture?.texture);\r\n } else {\r\n if (targetTexture) {\r\n engine.bindFramebuffer(targetTexture, faceIndex, undefined, undefined, forceFullscreenViewport);\r\n pp._outputTexture = targetTexture;\r\n } else {\r\n engine.restoreDefaultFramebuffer();\r\n pp._outputTexture = null;\r\n }\r\n engine._debugInsertMarker?.(`post process ${postProcesses[index].name} output`);\r\n }\r\n\r\n if (doNotPresent) {\r\n break;\r\n }\r\n\r\n const effect = pp.apply();\r\n\r\n if (effect) {\r\n pp.onBeforeRenderObservable.notifyObservers(effect);\r\n\r\n // VBOs\r\n this._prepareBuffers();\r\n engine.bindBuffers(this._vertexBuffers, this._indexBuffer, effect);\r\n\r\n // Draw order\r\n engine.drawElementsType(Constants.MATERIAL_TriangleFillMode, 0, 6);\r\n\r\n pp.onAfterRenderObservable.notifyObservers(effect);\r\n }\r\n }\r\n\r\n // Restore states\r\n engine.setDepthBuffer(true);\r\n engine.setDepthWrite(true);\r\n engine.setAlphaMode(Constants.ALPHA_DISABLE);\r\n }\r\n\r\n /**\r\n * Disposes of the post process manager.\r\n */\r\n public dispose(): void {\r\n const buffer = this._vertexBuffers[VertexBuffer.PositionKind];\r\n if (buffer) {\r\n buffer.dispose();\r\n this._vertexBuffers[VertexBuffer.PositionKind] = null;\r\n }\r\n\r\n if (this._indexBuffer) {\r\n this._scene.getEngine()._releaseBuffer(this._indexBuffer);\r\n this._indexBuffer = null;\r\n }\r\n }\r\n}\r\n","import { SmartArray, SmartArrayNoDuplicate } from \"../Misc/smartArray\";\r\nimport type { SubMesh } from \"../Meshes/subMesh\";\r\nimport type { AbstractMesh } from \"../Meshes/abstractMesh\";\r\nimport type { Nullable, DeepImmutable } from \"../types\";\r\nimport { Vector3 } from \"../Maths/math.vector\";\r\nimport type { IParticleSystem } from \"../Particles/IParticleSystem\";\r\nimport type { IEdgesRenderer } from \"./edgesRenderer\";\r\nimport type { ISpriteManager } from \"../Sprites/spriteManager\";\r\nimport { Constants } from \"../Engines/constants\";\r\nimport type { Material } from \"../Materials/material\";\r\nimport type { Scene } from \"../scene\";\r\nimport type { Camera } from \"../Cameras/camera\";\r\n\r\n/**\r\n * This represents the object necessary to create a rendering group.\r\n * This is exclusively used and created by the rendering manager.\r\n * To modify the behavior, you use the available helpers in your scene or meshes.\r\n * @internal\r\n */\r\nexport class RenderingGroup {\r\n private static _ZeroVector: DeepImmutable = Vector3.Zero();\r\n private _scene: Scene;\r\n private _opaqueSubMeshes = new SmartArray(256);\r\n private _transparentSubMeshes = new SmartArray(256);\r\n private _alphaTestSubMeshes = new SmartArray(256);\r\n private _depthOnlySubMeshes = new SmartArray(256);\r\n private _particleSystems = new SmartArray(256);\r\n private _spriteManagers = new SmartArray(256);\r\n\r\n private _opaqueSortCompareFn: Nullable<(a: SubMesh, b: SubMesh) => number>;\r\n private _alphaTestSortCompareFn: Nullable<(a: SubMesh, b: SubMesh) => number>;\r\n private _transparentSortCompareFn: (a: SubMesh, b: SubMesh) => number;\r\n\r\n private _renderOpaque: (subMeshes: SmartArray) => void;\r\n private _renderAlphaTest: (subMeshes: SmartArray) => void;\r\n private _renderTransparent: (subMeshes: SmartArray) => void;\r\n\r\n /** @internal */\r\n public _empty = true;\r\n\r\n /** @internal */\r\n public _edgesRenderers = new SmartArrayNoDuplicate(16);\r\n\r\n public onBeforeTransparentRendering: () => void;\r\n\r\n /**\r\n * Set the opaque sort comparison function.\r\n * If null the sub meshes will be render in the order they were created\r\n */\r\n public set opaqueSortCompareFn(value: Nullable<(a: SubMesh, b: SubMesh) => number>) {\r\n if (value) {\r\n this._opaqueSortCompareFn = value;\r\n } else {\r\n this._opaqueSortCompareFn = RenderingGroup.PainterSortCompare;\r\n }\r\n this._renderOpaque = this._renderOpaqueSorted;\r\n }\r\n\r\n /**\r\n * Set the alpha test sort comparison function.\r\n * If null the sub meshes will be render in the order they were created\r\n */\r\n public set alphaTestSortCompareFn(value: Nullable<(a: SubMesh, b: SubMesh) => number>) {\r\n if (value) {\r\n this._alphaTestSortCompareFn = value;\r\n } else {\r\n this._alphaTestSortCompareFn = RenderingGroup.PainterSortCompare;\r\n }\r\n this._renderAlphaTest = this._renderAlphaTestSorted;\r\n }\r\n\r\n /**\r\n * Set the transparent sort comparison function.\r\n * If null the sub meshes will be render in the order they were created\r\n */\r\n public set transparentSortCompareFn(value: Nullable<(a: SubMesh, b: SubMesh) => number>) {\r\n if (value) {\r\n this._transparentSortCompareFn = value;\r\n } else {\r\n this._transparentSortCompareFn = RenderingGroup.defaultTransparentSortCompare;\r\n }\r\n this._renderTransparent = this._renderTransparentSorted;\r\n }\r\n\r\n /**\r\n * Creates a new rendering group.\r\n * @param index The rendering group index\r\n * @param scene\r\n * @param opaqueSortCompareFn The opaque sort comparison function. If null no order is applied\r\n * @param alphaTestSortCompareFn The alpha test sort comparison function. If null no order is applied\r\n * @param transparentSortCompareFn The transparent sort comparison function. If null back to front + alpha index sort is applied\r\n */\r\n constructor(\r\n public index: number,\r\n scene: Scene,\r\n opaqueSortCompareFn: Nullable<(a: SubMesh, b: SubMesh) => number> = null,\r\n alphaTestSortCompareFn: Nullable<(a: SubMesh, b: SubMesh) => number> = null,\r\n transparentSortCompareFn: Nullable<(a: SubMesh, b: SubMesh) => number> = null\r\n ) {\r\n this._scene = scene;\r\n\r\n this.opaqueSortCompareFn = opaqueSortCompareFn;\r\n this.alphaTestSortCompareFn = alphaTestSortCompareFn;\r\n this.transparentSortCompareFn = transparentSortCompareFn;\r\n }\r\n\r\n /**\r\n * Render all the sub meshes contained in the group.\r\n * @param customRenderFunction Used to override the default render behaviour of the group.\r\n * @param renderSprites\r\n * @param renderParticles\r\n * @param activeMeshes\r\n */\r\n public render(\r\n customRenderFunction: Nullable<\r\n (\r\n opaqueSubMeshes: SmartArray,\r\n transparentSubMeshes: SmartArray,\r\n alphaTestSubMeshes: SmartArray,\r\n depthOnlySubMeshes: SmartArray\r\n ) => void\r\n >,\r\n renderSprites: boolean,\r\n renderParticles: boolean,\r\n activeMeshes: Nullable\r\n ): void {\r\n if (customRenderFunction) {\r\n customRenderFunction(this._opaqueSubMeshes, this._alphaTestSubMeshes, this._transparentSubMeshes, this._depthOnlySubMeshes);\r\n return;\r\n }\r\n\r\n const engine = this._scene.getEngine();\r\n\r\n // Depth only\r\n if (this._depthOnlySubMeshes.length !== 0) {\r\n engine.setColorWrite(false);\r\n this._renderAlphaTest(this._depthOnlySubMeshes);\r\n engine.setColorWrite(true);\r\n }\r\n\r\n // Opaque\r\n if (this._opaqueSubMeshes.length !== 0) {\r\n this._renderOpaque(this._opaqueSubMeshes);\r\n }\r\n\r\n // Alpha test\r\n if (this._alphaTestSubMeshes.length !== 0) {\r\n this._renderAlphaTest(this._alphaTestSubMeshes);\r\n }\r\n\r\n const stencilState = engine.getStencilBuffer();\r\n engine.setStencilBuffer(false);\r\n\r\n // Sprites\r\n if (renderSprites) {\r\n this._renderSprites();\r\n }\r\n\r\n // Particles\r\n if (renderParticles) {\r\n this._renderParticles(activeMeshes);\r\n }\r\n\r\n if (this.onBeforeTransparentRendering) {\r\n this.onBeforeTransparentRendering();\r\n }\r\n\r\n // Transparent\r\n if (this._transparentSubMeshes.length !== 0 || this._scene.useOrderIndependentTransparency) {\r\n engine.setStencilBuffer(stencilState);\r\n if (this._scene.useOrderIndependentTransparency) {\r\n const excludedMeshes = this._scene.depthPeelingRenderer!.render(this._transparentSubMeshes);\r\n if (excludedMeshes.length) {\r\n // Render leftover meshes that could not be processed by depth peeling\r\n this._renderTransparent(excludedMeshes);\r\n }\r\n } else {\r\n this._renderTransparent(this._transparentSubMeshes);\r\n }\r\n engine.setAlphaMode(Constants.ALPHA_DISABLE);\r\n }\r\n\r\n // Set back stencil to false in case it changes before the edge renderer.\r\n engine.setStencilBuffer(false);\r\n\r\n // Edges\r\n if (this._edgesRenderers.length) {\r\n for (let edgesRendererIndex = 0; edgesRendererIndex < this._edgesRenderers.length; edgesRendererIndex++) {\r\n this._edgesRenderers.data[edgesRendererIndex].render();\r\n }\r\n\r\n engine.setAlphaMode(Constants.ALPHA_DISABLE);\r\n }\r\n\r\n // Restore Stencil state.\r\n engine.setStencilBuffer(stencilState);\r\n }\r\n\r\n /**\r\n * Renders the opaque submeshes in the order from the opaqueSortCompareFn.\r\n * @param subMeshes The submeshes to render\r\n */\r\n private _renderOpaqueSorted(subMeshes: SmartArray): void {\r\n RenderingGroup._RenderSorted(subMeshes, this._opaqueSortCompareFn, this._scene.activeCamera, false);\r\n }\r\n\r\n /**\r\n * Renders the opaque submeshes in the order from the alphatestSortCompareFn.\r\n * @param subMeshes The submeshes to render\r\n */\r\n private _renderAlphaTestSorted(subMeshes: SmartArray): void {\r\n RenderingGroup._RenderSorted(subMeshes, this._alphaTestSortCompareFn, this._scene.activeCamera, false);\r\n }\r\n\r\n /**\r\n * Renders the opaque submeshes in the order from the transparentSortCompareFn.\r\n * @param subMeshes The submeshes to render\r\n */\r\n private _renderTransparentSorted(subMeshes: SmartArray): void {\r\n RenderingGroup._RenderSorted(subMeshes, this._transparentSortCompareFn, this._scene.activeCamera, true);\r\n }\r\n\r\n /**\r\n * Renders the submeshes in a specified order.\r\n * @param subMeshes The submeshes to sort before render\r\n * @param sortCompareFn The comparison function use to sort\r\n * @param camera The camera position use to preprocess the submeshes to help sorting\r\n * @param transparent Specifies to activate blending if true\r\n */\r\n private static _RenderSorted(\r\n subMeshes: SmartArray,\r\n sortCompareFn: Nullable<(a: SubMesh, b: SubMesh) => number>,\r\n camera: Nullable,\r\n transparent: boolean\r\n ): void {\r\n let subIndex = 0;\r\n let subMesh: SubMesh;\r\n const cameraPosition = camera ? camera.globalPosition : RenderingGroup._ZeroVector;\r\n\r\n if (transparent) {\r\n for (; subIndex < subMeshes.length; subIndex++) {\r\n subMesh = subMeshes.data[subIndex];\r\n subMesh._alphaIndex = subMesh.getMesh().alphaIndex;\r\n subMesh._distanceToCamera = Vector3.Distance(subMesh.getBoundingInfo().boundingSphere.centerWorld, cameraPosition);\r\n }\r\n }\r\n\r\n const sortedArray = subMeshes.length === subMeshes.data.length ? subMeshes.data : subMeshes.data.slice(0, subMeshes.length);\r\n\r\n if (sortCompareFn) {\r\n sortedArray.sort(sortCompareFn);\r\n }\r\n\r\n const scene = sortedArray[0].getMesh().getScene();\r\n for (subIndex = 0; subIndex < sortedArray.length; subIndex++) {\r\n subMesh = sortedArray[subIndex];\r\n\r\n if (scene._activeMeshesFrozenButKeepClipping && !subMesh.isInFrustum(scene._frustumPlanes)) {\r\n continue;\r\n }\r\n\r\n if (transparent) {\r\n const material = subMesh.getMaterial();\r\n\r\n if (material && material.needDepthPrePass) {\r\n const engine = material.getScene().getEngine();\r\n engine.setColorWrite(false);\r\n engine.setAlphaMode(Constants.ALPHA_DISABLE);\r\n subMesh.render(false);\r\n engine.setColorWrite(true);\r\n }\r\n }\r\n\r\n subMesh.render(transparent);\r\n }\r\n }\r\n\r\n /**\r\n * Build in function which can be applied to ensure meshes of a special queue (opaque, alpha test, transparent)\r\n * are rendered back to front if in the same alpha index.\r\n *\r\n * @param a The first submesh\r\n * @param b The second submesh\r\n * @returns The result of the comparison\r\n */\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n public static defaultTransparentSortCompare(a: SubMesh, b: SubMesh): number {\r\n // Alpha index first\r\n if (a._alphaIndex > b._alphaIndex) {\r\n return 1;\r\n }\r\n if (a._alphaIndex < b._alphaIndex) {\r\n return -1;\r\n }\r\n\r\n // Then distance to camera\r\n return RenderingGroup.backToFrontSortCompare(a, b);\r\n }\r\n\r\n /**\r\n * Build in function which can be applied to ensure meshes of a special queue (opaque, alpha test, transparent)\r\n * are rendered back to front.\r\n *\r\n * @param a The first submesh\r\n * @param b The second submesh\r\n * @returns The result of the comparison\r\n */\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n public static backToFrontSortCompare(a: SubMesh, b: SubMesh): number {\r\n // Then distance to camera\r\n if (a._distanceToCamera < b._distanceToCamera) {\r\n return 1;\r\n }\r\n if (a._distanceToCamera > b._distanceToCamera) {\r\n return -1;\r\n }\r\n\r\n return 0;\r\n }\r\n\r\n /**\r\n * Build in function which can be applied to ensure meshes of a special queue (opaque, alpha test, transparent)\r\n * are rendered front to back (prevent overdraw).\r\n *\r\n * @param a The first submesh\r\n * @param b The second submesh\r\n * @returns The result of the comparison\r\n */\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n public static frontToBackSortCompare(a: SubMesh, b: SubMesh): number {\r\n // Then distance to camera\r\n if (a._distanceToCamera < b._distanceToCamera) {\r\n return -1;\r\n }\r\n if (a._distanceToCamera > b._distanceToCamera) {\r\n return 1;\r\n }\r\n\r\n return 0;\r\n }\r\n\r\n /**\r\n * Build in function which can be applied to ensure meshes of a special queue (opaque, alpha test, transparent)\r\n * are grouped by material then geometry.\r\n *\r\n * @param a The first submesh\r\n * @param b The second submesh\r\n * @returns The result of the comparison\r\n */\r\n public static PainterSortCompare(a: SubMesh, b: SubMesh): number {\r\n const meshA = a.getMesh();\r\n const meshB = b.getMesh();\r\n\r\n if (meshA.material && meshB.material) {\r\n return meshA.material.uniqueId - meshB.material.uniqueId;\r\n }\r\n\r\n return meshA.uniqueId - meshB.uniqueId;\r\n }\r\n\r\n /**\r\n * Resets the different lists of submeshes to prepare a new frame.\r\n */\r\n public prepare(): void {\r\n this._opaqueSubMeshes.reset();\r\n this._transparentSubMeshes.reset();\r\n this._alphaTestSubMeshes.reset();\r\n this._depthOnlySubMeshes.reset();\r\n this._particleSystems.reset();\r\n this.prepareSprites();\r\n this._edgesRenderers.reset();\r\n this._empty = true;\r\n }\r\n\r\n /**\r\n * Resets the different lists of sprites to prepare a new frame.\r\n */\r\n public prepareSprites(): void {\r\n this._spriteManagers.reset();\r\n }\r\n\r\n public dispose(): void {\r\n this._opaqueSubMeshes.dispose();\r\n this._transparentSubMeshes.dispose();\r\n this._alphaTestSubMeshes.dispose();\r\n this._depthOnlySubMeshes.dispose();\r\n this._particleSystems.dispose();\r\n this._spriteManagers.dispose();\r\n this._edgesRenderers.dispose();\r\n }\r\n\r\n /**\r\n * Inserts the submesh in its correct queue depending on its material.\r\n * @param subMesh The submesh to dispatch\r\n * @param [mesh] Optional reference to the submeshes's mesh. Provide if you have an exiting reference to improve performance.\r\n * @param [material] Optional reference to the submeshes's material. Provide if you have an exiting reference to improve performance.\r\n */\r\n public dispatch(subMesh: SubMesh, mesh?: AbstractMesh, material?: Nullable): void {\r\n // Get mesh and materials if not provided\r\n if (mesh === undefined) {\r\n mesh = subMesh.getMesh();\r\n }\r\n if (material === undefined) {\r\n material = subMesh.getMaterial();\r\n }\r\n\r\n if (material === null || material === undefined) {\r\n return;\r\n }\r\n\r\n if (material.needAlphaBlendingForMesh(mesh)) {\r\n // Transparent\r\n this._transparentSubMeshes.push(subMesh);\r\n } else if (material.needAlphaTesting()) {\r\n // Alpha test\r\n if (material.needDepthPrePass) {\r\n this._depthOnlySubMeshes.push(subMesh);\r\n }\r\n\r\n this._alphaTestSubMeshes.push(subMesh);\r\n } else {\r\n if (material.needDepthPrePass) {\r\n this._depthOnlySubMeshes.push(subMesh);\r\n }\r\n\r\n this._opaqueSubMeshes.push(subMesh); // Opaque\r\n }\r\n\r\n mesh._renderingGroup = this;\r\n\r\n if (mesh._edgesRenderer && mesh.isEnabled() && mesh.isVisible && mesh._edgesRenderer.isEnabled) {\r\n this._edgesRenderers.pushNoDuplicate(mesh._edgesRenderer);\r\n }\r\n\r\n this._empty = false;\r\n }\r\n\r\n public dispatchSprites(spriteManager: ISpriteManager) {\r\n this._spriteManagers.push(spriteManager);\r\n this._empty = false;\r\n }\r\n\r\n public dispatchParticles(particleSystem: IParticleSystem) {\r\n this._particleSystems.push(particleSystem);\r\n this._empty = false;\r\n }\r\n\r\n private _renderParticles(activeMeshes: Nullable): void {\r\n if (this._particleSystems.length === 0) {\r\n return;\r\n }\r\n\r\n // Particles\r\n const activeCamera = this._scene.activeCamera;\r\n this._scene.onBeforeParticlesRenderingObservable.notifyObservers(this._scene);\r\n for (let particleIndex = 0; particleIndex < this._particleSystems.length; particleIndex++) {\r\n const particleSystem = this._particleSystems.data[particleIndex];\r\n\r\n if ((activeCamera && activeCamera.layerMask & particleSystem.layerMask) === 0) {\r\n continue;\r\n }\r\n\r\n const emitter: any = particleSystem.emitter;\r\n if (!emitter.position || !activeMeshes || activeMeshes.indexOf(emitter) !== -1) {\r\n this._scene._activeParticles.addCount(particleSystem.render(), false);\r\n }\r\n }\r\n this._scene.onAfterParticlesRenderingObservable.notifyObservers(this._scene);\r\n }\r\n\r\n private _renderSprites(): void {\r\n if (!this._scene.spritesEnabled || this._spriteManagers.length === 0) {\r\n return;\r\n }\r\n\r\n // Sprites\r\n const activeCamera = this._scene.activeCamera;\r\n this._scene.onBeforeSpritesRenderingObservable.notifyObservers(this._scene);\r\n for (let id = 0; id < this._spriteManagers.length; id++) {\r\n const spriteManager = this._spriteManagers.data[id];\r\n\r\n if ((activeCamera && activeCamera.layerMask & spriteManager.layerMask) !== 0) {\r\n spriteManager.render();\r\n }\r\n }\r\n this._scene.onAfterSpritesRenderingObservable.notifyObservers(this._scene);\r\n }\r\n}\r\n","import type { Nullable } from \"../types\";\r\nimport type { SmartArray } from \"../Misc/smartArray\";\r\nimport type { ISpriteManager } from \"../Sprites/spriteManager\";\r\nimport type { IParticleSystem } from \"../Particles/IParticleSystem\";\r\nimport { RenderingGroup } from \"./renderingGroup\";\r\n\r\nimport type { Scene } from \"../scene\";\r\nimport type { Camera } from \"../Cameras/camera\";\r\nimport type { Material } from \"../Materials/material\";\r\nimport type { SubMesh } from \"../Meshes/subMesh\";\r\nimport type { AbstractMesh } from \"../Meshes/abstractMesh\";\r\n\r\n/**\r\n * Interface describing the different options available in the rendering manager\r\n * regarding Auto Clear between groups.\r\n */\r\nexport interface IRenderingManagerAutoClearSetup {\r\n /**\r\n * Defines whether or not autoclear is enable.\r\n */\r\n autoClear: boolean;\r\n /**\r\n * Defines whether or not to autoclear the depth buffer.\r\n */\r\n depth: boolean;\r\n /**\r\n * Defines whether or not to autoclear the stencil buffer.\r\n */\r\n stencil: boolean;\r\n}\r\n\r\n/**\r\n * This class is used by the onRenderingGroupObservable\r\n */\r\nexport class RenderingGroupInfo {\r\n /**\r\n * The Scene that being rendered\r\n */\r\n scene: Scene;\r\n\r\n /**\r\n * The camera currently used for the rendering pass\r\n */\r\n camera: Nullable;\r\n\r\n /**\r\n * The ID of the renderingGroup being processed\r\n */\r\n renderingGroupId: number;\r\n\r\n /**\r\n * The rendering manager\r\n */\r\n renderingManager: RenderingManager;\r\n}\r\n\r\n/**\r\n * This is the manager responsible of all the rendering for meshes sprites and particles.\r\n * It is enable to manage the different groups as well as the different necessary sort functions.\r\n * This should not be used directly aside of the few static configurations\r\n */\r\nexport class RenderingManager {\r\n /**\r\n * The max id used for rendering groups (not included)\r\n */\r\n public static MAX_RENDERINGGROUPS = 4;\r\n\r\n /**\r\n * The min id used for rendering groups (included)\r\n */\r\n public static MIN_RENDERINGGROUPS = 0;\r\n\r\n /**\r\n * Used to globally prevent autoclearing scenes.\r\n */\r\n public static AUTOCLEAR = true;\r\n\r\n /**\r\n * @internal\r\n */\r\n public _useSceneAutoClearSetup = false;\r\n\r\n private _scene: Scene;\r\n private _renderingGroups = new Array();\r\n private _depthStencilBufferAlreadyCleaned: boolean;\r\n\r\n private _autoClearDepthStencil: { [id: number]: IRenderingManagerAutoClearSetup } = {};\r\n private _customOpaqueSortCompareFn: { [id: number]: Nullable<(a: SubMesh, b: SubMesh) => number> } = {};\r\n private _customAlphaTestSortCompareFn: { [id: number]: Nullable<(a: SubMesh, b: SubMesh) => number> } = {};\r\n private _customTransparentSortCompareFn: { [id: number]: Nullable<(a: SubMesh, b: SubMesh) => number> } = {};\r\n private _renderingGroupInfo: Nullable = new RenderingGroupInfo();\r\n\r\n private _maintainStateBetweenFrames = false;\r\n /**\r\n * Gets or sets a boolean indicating that the manager will not reset between frames.\r\n * This means that if a mesh becomes invisible or transparent it will not be visible until this boolean is set to false again.\r\n * By default, the rendering manager will dispatch all active meshes per frame (moving them to the transparent, opaque or alpha testing lists).\r\n * By turning this property on, you will accelerate the rendering by keeping all these lists unchanged between frames.\r\n */\r\n public get maintainStateBetweenFrames() {\r\n return this._maintainStateBetweenFrames;\r\n }\r\n\r\n public set maintainStateBetweenFrames(value: boolean) {\r\n if (value === this._maintainStateBetweenFrames) {\r\n return;\r\n }\r\n\r\n this._maintainStateBetweenFrames = value;\r\n if (!this._maintainStateBetweenFrames) {\r\n this.restoreDispachedFlags();\r\n }\r\n }\r\n\r\n /**\r\n * Restore wasDispatched flags on the lists of elements to render.\r\n */\r\n public restoreDispachedFlags() {\r\n for (const mesh of this._scene.meshes) {\r\n if (mesh.subMeshes) {\r\n for (const subMesh of mesh.subMeshes) {\r\n subMesh._wasDispatched = false;\r\n }\r\n }\r\n }\r\n\r\n if (this._scene.spriteManagers) {\r\n for (const spriteManager of this._scene.spriteManagers) {\r\n spriteManager._wasDispatched = false;\r\n }\r\n }\r\n\r\n for (const particleSystem of this._scene.particleSystems) {\r\n particleSystem._wasDispatched = false;\r\n }\r\n }\r\n\r\n /**\r\n * Instantiates a new rendering group for a particular scene\r\n * @param scene Defines the scene the groups belongs to\r\n */\r\n constructor(scene: Scene) {\r\n this._scene = scene;\r\n\r\n for (let i = RenderingManager.MIN_RENDERINGGROUPS; i < RenderingManager.MAX_RENDERINGGROUPS; i++) {\r\n this._autoClearDepthStencil[i] = { autoClear: true, depth: true, stencil: true };\r\n }\r\n }\r\n\r\n /**\r\n * @returns the rendering group with the specified id.\r\n * @param id the id of the rendering group (0 by default)\r\n */\r\n public getRenderingGroup(id: number): RenderingGroup {\r\n const renderingGroupId = id || 0;\r\n\r\n this._prepareRenderingGroup(renderingGroupId);\r\n\r\n return this._renderingGroups[renderingGroupId];\r\n }\r\n\r\n private _clearDepthStencilBuffer(depth = true, stencil = true): void {\r\n if (this._depthStencilBufferAlreadyCleaned) {\r\n return;\r\n }\r\n\r\n this._scene.getEngine().clear(null, false, depth, stencil);\r\n this._depthStencilBufferAlreadyCleaned = true;\r\n }\r\n\r\n /**\r\n * Renders the entire managed groups. This is used by the scene or the different render targets.\r\n * @internal\r\n */\r\n public render(\r\n customRenderFunction: Nullable<\r\n (\r\n opaqueSubMeshes: SmartArray,\r\n transparentSubMeshes: SmartArray,\r\n alphaTestSubMeshes: SmartArray,\r\n depthOnlySubMeshes: SmartArray\r\n ) => void\r\n >,\r\n activeMeshes: Nullable,\r\n renderParticles: boolean,\r\n renderSprites: boolean\r\n ): void {\r\n // Update the observable context (not null as it only goes away on dispose)\r\n const info = this._renderingGroupInfo!;\r\n info.scene = this._scene;\r\n info.camera = this._scene.activeCamera;\r\n info.renderingManager = this;\r\n\r\n // Dispatch sprites\r\n if (this._scene.spriteManagers && renderSprites) {\r\n for (let index = 0; index < this._scene.spriteManagers.length; index++) {\r\n const manager = this._scene.spriteManagers[index];\r\n this.dispatchSprites(manager);\r\n }\r\n }\r\n\r\n // Render\r\n for (let index = RenderingManager.MIN_RENDERINGGROUPS; index < RenderingManager.MAX_RENDERINGGROUPS; index++) {\r\n this._depthStencilBufferAlreadyCleaned = index === RenderingManager.MIN_RENDERINGGROUPS;\r\n const renderingGroup = this._renderingGroups[index];\r\n if (!renderingGroup || renderingGroup._empty) {\r\n continue;\r\n }\r\n\r\n const renderingGroupMask = 1 << index;\r\n info.renderingGroupId = index;\r\n\r\n // Before Observable\r\n this._scene.onBeforeRenderingGroupObservable.notifyObservers(info, renderingGroupMask);\r\n\r\n // Clear depth/stencil if needed\r\n if (RenderingManager.AUTOCLEAR) {\r\n const autoClear = this._useSceneAutoClearSetup ? this._scene.getAutoClearDepthStencilSetup(index) : this._autoClearDepthStencil[index];\r\n\r\n if (autoClear && autoClear.autoClear) {\r\n this._clearDepthStencilBuffer(autoClear.depth, autoClear.stencil);\r\n }\r\n }\r\n\r\n // Render\r\n for (const step of this._scene._beforeRenderingGroupDrawStage) {\r\n step.action(index);\r\n }\r\n renderingGroup.render(customRenderFunction, renderSprites, renderParticles, activeMeshes);\r\n for (const step of this._scene._afterRenderingGroupDrawStage) {\r\n step.action(index);\r\n }\r\n\r\n // After Observable\r\n this._scene.onAfterRenderingGroupObservable.notifyObservers(info, renderingGroupMask);\r\n }\r\n }\r\n\r\n /**\r\n * Resets the different information of the group to prepare a new frame\r\n * @internal\r\n */\r\n public reset(): void {\r\n if (this.maintainStateBetweenFrames) {\r\n return;\r\n }\r\n\r\n for (let index = RenderingManager.MIN_RENDERINGGROUPS; index < RenderingManager.MAX_RENDERINGGROUPS; index++) {\r\n const renderingGroup = this._renderingGroups[index];\r\n if (renderingGroup) {\r\n renderingGroup.prepare();\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Resets the sprites information of the group to prepare a new frame\r\n * @internal\r\n */\r\n public resetSprites(): void {\r\n if (this.maintainStateBetweenFrames) {\r\n return;\r\n }\r\n\r\n for (let index = RenderingManager.MIN_RENDERINGGROUPS; index < RenderingManager.MAX_RENDERINGGROUPS; index++) {\r\n const renderingGroup = this._renderingGroups[index];\r\n if (renderingGroup) {\r\n renderingGroup.prepareSprites();\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Dispose and release the group and its associated resources.\r\n * @internal\r\n */\r\n public dispose(): void {\r\n this.freeRenderingGroups();\r\n this._renderingGroups.length = 0;\r\n this._renderingGroupInfo = null;\r\n }\r\n\r\n /**\r\n * Clear the info related to rendering groups preventing retention points during dispose.\r\n */\r\n public freeRenderingGroups(): void {\r\n for (let index = RenderingManager.MIN_RENDERINGGROUPS; index < RenderingManager.MAX_RENDERINGGROUPS; index++) {\r\n const renderingGroup = this._renderingGroups[index];\r\n if (renderingGroup) {\r\n renderingGroup.dispose();\r\n }\r\n }\r\n }\r\n\r\n private _prepareRenderingGroup(renderingGroupId: number): void {\r\n if (this._renderingGroups[renderingGroupId] === undefined) {\r\n this._renderingGroups[renderingGroupId] = new RenderingGroup(\r\n renderingGroupId,\r\n this._scene,\r\n this._customOpaqueSortCompareFn[renderingGroupId],\r\n this._customAlphaTestSortCompareFn[renderingGroupId],\r\n this._customTransparentSortCompareFn[renderingGroupId]\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Add a sprite manager to the rendering manager in order to render it this frame.\r\n * @param spriteManager Define the sprite manager to render\r\n */\r\n public dispatchSprites(spriteManager: ISpriteManager) {\r\n if (this.maintainStateBetweenFrames && spriteManager._wasDispatched) {\r\n return;\r\n }\r\n spriteManager._wasDispatched = true;\r\n this.getRenderingGroup(spriteManager.renderingGroupId).dispatchSprites(spriteManager);\r\n }\r\n\r\n /**\r\n * Add a particle system to the rendering manager in order to render it this frame.\r\n * @param particleSystem Define the particle system to render\r\n */\r\n public dispatchParticles(particleSystem: IParticleSystem) {\r\n if (this.maintainStateBetweenFrames && particleSystem._wasDispatched) {\r\n return;\r\n }\r\n particleSystem._wasDispatched = true;\r\n this.getRenderingGroup(particleSystem.renderingGroupId).dispatchParticles(particleSystem);\r\n }\r\n\r\n /**\r\n * Add a submesh to the manager in order to render it this frame\r\n * @param subMesh The submesh to dispatch\r\n * @param mesh Optional reference to the submeshes's mesh. Provide if you have an exiting reference to improve performance.\r\n * @param material Optional reference to the submeshes's material. Provide if you have an exiting reference to improve performance.\r\n */\r\n public dispatch(subMesh: SubMesh, mesh?: AbstractMesh, material?: Nullable): void {\r\n if (mesh === undefined) {\r\n mesh = subMesh.getMesh();\r\n }\r\n if (this.maintainStateBetweenFrames && subMesh._wasDispatched) {\r\n return;\r\n }\r\n subMesh._wasDispatched = true;\r\n this.getRenderingGroup(mesh.renderingGroupId).dispatch(subMesh, mesh, material);\r\n }\r\n\r\n /**\r\n * Overrides the default sort function applied in the rendering group to prepare the meshes.\r\n * This allowed control for front to back rendering or reversely depending of the special needs.\r\n *\r\n * @param renderingGroupId The rendering group id corresponding to its index\r\n * @param opaqueSortCompareFn The opaque queue comparison function use to sort.\r\n * @param alphaTestSortCompareFn The alpha test queue comparison function use to sort.\r\n * @param transparentSortCompareFn The transparent queue comparison function use to sort.\r\n */\r\n public setRenderingOrder(\r\n renderingGroupId: number,\r\n opaqueSortCompareFn: Nullable<(a: SubMesh, b: SubMesh) => number> = null,\r\n alphaTestSortCompareFn: Nullable<(a: SubMesh, b: SubMesh) => number> = null,\r\n transparentSortCompareFn: Nullable<(a: SubMesh, b: SubMesh) => number> = null\r\n ) {\r\n this._customOpaqueSortCompareFn[renderingGroupId] = opaqueSortCompareFn;\r\n this._customAlphaTestSortCompareFn[renderingGroupId] = alphaTestSortCompareFn;\r\n this._customTransparentSortCompareFn[renderingGroupId] = transparentSortCompareFn;\r\n\r\n if (this._renderingGroups[renderingGroupId]) {\r\n const group = this._renderingGroups[renderingGroupId];\r\n group.opaqueSortCompareFn = this._customOpaqueSortCompareFn[renderingGroupId];\r\n group.alphaTestSortCompareFn = this._customAlphaTestSortCompareFn[renderingGroupId];\r\n group.transparentSortCompareFn = this._customTransparentSortCompareFn[renderingGroupId];\r\n }\r\n }\r\n\r\n /**\r\n * Specifies whether or not the stencil and depth buffer are cleared between two rendering groups.\r\n *\r\n * @param renderingGroupId The rendering group id corresponding to its index\r\n * @param autoClearDepthStencil Automatically clears depth and stencil between groups if true.\r\n * @param depth Automatically clears depth between groups if true and autoClear is true.\r\n * @param stencil Automatically clears stencil between groups if true and autoClear is true.\r\n */\r\n public setRenderingAutoClearDepthStencil(renderingGroupId: number, autoClearDepthStencil: boolean, depth = true, stencil = true): void {\r\n this._autoClearDepthStencil[renderingGroupId] = {\r\n autoClear: autoClearDepthStencil,\r\n depth: depth,\r\n stencil: stencil,\r\n };\r\n }\r\n\r\n /**\r\n * Gets the current auto clear configuration for one rendering group of the rendering\r\n * manager.\r\n * @param index the rendering group index to get the information for\r\n * @returns The auto clear setup for the requested rendering group\r\n */\r\n public getAutoClearDepthStencilSetup(index: number): IRenderingManagerAutoClearSetup {\r\n return this._autoClearDepthStencil[index];\r\n }\r\n}\r\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\n\nconst name = \"helperFunctions\";\nconst shader = `const PI: f32=3.1415926535897932384626433832795;const TWO_PI: f32=6.283185307179586;const HALF_PI: f32=1.5707963267948966;const RECIPROCAL_PI: f32=0.3183098861837907;const RECIPROCAL_PI2: f32=0.15915494309189535;const RECIPROCAL_PI4: f32=0.07957747154594767;const HALF_MIN: f32=5.96046448e-08; \nconst LinearEncodePowerApprox: f32=2.2;const GammaEncodePowerApprox: f32=1.0/LinearEncodePowerApprox;const LuminanceEncodeApprox: vec3f=vec3f(0.2126,0.7152,0.0722);const Epsilon:f32=0.0000001;fn square(x: f32)->f32 {return x*x;}\nfn saturate(x: f32)->f32 {return clamp(x,0.0,1.0);}\nfn saturateVec3(x: vec3f)->vec3f {return clamp(x,vec3f(),vec3f(1.0));}\nfn saturateEps(x: f32)->f32 {return clamp(x,Epsilon,1.0);}\nfn maxEps(x: f32)->f32 {return max(x,Epsilon);}\nfn maxEpsVec3(x: vec3f)->vec3f {return max(x,vec3f(Epsilon));}\nfn absEps(x: f32)->f32 {return abs(x)+Epsilon;}\nfn transposeMat3(inMatrix: mat3x3f)->mat3x3f {let i0: vec3f=inMatrix[0];let i1: vec3f=inMatrix[1];let i2: vec3f=inMatrix[2];let outMatrix:mat3x3f=mat3x3f(\nvec3(i0.x,i1.x,i2.x),\nvec3(i0.y,i1.y,i2.y),\nvec3(i0.z,i1.z,i2.z)\n);return outMatrix;}\nfn inverseMat3(inMatrix: mat3x3f)->mat3x3f {let a00: f32=inMatrix[0][0];let a01: f32=inMatrix[0][1];let a02: f32=inMatrix[0][2];let a10: f32=inMatrix[1][0];let a11: f32=inMatrix[1][1];let a12: f32=inMatrix[1][2];let a20: f32=inMatrix[2][0];let a21: f32=inMatrix[2][1];let a22: f32=inMatrix[2][2];let b01: f32=a22*a11-a12*a21;let b11: f32=-a22*a10+a12*a20;let b21: f32=a21*a10-a11*a20;let det: f32=a00*b01+a01*b11+a02*b21;return mat3x3f(b01/det,(-a22*a01+a02*a21)/det,(a12*a01-a02*a11)/det,\nb11/det,(a22*a00-a02*a20)/det,(-a12*a00+a02*a10)/det,\nb21/det,(-a21*a00+a01*a20)/det,(a11*a00-a01*a10)/det);}\n#if USE_EXACT_SRGB_CONVERSIONS\nfn toLinearSpaceExact(color: vec3f)->vec3f\n{let nearZeroSection: vec3f=0.0773993808*color;let remainingSection: vec3f=pow(0.947867299*(color+vec3f(0.055)),vec3f(2.4));return mix(remainingSection,nearZeroSection,lessThanEqual(color,vec3f(0.04045)));}\nfn toGammaSpaceExact(color: vec3f)->vec3f\n{let nearZeroSection: vec3f=12.92*color;let remainingSection: vec3f=1.055*pow(color,vec3f(0.41666))-vec3f(0.055);return mix(remainingSection,nearZeroSection,lessThanEqual(color,vec3f(0.0031308)));}\n#endif\nfn toLinearSpace(color: f32)->f32\n{\n#if USE_EXACT_SRGB_CONVERSIONS\nvar nearZeroSection=0.0773993808*color;var remainingSection=pow(0.947867299*(color+0.055),2.4);return select(remainingSection,nearZeroSection,color<=0.04045);\n#else\nreturn pow(color,LinearEncodePowerApprox);\n#endif\n}\nfn toLinearSpaceVec3(color: vec3f)->vec3f\n{\n#if USE_EXACT_SRGB_CONVERSIONS\nreturn toLinearSpaceExact(color);\n#else\nreturn pow(color,vec3f(LinearEncodePowerApprox));\n#endif\n}\nfn toLinearSpaceVec4(color: vec4)->vec4\n{\n#if USE_EXACT_SRGB_CONVERSIONS\nreturn vec4f(toLinearSpaceExact(color.rgb),color.a);\n#else\nreturn vec4f(pow(color.rgb,vec3f(LinearEncodePowerApprox)),color.a);\n#endif\n}\nfn toGammaSpace(color: vec4)->vec4\n{\n#if USE_EXACT_SRGB_CONVERSIONS\nreturn vec4(toGammaSpaceExact(color.rgb),color.a);\n#else\nreturn vec4(pow(color.rgb,vec3f(GammaEncodePowerApprox)),color.a);\n#endif\n}\nfn toGammaSpaceVec3(color: vec3f)->vec3f\n{\n#if USE_EXACT_SRGB_CONVERSIONS\nreturn toGammaSpaceExact(color);\n#else\nreturn pow(color,vec3f(GammaEncodePowerApprox));\n#endif\n}\nfn squareVec3(value: vec3f)->vec3f\n{return value*value;}\nfn pow5(value: f32)->f32 {let sq: f32=value*value;return sq*sq*value;}\nfn getLuminance(color: vec3f)->f32\n{return saturate(dot(color,LuminanceEncodeApprox));}\nfn getRand(seed: vec2)->f32 {return fract(sin(dot(seed.xy ,vec2(12.9898,78.233)))*43758.5453);}\nfn dither(seed: vec2,varianceAmount: f32)->f32 {let rand: f32=getRand(seed);let normVariance: f32=varianceAmount/255.0;let dither: f32=mix(-normVariance,normVariance,rand);return dither;}\nconst rgbdMaxRange: f32=255.0;fn toRGBD(color: vec3f)->vec4 {let maxRGB: f32=max(max(color.r,max(color.g,color.b)),Epsilon);var D: f32 =max(rgbdMaxRange/maxRGB,1.);D =clamp(floor(D)/255.0,0.,1.);var rgb: vec3f =color.rgb*D;rgb=toGammaSpaceVec3(rgb);return vec4(saturateVec3(rgb),D);}\nfn fromRGBD(rgbd: vec4)->vec3f {let rgb=toLinearSpaceVec3(rgbd.rgb);return rgb/rgbd.a;}\nfn parallaxCorrectNormal(vertexPos: vec3f,origVec: vec3f,cubeSize: vec3f,cubePos: vec3f)->vec3f {let invOrigVec: vec3f=vec3f(1.)/origVec;let halfSize: vec3f=cubeSize*0.5;let intersecAtMaxPlane: vec3f=(cubePos+halfSize-vertexPos)*invOrigVec;let intersecAtMinPlane: vec3f=(cubePos-halfSize-vertexPos)*invOrigVec;let largestIntersec: vec3f=max(intersecAtMaxPlane,intersecAtMinPlane);let distance: f32=min(min(largestIntersec.x,largestIntersec.y),largestIntersec.z);let intersectPositionWS: vec3f=vertexPos+origVec*distance;return intersectPositionWS-cubePos;}\nfn equirectangularToCubemapDirection(uv : vec2f)->vec3f {var longitude : f32=uv.x*TWO_PI-PI;var latitude : f32=HALF_PI-uv.y*PI;var direction : vec3f;direction.x=cos(latitude)*sin(longitude);direction.y=sin(latitude);direction.z=cos(latitude)*cos(longitude);return direction;}\nfn sqrtClamped(value: f32)->f32 {return sqrt(max(value,0.));}\nfn avg(value: vec3f)->f32 {return dot(value,vec3f(0.333333333));}\n`;\n// Sideeffect\nShaderStore.IncludesShadersStoreWGSL[name] = shader;\n/** @internal */\nexport const helperFunctionsWGSL = { name, shader };\n","// Do not edit.\nimport { ShaderStore } from \"../../Engines/shaderStore\";\n\nconst name = \"helperFunctions\";\nconst shader = `const float PI=3.1415926535897932384626433832795;const float TWO_PI=6.283185307179586;const float HALF_PI=1.5707963267948966;const float RECIPROCAL_PI=0.3183098861837907;const float RECIPROCAL_PI2=0.15915494309189535;const float RECIPROCAL_PI4=0.07957747154594767;const float HALF_MIN=5.96046448e-08; \nconst float LinearEncodePowerApprox=2.2;const float GammaEncodePowerApprox=1.0/LinearEncodePowerApprox;const vec3 LuminanceEncodeApprox=vec3(0.2126,0.7152,0.0722);const float Epsilon=0.0000001;\n#define saturate(x) clamp(x,0.0,1.0)\n#define absEps(x) abs(x)+Epsilon\n#define maxEps(x) max(x,Epsilon)\n#define saturateEps(x) clamp(x,Epsilon,1.0)\nmat3 transposeMat3(mat3 inMatrix) {vec3 i0=inMatrix[0];vec3 i1=inMatrix[1];vec3 i2=inMatrix[2];mat3 outMatrix=mat3(\nvec3(i0.x,i1.x,i2.x),\nvec3(i0.y,i1.y,i2.y),\nvec3(i0.z,i1.z,i2.z)\n);return outMatrix;}\nmat3 inverseMat3(mat3 inMatrix) {float a00=inMatrix[0][0],a01=inMatrix[0][1],a02=inMatrix[0][2];float a10=inMatrix[1][0],a11=inMatrix[1][1],a12=inMatrix[1][2];float a20=inMatrix[2][0],a21=inMatrix[2][1],a22=inMatrix[2][2];float b01=a22*a11-a12*a21;float b11=-a22*a10+a12*a20;float b21=a21*a10-a11*a20;float det=a00*b01+a01*b11+a02*b21;return mat3(b01,(-a22*a01+a02*a21),(a12*a01-a02*a11),\nb11,(a22*a00-a02*a20),(-a12*a00+a02*a10),\nb21,(-a21*a00+a01*a20),(a11*a00-a01*a10))/det;}\n#if USE_EXACT_SRGB_CONVERSIONS\nvec3 toLinearSpaceExact(vec3 color)\n{vec3 nearZeroSection=0.0773993808*color;vec3 remainingSection=pow(0.947867299*(color+vec3(0.055)),vec3(2.4));\n#if defined(WEBGL2) || defined(WEBGPU) || defined(NATIVE)\nreturn mix(remainingSection,nearZeroSection,lessThanEqual(color,vec3(0.04045)));\n#else\nreturn\nvec3(\ncolor.r<=0.04045 ? nearZeroSection.r : remainingSection.r,\ncolor.g<=0.04045 ? nearZeroSection.g : remainingSection.g,\ncolor.b<=0.04045 ? nearZeroSection.b : remainingSection.b);\n#endif\n}\nvec3 toGammaSpaceExact(vec3 color)\n{vec3 nearZeroSection=12.92*color;vec3 remainingSection=1.055*pow(color,vec3(0.41666))-vec3(0.055);\n#if defined(WEBGL2) || defined(WEBGPU) || defined(NATIVE)\nreturn mix(remainingSection,nearZeroSection,lessThanEqual(color,vec3(0.0031308)));\n#else\nreturn\nvec3(\ncolor.r<=0.0031308 ? nearZeroSection.r : remainingSection.r,\ncolor.g<=0.0031308 ? nearZeroSection.g : remainingSection.g,\ncolor.b<=0.0031308 ? nearZeroSection.b : remainingSection.b);\n#endif\n}\n#endif\nfloat toLinearSpace(float color)\n{\n#if USE_EXACT_SRGB_CONVERSIONS\nfloat nearZeroSection=0.0773993808*color;float remainingSection=pow(0.947867299*(color+0.055),2.4);return color<=0.04045 ? nearZeroSection : remainingSection;\n#else\nreturn pow(color,LinearEncodePowerApprox);\n#endif\n}\nvec3 toLinearSpace(vec3 color)\n{\n#if USE_EXACT_SRGB_CONVERSIONS\nreturn toLinearSpaceExact(color);\n#else\nreturn pow(color,vec3(LinearEncodePowerApprox));\n#endif\n}\nvec4 toLinearSpace(vec4 color)\n{\n#if USE_EXACT_SRGB_CONVERSIONS\nreturn vec4(toLinearSpaceExact(color.rgb),color.a);\n#else\nreturn vec4(pow(color.rgb,vec3(LinearEncodePowerApprox)),color.a);\n#endif\n}\nfloat toGammaSpace(float color)\n{\n#if USE_EXACT_SRGB_CONVERSIONS\nfloat nearZeroSection=12.92*color;float remainingSection=1.055*pow(color,0.41666)-0.055;return color<=0.0031308 ? nearZeroSection : remainingSection;\n#else\nreturn pow(color,GammaEncodePowerApprox);\n#endif\n}\nvec3 toGammaSpace(vec3 color)\n{\n#if USE_EXACT_SRGB_CONVERSIONS\nreturn toGammaSpaceExact(color);\n#else\nreturn pow(color,vec3(GammaEncodePowerApprox));\n#endif\n}\nvec4 toGammaSpace(vec4 color)\n{\n#if USE_EXACT_SRGB_CONVERSIONS\nreturn vec4(toGammaSpaceExact(color.rgb),color.a);\n#else\nreturn vec4(pow(color.rgb,vec3(GammaEncodePowerApprox)),color.a);\n#endif\n}\nfloat square(float value)\n{return value*value;}\nvec3 square(vec3 value)\n{return value*value;}\nfloat pow5(float value) {float sq=value*value;return sq*sq*value;}\nfloat getLuminance(vec3 color)\n{return saturate(dot(color,LuminanceEncodeApprox));}\nfloat getRand(vec2 seed) {return fract(sin(dot(seed.xy ,vec2(12.9898,78.233)))*43758.5453);}\nfloat dither(vec2 seed,float varianceAmount) {float rand=getRand(seed);float normVariance=varianceAmount/255.0;float dither=mix(-normVariance,normVariance,rand);return dither;}\nconst float rgbdMaxRange=255.;vec4 toRGBD(vec3 color) {float maxRGB=maxEps(max(color.r,max(color.g,color.b)));float D =max(rgbdMaxRange/maxRGB,1.);D =saturate(floor(D)/255.);vec3 rgb=color.rgb*D;rgb=toGammaSpace(rgb);return vec4(saturate(rgb),D);}\nvec3 fromRGBD(vec4 rgbd) {rgbd.rgb=toLinearSpace(rgbd.rgb);return rgbd.rgb/rgbd.a;}\nvec3 parallaxCorrectNormal( vec3 vertexPos,vec3 origVec,vec3 cubeSize,vec3 cubePos ) {vec3 invOrigVec=vec3(1.)/origVec;vec3 halfSize=cubeSize*0.5;vec3 intersecAtMaxPlane=(cubePos+halfSize-vertexPos)*invOrigVec;vec3 intersecAtMinPlane=(cubePos-halfSize-vertexPos)*invOrigVec;vec3 largestIntersec=max(intersecAtMaxPlane,intersecAtMinPlane);float distance=min(min(largestIntersec.x,largestIntersec.y),largestIntersec.z);vec3 intersectPositionWS=vertexPos+origVec*distance;return intersectPositionWS-cubePos;}\nvec3 equirectangularToCubemapDirection(vec2 uv) {float longitude=uv.x*TWO_PI-PI;float latitude=HALF_PI-uv.y*PI;vec3 direction;direction.x=cos(latitude)*sin(longitude);direction.y=sin(latitude);direction.z=cos(latitude)*cos(longitude);return direction;}\nfloat sqrtClamped(float value) {return sqrt(max(value,0.));}\nfloat avg(vec3 value) {return dot(value,vec3(0.333333333));}`;\n// Sideeffect\nShaderStore.IncludesShadersStore[name] = shader;\n/** @internal */\nexport const helperFunctions = { name, shader };\n","\n/******************************************************************************\nCopyright (c) Microsoft Corporation.\nPermission to use, copy, modify, and/or distribute this software for any\npurpose with or without fee is hereby granted.\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\nPERFORMANCE OF THIS SOFTWARE.\n***************************************************************************** */\n/* global Reflect, Promise */\n\nvar extendStatics = function(d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n};\n\nexport function __extends(d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n}\n\nexport var __assign = function() {\n __assign = Object.assign || function __assign(t) {\n for (var s, i = 1, n = arguments.length; i < n; i++) {\n s = arguments[i];\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\n }\n return t;\n }\n return __assign.apply(this, arguments);\n}\n\nexport function __rest(s, e) {\n var t = {};\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\n t[p] = s[p];\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\n t[p[i]] = s[p[i]];\n }\n return t;\n}\n\nexport function __decorate(decorators, target, key, desc) {\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\n return c > 3 && r && Object.defineProperty(target, key, r), r;\n}\n\nexport function __param(paramIndex, decorator) {\n return function (target, key) { decorator(target, key, paramIndex); }\n}\n\nexport function __metadata(metadataKey, metadataValue) {\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\n}\n\nexport function __awaiter(thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n}\n\nexport function __generator(thisArg, body) {\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\n function verb(n) { return function (v) { return step([n, v]); }; }\n function step(op) {\n if (f) throw new TypeError(\"Generator is already executing.\");\n while (_) try {\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\n if (y = 0, t) op = [op[0] & 2, t.value];\n switch (op[0]) {\n case 0: case 1: t = op; break;\n case 4: _.label++; return { value: op[1], done: false };\n case 5: _.label++; y = op[1]; op = [0]; continue;\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\n default:\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\n if (t[2]) _.ops.pop();\n _.trys.pop(); continue;\n }\n op = body.call(thisArg, _);\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\n }\n}\n\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() { return m[k]; } };\n }\n Object.defineProperty(o, k2, desc);\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n});\n\nexport function __exportStar(m, o) {\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\n}\n\nexport function __values(o) {\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\n if (m) return m.call(o);\n if (o && typeof o.length === \"number\") return {\n next: function () {\n if (o && i >= o.length) o = void 0;\n return { value: o && o[i++], done: !o };\n }\n };\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\n}\n\nexport function __read(o, n) {\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\n if (!m) return o;\n var i = m.call(o), r, ar = [], e;\n try {\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\n }\n catch (error) { e = { error: error }; }\n finally {\n try {\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\n }\n finally { if (e) throw e.error; }\n }\n return ar;\n}\n\n/** @deprecated */\nexport function __spread() {\n for (var ar = [], i = 0; i < arguments.length; i++)\n ar = ar.concat(__read(arguments[i]));\n return ar;\n}\n\n/** @deprecated */\nexport function __spreadArrays() {\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\n r[k] = a[j];\n return r;\n}\n\nexport function __spreadArray(to, from, pack) {\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\n if (ar || !(i in from)) {\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\n ar[i] = from[i];\n }\n }\n return to.concat(ar || Array.prototype.slice.call(from));\n}\n\nexport function __await(v) {\n return this instanceof __await ? (this.v = v, this) : new __await(v);\n}\n\nexport function __asyncGenerator(thisArg, _arguments, generator) {\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\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); }); }; }\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\n function fulfill(value) { resume(\"next\", value); }\n function reject(value) { resume(\"throw\", value); }\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\n}\n\nexport function __asyncDelegator(o) {\n var i, p;\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; } : f; }\n}\n\nexport function __asyncValues(o) {\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n var m = o[Symbol.asyncIterator], i;\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\n}\n\nexport function __makeTemplateObject(cooked, raw) {\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\n return cooked;\n};\n\nvar __setModuleDefault = Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n};\n\nexport function __importStar(mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n __setModuleDefault(result, mod);\n return result;\n}\n\nexport function __importDefault(mod) {\n return (mod && mod.__esModule) ? mod : { default: mod };\n}\n\nexport function __classPrivateFieldGet(receiver, state, kind, f) {\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\n}\n\nexport function __classPrivateFieldSet(receiver, state, value, kind, f) {\n if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\n return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\n}\n\nexport function __classPrivateFieldIn(state, receiver) {\n if (receiver === null || (typeof receiver !== \"object\" && typeof receiver !== \"function\")) throw new TypeError(\"Cannot use 'in' operator on non-object\");\n return typeof state === \"function\" ? receiver === state : state.has(receiver);\n}\n"],"names":["PickingInfo","hit","distance","pickedPoint","pickedMesh","bu","bv","faceId","subMeshFaceId","subMeshId","pickedSprite","thinInstanceIndex","ray","originMesh","aimTransform","gripTransform","useWorldCoordinates","useVerticesNormals","this","isVerticesDataPresent","NormalKind","result","indices","getIndices","length","tmp0","Vector3","tmp1","tmp2","normals","getVerticesData","normal0","FromArrayToRef","copyFromFloats","normal1","normal2","scale","x","y","z","positions","PositionKind","vertex1","vertex2","vertex3","p1p2","subtract","p3p2","Cross","transformNormalToWorld","n","wm","getWorldMatrix","nonUniformScaling","Matrix","copyFrom","setTranslationFromFloats","invert","transposeToRef","TransformNormalToRef","normalForDirectionChecking","Dot","direction","negateInPlace","normalize","uvSet","UVKind","uvs","uv0","FromArray","uv1","uv2","BaseTexture","sceneOrEngine","internalTexture","metadata","reservedDataStore","_hasAlpha","_getAlphaFromRGB","level","_coordinatesIndex","optimizeUVAllocation","_coordinatesMode","wrapR","anisotropicFilteringLevel","DEFAULT_ANISOTROPIC_FILTERING_LEVEL","_isCube","_gammaSpace","invertZ","lodLevelInAlpha","isRenderTarget","_prefiltered","_forceSerialize","animations","onDisposeObservable","_onDisposeObserver","_scene","_uid","_parentContainer","_loadingError","_IsScene","_engine","LastCreatedScene","uniqueId","getUniqueId","addTexture","getEngine","_texture","value","markAllMaterialsAsDirty","mat","hasTexture","_wrapU","_wrapV","isCube","is3D","is2DArray","_useSRGBBuffer","gamma","getScene","_isRGBD","isRGBD","_lodGenerationOffset","_lodGenerationScale","_linearSpecularLOD","_irradianceTexture","name","callback","remove","add","_errorObject","IdentityReadOnly","getReflectionTextureMatrix","isBlocking","isReady","loadingError","ratio","url","noMipmap","sampling","invertY","useSRGBBuffer","engine","_getEngine","correctedUseSRGBBuffer","_getUseSRGBBuffer","texturesCache","getLoadedTexturesCache","index","texturesCacheEntry","undefined","generateMipMaps","samplingMode","incrementReferences","type","format","scene","faceIndex","buffer","flushRenderer","noDataConversion","width","Number","MAX_VALUE","height","size","getSize","maxWidth","maxHeight","Math","pow","round","min","_readTexturePixels","e","_readTexturePixelsSync","_lodTextureHigh","_lodTextureMid","_lodTextureLow","stopAnimation","removePendingData","textures","indexOf","splice","onTextureRemovedObservable","notifyObservers","clear","allowEmptyName","serializationObject","Serialize","AppendSerializedAnimations","numRemaining","i","texture","onLoadObservable","addOnce","getClassName","GenerateBase64StringFromPixelData","pixels","Float32Array","len","byteLength","BYTES_PER_ELEMENT","npixels","Uint8Array","val","canvas","document","createElement","ctx","getContext","imageData","createImageData","data","set","putImageData","canvas2","ctx2","translate","drawImage","toDataURL","GenerateBase64StringFromTexture","getInternalTexture","_readPixelsSync","GenerateBase64StringFromTextureAsync","readPixels","useOpenGLOrientationForUV","Texture","noMipmapOrOptions","TRILINEAR_SAMPLINGMODE","onLoad","onError","deleteBuffer","mimeType","loaderOptions","creationFlags","forcedExtension","uOffset","vOffset","uScale","vScale","uAng","vAng","wAng","uRotationCenter","vRotationCenter","wRotationCenter","homogeneousRotationInUVTransform","inspectableCustomProperties","_noMipmap","_invertY","_rowGenerationMatrix","_cachedTextureMatrix","_projectionModeMatrix","_t0","_t1","_t2","_cachedUOffset","_cachedVOffset","_cachedUScale","_cachedVScale","_cachedUAng","_cachedVAng","_cachedWAng","_cachedReflectionProjectionMatrixId","_cachedURotationCenter","_cachedVRotationCenter","_cachedWRotationCenter","_cachedHomogeneousRotationInUVTransform","_cachedIdentity3x2","_cachedReflectionTextureMatrix","_cachedReflectionUOffset","_cachedReflectionVOffset","_cachedReflectionUScale","_cachedReflectionVScale","_cachedReflectionCoordinatesMode","_buffer","_deleteBuffer","_format","_delayedOnLoad","_delayedOnError","_isBlocking","gammaSpace","_initialSamplingMode","_mimeType","_loaderOptions","_creationFlags","_forcedExtension","onBeforeTextureInitObservable","load","_invertVScale","_cachedWrapU","wrapU","_cachedWrapV","wrapV","_cachedWrapR","hasObservers","resetCachedMaterial","errorHandler","message","exception","OnTextureLoadErrorObservable","_getFromCache","SetImmediate","loadObserver","onLoadedObservable","onErrorObservable","useDelayedTextureLoading","delayLoadState","createTexture","releaseInternalTexture","startsWith","delayLoad","t","TransformCoordinatesFromFloatsToRef","uBase","Zero","RotationYawPitchRollToRef","TranslationToRef","ScalingToRef","multiplyToRef","setRowFromFloats","m","_prepareRowForTextureGeneration","subtractInPlace","FromValuesToRef","previousIdentity3x2","isIdentityAs3x2","coordinatesMode","PROJECTION_MODE","getProjectionMatrix","updateFlag","flagMaterialsAsTextureDirty","PLANAR_MODE","IdentityToRef","projectionMatrix","options","textureFormat","Clone","savedName","SerializeBuffers","_SerializeInternalTextureUniqueId","ForceSerializeBuffers","substring","base64String","replace","_features","supportSyncTextureRead","internalTextureUniqueId","internalTextureLabel","label","src","parsedTexture","rootUrl","customType","parsedCustomTexture","Instantiate","Parse","updateSamplingMode","_samplingMode","_CubeTextureParser","hasInternalTextureUniqueId","cache","onLoaded","animationIndex","parsedAnimation","internalClass","push","_setUniqueId","mirrorPlane","mirrorTexture","_CreateMirror","renderTargetSize","_waitingRenderList","renderList","renderTargetTexture","reflectionProbes","probe","cubeTexture","_CreateRenderTargetTexture","isVideo","_CreateVideoTexture","settings","CreateFromBase64String","UseSerializedUrlIfAny","jsonTexture","NEAREST_SAMPLINGMODE","NEAREST_NEAREST_MIPLINEAR","BILINEAR_SAMPLINGMODE","LINEAR_LINEAR_MIPNEAREST","LINEAR_LINEAR_MIPLINEAR","NEAREST_NEAREST_MIPNEAREST","NEAREST_LINEAR_MIPNEAREST","NEAREST_LINEAR_MIPLINEAR","NEAREST_LINEAR","NEAREST_NEAREST","LINEAR_NEAREST_MIPNEAREST","LINEAR_NEAREST_MIPLINEAR","LINEAR_LINEAR","LINEAR_NEAREST","EXPLICIT_MODE","SPHERICAL_MODE","CUBIC_MODE","SKYBOX_MODE","INVCUBIC_MODE","EQUIRECTANGULAR_MODE","FIXED_EQUIRECTANGULAR_MODE","FIXED_EQUIRECTANGULAR_MIRRORED_MODE","CLAMP_ADDRESSMODE","WRAP_ADDRESSMODE","MIRROR_ADDRESSMODE","_TextureParser","UniformBuffer","dynamic","forceNoUniformBuffer","_valueCache","_noUBO","supportsUniformBuffers","_dynamic","_name","_data","_uniformLocations","_uniformSizes","_uniformArraySizes","_uniformLocationPointer","_needSync","trackUbosInFrame","_buffers","_bufferIndex","_createBufferOnWrite","_currentFrameId","updateMatrix3x3","_updateMatrix3x3ForEffect","updateMatrix2x2","_updateMatrix2x2ForEffect","updateFloat","_updateFloatForEffect","updateFloat2","_updateFloat2ForEffect","updateFloat3","_updateFloat3ForEffect","updateFloat4","_updateFloat4ForEffect","updateFloatArray","_updateFloatArrayForEffect","updateArray","_updateArrayForEffect","updateIntArray","_updateIntArrayForEffect","updateUIntArray","_updateUIntArrayForEffect","updateMatrix","_updateMatrixForEffect","updateMatrices","_updateMatricesForEffect","updateVector3","_updateVector3ForEffect","updateVector4","_updateVector4ForEffect","updateColor3","_updateColor3ForEffect","updateColor4","_updateColor4ForEffect","updateDirectColor4","_updateDirectColor4ForEffect","updateInt","_updateIntForEffect","updateInt2","_updateInt2ForEffect","updateInt3","_updateInt3ForEffect","updateInt4","_updateInt4ForEffect","updateUInt","_updateUIntForEffect","updateUInt2","_updateUInt2ForEffect","updateUInt3","_updateUInt3ForEffect","updateUInt4","_updateUInt4ForEffect","_uniformBuffers","_updateMatrix3x3ForUniform","_updateMatrix2x2ForUniform","_updateFloatForUniform","_updateFloat2ForUniform","_updateFloat3ForUniform","_updateFloat4ForUniform","_updateFloatArrayForUniform","_updateArrayForUniform","_updateIntArrayForUniform","_updateUIntArrayForUniform","_updateMatrixForUniform","_updateMatricesForUniform","_updateVector3ForUniform","_updateVector4ForUniform","_updateColor3ForUniform","_updateColor4ForUniform","_updateDirectColor4ForUniform","_updateIntForUniform","_updateInt2ForUniform","_updateInt3ForUniform","_updateInt4ForUniform","_updateUIntForUniform","_updateUInt2ForUniform","_updateUInt3ForUniform","_updateUInt4ForUniform","_bufferData","alignment","oldPointer","diff","arraySize","Array","_fillAlignment","strideSize","addUniform","prototype","slice","call","asArray","temp","color","r","g","b","alpha","vector","_rebuild","names","join","createDynamicUniformBuffer","_getNames","createUniformBuffer","checkUbosContentBeforeUpload","_currentEffect","buf1","buf2","dst","bindUniformBuffer","_buffersEqual","_copyBuffer","updateUniformBuffer","_collectUbosUpdatedInFrame","_UpdatedUbosInFrame","create","frameId","uniformName","_checkNewFrame","location","Error","changed","uniformBufferHardCheckMatrix","fround","_createNewBuffer","arraySizes","countToFour","baseStride","FloatRound","matrix","flag","_TempBuffer","updateUniform","setMatrix3x3","setMatrix2x2","setFloat","suffix","setFloat2","setFloat3","w","setFloat4","array","setFloatArray","updateUniformArray","setArray","setIntArray","_TempBufferInt32View","setUIntArray","_TempBufferUInt32View","setMatrix","_cacheMatrix","setMatrices","setVector3","setVector4","setColor3","setColor4","setDirectColor4","a","setInt","setInt2","setInt3","setInt4","setUInt","setUInt2","setUInt3","setUInt4","setTexture","setTextureArray","_bindTexture","update","effect","_currentEffectName","dataBuffer","uniformBuffers","pop","_releaseBuffer","_MAX_UNIFORM_SIZE","Int32Array","Uint32Array","Space","Coordinate","Axis","X","Y","Z","colorChannelToLinearSpace","colorChannelToLinearSpaceExact","colorChannelToGammaSpace","colorChannelToGammaSpaceExact","Color3","hash","offset","Color4","otherColor","_other","ReferenceError","_result","other","minimizeInPlaceFromFloats","maximizeInPlaceFromFloats","max","equalsToFloats","epsilon","source","v","intR","intG","intB","hex","parseInt","toHSVToRef","h","s","dm","exact","convertedColor","toLinearSpaceToRef","toGammaSpaceToRef","hue","saturation","chroma","abs","HSVtoRGBToRef","fromHexString","start","end","amount","LerpToRef","left","right","value1","tangent1","value2","tangent2","squared","cubed","part1","part2","part3","part4","time","Black","Hermite1stDerivativeToRef","t2","_BlackReadOnly","random","_V8PerformanceHack","Object","defineProperties","dimension","rank","returnAsColor3","intA","color3","colors","count","colors4","newIndex","TmpColors","ToGammaSpace","ToLinearSpace","Epsilon","sqrt","Frustum","transform","frustumPlanes","GetPlanesToRef","frustumPlane","normal","d","GetNearPlaneToRef","GetFarPlaneToRef","GetLeftPlaneToRef","GetRightPlaneToRef","GetTopPlaneToRef","GetBottomPlaneToRef","point","dotCoordinate","Plane","c","getHashCode","norm","magnitude","transformation","invertedMatrix","_TmpMatrix","invertToRef","point1","point2","point3","invPyth","x1","y1","z1","x2","y2","z2","yz","xz","xy","pyth","copyFromPoints","origin","plane","FromPositionAndNormalToRef","dot","Identity","WithinEpsilon","RandomRange","Lerp","Clamp","NormalizeRadians","angle","PI","floor","ToHex","str","toString","toUpperCase","ILog2","log2","NaN","Infinity","_ExtractAsInt","Vector2","otherVector","cos","sin","normalizeFromLength","scaleInPlace","normalized","normalizeToRef","scaleToRef","_ZeroReadOnly","value3","value4","ref","NormalizeToRef","TransformToRef","p","p0","p1","p2","sign","DistanceSquared","CenterToRef","segA","segB","l2","Distance","proj","multiplyByFloats","_isDirty","_x","_y","_z","Quaternion","RotationYawPitchRoll","subtractFromFloatsToRef","radius","theta","acos","phi","atan2","q","vx","vy","vz","qx","qy","qz","qw","_w","tx","ty","tz","applyRotationQuaternionToRef","projectOnPlaneToRef","V","MathTmp","subtractToRef","denom","setAll","scaledV","addToRef","absX","absY","absZ","lengthSquared","order","toLowerCase","tem","quaternion","toRotationMatrix","TransformCoordinatesToRef","rotateByQuaternionToRef","CrossToRef","vector0","vector1","axis","d0","v0","v1","isNaN","vNormal","forward","target","TmpVectors","PitchYawRollToMoveBetweenPointsToRef","slerp","vector0Dir","vector1Dir","vector0Length","vector1Length","scale0","scale1","omega","invSin","addInPlace","goal","deltaTime","lerpTime","SlerpToRef","_UpReadOnly","_DownReadOnly","_RightReadOnly","_LeftReadOnly","_LeftHandedForwardReadOnly","_RightHandedForwardReadOnly","_LeftHandedBackwardReadOnly","_RightHandedBackwardReadOnly","_OneReadOnly","rx","ry","rz","rw","TransformNormalFromFloatsToRef","ClampToRef","minimizeInPlace","maximizeInPlace","world","viewport","ProjectToRef","cw","ch","cx","cy","viewportMatrix","isNDCHalfZRange","LastCreatedEngine","zScale","zOffset","inDirection","ReflectToRef","tmp","num","viewportWidth","viewportHeight","Unproject","view","projection","UnprojectToRef","UnprojectFloatsToRef","sourceX","sourceY","sourceZ","screenSource","_UnprojectFromInvertedMatrixToRef","p1p0","p2p0","p2p1","vectorp0","p1p0L","p2p0L","p2p1L","nl","l","cosA","projVector","v2","projP","s0","s1","e0","e1","s2","edge","tmp3","e0proj","e0projL","cosG","triProj","axis1","axis2","axis3","rotation","RotationFromAxisToRef","quat","RotationQuaternionFromAxisToRef","toEulerAnglesToRef","Up","Down","Forward","Backward","Right","Left","One","Vector4","divideToRef","reference","otherQuaternion","q1","negateToRef","conjugate","conjugateInPlace","zAxisY","limit","sqw","sqz","sqx","sqy","asin","sinHalfBeta","cosHalfBeta","beta","gammaPlusAlpha","gammaMinusAlpha","FromQuaternionToRef","FromRotationMatrixToRef","m11","m12","m13","m21","m22","m23","m31","m32","m33","trace","quat0","quat1","RotationAxisToRef","sinByLength","vec","vecFrom","vecTo","yaw","pitch","roll","halfRoll","halfPitch","halfYaw","sinRoll","cosRoll","sinPitch","cosPitch","sinYaw","cosYaw","RotationAlphaBetaGammaToRef","halfGammaPlusAlpha","halfGammaMinusAlpha","halfBeta","rotMat","FromXYZAxesToRef","up","FromLookDirectionLHToRef","LookDirectionLHToRef","FromLookDirectionRHToRef","LookDirectionRHToRef","num2","num3","num4","num5","num6","_isIdentity","_isIdentityDirty","_isIdentity3x2","_isIdentity3x2Dirty","MatrixTrackPrecisionChange","MatrixTrackedMatrices","_m","MatrixCurrentType","markAsUpdated","_UpdateFlagSeed","isIdentity","isIdentityDirty","isIdentity3x2","isIdentity3x2Dirty","m00","m01","m02","m03","m10","m20","m30","det_22_33","det_21_33","det_21_32","det_20_33","det_20_32","det_20_31","floats","_updateIdentityStatus","resultM","otherM","args","values","cofact_00","cofact_01","cofact_02","cofact_03","det","detInv","det_12_33","det_11_33","det_11_32","det_10_33","det_10_32","det_10_31","det_12_23","det_11_23","det_11_22","det_10_23","det_10_22","det_10_21","cofact_10","cofact_11","cofact_12","cofact_13","cofact_20","cofact_21","cofact_22","cofact_23","cofact_30","cofact_31","cofact_32","cofact_33","vector3","copyToArray","o","multiplyToArray","tm0","tm1","tm2","tm3","tm4","tm5","tm6","tm7","tm8","tm9","tm10","tm11","tm12","tm13","tm14","tm15","om0","om1","om2","om3","om4","om5","om6","om7","om8","om9","om10","om11","om12","om13","om14","om15","om","floorToRef","fractToRef","node","rotationQuaternion","decompose","scaling","position","translation","preserveScalingNode","useAbsoluteScaling","signX","absoluteScaling","signY","signZ","determinant","sx","sy","sz","rowVector","row","TransposeToRef","getRotationMatrixToRef","MatrixUse64Bits","_IdentityReadOnly","initialM11","initialM12","initialM13","initialM14","initialM21","initialM22","initialM23","initialM24","initialM31","initialM32","initialM33","initialM34","initialM41","initialM42","initialM43","initialM44","ComposeToRef","xx","yy","zz","wx","wy","wz","identity","FromValues","zero","RotationXToRef","RotationYToRef","RotationZToRef","c1","from","to","useYAxisForCoplanar","k","startValue","endValue","gradient","startM","endM","DecomposeLerpToRef","startScale","startRotation","startTranslation","endScale","endRotation","endTranslation","resultScale","resultRotation","resultTranslation","eye","LookAtLHToRef","xAxis","yAxis","zAxis","xSquareLength","ex","ey","ez","LookAtRHToRef","back","znear","zfar","halfZRange","OrthoLHToRef","mtxConvertNDCToHalfZRange","bottom","top","OrthoOffCenterLHToRef","i0","i1","OrthoOffCenterRHToRef","projectionPlaneTilt","rot","tan","fov","aspect","reverseDepthBufferMode","PerspectiveFovLHToRef","isVerticalFovFixed","f","PerspectiveFovRHToRef","zmin","zmax","arr","mm","rm0","rm1","rm2","rm3","rm4","rm5","rm6","rm7","rm8","rm9","rm10","rm11","rm12","rm13","rm14","rm15","rm","ReflectionToRef","temp2","temp3","xaxis","yaxis","zaxis","zw","zx","yw","xw","Orientation","SH3ylmBasisConstants","SH3ylmBasisTrigonometricTerms","applySH3","lm","SHCosKernelConvolution","SphericalHarmonics","preScaled","l00","l1_1","l10","l11","l2_2","l2_1","l20","l21","l22","deltaSolidAngle","colorVector","FromFloatsToRef","updateFromArray","polynomial","SphericalPolynomial","_harmonics","FromPolynomial","preScaleForRendering","harmonics","updateFromHarmonics","sp","FileFaceOrientation","worldAxisForNormal","worldAxisForFileX","worldAxisForFileY","CubeMapToSphericalPolynomialTools","flushFramebuffer","upPromise","downPromise","rightPromise","leftPromise","frontPromise","backPromise","textureType","Promise","resolve","all","then","down","front","cubeInfo","ConvertCubeMapToSphericalPolynomial","sphericalHarmonics","totalSolidAngle","du","dv","halfTexel","minUV","fileFace","_FileFaces","dataArray","stride","u","worldDirection","_AreaElement","MAX_HDRI_VALUE","PRESERVE_CLAMPED_COLORS","currentMax","factor","addLight","correctionFactor","convertIncidentRadianceToIrradiance","convertIrradianceToLambertianRadiance","FromHarmonics","BuildArray","itemBuilder","BuildTuple","observedArrayFunctions","_ObserveArray","unObserveFunctions","map","object","functionName","oldFunction","previousLength","returnValue","previous","apply","arguments","next","_observeArrayfunction","forEach","unObserveFunction","_partialLoadFile","loadedFiles","onfinish","onErrorCallBack","_loadFile","_internalCount","request","status","statusText","_cascadeLoadFiles","files","_cascadeLoadImgs","loadedImages","_partialLoadImg","tokenPendingData","img","offlineProvider","addPendingData","createCubeTextureBase","createPolynomials","lodScale","lodOffset","fallback","beforeLoadCubeDataCallback","imageHandler","_caps","supportSRGBBuffers","version","isWebGPU","_doNotHandleContextLost","_extension","_files","originalRootUrl","_transformTextureUrl","rootUrlWithoutUriParams","split","lastDot","lastIndexOf","extension","loaderPromise","onInternalError","Warn","loader","onloaddata","loadCubeData","supportCascades","images","image","imgs","_internalTexturesCache","DDSD_MIPMAPCOUNT","DDPF_LUMINANCE","FourCCToInt32","charCodeAt","FOURCC_DXT1","FOURCC_DXT3","FOURCC_DXT5","FOURCC_DX10","DDSTools","header","byteOffset","extendedHeader","headerLengthInt","mipmapCount","fourCC","dxgiFormat","isFourCC","isRGB","isLuminance","isCompressed","dataOffset","dataLength","arrayBuffer","lod","destArray","srcData","Uint16Array","srcPos","StoreLODInAlphaChannel","rOffset","gOffset","bOffset","aOffset","byteArray","_ExtractLongWordOrder","info","loadMipmaps","faces","lodIndex","currentFace","destTypeMustBeFilterable","sphericalPolynomialFaces","sphericalPolynomial","ext","getCaps","s3tc","mip","internalCompressedFormat","blockBytes","bpp","computeFormats","supported","String","fromCharCode","_getRGBABufferInternalSizedFormat","startFace","caps","face","floatArray","_badOS","_badDesktopOS","textureHalfFloat","textureFloat","_GetFloatAsUIntRGBAArrayBuffer","_GetFloatRGBAArrayBuffer","_GetHalfFloatAsUIntRGBAArrayBuffer","_GetHalfFloatAsFloatRGBAArrayBuffer","floatAvailable","textureFloatLinearFiltering","halfFloatAvailable","textureHalfFloatLinearFiltering","destType","dataGetter","dataGetterPolynomial","_GetFloatAsHalfFloatRGBAArrayBuffer","_GetHalfFloatRGBAArrayBuffer","_uploadDataToTextureDirectly","_GetRGBArrayBuffer","_GetRGBAArrayBuffer","unpackAlignment","_getUnpackAlignement","unpaddedRowSize","_GetLuminanceArrayBuffer","_uploadCompressedDataToTextureDirectly","__mergedStore","__decoratorInitialStore","GetDirectStore","classKey","GetMergedStore","store","currentTarget","currentKey","initialStore","property","parent","done","getPrototypeOf","generateSerializableMember","sourceName","propertyKey","classStore","serialize","serializeAsTexture","serializeAsVector3","serializeAsColorCurves","serializeAsColor4","serializeAsQuaternion","nativeOverride","descriptor","predicate","jsFunc","func","_native","nativeFunc","filter","_copySource","creationFunction","instanciate","destination","HasTags","AddTagsTo","GetTags","textureMap","propertyDescriptor","sourceProperty","propertyType","SerializationHelper","AllowLoadingUniqueId","cloneTexturesOnlyOnce","clone","animation","entity","tags","serializedProperties","targetPropertyName","id","dest","_FresnelParametersParser","getLastMeshById","_ColorCurvesParser","_ImageProcessingConfigurationParser","getCameraById","ParseProperties","_dumpToolsEngine","_enginePromise","reject","preserveDrawingBuffer","depth","stencil","premultipliedAlpha","antialias","failIfMajorPerformanceCaveat","thinEngineClass","ThinEngine","OffscreenCanvas","Instances","OnEnginesDisposedObservable","isDisposed","Dispose","parallelShaderCompile","renderer","passPixelShader","wrapper","fragmentShader","shader","samplerNames","catch","DumpFramebuffer","successCallback","fileName","quality","bufferView","DumpData","DumpDataAsync","toArrayBuffer","_CreateDumpRenderer","setSize","data2","createRawTexture","setViewport","applyEffectWrapper","draw","ToBlob","blob","fileReader","FileReader","onload","event","readAsArrayBuffer","EncodeScreenshotCanvasData","dispose","dumpToolsEngine","DumpTools","PerfCounter","_startMonitoringTime","_min","_max","_average","_lastSecAverage","_current","_totalValueCount","_totalAccumulated","_lastSecAccumulated","_lastSecTime","_lastSecValueCount","newCount","fetchResult","Enabled","_fetchResult","Now","newFrame","fetchNewFrame","currentTime","now","SmartArray","capacity","_id","_GlobalId","compareFn","sort","reset","SmartArrayNoDuplicate","_duplicateId","__smartArrayFlags","item","pushNoDuplicate","AndOrNotEvaluator","query","evaluateCallback","match","_HandleParenthesisContent","Eval","parenthesisContent","or","hasOwnProperty","ori","_SimplifyNegation","trim","and","j","andj","booleanString","Tags","obj","_tags","hasTags","addTags","tagsString","removeTags","RemoveTagsFrom","matchesTagsQuery","tagsQuery","MatchesQuery","asString","tagsArray","tag","_AddTagTo","EnableFor","_RemoveTagFrom","ObjectRenderer","_unObserveRenderList","_renderListHasChanged","_functionName","newLength","_renderList","meshes","mesh","_markSubMeshesAsLightDirty","particleSystemList","getCustomRenderList","renderParticles","renderSprites","forceLayerMaskCheck","onBeforeRenderObservable","onAfterRenderObservable","onBeforeRenderingManagerRenderObservable","onAfterRenderingManagerRenderObservable","onFastPathRenderObservable","_currentRefreshId","_refreshRate","_currentSceneCamera","_renderPassIds","numPasses","doNotChangeAspectRatio","_createRenderPassId","renderPassId","_renderingManager","_useSceneAutoClearSetup","_renderPassNames","material","isArray","setMaterialForRenderPass","releaseRenderPassId","_releaseRenderPassId","createRenderPassId","resetRefreshCounter","refreshRate","prepareRenderList","initRender","_checkReadiness","finishRender","renderListPredicate","getMeshById","sceneMeshes","camera","activeCamera","setTransformMatrix","getViewMatrix","rigParent","_defaultRenderListPrepared","passIndex","skipOnAfterRenderObservable","currentRenderPassId","snapshotRendering","snapshotRenderingMode","currentRenderList","defaultRenderList","getActiveMeshes","defaultRenderListLength","_prepareRenderingManager","render","customRenderFunction","updateTransformMatrix","isEnabled","isBlocked","isVisible","subMeshes","customIsReadyFunction","incrementRenderId","particleSystems","currentRenderListLength","checkLayerMask","cameraForLOD","sceneRenderId","getRenderId","currentFrameId","getFrameId","meshIndex","meshToRender","meshToRenderAndFrameId","_internalAbstractMeshDataInfo","_currentLOD","get","customLODSelector","getLOD","billboardMode","computeWorldMatrix","_preActivateForIntermediateRendering","isMasked","layerMask","_activate","isAnInstance","_actAsRegularMesh","_onlyForInstancesIntermediate","_isActiveIntermediate","_prepareSkeleton","subIndex","subMesh","dispatch","_postActivate","particleIndex","particleSystem","emitter","isStarted","dispatchParticles","renderingGroupId","opaqueSortCompareFn","alphaTestSortCompareFn","transparentSortCompareFn","setRenderingOrder","autoClearDepthStencil","setRenderingAutoClearDepthStencil","newRenderer","renderListLength","getMaterialForRenderPass","REFRESHRATE_RENDER_ONCE","freeRenderingGroups","REFRESHRATE_RENDER_ONEVERYFRAME","REFRESHRATE_RENDER_ONEVERYTWOFRAMES","setDepthStencilTexture","channel","_samplers","_uniforms","RenderTargetTexture","colorAttachment","existingObjectRenderer","generateDepthBuffer","generateStencilBuffer","isMulti","delayAllocation","samples","noColorAttachment","ignoreCameraViewport","onBeforeBindObservable","onAfterUnbindObservable","onClearObservable","onResizeObservable","_cleared","skipInitialClear","_samples","_canRescale","_renderTarget","_dontDisposeObjectRenderer","boundingBoxPosition","_disableEngineStages","_dumpToolsLoading","_initialSizeParameter","_processSizeParameter","_objectRenderer","getRenderLayers","_onBeforeRenderingManagerRenderObserver","_beforeRenderTargetClearStage","action","_currentFaceIndex","_currentLayer","clearColor","_doNotChangeAspectRatio","_beforeRenderTargetDrawStage","_onAfterRenderingManagerRenderObserver","_afterRenderTargetDrawStage","saveGenerateMipMaps","_postProcessManager","_finalizeFrame","_postProcesses","_currentUseCameraPostProcess","postProcessManager","_afterRenderTargetPostProcessStage","_currentDumpForDebug","_dumpTools","getRenderWidth","getRenderHeight","_onFastPathRenderObserver","_resizeObserver","_generateMipMaps","_renderTargetOptions","createRenderTargetCubeTexture","getRenderSize","_textureMatrix","createRenderTargetTexture","_size","_prePassRenderTarget","enabled","_onAfterUnbindObserver","_onBeforeRenderObserver","_onAfterRenderObserver","_onClearObserver","renderPassIds","currentRefreshId","setMaterialForRendering","_sizeRatio","resize","_boundingBoxSize","equals","_depthStencilTexture","comparisonFunction","bilinearFiltering","generateStencil","createDepthStencilTexture","_bestReflectionRenderTargetDimension","setSamples","postProcess","autoClear","shouldRender","layers","newSize","wasCube","useCameraPostProcess","dumpForDebug","_render","module","useCameraPostProcesses","_renderToTarget","layer","renderDimension","curved","minimum","bindFramebuffer","unBindFramebuffer","_prePassEnabled","_prepareFrame","_bindFrameBuffer","_debugPushGroup","_debugPopGroup","_unbindFrameBuffer","generateMipMapsForCubemap","textureSize","newTexture","hasAlpha","releaseTextures","clearPostProcesses","customRenderTargets","cameras","PerformanceMonitor","frameSampleSize","_enabled","_rollingFrameTime","RollingAverage","timeMs","_lastFrameTimeMs","dt","average","variance","history","isSaturated","delta","bottomValue","_pos","_sampleCount","_m2","_wrapPosition","gl","_gl","_dummyFramebuffer","dummy","createFramebuffer","FRAMEBUFFER","framebufferTexture2D","COLOR_ATTACHMENT0","TEXTURE_CUBE_MAP_POSITIVE_X","_hardwareTexture","underlyingResource","TEXTURE_2D","readType","_getWebGLTextureType","UNSIGNED_BYTE","FLOAT","RGBA","_currentFramebuffer","updateDynamicIndexBuffer","indexBuffer","_currentBoundBuffer","ELEMENT_ARRAY_BUFFER","bindIndexBuffer","is32Bits","bufferData","DYNAMIC_DRAW","_resetIndexBufferBinding","updateDynamicVertexBuffer","vertexBuffer","bindArrayBuffer","bufferSubData","ARRAY_BUFFER","subarray","ArrayBuffer","_resetVertexBufferBinding","_createDepthStencilCubeTexture","webGLVersion","internalOptions","_bindTextureDirectly","TEXTURE_CUBE_MAP","_setupDepthStencilTexture","texImage2D","DEPTH24_STENCIL8","DEPTH_STENCIL","UNSIGNED_INT_24_8","DEPTH_COMPONENT24","DEPTH_COMPONENT","UNSIGNED_INT","_setCubeMapTextureParams","loadMipmap","maxLevel","texParameteri","TEXTURE_MAG_FILTER","LINEAR","TEXTURE_MIN_FILTER","LINEAR_MIPMAP_LINEAR","TEXTURE_WRAP_S","CLAMP_TO_EDGE","TEXTURE_WRAP_T","textureMaxLevel","TEXTURE_MAX_LEVEL","_maxLodLevel","createCubeTexture","needPOTTextures","maxCubemapTextureSize","TEXTURE_CUBE_MAP_POSITIVE_Y","TEXTURE_CUBE_MAP_POSITIVE_Z","TEXTURE_CUBE_MAP_NEGATIVE_X","TEXTURE_CUBE_MAP_NEGATIVE_Y","TEXTURE_CUBE_MAP_NEGATIVE_Z","_unpackFlipY","internalFormat","_getInternalFormat","_glSRGBExtensionValues","SRGB8_ALPHA8","texelFormat","_prepareWorkingCanvas","_workingCanvas","_workingContext","generateMipmap","unbind","uniform","_boundUniforms","depthStencilTexture","_setTexture","rtWrapper","_createHardwareRenderTargetWrapper","fullOptions","filters","_getSamplingParameters","mag","framebuffer","_bindUnboundFramebuffer","_depthStencilBuffer","_setupFramebufferDepthAttachments","_framebuffer","_generateDepthBuffer","_generateStencilBuffer","setTextures","createPrefilteredCubeTexture","loadData","_sphericalPolynomial","_source","textureLOD","mipSlices","roughness","minLODIndex","maxLODIndex","mipmapIndex","glTextureFromLod","isDDS","UploadDDSLevels","lodTexture","elements","_label","ubo","createBuffer","UNIFORM_BUFFER","STATIC_DRAW","references","uniformBuffer","bindBuffer","bindUniformBufferBase","bindBufferBase","bindUniformBlock","pipelineContext","blockName","program","uniformLocation","getUniformBlockIndex","uniformBlockBinding","displayLoadingUI","loadingScreen","hideLoadingUI","_loadingScreen","defineProperty","_renderingCanvas","DefaultLoadingScreenFactory","enumerable","configurable","loadingUIText","loadingUIBackgroundColor","getInputElement","getRenderingCanvasClientRect","getBoundingClientRect","getInputElementClientRect","getAspectRatio","viewportOwner","useScreen","getScreenAspectRatio","_verifyPointerLock","_onPointerLockChange","setAlphaEquation","equation","_alphaEquation","_alphaState","setAlphaEquationParameters","getDepthFunction","_depthCullingState","depthFunc","setDepthFunction","setDepthFunctionToGreater","setDepthFunctionToGreaterOrEqual","setDepthFunctionToLess","setDepthFunctionToLessOrEqual","getDepthWrite","depthMask","setDepthWrite","enable","getStencilBuffer","_stencilState","stencilTest","setStencilBuffer","getStencilMask","stencilMask","setStencilMask","mask","getStencilFunction","stencilFunc","getStencilFunctionReference","stencilFuncRef","getStencilFunctionMask","stencilFuncMask","setStencilFunction","setStencilFunctionReference","setStencilFunctionMask","getStencilOperationFail","stencilOpStencilFail","getStencilOperationDepthFail","stencilOpDepthFail","getStencilOperationPass","stencilOpStencilDepthPass","setStencilOperationFail","operation","setStencilOperationDepthFail","setStencilOperationPass","cacheStencilState","_cachedStencilBuffer","_cachedStencilFunction","_cachedStencilMask","_cachedStencilOperationPass","_cachedStencilOperationFail","_cachedStencilOperationDepthFail","_cachedStencilReference","restoreStencilState","setAlphaConstants","setAlphaBlendConstants","getAlphaMode","_alphaMode","getAlphaEquation","getRenderPassNames","getCurrentRenderPassName","_RenderPassIdCounter","scenes","_removeDrawWrapper","RequestPointerlock","element","requestPointerLock","promise","focus","AudioEngineFactory","hostElement","audioContext","audioDestination","AudioEngine","_audioContext","_audioContextInitialized","_muteButton","_audioDestination","canUseWebAudio","WarnedWebAudioUnsupported","isMP3supported","isOGGsupported","unlocked","useCustomUnlockedButton","onAudioUnlockedObservable","onAudioLockedObservable","_tryToRun","_onResize","_moveButtonToTopLeft","window","AudioContext","audioElem","_hostElement","canPlayType","_initializeAudioContext","_triggerSuspendedState","state","_hideMuteButton","suspend","_triggerRunningState","addEventListener","_resumeAudioContext","once","passive","signal","AbortSignal","timeout","resume","masterGain","createGain","gain","connect","_displayMuteButton","className","title","css","SVGSVGElement","style","appendChild","createTextNode","getElementsByTagName","body","unlock","offsetTop","offsetLeft","removeChild","_connectedAnalyser","stopDebugCanvas","disconnect","removeEventListener","newVolume","analyser","connectAudioNodes","Engine","canvasOrContext","adaptToDeviceRatio","customAnimationFrameRequester","_performanceMonitor","_drawCalls","supportRenderPasses","_creationOptions","_RescalePostProcessFactory","sampleFrame","_fps","averageFPS","_deltaTime","instantaneousFrameTime","_rescalePostProcess","commonEngine","creationOptions","_onCanvasFocus","onCanvasFocusObservable","_onCanvasBlur","onCanvasBlurObservable","_onCanvasContextMenu","evt","disableContextMenu","preventDefault","_onBlur","disablePerformanceMonitorInBackground","performanceMonitor","disable","_windowIsBackground","_onFocus","_onCanvasPointerOut","ev","elementFromPoint","clientX","clientY","onCanvasPointerOutObservable","hostWindow","getHostWindow","doNotHandleTouchAction","setAttribute","touchAction","webkitTapHighlightColor","_DisableTouchAction","audioEngine","getRenderingCanvas","getAudioContext","getAudioDestination","_onFullscreenChange","isFullscreen","fullscreenElement","_pointerLockRequested","isPointerLock","pointerLockElement","enableOfflineSupport","OfflineProviderFactory","_deterministicLockstep","deterministicLockstep","_lockstepMaxSteps","lockstepMaxSteps","_timeStep","timeStep","_CommonInit","bufferWidth","bufferHeight","context","createCanvas","getImageData","ResizeImageBitmap","imageSource","Image","decode","createImageBitmap","imageBitmap","onerror","CreateImageBitmapFromSource","exitFullscreen","enterFullscreen","requestFunction","requestFullscreen","webkitRequestFullscreen","RequestFullscreen","anyDoc","webkitCancelFullScreen","ExitFullscreen","DITHER","RASTERIZER_DISCARD","currentViewport","_cachedViewport","_viewport","enableScissor","disableScissor","SCISSOR_TEST","scissor","useArrayBuffer","shaders","getAttachedShaders","getShaderSource","dimensions","_framebufferDimensionsObject","_rebuildGeometries","_virtualScenes","font","text","textContent","block","display","verticalAlign","div","whiteSpace","fontAscent","fontHeight","ascent","descent","GetFontOffset","_frameHandler","cancelAnimationFrame","requestID","timestamp","_processFrame","_activeRenderLoops","_queueNewFrame","renderFunction","_boundRenderFunction","exitPointerLock","_measureFps","webGLPipelineContext","transformFeedback","deleteTransformFeedback","vertexCode","fragmentCode","defines","transformFeedbackVaryings","onBeforeShaderCompilationObservable","onAfterShaderCompilationObservable","vertexShader","shaderProgram","createProgram","attachShader","createTransformFeedback","bindTransformFeedback","setTranformFeedbackVaryings","linkProgram","isParallelCompiled","_finalizePipelineContext","postProcesses","_outputTexture","onComplete","rtt","externalTextureSamplerBinding","onCompiled","onApply","hostingScene","directRender","copyTexImage2D","getEffect","executeWhenCompiled","onEffectCreatedObservable","hasMipMaps","hardwareTexture","baseWidth","baseHeight","useMipMaps","updateTextureSamplingMode","bindTarget","TEXTURE_COMPARE_FUNC","TEXTURE_COMPARE_MODE","NONE","COMPARE_REF_TO_TEXTURE","_comparisonFunction","sync","flags","intervalms","res","clientWaitSync","WAIT_FAILED","TIMEOUT_EXPIRED","outputBuffer","_webGLVersion","buf","PIXEL_PACK_BUFFER","STREAM_READ","fenceSync","SYNC_GPU_COMMANDS_COMPLETE","flush","_clientWaitAsync","deleteSync","getBufferSubData","_CommonDispose","NpmPackage","Version","ALPHA_DISABLE","ALPHA_ADD","ALPHA_COMBINE","ALPHA_SUBTRACT","ALPHA_MULTIPLY","ALPHA_MAXIMIZED","ALPHA_ONEONE","ALPHA_PREMULTIPLIED","ALPHA_PREMULTIPLIED_PORTERDUFF","ALPHA_INTERPOLATE","ALPHA_SCREENMODE","DELAYLOADSTATE_NONE","DELAYLOADSTATE_LOADED","DELAYLOADSTATE_LOADING","DELAYLOADSTATE_NOTLOADED","NEVER","ALWAYS","LESS","EQUAL","LEQUAL","GREATER","GEQUAL","NOTEQUAL","KEEP","REPLACE","INCR","DECR","INVERT","INCR_WRAP","DECR_WRAP","TEXTURE_CLAMP_ADDRESSMODE","TEXTURE_WRAP_ADDRESSMODE","TEXTURE_MIRROR_ADDRESSMODE","TEXTUREFORMAT_ALPHA","TEXTUREFORMAT_LUMINANCE","TEXTUREFORMAT_LUMINANCE_ALPHA","TEXTUREFORMAT_RGB","TEXTUREFORMAT_RGBA","TEXTUREFORMAT_RED","TEXTUREFORMAT_R","TEXTUREFORMAT_R16_UNORM","TEXTUREFORMAT_RG16_UNORM","TEXTUREFORMAT_RGB16_UNORM","TEXTUREFORMAT_RGBA16_UNORM","TEXTUREFORMAT_R16_SNORM","TEXTUREFORMAT_RG16_SNORM","TEXTUREFORMAT_RGB16_SNORM","TEXTUREFORMAT_RGBA16_SNORM","TEXTUREFORMAT_RG","TEXTUREFORMAT_RED_INTEGER","TEXTUREFORMAT_R_INTEGER","TEXTUREFORMAT_RG_INTEGER","TEXTUREFORMAT_RGB_INTEGER","TEXTUREFORMAT_RGBA_INTEGER","TEXTURETYPE_UNSIGNED_BYTE","TEXTURETYPE_UNSIGNED_INT","TEXTURETYPE_FLOAT","TEXTURETYPE_HALF_FLOAT","TEXTURETYPE_BYTE","TEXTURETYPE_SHORT","TEXTURETYPE_UNSIGNED_SHORT","TEXTURETYPE_INT","TEXTURETYPE_UNSIGNED_INTEGER","TEXTURETYPE_UNSIGNED_SHORT_4_4_4_4","TEXTURETYPE_UNSIGNED_SHORT_5_5_5_1","TEXTURETYPE_UNSIGNED_SHORT_5_6_5","TEXTURETYPE_UNSIGNED_INT_2_10_10_10_REV","TEXTURETYPE_UNSIGNED_INT_24_8","TEXTURETYPE_UNSIGNED_INT_10F_11F_11F_REV","TEXTURETYPE_UNSIGNED_INT_5_9_9_9_REV","TEXTURETYPE_FLOAT_32_UNSIGNED_INT_24_8_REV","TEXTURE_NEAREST_SAMPLINGMODE","TEXTURE_BILINEAR_SAMPLINGMODE","TEXTURE_TRILINEAR_SAMPLINGMODE","TEXTURE_NEAREST_NEAREST_MIPLINEAR","TEXTURE_LINEAR_LINEAR_MIPNEAREST","TEXTURE_LINEAR_LINEAR_MIPLINEAR","TEXTURE_NEAREST_NEAREST_MIPNEAREST","TEXTURE_NEAREST_LINEAR_MIPNEAREST","TEXTURE_NEAREST_LINEAR_MIPLINEAR","TEXTURE_NEAREST_LINEAR","TEXTURE_NEAREST_NEAREST","TEXTURE_LINEAR_NEAREST_MIPNEAREST","TEXTURE_LINEAR_NEAREST_MIPLINEAR","TEXTURE_LINEAR_LINEAR","TEXTURE_LINEAR_NEAREST","TEXTURE_EXPLICIT_MODE","TEXTURE_SPHERICAL_MODE","TEXTURE_PLANAR_MODE","TEXTURE_CUBIC_MODE","TEXTURE_PROJECTION_MODE","TEXTURE_SKYBOX_MODE","TEXTURE_INVCUBIC_MODE","TEXTURE_EQUIRECTANGULAR_MODE","TEXTURE_FIXED_EQUIRECTANGULAR_MODE","TEXTURE_FIXED_EQUIRECTANGULAR_MIRRORED_MODE","SCALEMODE_FLOOR","SCALEMODE_NEAREST","SCALEMODE_CEILING","ThinPassPostProcess","useShaderStore","useAsPostProcess","FragmentUrl","useWebGPU","list","_webGPUReady","ThinPassCubePostProcess","_face","updateEffect","PassPostProcess","reusable","localOptions","blockCompilation","effectWrapper","parsedPostProcess","targetCamera","renderTargetSamplingMode","floatView","int32View","PassCubePostProcess","_effectWrapper","ApplyPostProcess","postProcessName","encodedTexture","restoreDefaultFramebuffer","_releaseTexture","_swapAndDie","ToHalfFloat","bits","FromHalfFloat","setTextureFromPostProcess","postProcessInput","_forcedOutputTexture","_textures","_currentRenderTextureInd","setTextureFromPostProcessOutput","PostProcess","fragmentUrl","parameters","samplers","nodeMaterialSource","forceAutoClearInAlphaMode","enablePixelPerfectMode","forceFullscreenViewport","scaleMode","alwaysForcePOT","adaptScaleToCurrentViewport","_reusable","_renderId","_textureCache","_scaleRatio","_texelSize","onActivateObservable","onSizeChangedObservable","onApplyObservable","uniforms","vertexUrl","indexParameters","shaderLanguage","extraInitializations","useExistingThinPostProcess","_camera","attachPostProcess","_options","_textureType","_textureFormat","_shaderLanguage","_fragmentUrl","_vertexUrl","_parameters","_indexParameters","importPromises","_gatherImports","ForceGLSL","_postConstructor","alphaMode","maxMSAASamples","_onActivateObserver","_onSizeChangedObserver","_onApplyObserver","markTextureDirty","_shareOutputWithPostProcess","texelSize","drawWrapper","_disposeTextures","_postProcessDefines","textureOptions","postProcessChannel","tex","lastUsedRenderId","currentRenderId","currentlyUsed","needMipMaps","forceDepthStencil","firstPP","isStencilEnable","_createRenderTargetTexture","inputTexture","cameraOrScene","sourceTexture","cameraRigMode","maxSize","maxTextureSize","requiredWidth","requiredHeight","desiredWidth","desiredHeight","_getTarget","updateRenderTargetTextureSampleCount","_flushTextureCache","_debugInsertMarker","_allowPostProcessClearColor","isSupported","aspectRatio","enableEffect","setState","setDepthBuffer","alphaConstants","setVector2","bind","_disposeTextureCache","prePassRenderer","_prePassEffectConfiguration","addEffectConfiguration","detachPostProcess","firstPostProcess","_getFirstPostProcess","getCamera","cameraId","force","customShaderCodeProcessing","RegisterShaderCodeProcessing","postProcessType","_Parse","PostProcessManager","_vertexBuffers","vertices","_buildIndexBuffer","_indexBuffer","createIndexBuffer","vb","pp","postProcessesEnabled","activate","targetTexture","lodLevel","doNotBindFrambuffer","_prepareBuffers","bindBuffers","drawElementsType","doNotPresent","setAlphaMode","RenderingGroup","_opaqueSubMeshes","_transparentSubMeshes","_alphaTestSubMeshes","_depthOnlySubMeshes","_particleSystems","_spriteManagers","_empty","_edgesRenderers","_opaqueSortCompareFn","PainterSortCompare","_renderOpaque","_renderOpaqueSorted","_alphaTestSortCompareFn","_renderAlphaTest","_renderAlphaTestSorted","_transparentSortCompareFn","defaultTransparentSortCompare","_renderTransparent","_renderTransparentSorted","activeMeshes","setColorWrite","stencilState","_renderSprites","_renderParticles","onBeforeTransparentRendering","useOrderIndependentTransparency","excludedMeshes","depthPeelingRenderer","edgesRendererIndex","_RenderSorted","prepareSprites","getMesh","getMaterial","needAlphaBlendingForMesh","needAlphaTesting","needDepthPrePass","_renderingGroup","_edgesRenderer","spriteManager","onBeforeParticlesRenderingObservable","_activeParticles","addCount","onAfterParticlesRenderingObservable","spritesEnabled","onBeforeSpritesRenderingObservable","onAfterSpritesRenderingObservable","sortCompareFn","transparent","cameraPosition","globalPosition","_ZeroVector","_alphaIndex","alphaIndex","_distanceToCamera","getBoundingInfo","boundingSphere","centerWorld","sortedArray","_activeMeshesFrozenButKeepClipping","isInFrustum","_frustumPlanes","backToFrontSortCompare","meshA","meshB","RenderingGroupInfo","RenderingManager","_renderingGroups","_autoClearDepthStencil","_customOpaqueSortCompareFn","_customAlphaTestSortCompareFn","_customTransparentSortCompareFn","_renderingGroupInfo","_maintainStateBetweenFrames","MIN_RENDERINGGROUPS","MAX_RENDERINGGROUPS","restoreDispachedFlags","_wasDispatched","spriteManagers","_prepareRenderingGroup","_depthStencilBufferAlreadyCleaned","renderingManager","manager","dispatchSprites","renderingGroup","renderingGroupMask","onBeforeRenderingGroupObservable","AUTOCLEAR","getAutoClearDepthStencilSetup","_clearDepthStencilBuffer","_beforeRenderingGroupDrawStage","_afterRenderingGroupDrawStage","onAfterRenderingGroupObservable","maintainStateBetweenFrames","prepare","getRenderingGroup","group","IncludesShadersStoreWGSL","IncludesShadersStore","__decorate","decorators","key","desc","getOwnPropertyDescriptor","Reflect","decorate"],"sourceRoot":""}