debugLayer.js 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. import { Tools } from "../Misc/tools.js";
  2. import { Observable } from "../Misc/observable.js";
  3. import { Scene } from "../scene.js";
  4. import { Engine } from "../Engines/engine.js";
  5. import { EngineStore } from "../Engines/engineStore.js";
  6. Object.defineProperty(Scene.prototype, "debugLayer", {
  7. get: function () {
  8. if (!this._debugLayer) {
  9. this._debugLayer = new DebugLayer(this);
  10. }
  11. return this._debugLayer;
  12. },
  13. enumerable: true,
  14. configurable: true,
  15. });
  16. /**
  17. * Enum of inspector action tab
  18. */
  19. export var DebugLayerTab;
  20. (function (DebugLayerTab) {
  21. /**
  22. * Properties tag (default)
  23. */
  24. DebugLayerTab[DebugLayerTab["Properties"] = 0] = "Properties";
  25. /**
  26. * Debug tab
  27. */
  28. DebugLayerTab[DebugLayerTab["Debug"] = 1] = "Debug";
  29. /**
  30. * Statistics tab
  31. */
  32. DebugLayerTab[DebugLayerTab["Statistics"] = 2] = "Statistics";
  33. /**
  34. * Tools tab
  35. */
  36. DebugLayerTab[DebugLayerTab["Tools"] = 3] = "Tools";
  37. /**
  38. * Settings tab
  39. */
  40. DebugLayerTab[DebugLayerTab["Settings"] = 4] = "Settings";
  41. })(DebugLayerTab || (DebugLayerTab = {}));
  42. /**
  43. * The debug layer (aka Inspector) is the go to tool in order to better understand
  44. * what is happening in your scene
  45. * @see https://doc.babylonjs.com/toolsAndResources/inspector
  46. */
  47. export class DebugLayer {
  48. /**
  49. * Observable triggered when a property is changed through the inspector.
  50. */
  51. get onPropertyChangedObservable() {
  52. if (this.BJSINSPECTOR && this.BJSINSPECTOR.Inspector) {
  53. return this.BJSINSPECTOR.Inspector.OnPropertyChangedObservable;
  54. }
  55. if (!this._onPropertyChangedObservable) {
  56. this._onPropertyChangedObservable = new Observable();
  57. }
  58. return this._onPropertyChangedObservable;
  59. }
  60. /**
  61. * Observable triggered when the selection is changed through the inspector.
  62. */
  63. get onSelectionChangedObservable() {
  64. if (this.BJSINSPECTOR && this.BJSINSPECTOR.Inspector) {
  65. return this.BJSINSPECTOR.Inspector.OnSelectionChangeObservable;
  66. }
  67. if (!this._onSelectionChangedObservable) {
  68. this._onSelectionChangedObservable = new Observable();
  69. }
  70. return this._onSelectionChangedObservable;
  71. }
  72. /**
  73. * Instantiates a new debug layer.
  74. * The debug layer (aka Inspector) is the go to tool in order to better understand
  75. * what is happening in your scene
  76. * @see https://doc.babylonjs.com/toolsAndResources/inspector
  77. * @param scene Defines the scene to inspect
  78. */
  79. constructor(scene) {
  80. // eslint-disable-next-line @typescript-eslint/naming-convention
  81. this.BJSINSPECTOR = this._getGlobalInspector();
  82. this._scene = scene || EngineStore.LastCreatedScene;
  83. if (!this._scene) {
  84. return;
  85. }
  86. this._scene.onDisposeObservable.add(() => {
  87. // Debug layer
  88. if (this._scene._debugLayer) {
  89. this._scene._debugLayer.hide();
  90. }
  91. });
  92. }
  93. /**
  94. * Creates the inspector window.
  95. * @param config
  96. */
  97. _createInspector(config) {
  98. if (this.isVisible()) {
  99. return;
  100. }
  101. if (this._onPropertyChangedObservable) {
  102. for (const observer of this._onPropertyChangedObservable.observers) {
  103. this.BJSINSPECTOR.Inspector.OnPropertyChangedObservable.add(observer);
  104. }
  105. this._onPropertyChangedObservable.clear();
  106. this._onPropertyChangedObservable = undefined;
  107. }
  108. if (this._onSelectionChangedObservable) {
  109. for (const observer of this._onSelectionChangedObservable.observers) {
  110. this.BJSINSPECTOR.Inspector.OnSelectionChangedObservable.add(observer);
  111. }
  112. this._onSelectionChangedObservable.clear();
  113. this._onSelectionChangedObservable = undefined;
  114. }
  115. const userOptions = {
  116. ...DebugLayer.Config,
  117. ...config,
  118. };
  119. this.BJSINSPECTOR = this.BJSINSPECTOR || this._getGlobalInspector();
  120. this.BJSINSPECTOR.Inspector.Show(this._scene, userOptions);
  121. }
  122. /**
  123. * Select a specific entity in the scene explorer and highlight a specific block in that entity property grid
  124. * @param entity defines the entity to select
  125. * @param lineContainerTitles defines the specific blocks to highlight (could be a string or an array of strings)
  126. */
  127. select(entity, lineContainerTitles) {
  128. if (this.BJSINSPECTOR) {
  129. if (lineContainerTitles) {
  130. if (Object.prototype.toString.call(lineContainerTitles) == "[object String]") {
  131. this.BJSINSPECTOR.Inspector.MarkLineContainerTitleForHighlighting(lineContainerTitles);
  132. }
  133. else {
  134. this.BJSINSPECTOR.Inspector.MarkMultipleLineContainerTitlesForHighlighting(lineContainerTitles);
  135. }
  136. }
  137. this.BJSINSPECTOR.Inspector.OnSelectionChangeObservable.notifyObservers(entity);
  138. }
  139. }
  140. /**
  141. * Get the inspector from bundle or global
  142. * @returns the inspector instance if found otherwise, null
  143. */
  144. _getGlobalInspector() {
  145. // UMD Global name detection from Webpack Bundle UMD Name.
  146. if (typeof INSPECTOR !== "undefined") {
  147. return INSPECTOR;
  148. }
  149. // In case of module let s check the global emitted from the Inspector entry point.
  150. if (typeof BABYLON !== "undefined" && typeof BABYLON.Inspector !== "undefined") {
  151. return BABYLON;
  152. }
  153. return undefined;
  154. }
  155. /**
  156. * Get if the inspector is visible or not.
  157. * @returns true if visible otherwise, false
  158. */
  159. isVisible() {
  160. return this.BJSINSPECTOR && this.BJSINSPECTOR.Inspector.IsVisible;
  161. }
  162. /**
  163. * Hide the inspector and close its window.
  164. */
  165. hide() {
  166. if (this.BJSINSPECTOR) {
  167. this.BJSINSPECTOR.Inspector.Hide();
  168. }
  169. }
  170. /**
  171. * Update the scene in the inspector
  172. */
  173. setAsActiveScene() {
  174. if (this.BJSINSPECTOR) {
  175. this.BJSINSPECTOR.Inspector._SetNewScene(this._scene);
  176. }
  177. }
  178. /**
  179. * Launch the debugLayer.
  180. * @param config Define the configuration of the inspector
  181. * @returns a promise fulfilled when the debug layer is visible
  182. */
  183. show(config) {
  184. return new Promise((resolve) => {
  185. if (typeof this.BJSINSPECTOR == "undefined") {
  186. const inspectorUrl = config && config.inspectorURL ? config.inspectorURL : DebugLayer.InspectorURL;
  187. // Load inspector and add it to the DOM
  188. Tools.LoadBabylonScript(inspectorUrl, () => {
  189. this._createInspector(config);
  190. resolve(this);
  191. });
  192. }
  193. else {
  194. // Otherwise creates the inspector
  195. this._createInspector(config);
  196. resolve(this);
  197. }
  198. });
  199. }
  200. }
  201. /**
  202. * Define the url to get the inspector script from.
  203. * By default it uses the babylonjs CDN.
  204. * @ignoreNaming
  205. */
  206. DebugLayer.InspectorURL = `${Tools._DefaultCdnUrl}/v${Engine.Version}/inspector/babylon.inspector.bundle.js`;
  207. /**
  208. * The default configuration of the inspector
  209. */
  210. DebugLayer.Config = {
  211. overlay: false,
  212. showExplorer: true,
  213. showInspector: true,
  214. embedMode: false,
  215. handleResize: true,
  216. enablePopup: true,
  217. };
  218. //# sourceMappingURL=debugLayer.js.map