CesiumInspector.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. import {
  2. defined,
  3. destroyObject,
  4. DeveloperError,
  5. getElement,
  6. } from "@cesium/engine";
  7. import knockout from "../ThirdParty/knockout.js";
  8. import InspectorShared from "../InspectorShared.js";
  9. import CesiumInspectorViewModel from "./CesiumInspectorViewModel.js";
  10. /**
  11. * Inspector widget to aid in debugging
  12. *
  13. * @alias CesiumInspector
  14. * @constructor
  15. *
  16. * @param {Element|string} container The DOM element or ID that will contain the widget.
  17. * @param {Scene} scene The Scene instance to use.
  18. *
  19. * @demo {@link https://sandcastle.cesium.com/index.html?src=Cesium%20Inspector.html|Cesium Sandcastle Cesium Inspector Demo}
  20. */
  21. function CesiumInspector(container, scene) {
  22. //>>includeStart('debug', pragmas.debug);
  23. if (!defined(container)) {
  24. throw new DeveloperError("container is required.");
  25. }
  26. if (!defined(scene)) {
  27. throw new DeveloperError("scene is required.");
  28. }
  29. //>>includeEnd('debug');
  30. container = getElement(container);
  31. const performanceContainer = document.createElement("div");
  32. const viewModel = new CesiumInspectorViewModel(scene, performanceContainer);
  33. this._viewModel = viewModel;
  34. this._container = container;
  35. const element = document.createElement("div");
  36. this._element = element;
  37. const text = document.createElement("div");
  38. text.textContent = "Cesium Inspector";
  39. text.className = "cesium-cesiumInspector-button";
  40. text.setAttribute("data-bind", "click: toggleDropDown");
  41. element.appendChild(text);
  42. element.className = "cesium-cesiumInspector";
  43. element.setAttribute(
  44. "data-bind",
  45. 'css: { "cesium-cesiumInspector-visible" : dropDownVisible, "cesium-cesiumInspector-hidden" : !dropDownVisible }'
  46. );
  47. container.appendChild(this._element);
  48. const panel = document.createElement("div");
  49. panel.className = "cesium-cesiumInspector-dropDown";
  50. element.appendChild(panel);
  51. const createSection = InspectorShared.createSection;
  52. const createCheckbox = InspectorShared.createCheckbox;
  53. // General
  54. const generalSection = createSection(
  55. panel,
  56. "General",
  57. "generalVisible",
  58. "toggleGeneral"
  59. );
  60. const debugShowFrustums = createCheckbox("Show Frustums", "frustums");
  61. const frustumStatistics = document.createElement("div");
  62. frustumStatistics.className = "cesium-cesiumInspector-frustumStatistics";
  63. frustumStatistics.setAttribute(
  64. "data-bind",
  65. "visible: frustums, html: frustumStatisticText"
  66. );
  67. debugShowFrustums.appendChild(frustumStatistics);
  68. generalSection.appendChild(debugShowFrustums);
  69. generalSection.appendChild(
  70. createCheckbox("Show Frustum Planes", "frustumPlanes")
  71. );
  72. generalSection.appendChild(
  73. createCheckbox("Performance Display", "performance")
  74. );
  75. performanceContainer.className = "cesium-cesiumInspector-performanceDisplay";
  76. generalSection.appendChild(performanceContainer);
  77. const shaderCacheDisplay = document.createElement("div");
  78. shaderCacheDisplay.className = "cesium-cesiumInspector-shaderCache";
  79. shaderCacheDisplay.setAttribute("data-bind", "html: shaderCacheText");
  80. generalSection.appendChild(shaderCacheDisplay);
  81. const depthFrustum = document.createElement("div");
  82. generalSection.appendChild(depthFrustum);
  83. // Use a span with HTML binding so that we can indent with non-breaking spaces.
  84. const gLabel = document.createElement("span");
  85. gLabel.setAttribute(
  86. "data-bind",
  87. 'html: "     Frustum:"'
  88. );
  89. depthFrustum.appendChild(gLabel);
  90. const gText = document.createElement("span");
  91. gText.setAttribute("data-bind", "text: depthFrustumText");
  92. depthFrustum.appendChild(gText);
  93. const gMinusButton = document.createElement("input");
  94. gMinusButton.type = "button";
  95. gMinusButton.value = "-";
  96. gMinusButton.className = "cesium-cesiumInspector-pickButton";
  97. gMinusButton.setAttribute("data-bind", "click: decrementDepthFrustum");
  98. depthFrustum.appendChild(gMinusButton);
  99. const gPlusButton = document.createElement("input");
  100. gPlusButton.type = "button";
  101. gPlusButton.value = "+";
  102. gPlusButton.className = "cesium-cesiumInspector-pickButton";
  103. gPlusButton.setAttribute("data-bind", "click: incrementDepthFrustum");
  104. depthFrustum.appendChild(gPlusButton);
  105. // Primitives
  106. const primSection = createSection(
  107. panel,
  108. "Primitives",
  109. "primitivesVisible",
  110. "togglePrimitives"
  111. );
  112. const pickPrimRequired = document.createElement("div");
  113. pickPrimRequired.className = "cesium-cesiumInspector-pickSection";
  114. primSection.appendChild(pickPrimRequired);
  115. const pickPrimitiveButton = document.createElement("input");
  116. pickPrimitiveButton.type = "button";
  117. pickPrimitiveButton.value = "Pick a primitive";
  118. pickPrimitiveButton.className = "cesium-cesiumInspector-pickButton";
  119. pickPrimitiveButton.setAttribute(
  120. "data-bind",
  121. 'css: {"cesium-cesiumInspector-pickButtonHighlight" : pickPrimitiveActive}, click: pickPrimitive'
  122. );
  123. let buttonWrap = document.createElement("div");
  124. buttonWrap.className = "cesium-cesiumInspector-center";
  125. buttonWrap.appendChild(pickPrimitiveButton);
  126. pickPrimRequired.appendChild(buttonWrap);
  127. pickPrimRequired.appendChild(
  128. createCheckbox(
  129. "Show bounding sphere",
  130. "primitiveBoundingSphere",
  131. "hasPickedPrimitive"
  132. )
  133. );
  134. pickPrimRequired.appendChild(
  135. createCheckbox(
  136. "Show reference frame",
  137. "primitiveReferenceFrame",
  138. "hasPickedPrimitive"
  139. )
  140. );
  141. this._primitiveOnly = createCheckbox(
  142. "Show only selected",
  143. "filterPrimitive",
  144. "hasPickedPrimitive"
  145. );
  146. pickPrimRequired.appendChild(this._primitiveOnly);
  147. // Terrain
  148. const terrainSection = createSection(
  149. panel,
  150. "Terrain",
  151. "terrainVisible",
  152. "toggleTerrain"
  153. );
  154. const pickTileRequired = document.createElement("div");
  155. pickTileRequired.className = "cesium-cesiumInspector-pickSection";
  156. terrainSection.appendChild(pickTileRequired);
  157. const pickTileButton = document.createElement("input");
  158. pickTileButton.type = "button";
  159. pickTileButton.value = "Pick a tile";
  160. pickTileButton.className = "cesium-cesiumInspector-pickButton";
  161. pickTileButton.setAttribute(
  162. "data-bind",
  163. 'css: {"cesium-cesiumInspector-pickButtonHighlight" : pickTileActive}, click: pickTile'
  164. );
  165. buttonWrap = document.createElement("div");
  166. buttonWrap.appendChild(pickTileButton);
  167. buttonWrap.className = "cesium-cesiumInspector-center";
  168. pickTileRequired.appendChild(buttonWrap);
  169. const tileInfo = document.createElement("div");
  170. pickTileRequired.appendChild(tileInfo);
  171. const parentTile = document.createElement("input");
  172. parentTile.type = "button";
  173. parentTile.value = "Parent";
  174. parentTile.className = "cesium-cesiumInspector-pickButton";
  175. parentTile.setAttribute("data-bind", "click: selectParent");
  176. const nwTile = document.createElement("input");
  177. nwTile.type = "button";
  178. nwTile.value = "NW";
  179. nwTile.className = "cesium-cesiumInspector-pickButton";
  180. nwTile.setAttribute("data-bind", "click: selectNW");
  181. const neTile = document.createElement("input");
  182. neTile.type = "button";
  183. neTile.value = "NE";
  184. neTile.className = "cesium-cesiumInspector-pickButton";
  185. neTile.setAttribute("data-bind", "click: selectNE");
  186. const swTile = document.createElement("input");
  187. swTile.type = "button";
  188. swTile.value = "SW";
  189. swTile.className = "cesium-cesiumInspector-pickButton";
  190. swTile.setAttribute("data-bind", "click: selectSW");
  191. const seTile = document.createElement("input");
  192. seTile.type = "button";
  193. seTile.value = "SE";
  194. seTile.className = "cesium-cesiumInspector-pickButton";
  195. seTile.setAttribute("data-bind", "click: selectSE");
  196. const tileText = document.createElement("div");
  197. tileText.className = "cesium-cesiumInspector-tileText";
  198. tileInfo.className = "cesium-cesiumInspector-frustumStatistics";
  199. tileInfo.appendChild(tileText);
  200. tileInfo.setAttribute("data-bind", "visible: hasPickedTile");
  201. tileText.setAttribute("data-bind", "html: tileText");
  202. const relativeText = document.createElement("div");
  203. relativeText.className = "cesium-cesiumInspector-relativeText";
  204. relativeText.textContent = "Select relative:";
  205. tileInfo.appendChild(relativeText);
  206. const table = document.createElement("table");
  207. const tr1 = document.createElement("tr");
  208. const tr2 = document.createElement("tr");
  209. const td1 = document.createElement("td");
  210. td1.appendChild(parentTile);
  211. const td2 = document.createElement("td");
  212. td2.appendChild(nwTile);
  213. const td3 = document.createElement("td");
  214. td3.appendChild(neTile);
  215. tr1.appendChild(td1);
  216. tr1.appendChild(td2);
  217. tr1.appendChild(td3);
  218. const td4 = document.createElement("td");
  219. const td5 = document.createElement("td");
  220. td5.appendChild(swTile);
  221. const td6 = document.createElement("td");
  222. td6.appendChild(seTile);
  223. tr2.appendChild(td4);
  224. tr2.appendChild(td5);
  225. tr2.appendChild(td6);
  226. table.appendChild(tr1);
  227. table.appendChild(tr2);
  228. tileInfo.appendChild(table);
  229. pickTileRequired.appendChild(
  230. createCheckbox(
  231. "Show bounding volume",
  232. "tileBoundingSphere",
  233. "hasPickedTile"
  234. )
  235. );
  236. pickTileRequired.appendChild(
  237. createCheckbox("Show only selected", "filterTile", "hasPickedTile")
  238. );
  239. terrainSection.appendChild(createCheckbox("Wireframe", "wireframe"));
  240. terrainSection.appendChild(
  241. createCheckbox("Suspend LOD update", "suspendUpdates")
  242. );
  243. terrainSection.appendChild(
  244. createCheckbox("Show tile coordinates", "tileCoordinates")
  245. );
  246. knockout.applyBindings(viewModel, this._element);
  247. }
  248. Object.defineProperties(CesiumInspector.prototype, {
  249. /**
  250. * Gets the parent container.
  251. * @memberof CesiumInspector.prototype
  252. *
  253. * @type {Element}
  254. */
  255. container: {
  256. get: function () {
  257. return this._container;
  258. },
  259. },
  260. /**
  261. * Gets the view model.
  262. * @memberof CesiumInspector.prototype
  263. *
  264. * @type {CesiumInspectorViewModel}
  265. */
  266. viewModel: {
  267. get: function () {
  268. return this._viewModel;
  269. },
  270. },
  271. });
  272. /**
  273. * @returns {boolean} true if the object has been destroyed, false otherwise.
  274. */
  275. CesiumInspector.prototype.isDestroyed = function () {
  276. return false;
  277. };
  278. /**
  279. * Destroys the widget. Should be called if permanently
  280. * removing the widget from layout.
  281. */
  282. CesiumInspector.prototype.destroy = function () {
  283. knockout.cleanNode(this._element);
  284. this._container.removeChild(this._element);
  285. this.viewModel.destroy();
  286. return destroyObject(this);
  287. };
  288. export default CesiumInspector;