text: import { Observable } from "@babylonjs/core/Misc/observable";
  import { Vector3 } from "@babylonjs/core/Maths/math.vector";
  import { PointerEventTypes } from '@babylonjs/core/Events/pointerEvents';
  import { HemisphericLight } from "@babylonjs/core/Lights/hemisphericLight";
  import { UtilityLayerRenderer } from "@babylonjs/core/Rendering/utilityLayerRenderer";
  import { EngineStore } from "@babylonjs/core/Engines/engineStore";
  import { Container3D } from "./controls/container3D";
  /**
   * Class used to manage 3D user interface
   * @see https://doc.babylonjs.com/how_to/gui3d
   */
  var GUI3DManager = /** @class */ (function () {
      /**
       * Creates a new GUI3DManager
       * @param scene
       */
      function GUI3DManager(scene) {
          var _this = this;
          /** @hidden */
          this._lastControlOver = {};
          /** @hidden */
          this._lastControlDown = {};
          /**
           * Observable raised when the point picked by the pointer events changed
           */
          this.onPickedPointChangedObservable = new Observable();
          // Shared resources
          /** @hidden */
          this._sharedMaterials = {};
          this._scene = scene || EngineStore.LastCreatedScene;
          this._sceneDisposeObserver = this._scene.onDisposeObservable.add(function () {
              _this._sceneDisposeObserver = null;
              _this._utilityLayer = null;
              _this.dispose();
          });
          this._utilityLayer = new UtilityLayerRenderer(this._scene);
          this._utilityLayer.onlyCheckPointerDownEvents = false;
          this._utilityLayer.pickUtilitySceneFirst = false;
          this._utilityLayer.mainSceneTrackerPredicate = function (mesh) {
              return mesh && mesh.metadata && mesh.metadata._node;
          };
          // Root
          this._rootContainer = new Container3D("RootContainer");
          this._rootContainer._host = this;
          var utilityLayerScene = this._utilityLayer.utilityLayerScene;
          // Events
          this._pointerOutObserver = this._utilityLayer.onPointerOutObservable.add(function (pointerId) {
              _this._handlePointerOut(pointerId, true);
          });
          this._pointerObserver = utilityLayerScene.onPointerObservable.add(function (pi, state) {
              _this._doPicking(pi);
          });
          // Scene
          this._utilityLayer.utilityLayerScene.autoClear = false;
          this._utilityLayer.utilityLayerScene.autoClearDepthAndStencil = false;
          new HemisphericLight("hemi", Vector3.Up(), this._utilityLayer.utilityLayerScene);
      }
      Object.defineProperty(GUI3DManager.prototype, "scene", {
          /** Gets the hosting scene */
          get: function () {
              return this._scene;
          },
          enumerable: false,
          configurable: true
      });
      Object.defineProperty(GUI3DManager.prototype, "utilityLayer", {
          /** Gets associated utility layer */
          get: function () {
              return this._utilityLayer;
          },
          enumerable: false,
          configurable: true
      });
      GUI3DManager.prototype._handlePointerOut = function (pointerId, isPointerUp) {
          var previousControlOver = this._lastControlOver[pointerId];
          if (previousControlOver) {
              previousControlOver._onPointerOut(previousControlOver);
              delete this._lastControlOver[pointerId];
          }
          if (isPointerUp) {
              if (this._lastControlDown[pointerId]) {
                  this._lastControlDown[pointerId].forcePointerUp();
                  delete this._lastControlDown[pointerId];
              }
          }
          this.onPickedPointChangedObservable.notifyObservers(null);
      };
      GUI3DManager.prototype._doPicking = function (pi) {
          if (!this._utilityLayer || !this._utilityLayer.shouldRender || !this._utilityLayer.utilityLayerScene.activeCamera) {
              return false;
          }
          var pointerEvent = (pi.event);
          var pointerId = pointerEvent.pointerId || 0;
          var buttonIndex = pointerEvent.button;
          var pickingInfo = pi.pickInfo;
          if (!pickingInfo || !pickingInfo.hit) {
              this._handlePointerOut(pointerId, pi.type === PointerEventTypes.POINTERUP);
              return false;
          }
          var control = (pickingInfo.pickedMesh.metadata);
          if (pickingInfo.pickedPoint) {
              this.onPickedPointChangedObservable.notifyObservers(pickingInfo.pickedPoint);
          }
          if (!control._processObservables(pi.type, pickingInfo.pickedPoint, pointerId, buttonIndex)) {
              if (pi.type === PointerEventTypes.POINTERMOVE) {
                  if (this._lastControlOver[pointerId]) {
                      this._lastControlOver[pointerId]._onPointerOut(this._lastControlOver[pointerId]);
                  }
                  delete this._lastControlOver[pointerId];
              }
          }
          if (pi.type === PointerEventTypes.POINTERUP) {
              if (this._lastControlDown[pointerEvent.pointerId]) {
                  this._lastControlDown[pointerEvent.pointerId].forcePointerUp();
                  delete this._lastControlDown[pointerEvent.pointerId];
              }
              if (pointerEvent.pointerType === "touch") {
                  this._handlePointerOut(pointerId, false);
              }
          }
          return true;
      };
      Object.defineProperty(GUI3DManager.prototype, "rootContainer", {
          /**
           * Gets the root container
           */
          get: function () {
              return this._rootContainer;
          },
          enumerable: false,
          configurable: true
      });
      /**
       * Gets a boolean indicating if the given control is in the root child list
       * @param control defines the control to check
       * @returns true if the control is in the root child list
       */
      GUI3DManager.prototype.containsControl = function (control) {
          return this._rootContainer.containsControl(control);
      };
      /**
       * Adds a control to the root child list
       * @param control defines the control to add
       * @returns the current manager
       */
      GUI3DManager.prototype.addControl = function (control) {
          this._rootContainer.addControl(control);
          return this;
      };
      /**
       * Removes a control from the root child list
       * @param control defines the control to remove
       * @returns the current container
       */
      GUI3DManager.prototype.removeControl = function (control) {
          this._rootContainer.removeControl(control);
          return this;
      };
      /**
       * Releases all associated resources
       */
      GUI3DManager.prototype.dispose = function () {
          this._rootContainer.dispose();
          for (var materialName in this._sharedMaterials) {
              if (!this._sharedMaterials.hasOwnProperty(materialName)) {
                  continue;
              }
              this._sharedMaterials[materialName].dispose();
          }
          this._sharedMaterials = {};
          if (this._pointerOutObserver && this._utilityLayer) {
              this._utilityLayer.onPointerOutObservable.remove(this._pointerOutObserver);
              this._pointerOutObserver = null;
          }
          this.onPickedPointChangedObservable.clear();
          var utilityLayerScene = this._utilityLayer ? this._utilityLayer.utilityLayerScene : null;
          if (utilityLayerScene) {
              if (this._pointerObserver) {
                  utilityLayerScene.onPointerObservable.remove(this._pointerObserver);
                  this._pointerObserver = null;
              }
          }
          if (this._scene) {
              if (this._sceneDisposeObserver) {
                  this._scene.onDisposeObservable.remove(this._sceneDisposeObserver);
                  this._sceneDisposeObserver = null;
              }
          }
          if (this._utilityLayer) {
              this._utilityLayer.dispose();
          }
      };
      return GUI3DManager;
  }());
  export { GUI3DManager };
  //# sourceMappingURL=gui3DManager.js.map