CesiumInspector.js 10 KB

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