button3D.ts 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. import { AbstractButton3D } from "./abstractButton3D";
  2. import { Material, Nullable, int, Color3, StandardMaterial, Texture, Scene, TransformNode, Vector4, MeshBuilder, AbstractMesh } from "babylonjs";
  3. import { AdvancedDynamicTexture } from "../../2D/advancedDynamicTexture";
  4. import { Control } from "../../2D/controls/control";
  5. /**
  6. * Class used to create a button in 3D
  7. */
  8. export class Button3D extends AbstractButton3D {
  9. /** @hidden */
  10. protected _currentMaterial: Material;
  11. private _facadeTexture: Nullable<AdvancedDynamicTexture>;
  12. private _content: Control;
  13. private _contentResolution = 512;
  14. private _contentScaleRatio = 2;
  15. /**
  16. * Gets or sets the texture resolution used to render content (512 by default)
  17. */
  18. public get contentResolution(): int {
  19. return this._contentResolution;
  20. }
  21. public set contentResolution(value: int) {
  22. if (this._contentResolution === value) {
  23. return;
  24. }
  25. this._contentResolution = value;
  26. this._resetContent();
  27. }
  28. /**
  29. * Gets or sets the texture scale ratio used to render content (2 by default)
  30. */
  31. public get contentScaleRatio(): number {
  32. return this._contentScaleRatio;
  33. }
  34. public set contentScaleRatio(value: number) {
  35. if (this._contentScaleRatio === value) {
  36. return;
  37. }
  38. this._contentScaleRatio = value;
  39. this._resetContent();
  40. }
  41. protected _disposeFacadeTexture() {
  42. if (this._facadeTexture) {
  43. this._facadeTexture.dispose();
  44. this._facadeTexture = null;
  45. }
  46. }
  47. protected _resetContent() {
  48. this._disposeFacadeTexture();
  49. this.content = this._content;
  50. }
  51. /**
  52. * Creates a new button
  53. * @param name defines the control name
  54. */
  55. constructor(name?: string) {
  56. super(name);
  57. // Default animations
  58. this.pointerEnterAnimation = () => {
  59. if (!this.mesh) {
  60. return;
  61. }
  62. (<StandardMaterial>this._currentMaterial).emissiveColor = Color3.Red();
  63. };
  64. this.pointerOutAnimation = () => {
  65. (<StandardMaterial>this._currentMaterial).emissiveColor = Color3.Black();
  66. };
  67. this.pointerDownAnimation = () => {
  68. if (!this.mesh) {
  69. return;
  70. }
  71. this.mesh.scaling.scaleInPlace(0.95);
  72. };
  73. this.pointerUpAnimation = () => {
  74. if (!this.mesh) {
  75. return;
  76. }
  77. this.mesh.scaling.scaleInPlace(1.0 / 0.95);
  78. };
  79. }
  80. /**
  81. * Gets or sets the GUI 2D content used to display the button's facade
  82. */
  83. public get content(): Control {
  84. return this._content;
  85. }
  86. public set content(value: Control) {
  87. this._content = value;
  88. if (!this._host || !this._host.utilityLayer) {
  89. return;
  90. }
  91. if (!this._facadeTexture) {
  92. this._facadeTexture = new AdvancedDynamicTexture("Facade", this._contentResolution, this._contentResolution, this._host.utilityLayer.utilityLayerScene, true, Texture.TRILINEAR_SAMPLINGMODE);
  93. this._facadeTexture.rootContainer.scaleX = this._contentScaleRatio;
  94. this._facadeTexture.rootContainer.scaleY = this._contentScaleRatio;
  95. this._facadeTexture.premulAlpha = true;
  96. }
  97. this._facadeTexture.addControl(value);
  98. this._applyFacade(this._facadeTexture);
  99. }
  100. /**
  101. * Apply the facade texture (created from the content property).
  102. * This function can be overloaded by child classes
  103. * @param facadeTexture defines the AdvancedDynamicTexture to use
  104. */
  105. protected _applyFacade(facadeTexture: AdvancedDynamicTexture) {
  106. (<any>this._currentMaterial).emissiveTexture = facadeTexture;
  107. }
  108. protected _getTypeName(): string {
  109. return "Button3D";
  110. }
  111. // Mesh association
  112. protected _createNode(scene: Scene): TransformNode {
  113. var faceUV = new Array(6);
  114. for (var i = 0; i < 6; i++) {
  115. faceUV[i] = new Vector4(0, 0, 0, 0);
  116. }
  117. faceUV[1] = new Vector4(0, 0, 1, 1);
  118. let mesh = MeshBuilder.CreateBox(this.name + "_rootMesh", {
  119. width: 1.0,
  120. height: 1.0,
  121. depth: 0.08,
  122. faceUV: faceUV
  123. }, scene);
  124. return mesh;
  125. }
  126. protected _affectMaterial(mesh: AbstractMesh) {
  127. let material = new StandardMaterial(this.name + "Material", mesh.getScene());
  128. material.specularColor = Color3.Black();
  129. mesh.material = material;
  130. this._currentMaterial = material;
  131. this._resetContent();
  132. }
  133. /**
  134. * Releases all associated resources
  135. */
  136. public dispose() {
  137. super.dispose();
  138. this._disposeFacadeTexture();
  139. if (this._currentMaterial) {
  140. this._currentMaterial.dispose();
  141. }
  142. }
  143. }