UNPKG

@babylonjs/gui

Version:

Babylon.js GUI module =====================

536 lines 21.6 kB
import { __decorate } from "@babylonjs/core/tslib.es6.js"; import { serializeAsColor4, serializeAsVector3, serialize } from "@babylonjs/core/Misc/decorators.js"; import { SerializationHelper } from "@babylonjs/core/Misc/decorators.serialization.js"; import { Vector3, Vector4 } from "@babylonjs/core/Maths/math.vector.js"; import { Texture } from "@babylonjs/core/Materials/Textures/texture.js"; import { MaterialDefines } from "@babylonjs/core/Materials/materialDefines.js"; import { PushMaterial } from "@babylonjs/core/Materials/pushMaterial.js"; import { VertexBuffer } from "@babylonjs/core/Buffers/buffer.js"; import { RegisterClass } from "@babylonjs/core/Misc/typeStore.js"; import { Color3, Color4 } from "@babylonjs/core/Maths/math.color.js"; import { EffectFallbacks } from "@babylonjs/core/Materials/effectFallbacks.js"; import { Constants } from "@babylonjs/core/Engines/constants.js"; import "./shaders/fluentButton.fragment.js"; import "./shaders/fluentButton.vertex.js"; import { HandleFallbacksForShadows, PrepareAttributesForInstances, PrepareDefinesForAttributes, PrepareUniformsAndSamplersList } from "@babylonjs/core/Materials/materialHelper.functions.js"; import { Tools } from "@babylonjs/core/Misc/tools.js"; /** @internal */ class FluentButtonMaterialDefines extends MaterialDefines { constructor() { super(); this.RELATIVE_WIDTH = true; this.ENABLE_FADE = true; this._needNormals = true; this._needUVs = true; this.rebuild(); } } /** * Class used to render square buttons with fluent design * @since 5.0.0 */ export class FluentButtonMaterial extends PushMaterial { constructor(name, scene) { super(name, scene); /** * Gets or sets the width of the glowing edge, relative to the scale of the button. * (Default is 4% of the height). */ this.edgeWidth = 0.04; /** * Gets or sets the color of the glowing edge. */ this.edgeColor = new Color4(0.592157, 0.592157, 0.592157, 1.0); /** * Gets or sets the maximum intensity of the proximity light. */ this.proximityMaxIntensity = 0.45; /** * Gets or sets the maximum distance for the proximity light (Default is 16mm). */ this.proximityFarDistance = 0.16; /** * Gets or sets the radius of the proximity light when near to the surface. */ this.proximityNearRadius = 1.5; /** * Gets or sets the anisotropy of the proximity light. */ this.proximityAnisotropy = 1; /** * Gets or sets the amount of fuzzing in the selection focus. */ this.selectionFuzz = 0.5; /** * Gets or sets an override value to display the button as selected. */ this.selected = 0; /** * Gets or sets a value to manually fade the blob size. */ this.selectionFade = 0; /** * Gets or sets a value to manually shrink the blob size as it fades (see selectionFade). */ this.selectionFadeSize = 0.3; /** * Gets or sets the distance from the button the cursor should be for the button * to appear selected (Default is 8cm). */ this.selectedDistance = 0.08; /** * Gets or sets the fall-off distance for the selection fade (Default is 8cm). */ this.selectedFadeLength = 0.08; /** * Gets or sets the intensity of the luminous blob (Ranges 0-1, default is 0.5). */ this.blobIntensity = 0.5; /** * The size of the blob when the pointer is at the blobFarDistance (Default is 5cm). */ this.blobFarSize = 0.05; /** * The distance at which the pointer is considered near. See [left|right]BlobNearSize. (Default is 0cm). */ this.blobNearDistance = 0; /** * The distance at which the pointer is considered far. See [left|right]BlobFarSize. (Default is 8cm). */ this.blobFarDistance = 0.08; /** * The distance over which the blob intensity fades from full to none (Default is 8cm). */ this.blobFadeLength = 0.08; /** * Gets or sets whether the blob corresponding to the left index finger is enabled. */ this.leftBlobEnable = true; /** * Gets or sets the size of the left blob when the left pointer is considered near. See blobNearDistance. (Default is 2.5cm). */ this.leftBlobNearSize = 0.025; /** * Gets or sets the progress of the pulse animation on the left blob (Ranges 0-1). */ this.leftBlobPulse = 0; /** * Gets or sets the fade factor on the left blob. */ this.leftBlobFade = 1; /** * Gets or sets the inner fade on the left blob; */ this.leftBlobInnerFade = 0.01; /** * Gets or sets whether the blob corresponding to the right index finger is enabled. */ this.rightBlobEnable = true; /** * Gets or sets the size of the right blob when the right pointer is considered near. See blobNearDistance. (Default is 2.5cm). */ this.rightBlobNearSize = 0.025; /** * Gets or sets the progress of the pulse animation on the right blob (Ranges 0-1). */ this.rightBlobPulse = 0; /** * Gets or sets the fade factor on the right blob. */ this.rightBlobFade = 1; /** * Gets or sets the inner fade on the right blob; */ this.rightBlobInnerFade = 0.01; /** * Gets or sets the direction of the active face before the world transform is applied. * This should almost always be set to -z. */ this.activeFaceDir = new Vector3(0, 0, -1); /** * Gets or sets the button's up direction before the world transform is applied. * This should almost always be set to +y. */ this.activeFaceUp = new Vector3(0, 1, 0); /** * Gets or sets whether the edge fade effect is enabled. */ this.enableFade = true; /** * Gets or sets a value corresponding to the width of the edge fade effect (Default 1.5). */ this.fadeWidth = 1.5; /** * Gets or sets whether the active face is smoothly interpolated. */ this.smoothActiveFace = true; /** * Gets or sets whether the frame of the fluent button model is visible. * This is usually only enabled for debugging purposes. */ this.showFrame = false; /** * Gets or sets whether the blob color texture is used for the proximity * light effect. This is usually only disabled for debugging purposes. */ this.useBlobTexture = true; /** * Gets or sets the world-space position of the tip of the left index finger. */ this.globalLeftIndexTipPosition = Vector3.Zero(); /** * Gets or sets the world-space position of the tip of the right index finger. */ this.globalRightIndexTipPosition = Vector3.Zero(); this.alphaMode = Constants.ALPHA_ADD; this.disableDepthWrite = true; this.backFaceCulling = false; const blobTextureUrl = Tools.GetAssetUrl(FluentButtonMaterial.BLOB_TEXTURE_URL); this._blobTexture = new Texture(blobTextureUrl, this.getScene(), true, false, Texture.NEAREST_SAMPLINGMODE); } needAlphaBlending() { return true; } needAlphaTesting() { return true; } getAlphaTestTexture() { return null; } // Methods isReadyForSubMesh(mesh, subMesh) { const drawWrapper = subMesh._drawWrapper; if (this.isFrozen) { if (drawWrapper.effect && drawWrapper._wasPreviouslyReady) { return true; } } if (!subMesh.materialDefines) { subMesh.materialDefines = new FluentButtonMaterialDefines(); } const defines = subMesh.materialDefines; const scene = this.getScene(); if (this._isReadyForSubMesh(subMesh)) { return true; } const engine = scene.getEngine(); // Attribs PrepareDefinesForAttributes(mesh, defines, true, false); // Get correct effect if (defines.isDirty) { defines.markAsProcessed(); scene.resetCachedMaterial(); // Fallbacks const fallbacks = new EffectFallbacks(); if (defines.FOG) { fallbacks.addFallback(1, "FOG"); } HandleFallbacksForShadows(defines, fallbacks); defines.IMAGEPROCESSINGPOSTPROCESS = scene.imageProcessingConfiguration.applyByPostProcess; //Attributes const attribs = [VertexBuffer.PositionKind]; if (defines.NORMAL) { attribs.push(VertexBuffer.NormalKind); } if (defines.UV1) { attribs.push(VertexBuffer.UVKind); } if (defines.UV2) { attribs.push(VertexBuffer.UV2Kind); } if (defines.VERTEXCOLOR) { attribs.push(VertexBuffer.ColorKind); } if (defines.TANGENT) { attribs.push(VertexBuffer.TangentKind); } PrepareAttributesForInstances(attribs, defines); // Legacy browser patch const shaderName = "fluentButton"; const join = defines.toString(); const uniforms = [ "world", "viewProjection", "cameraPosition", "_Edge_Width_", "_Edge_Color_", "_Relative_Width_", "_Proximity_Max_Intensity_", "_Proximity_Far_Distance_", "_Proximity_Near_Radius_", "_Proximity_Anisotropy_", "_Selection_Fuzz_", "_Selected_", "_Selection_Fade_", "_Selection_Fade_Size_", "_Selected_Distance_", "_Selected_Fade_Length_", "_Blob_Enable_", "_Blob_Position_", "_Blob_Intensity_", "_Blob_Near_Size_", "_Blob_Far_Size_", "_Blob_Near_Distance_", "_Blob_Far_Distance_", "_Blob_Fade_Length_", "_Blob_Inner_Fade_", "_Blob_Pulse_", "_Blob_Fade_", "_Blob_Texture_", "_Blob_Enable_2_", "_Blob_Position_2_", "_Blob_Near_Size_2_", "_Blob_Inner_Fade_2_", "_Blob_Pulse_2_", "_Blob_Fade_2_", "_Active_Face_Dir_", "_Active_Face_Up_", "_Enable_Fade_", "_Fade_Width_", "_Smooth_Active_Face_", "_Show_Frame_", "_Use_Blob_Texture_", "Use_Global_Left_Index", "Use_Global_Right_Index", "Global_Left_Index_Tip_Position", "Global_Right_Index_Tip_Position", "Global_Left_Thumb_Tip_Position", "Global_Right_Thumb_Tip_Position", "Global_Left_Index_Tip_Proximity", "Global_Right_Index_Tip_Proximity", ]; const samplers = ["_Blob_Texture_"]; const uniformBuffers = []; PrepareUniformsAndSamplersList({ uniformsNames: uniforms, uniformBuffersNames: uniformBuffers, samplers: samplers, defines: defines, maxSimultaneousLights: 4, }); subMesh.setEffect(scene.getEngine().createEffect(shaderName, { attributes: attribs, uniformsNames: uniforms, uniformBuffersNames: uniformBuffers, samplers: samplers, defines: join, fallbacks: fallbacks, onCompiled: this.onCompiled, onError: this.onError, indexParameters: { maxSimultaneousLights: 4 }, }, engine), defines, this._materialContext); } if (!subMesh.effect || !subMesh.effect.isReady()) { return false; } defines._renderId = scene.getRenderId(); drawWrapper._wasPreviouslyReady = true; return true; } bindForSubMesh(world, mesh, subMesh) { const scene = this.getScene(); const defines = subMesh.materialDefines; if (!defines) { return; } const effect = subMesh.effect; if (!effect) { return; } this._activeEffect = effect; // Matrices this.bindOnlyWorldMatrix(world); this._activeEffect.setMatrix("viewProjection", scene.getTransformMatrix()); this._activeEffect.setVector3("cameraPosition", scene.activeCamera.position); // "Blob Texture" this._activeEffect.setTexture("_Blob_Texture_", this._blobTexture); // "Wireframe" this._activeEffect.setFloat("_Edge_Width_", this.edgeWidth); this._activeEffect.setColor4("_Edge_Color_", new Color3(this.edgeColor.r, this.edgeColor.g, this.edgeColor.b), this.edgeColor.a); //define _Relative_Width_ true; // "Proximity" this._activeEffect.setFloat("_Proximity_Max_Intensity_", this.proximityMaxIntensity); this._activeEffect.setFloat("_Proximity_Far_Distance_", this.proximityFarDistance); this._activeEffect.setFloat("_Proximity_Near_Radius_", this.proximityNearRadius); this._activeEffect.setFloat("_Proximity_Anisotropy_", this.proximityAnisotropy); // "Selection" this._activeEffect.setFloat("_Selection_Fuzz_", this.selectionFuzz); this._activeEffect.setFloat("_Selected_", this.selected); this._activeEffect.setFloat("_Selection_Fade_", this.selectionFade); this._activeEffect.setFloat("_Selection_Fade_Size_", this.selectionFadeSize); this._activeEffect.setFloat("_Selected_Distance_", this.selectedDistance); this._activeEffect.setFloat("_Selected_Fade_Length_", this.selectedFadeLength); // "Blob" this._activeEffect.setFloat("_Blob_Enable_", this.leftBlobEnable ? 1.0 : 0.0); this._activeEffect.setFloat("_Blob_Intensity_", this.blobIntensity); this._activeEffect.setFloat("_Blob_Near_Size_", this.leftBlobNearSize); this._activeEffect.setFloat("_Blob_Far_Size_", this.blobFarSize); this._activeEffect.setFloat("_Blob_Near_Distance_", this.blobNearDistance); this._activeEffect.setFloat("_Blob_Far_Distance_", this.blobFarDistance); this._activeEffect.setFloat("_Blob_Fade_Length_", this.blobFadeLength); this._activeEffect.setFloat("_Blob_Inner_Fade_", this.leftBlobInnerFade); this._activeEffect.setFloat("_Blob_Pulse_", this.leftBlobPulse); this._activeEffect.setFloat("_Blob_Fade_", this.leftBlobFade); // "Blob 2" this._activeEffect.setFloat("_Blob_Enable_2_", this.rightBlobEnable ? 1.0 : 0.0); this._activeEffect.setFloat("_Blob_Near_Size_2_", this.rightBlobNearSize); this._activeEffect.setFloat("_Blob_Inner_Fade_2_", this.rightBlobInnerFade); this._activeEffect.setFloat("_Blob_Pulse_2_", this.rightBlobPulse); this._activeEffect.setFloat("_Blob_Fade_2_", this.rightBlobFade); // "Active Face" this._activeEffect.setVector3("_Active_Face_Dir_", this.activeFaceDir); this._activeEffect.setVector3("_Active_Face_Up_", this.activeFaceUp); // "Hololens Edge Fade" //define _Enable_Fade_ true; this._activeEffect.setFloat("_Fade_Width_", this.fadeWidth); this._activeEffect.setFloat("_Smooth_Active_Face_", this.smoothActiveFace ? 1.0 : 0.0); // "Debug" this._activeEffect.setFloat("_Show_Frame_", this.showFrame ? 1.0 : 0.0); this._activeEffect.setFloat("_Use_Blob_Texture_", this.useBlobTexture ? 1.0 : 0.0); // Global inputs this._activeEffect.setFloat("Use_Global_Left_Index", 1.0); this._activeEffect.setFloat("Use_Global_Right_Index", 1.0); this._activeEffect.setVector4("Global_Left_Index_Tip_Position", new Vector4(this.globalLeftIndexTipPosition.x, this.globalLeftIndexTipPosition.y, this.globalLeftIndexTipPosition.z, 1.0)); this._activeEffect.setVector4("Global_Right_Index_Tip_Position", new Vector4(this.globalRightIndexTipPosition.x, this.globalRightIndexTipPosition.y, this.globalRightIndexTipPosition.z, 1.0)); this._afterBind(mesh, this._activeEffect, subMesh); } /** * Get the list of animatables in the material. * @returns the list of animatables object used in the material */ getAnimatables() { return []; } dispose(forceDisposeEffect) { super.dispose(forceDisposeEffect); } clone(name) { return SerializationHelper.Clone(() => new FluentButtonMaterial(name, this.getScene()), this); } serialize() { const serializationObject = super.serialize(); serializationObject.customType = "BABYLON.FluentButtonMaterial"; return serializationObject; } getClassName() { return "FluentButtonMaterial"; } // Statics static Parse(source, scene, rootUrl) { return SerializationHelper.Parse(() => new FluentButtonMaterial(source.name, scene), source, scene, rootUrl); } } /** * URL pointing to the texture used to define the coloring for the fluent blob effect. */ FluentButtonMaterial.BLOB_TEXTURE_URL = "https://assets.babylonjs.com/core/MRTK/mrtk-fluent-button-blob.png"; __decorate([ serialize() ], FluentButtonMaterial.prototype, "edgeWidth", void 0); __decorate([ serializeAsColor4() ], FluentButtonMaterial.prototype, "edgeColor", void 0); __decorate([ serialize() ], FluentButtonMaterial.prototype, "proximityMaxIntensity", void 0); __decorate([ serialize() ], FluentButtonMaterial.prototype, "proximityFarDistance", void 0); __decorate([ serialize() ], FluentButtonMaterial.prototype, "proximityNearRadius", void 0); __decorate([ serialize() ], FluentButtonMaterial.prototype, "proximityAnisotropy", void 0); __decorate([ serialize() ], FluentButtonMaterial.prototype, "selectionFuzz", void 0); __decorate([ serialize() ], FluentButtonMaterial.prototype, "selected", void 0); __decorate([ serialize() ], FluentButtonMaterial.prototype, "selectionFade", void 0); __decorate([ serialize() ], FluentButtonMaterial.prototype, "selectionFadeSize", void 0); __decorate([ serialize() ], FluentButtonMaterial.prototype, "selectedDistance", void 0); __decorate([ serialize() ], FluentButtonMaterial.prototype, "selectedFadeLength", void 0); __decorate([ serialize() ], FluentButtonMaterial.prototype, "blobIntensity", void 0); __decorate([ serialize() ], FluentButtonMaterial.prototype, "blobFarSize", void 0); __decorate([ serialize() ], FluentButtonMaterial.prototype, "blobNearDistance", void 0); __decorate([ serialize() ], FluentButtonMaterial.prototype, "blobFarDistance", void 0); __decorate([ serialize() ], FluentButtonMaterial.prototype, "blobFadeLength", void 0); __decorate([ serialize() ], FluentButtonMaterial.prototype, "leftBlobEnable", void 0); __decorate([ serialize() ], FluentButtonMaterial.prototype, "leftBlobNearSize", void 0); __decorate([ serialize() ], FluentButtonMaterial.prototype, "leftBlobPulse", void 0); __decorate([ serialize() ], FluentButtonMaterial.prototype, "leftBlobFade", void 0); __decorate([ serialize() ], FluentButtonMaterial.prototype, "leftBlobInnerFade", void 0); __decorate([ serialize() ], FluentButtonMaterial.prototype, "rightBlobEnable", void 0); __decorate([ serialize() ], FluentButtonMaterial.prototype, "rightBlobNearSize", void 0); __decorate([ serialize() ], FluentButtonMaterial.prototype, "rightBlobPulse", void 0); __decorate([ serialize() ], FluentButtonMaterial.prototype, "rightBlobFade", void 0); __decorate([ serialize() ], FluentButtonMaterial.prototype, "rightBlobInnerFade", void 0); __decorate([ serializeAsVector3() ], FluentButtonMaterial.prototype, "activeFaceDir", void 0); __decorate([ serializeAsVector3() ], FluentButtonMaterial.prototype, "activeFaceUp", void 0); __decorate([ serialize() ], FluentButtonMaterial.prototype, "enableFade", void 0); __decorate([ serialize() ], FluentButtonMaterial.prototype, "fadeWidth", void 0); __decorate([ serialize() ], FluentButtonMaterial.prototype, "smoothActiveFace", void 0); __decorate([ serialize() ], FluentButtonMaterial.prototype, "showFrame", void 0); __decorate([ serialize() ], FluentButtonMaterial.prototype, "useBlobTexture", void 0); __decorate([ serializeAsVector3() ], FluentButtonMaterial.prototype, "globalLeftIndexTipPosition", void 0); __decorate([ serializeAsVector3() ], FluentButtonMaterial.prototype, "globalRightIndexTipPosition", void 0); RegisterClass("BABYLON.GUI.FluentButtonMaterial", FluentButtonMaterial); //# sourceMappingURL=fluentButtonMaterial.js.map