CesiumInspectorViewModel.js 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978
  1. import Cartesian3 from "../../Core/Cartesian3.js";
  2. import defined from "../../Core/defined.js";
  3. import destroyObject from "../../Core/destroyObject.js";
  4. import DeveloperError from "../../Core/DeveloperError.js";
  5. import Ray from "../../Core/Ray.js";
  6. import Rectangle from "../../Core/Rectangle.js";
  7. import ScreenSpaceEventHandler from "../../Core/ScreenSpaceEventHandler.js";
  8. import ScreenSpaceEventType from "../../Core/ScreenSpaceEventType.js";
  9. import DebugModelMatrixPrimitive from "../../Scene/DebugModelMatrixPrimitive.js";
  10. import PerformanceDisplay from "../../Scene/PerformanceDisplay.js";
  11. import TileCoordinatesImageryProvider from "../../Scene/TileCoordinatesImageryProvider.js";
  12. import knockout from "../../ThirdParty/knockout.js";
  13. import createCommand from "../createCommand.js";
  14. function frustumStatisticsToString(statistics) {
  15. let str;
  16. if (defined(statistics)) {
  17. str = "Command Statistics";
  18. const com = statistics.commandsInFrustums;
  19. for (const n in com) {
  20. if (com.hasOwnProperty(n)) {
  21. let num = parseInt(n, 10);
  22. let s;
  23. if (num === 7) {
  24. s = "1, 2 and 3";
  25. } else {
  26. const f = [];
  27. for (let i = 2; i >= 0; i--) {
  28. const p = Math.pow(2, i);
  29. if (num >= p) {
  30. f.push(i + 1);
  31. num -= p;
  32. }
  33. }
  34. s = f.reverse().join(" and ");
  35. }
  36. str += `<br>&nbsp;&nbsp;&nbsp;&nbsp;${com[n]} in frustum ${s}`;
  37. }
  38. }
  39. str += `<br>Total: ${statistics.totalCommands}`;
  40. }
  41. return str;
  42. }
  43. function boundDepthFrustum(lower, upper, proposed) {
  44. let bounded = Math.min(proposed, upper);
  45. bounded = Math.max(bounded, lower);
  46. return bounded;
  47. }
  48. const scratchPickRay = new Ray();
  49. const scratchPickCartesian = new Cartesian3();
  50. /**
  51. * The view model for {@link CesiumInspector}.
  52. * @alias CesiumInspectorViewModel
  53. * @constructor
  54. *
  55. * @param {Scene} scene The scene instance to use.
  56. * @param {Element} performanceContainer The instance to use for performance container.
  57. */
  58. function CesiumInspectorViewModel(scene, performanceContainer) {
  59. //>>includeStart('debug', pragmas.debug);
  60. if (!defined(scene)) {
  61. throw new DeveloperError("scene is required");
  62. }
  63. if (!defined(performanceContainer)) {
  64. throw new DeveloperError("performanceContainer is required");
  65. }
  66. //>>includeEnd('debug');
  67. const that = this;
  68. const canvas = scene.canvas;
  69. const eventHandler = new ScreenSpaceEventHandler(canvas);
  70. this._eventHandler = eventHandler;
  71. this._scene = scene;
  72. this._canvas = canvas;
  73. this._primitive = undefined;
  74. this._tile = undefined;
  75. this._modelMatrixPrimitive = undefined;
  76. this._performanceDisplay = undefined;
  77. this._performanceContainer = performanceContainer;
  78. const globe = this._scene.globe;
  79. globe.depthTestAgainstTerrain = true;
  80. /**
  81. * Gets or sets the show frustums state. This property is observable.
  82. * @type {Boolean}
  83. * @default false
  84. */
  85. this.frustums = false;
  86. /**
  87. * Gets or sets the show frustum planes state. This property is observable.
  88. * @type {Boolean}
  89. * @default false
  90. */
  91. this.frustumPlanes = false;
  92. /**
  93. * Gets or sets the show performance display state. This property is observable.
  94. * @type {Boolean}
  95. * @default false
  96. */
  97. this.performance = false;
  98. /**
  99. * Gets or sets the shader cache text. This property is observable.
  100. * @type {String}
  101. * @default ''
  102. */
  103. this.shaderCacheText = "";
  104. /**
  105. * Gets or sets the show primitive bounding sphere state. This property is observable.
  106. * @type {Boolean}
  107. * @default false
  108. */
  109. this.primitiveBoundingSphere = false;
  110. /**
  111. * Gets or sets the show primitive reference frame state. This property is observable.
  112. * @type {Boolean}
  113. * @default false
  114. */
  115. this.primitiveReferenceFrame = false;
  116. /**
  117. * Gets or sets the filter primitive state. This property is observable.
  118. * @type {Boolean}
  119. * @default false
  120. */
  121. this.filterPrimitive = false;
  122. /**
  123. * Gets or sets the show tile bounding sphere state. This property is observable.
  124. * @type {Boolean}
  125. * @default false
  126. */
  127. this.tileBoundingSphere = false;
  128. /**
  129. * Gets or sets the filter tile state. This property is observable.
  130. * @type {Boolean}
  131. * @default false
  132. */
  133. this.filterTile = false;
  134. /**
  135. * Gets or sets the show wireframe state. This property is observable.
  136. * @type {Boolean}
  137. * @default false
  138. */
  139. this.wireframe = false;
  140. /**
  141. * Gets or sets the index of the depth frustum to display. This property is observable.
  142. * @type {Number}
  143. * @default 1
  144. */
  145. this.depthFrustum = 1;
  146. this._numberOfFrustums = 1;
  147. /**
  148. * Gets or sets the suspend updates state. This property is observable.
  149. * @type {Boolean}
  150. * @default false
  151. */
  152. this.suspendUpdates = false;
  153. /**
  154. * Gets or sets the show tile coordinates state. This property is observable.
  155. * @type {Boolean}
  156. * @default false
  157. */
  158. this.tileCoordinates = false;
  159. /**
  160. * Gets or sets the frustum statistic text. This property is observable.
  161. * @type {String}
  162. * @default ''
  163. */
  164. this.frustumStatisticText = false;
  165. /**
  166. * Gets or sets the selected tile information text. This property is observable.
  167. * @type {String}
  168. * @default ''
  169. */
  170. this.tileText = "";
  171. /**
  172. * Gets if a primitive has been selected. This property is observable.
  173. * @type {Boolean}
  174. * @default false
  175. */
  176. this.hasPickedPrimitive = false;
  177. /**
  178. * Gets if a tile has been selected. This property is observable
  179. * @type {Boolean}
  180. * @default false
  181. */
  182. this.hasPickedTile = false;
  183. /**
  184. * Gets if the picking primitive command is active. This property is observable.
  185. * @type {Boolean}
  186. * @default false
  187. */
  188. this.pickPrimitiveActive = false;
  189. /**
  190. * Gets if the picking tile command is active. This property is observable.
  191. * @type {Boolean}
  192. * @default false
  193. */
  194. this.pickTileActive = false;
  195. /**
  196. * Gets or sets if the cesium inspector drop down is visible. This property is observable.
  197. * @type {Boolean}
  198. * @default true
  199. */
  200. this.dropDownVisible = true;
  201. /**
  202. * Gets or sets if the general section is visible. This property is observable.
  203. * @type {Boolean}
  204. * @default true
  205. */
  206. this.generalVisible = true;
  207. /**
  208. * Gets or sets if the primitive section is visible. This property is observable.
  209. * @type {Boolean}
  210. * @default false
  211. */
  212. this.primitivesVisible = false;
  213. /**
  214. * Gets or sets if the terrain section is visible. This property is observable.
  215. * @type {Boolean}
  216. * @default false
  217. */
  218. this.terrainVisible = false;
  219. /**
  220. * Gets or sets the index of the depth frustum text. This property is observable.
  221. * @type {String}
  222. * @default ''
  223. */
  224. this.depthFrustumText = "";
  225. knockout.track(this, [
  226. "frustums",
  227. "frustumPlanes",
  228. "performance",
  229. "shaderCacheText",
  230. "primitiveBoundingSphere",
  231. "primitiveReferenceFrame",
  232. "filterPrimitive",
  233. "tileBoundingSphere",
  234. "filterTile",
  235. "wireframe",
  236. "depthFrustum",
  237. "suspendUpdates",
  238. "tileCoordinates",
  239. "frustumStatisticText",
  240. "tileText",
  241. "hasPickedPrimitive",
  242. "hasPickedTile",
  243. "pickPrimitiveActive",
  244. "pickTileActive",
  245. "dropDownVisible",
  246. "generalVisible",
  247. "primitivesVisible",
  248. "terrainVisible",
  249. "depthFrustumText",
  250. ]);
  251. this._toggleDropDown = createCommand(function () {
  252. that.dropDownVisible = !that.dropDownVisible;
  253. });
  254. this._toggleGeneral = createCommand(function () {
  255. that.generalVisible = !that.generalVisible;
  256. });
  257. this._togglePrimitives = createCommand(function () {
  258. that.primitivesVisible = !that.primitivesVisible;
  259. });
  260. this._toggleTerrain = createCommand(function () {
  261. that.terrainVisible = !that.terrainVisible;
  262. });
  263. this._frustumsSubscription = knockout
  264. .getObservable(this, "frustums")
  265. .subscribe(function (val) {
  266. that._scene.debugShowFrustums = val;
  267. that._scene.requestRender();
  268. });
  269. this._frustumPlanesSubscription = knockout
  270. .getObservable(this, "frustumPlanes")
  271. .subscribe(function (val) {
  272. that._scene.debugShowFrustumPlanes = val;
  273. that._scene.requestRender();
  274. });
  275. this._performanceSubscription = knockout
  276. .getObservable(this, "performance")
  277. .subscribe(function (val) {
  278. if (val) {
  279. that._performanceDisplay = new PerformanceDisplay({
  280. container: that._performanceContainer,
  281. });
  282. } else {
  283. that._performanceContainer.innerHTML = "";
  284. }
  285. });
  286. this._showPrimitiveBoundingSphere = createCommand(function () {
  287. that._primitive.debugShowBoundingVolume = that.primitiveBoundingSphere;
  288. that._scene.requestRender();
  289. return true;
  290. });
  291. this._primitiveBoundingSphereSubscription = knockout
  292. .getObservable(this, "primitiveBoundingSphere")
  293. .subscribe(function () {
  294. that._showPrimitiveBoundingSphere();
  295. });
  296. this._showPrimitiveReferenceFrame = createCommand(function () {
  297. if (that.primitiveReferenceFrame) {
  298. const modelMatrix = that._primitive.modelMatrix;
  299. that._modelMatrixPrimitive = new DebugModelMatrixPrimitive({
  300. modelMatrix: modelMatrix,
  301. });
  302. that._scene.primitives.add(that._modelMatrixPrimitive);
  303. } else if (defined(that._modelMatrixPrimitive)) {
  304. that._scene.primitives.remove(that._modelMatrixPrimitive);
  305. that._modelMatrixPrimitive = undefined;
  306. }
  307. that._scene.requestRender();
  308. return true;
  309. });
  310. this._primitiveReferenceFrameSubscription = knockout
  311. .getObservable(this, "primitiveReferenceFrame")
  312. .subscribe(function () {
  313. that._showPrimitiveReferenceFrame();
  314. });
  315. this._doFilterPrimitive = createCommand(function () {
  316. if (that.filterPrimitive) {
  317. that._scene.debugCommandFilter = function (command) {
  318. if (
  319. defined(that._modelMatrixPrimitive) &&
  320. command.owner === that._modelMatrixPrimitive._primitive
  321. ) {
  322. return true;
  323. } else if (defined(that._primitive)) {
  324. return (
  325. command.owner === that._primitive ||
  326. command.owner === that._primitive._billboardCollection ||
  327. command.owner.primitive === that._primitive
  328. );
  329. }
  330. return false;
  331. };
  332. } else {
  333. that._scene.debugCommandFilter = undefined;
  334. }
  335. return true;
  336. });
  337. this._filterPrimitiveSubscription = knockout
  338. .getObservable(this, "filterPrimitive")
  339. .subscribe(function () {
  340. that._doFilterPrimitive();
  341. that._scene.requestRender();
  342. });
  343. this._wireframeSubscription = knockout
  344. .getObservable(this, "wireframe")
  345. .subscribe(function (val) {
  346. globe._surface.tileProvider._debug.wireframe = val;
  347. that._scene.requestRender();
  348. });
  349. this._depthFrustumSubscription = knockout
  350. .getObservable(this, "depthFrustum")
  351. .subscribe(function (val) {
  352. that._scene.debugShowDepthFrustum = val;
  353. that._scene.requestRender();
  354. });
  355. this._incrementDepthFrustum = createCommand(function () {
  356. const next = that.depthFrustum + 1;
  357. that.depthFrustum = boundDepthFrustum(1, that._numberOfFrustums, next);
  358. that._scene.requestRender();
  359. return true;
  360. });
  361. this._decrementDepthFrustum = createCommand(function () {
  362. const next = that.depthFrustum - 1;
  363. that.depthFrustum = boundDepthFrustum(1, that._numberOfFrustums, next);
  364. that._scene.requestRender();
  365. return true;
  366. });
  367. this._suspendUpdatesSubscription = knockout
  368. .getObservable(this, "suspendUpdates")
  369. .subscribe(function (val) {
  370. globe._surface._debug.suspendLodUpdate = val;
  371. if (!val) {
  372. that.filterTile = false;
  373. }
  374. });
  375. let tileBoundariesLayer;
  376. this._showTileCoordinates = createCommand(function () {
  377. if (that.tileCoordinates && !defined(tileBoundariesLayer)) {
  378. tileBoundariesLayer = scene.imageryLayers.addImageryProvider(
  379. new TileCoordinatesImageryProvider({
  380. tilingScheme: scene.terrainProvider.tilingScheme,
  381. })
  382. );
  383. } else if (!that.tileCoordinates && defined(tileBoundariesLayer)) {
  384. scene.imageryLayers.remove(tileBoundariesLayer);
  385. tileBoundariesLayer = undefined;
  386. }
  387. return true;
  388. });
  389. this._tileCoordinatesSubscription = knockout
  390. .getObservable(this, "tileCoordinates")
  391. .subscribe(function () {
  392. that._showTileCoordinates();
  393. that._scene.requestRender();
  394. });
  395. this._tileBoundingSphereSubscription = knockout
  396. .getObservable(this, "tileBoundingSphere")
  397. .subscribe(function () {
  398. that._showTileBoundingSphere();
  399. that._scene.requestRender();
  400. });
  401. this._showTileBoundingSphere = createCommand(function () {
  402. if (that.tileBoundingSphere) {
  403. globe._surface.tileProvider._debug.boundingSphereTile = that._tile;
  404. } else {
  405. globe._surface.tileProvider._debug.boundingSphereTile = undefined;
  406. }
  407. that._scene.requestRender();
  408. return true;
  409. });
  410. this._doFilterTile = createCommand(function () {
  411. if (!that.filterTile) {
  412. that.suspendUpdates = false;
  413. } else {
  414. that.suspendUpdates = true;
  415. globe._surface._tilesToRender = [];
  416. if (defined(that._tile) && that._tile.renderable) {
  417. globe._surface._tilesToRender.push(that._tile);
  418. }
  419. }
  420. return true;
  421. });
  422. this._filterTileSubscription = knockout
  423. .getObservable(this, "filterTile")
  424. .subscribe(function () {
  425. that.doFilterTile();
  426. that._scene.requestRender();
  427. });
  428. function pickPrimitive(e) {
  429. const newPick = that._scene.pick({
  430. x: e.position.x,
  431. y: e.position.y,
  432. });
  433. if (defined(newPick)) {
  434. that.primitive = defined(newPick.collection)
  435. ? newPick.collection
  436. : newPick.primitive;
  437. }
  438. that._scene.requestRender();
  439. that.pickPrimitiveActive = false;
  440. }
  441. this._pickPrimitive = createCommand(function () {
  442. that.pickPrimitiveActive = !that.pickPrimitiveActive;
  443. });
  444. this._pickPrimitiveActiveSubscription = knockout
  445. .getObservable(this, "pickPrimitiveActive")
  446. .subscribe(function (val) {
  447. if (val) {
  448. eventHandler.setInputAction(
  449. pickPrimitive,
  450. ScreenSpaceEventType.LEFT_CLICK
  451. );
  452. } else {
  453. eventHandler.removeInputAction(ScreenSpaceEventType.LEFT_CLICK);
  454. }
  455. });
  456. function selectTile(e) {
  457. let selectedTile;
  458. const ellipsoid = globe.ellipsoid;
  459. const ray = that._scene.camera.getPickRay(e.position, scratchPickRay);
  460. const cartesian = globe.pick(ray, that._scene, scratchPickCartesian);
  461. if (defined(cartesian)) {
  462. const cartographic = ellipsoid.cartesianToCartographic(cartesian);
  463. const tilesRendered =
  464. globe._surface.tileProvider._tilesToRenderByTextureCount;
  465. for (
  466. let textureCount = 0;
  467. !selectedTile && textureCount < tilesRendered.length;
  468. ++textureCount
  469. ) {
  470. const tilesRenderedByTextureCount = tilesRendered[textureCount];
  471. if (!defined(tilesRenderedByTextureCount)) {
  472. continue;
  473. }
  474. for (
  475. let tileIndex = 0;
  476. !selectedTile && tileIndex < tilesRenderedByTextureCount.length;
  477. ++tileIndex
  478. ) {
  479. const tile = tilesRenderedByTextureCount[tileIndex];
  480. if (Rectangle.contains(tile.rectangle, cartographic)) {
  481. selectedTile = tile;
  482. }
  483. }
  484. }
  485. }
  486. that.tile = selectedTile;
  487. that.pickTileActive = false;
  488. }
  489. this._pickTile = createCommand(function () {
  490. that.pickTileActive = !that.pickTileActive;
  491. });
  492. this._pickTileActiveSubscription = knockout
  493. .getObservable(this, "pickTileActive")
  494. .subscribe(function (val) {
  495. if (val) {
  496. eventHandler.setInputAction(
  497. selectTile,
  498. ScreenSpaceEventType.LEFT_CLICK
  499. );
  500. } else {
  501. eventHandler.removeInputAction(ScreenSpaceEventType.LEFT_CLICK);
  502. }
  503. });
  504. this._removePostRenderEvent = scene.postRender.addEventListener(function () {
  505. that._update();
  506. });
  507. }
  508. Object.defineProperties(CesiumInspectorViewModel.prototype, {
  509. /**
  510. * Gets the scene to control.
  511. * @memberof CesiumInspectorViewModel.prototype
  512. *
  513. * @type {Scene}
  514. */
  515. scene: {
  516. get: function () {
  517. return this._scene;
  518. },
  519. },
  520. /**
  521. * Gets the container of the PerformanceDisplay
  522. * @memberof CesiumInspectorViewModel.prototype
  523. *
  524. * @type {Element}
  525. */
  526. performanceContainer: {
  527. get: function () {
  528. return this._performanceContainer;
  529. },
  530. },
  531. /**
  532. * Gets the command to toggle the visibility of the drop down.
  533. * @memberof CesiumInspectorViewModel.prototype
  534. *
  535. * @type {Command}
  536. */
  537. toggleDropDown: {
  538. get: function () {
  539. return this._toggleDropDown;
  540. },
  541. },
  542. /**
  543. * Gets the command to toggle the visibility of a BoundingSphere for a primitive
  544. * @memberof CesiumInspectorViewModel.prototype
  545. *
  546. * @type {Command}
  547. */
  548. showPrimitiveBoundingSphere: {
  549. get: function () {
  550. return this._showPrimitiveBoundingSphere;
  551. },
  552. },
  553. /**
  554. * Gets the command to toggle the visibility of a {@link DebugModelMatrixPrimitive} for the model matrix of a primitive
  555. * @memberof CesiumInspectorViewModel.prototype
  556. *
  557. * @type {Command}
  558. */
  559. showPrimitiveReferenceFrame: {
  560. get: function () {
  561. return this._showPrimitiveReferenceFrame;
  562. },
  563. },
  564. /**
  565. * Gets the command to toggle a filter that renders only a selected primitive
  566. * @memberof CesiumInspectorViewModel.prototype
  567. *
  568. * @type {Command}
  569. */
  570. doFilterPrimitive: {
  571. get: function () {
  572. return this._doFilterPrimitive;
  573. },
  574. },
  575. /**
  576. * Gets the command to increment the depth frustum index to be shown
  577. * @memberof CesiumInspectorViewModel.prototype
  578. *
  579. * @type {Command}
  580. */
  581. incrementDepthFrustum: {
  582. get: function () {
  583. return this._incrementDepthFrustum;
  584. },
  585. },
  586. /**
  587. * Gets the command to decrement the depth frustum index to be shown
  588. * @memberof CesiumInspectorViewModel.prototype
  589. *
  590. * @type {Command}
  591. */
  592. decrementDepthFrustum: {
  593. get: function () {
  594. return this._decrementDepthFrustum;
  595. },
  596. },
  597. /**
  598. * Gets the command to toggle the visibility of tile coordinates
  599. * @memberof CesiumInspectorViewModel.prototype
  600. *
  601. * @type {Command}
  602. */
  603. showTileCoordinates: {
  604. get: function () {
  605. return this._showTileCoordinates;
  606. },
  607. },
  608. /**
  609. * Gets the command to toggle the visibility of a BoundingSphere for a selected tile
  610. * @memberof CesiumInspectorViewModel.prototype
  611. *
  612. * @type {Command}
  613. */
  614. showTileBoundingSphere: {
  615. get: function () {
  616. return this._showTileBoundingSphere;
  617. },
  618. },
  619. /**
  620. * Gets the command to toggle a filter that renders only a selected tile
  621. * @memberof CesiumInspectorViewModel.prototype
  622. *
  623. * @type {Command}
  624. */
  625. doFilterTile: {
  626. get: function () {
  627. return this._doFilterTile;
  628. },
  629. },
  630. /**
  631. * Gets the command to expand and collapse the general section
  632. * @memberof CesiumInspectorViewModel.prototype
  633. *
  634. * @type {Command}
  635. */
  636. toggleGeneral: {
  637. get: function () {
  638. return this._toggleGeneral;
  639. },
  640. },
  641. /**
  642. * Gets the command to expand and collapse the primitives section
  643. * @memberof CesiumInspectorViewModel.prototype
  644. *
  645. * @type {Command}
  646. */
  647. togglePrimitives: {
  648. get: function () {
  649. return this._togglePrimitives;
  650. },
  651. },
  652. /**
  653. * Gets the command to expand and collapse the terrain section
  654. * @memberof CesiumInspectorViewModel.prototype
  655. *
  656. * @type {Command}
  657. */
  658. toggleTerrain: {
  659. get: function () {
  660. return this._toggleTerrain;
  661. },
  662. },
  663. /**
  664. * Gets the command to pick a primitive
  665. * @memberof CesiumInspectorViewModel.prototype
  666. *
  667. * @type {Command}
  668. */
  669. pickPrimitive: {
  670. get: function () {
  671. return this._pickPrimitive;
  672. },
  673. },
  674. /**
  675. * Gets the command to pick a tile
  676. * @memberof CesiumInspectorViewModel.prototype
  677. *
  678. * @type {Command}
  679. */
  680. pickTile: {
  681. get: function () {
  682. return this._pickTile;
  683. },
  684. },
  685. /**
  686. * Gets the command to pick a tile
  687. * @memberof CesiumInspectorViewModel.prototype
  688. *
  689. * @type {Command}
  690. */
  691. selectParent: {
  692. get: function () {
  693. const that = this;
  694. return createCommand(function () {
  695. that.tile = that.tile.parent;
  696. });
  697. },
  698. },
  699. /**
  700. * Gets the command to pick a tile
  701. * @memberof CesiumInspectorViewModel.prototype
  702. *
  703. * @type {Command}
  704. */
  705. selectNW: {
  706. get: function () {
  707. const that = this;
  708. return createCommand(function () {
  709. that.tile = that.tile.northwestChild;
  710. });
  711. },
  712. },
  713. /**
  714. * Gets the command to pick a tile
  715. * @memberof CesiumInspectorViewModel.prototype
  716. *
  717. * @type {Command}
  718. */
  719. selectNE: {
  720. get: function () {
  721. const that = this;
  722. return createCommand(function () {
  723. that.tile = that.tile.northeastChild;
  724. });
  725. },
  726. },
  727. /**
  728. * Gets the command to pick a tile
  729. * @memberof CesiumInspectorViewModel.prototype
  730. *
  731. * @type {Command}
  732. */
  733. selectSW: {
  734. get: function () {
  735. const that = this;
  736. return createCommand(function () {
  737. that.tile = that.tile.southwestChild;
  738. });
  739. },
  740. },
  741. /**
  742. * Gets the command to pick a tile
  743. * @memberof CesiumInspectorViewModel.prototype
  744. *
  745. * @type {Command}
  746. */
  747. selectSE: {
  748. get: function () {
  749. const that = this;
  750. return createCommand(function () {
  751. that.tile = that.tile.southeastChild;
  752. });
  753. },
  754. },
  755. /**
  756. * Gets or sets the current selected primitive
  757. * @memberof CesiumInspectorViewModel.prototype
  758. *
  759. * @type {Command}
  760. */
  761. primitive: {
  762. get: function () {
  763. return this._primitive;
  764. },
  765. set: function (newPrimitive) {
  766. const oldPrimitive = this._primitive;
  767. if (newPrimitive !== oldPrimitive) {
  768. this.hasPickedPrimitive = true;
  769. if (defined(oldPrimitive)) {
  770. oldPrimitive.debugShowBoundingVolume = false;
  771. }
  772. this._scene.debugCommandFilter = undefined;
  773. if (defined(this._modelMatrixPrimitive)) {
  774. this._scene.primitives.remove(this._modelMatrixPrimitive);
  775. this._modelMatrixPrimitive = undefined;
  776. }
  777. this._primitive = newPrimitive;
  778. newPrimitive.show = false;
  779. setTimeout(function () {
  780. newPrimitive.show = true;
  781. }, 50);
  782. this.showPrimitiveBoundingSphere();
  783. this.showPrimitiveReferenceFrame();
  784. this.doFilterPrimitive();
  785. }
  786. },
  787. },
  788. /**
  789. * Gets or sets the current selected tile
  790. * @memberof CesiumInspectorViewModel.prototype
  791. *
  792. * @type {Command}
  793. */
  794. tile: {
  795. get: function () {
  796. return this._tile;
  797. },
  798. set: function (newTile) {
  799. if (defined(newTile)) {
  800. this.hasPickedTile = true;
  801. const oldTile = this._tile;
  802. if (newTile !== oldTile) {
  803. this.tileText = `L: ${newTile.level} X: ${newTile.x} Y: ${newTile.y}`;
  804. this.tileText += `<br>SW corner: ${newTile.rectangle.west}, ${newTile.rectangle.south}`;
  805. this.tileText += `<br>NE corner: ${newTile.rectangle.east}, ${newTile.rectangle.north}`;
  806. const data = newTile.data;
  807. if (defined(data) && defined(data.tileBoundingRegion)) {
  808. this.tileText += `<br>Min: ${data.tileBoundingRegion.minimumHeight} Max: ${data.tileBoundingRegion.maximumHeight}`;
  809. } else {
  810. this.tileText += "<br>(Tile is not loaded)";
  811. }
  812. }
  813. this._tile = newTile;
  814. this.showTileBoundingSphere();
  815. this.doFilterTile();
  816. } else {
  817. this.hasPickedTile = false;
  818. this._tile = undefined;
  819. }
  820. },
  821. },
  822. });
  823. /**
  824. * Updates the view model
  825. * @private
  826. */
  827. CesiumInspectorViewModel.prototype._update = function () {
  828. if (this.frustums) {
  829. this.frustumStatisticText = frustumStatisticsToString(
  830. this._scene.debugFrustumStatistics
  831. );
  832. }
  833. // Determine the number of frustums being used.
  834. const numberOfFrustums = this._scene.numberOfFrustums;
  835. this._numberOfFrustums = numberOfFrustums;
  836. // Bound the frustum to be displayed.
  837. this.depthFrustum = boundDepthFrustum(1, numberOfFrustums, this.depthFrustum);
  838. // Update the displayed text.
  839. this.depthFrustumText = `${this.depthFrustum} of ${numberOfFrustums}`;
  840. if (this.performance) {
  841. this._performanceDisplay.update();
  842. }
  843. if (this.primitiveReferenceFrame) {
  844. this._modelMatrixPrimitive.modelMatrix = this._primitive.modelMatrix;
  845. }
  846. this.shaderCacheText = `Cached shaders: ${this._scene.context.shaderCache.numberOfShaders}`;
  847. };
  848. /**
  849. * @returns {Boolean} true if the object has been destroyed, false otherwise.
  850. */
  851. CesiumInspectorViewModel.prototype.isDestroyed = function () {
  852. return false;
  853. };
  854. /**
  855. * Destroys the widget. Should be called if permanently
  856. * removing the widget from layout.
  857. */
  858. CesiumInspectorViewModel.prototype.destroy = function () {
  859. this._eventHandler.destroy();
  860. this._removePostRenderEvent();
  861. this._frustumsSubscription.dispose();
  862. this._frustumPlanesSubscription.dispose();
  863. this._performanceSubscription.dispose();
  864. this._primitiveBoundingSphereSubscription.dispose();
  865. this._primitiveReferenceFrameSubscription.dispose();
  866. this._filterPrimitiveSubscription.dispose();
  867. this._wireframeSubscription.dispose();
  868. this._depthFrustumSubscription.dispose();
  869. this._suspendUpdatesSubscription.dispose();
  870. this._tileCoordinatesSubscription.dispose();
  871. this._tileBoundingSphereSubscription.dispose();
  872. this._filterTileSubscription.dispose();
  873. this._pickPrimitiveActiveSubscription.dispose();
  874. this._pickTileActiveSubscription.dispose();
  875. return destroyObject(this);
  876. };
  877. export default CesiumInspectorViewModel;