abstractEngine.query.js 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. import { AbstractMesh } from "../../Meshes/abstractMesh.js";
  2. import { AbstractEngine } from "../abstractEngine.js";
  3. /** @internal */
  4. // eslint-disable-next-line @typescript-eslint/naming-convention
  5. export class _OcclusionDataStorage {
  6. constructor() {
  7. /** @internal */
  8. this.occlusionInternalRetryCounter = 0;
  9. /** @internal */
  10. this.isOcclusionQueryInProgress = false;
  11. /** @internal */
  12. this.isOccluded = false;
  13. /** @internal */
  14. this.occlusionRetryCount = -1;
  15. /** @internal */
  16. this.occlusionType = AbstractMesh.OCCLUSION_TYPE_NONE;
  17. /** @internal */
  18. this.occlusionQueryAlgorithmType = AbstractMesh.OCCLUSION_ALGORITHM_TYPE_CONSERVATIVE;
  19. /** @internal */
  20. this.forceRenderingWhenOccluded = false;
  21. }
  22. }
  23. AbstractEngine.prototype.getGPUFrameTimeCounter = function () {
  24. return null;
  25. };
  26. AbstractEngine.prototype.captureGPUFrameTime = function (value) {
  27. // Do nothing. Must be implemented by child classes
  28. };
  29. AbstractEngine.prototype.createQuery = function () {
  30. return null;
  31. };
  32. AbstractEngine.prototype.deleteQuery = function (query) {
  33. // Do nothing. Must be implemented by child classes
  34. return this;
  35. };
  36. AbstractEngine.prototype.isQueryResultAvailable = function (query) {
  37. // Do nothing. Must be implemented by child classes
  38. return false;
  39. };
  40. AbstractEngine.prototype.getQueryResult = function (query) {
  41. // Do nothing. Must be implemented by child classes
  42. return 0;
  43. };
  44. AbstractEngine.prototype.beginOcclusionQuery = function (algorithmType, query) {
  45. // Do nothing. Must be implemented by child classes
  46. return false;
  47. };
  48. AbstractEngine.prototype.endOcclusionQuery = function (algorithmType) {
  49. // Do nothing. Must be implemented by child classes
  50. return this;
  51. };
  52. Object.defineProperty(AbstractMesh.prototype, "isOcclusionQueryInProgress", {
  53. get: function () {
  54. return this._occlusionDataStorage.isOcclusionQueryInProgress;
  55. },
  56. set: function (value) {
  57. this._occlusionDataStorage.isOcclusionQueryInProgress = value;
  58. },
  59. enumerable: false,
  60. configurable: true,
  61. });
  62. Object.defineProperty(AbstractMesh.prototype, "_occlusionDataStorage", {
  63. get: function () {
  64. if (!this.__occlusionDataStorage) {
  65. this.__occlusionDataStorage = new _OcclusionDataStorage();
  66. }
  67. return this.__occlusionDataStorage;
  68. },
  69. enumerable: false,
  70. configurable: true,
  71. });
  72. Object.defineProperty(AbstractMesh.prototype, "isOccluded", {
  73. get: function () {
  74. return this._occlusionDataStorage.isOccluded;
  75. },
  76. set: function (value) {
  77. this._occlusionDataStorage.isOccluded = value;
  78. },
  79. enumerable: true,
  80. configurable: true,
  81. });
  82. Object.defineProperty(AbstractMesh.prototype, "occlusionQueryAlgorithmType", {
  83. get: function () {
  84. return this._occlusionDataStorage.occlusionQueryAlgorithmType;
  85. },
  86. set: function (value) {
  87. this._occlusionDataStorage.occlusionQueryAlgorithmType = value;
  88. },
  89. enumerable: true,
  90. configurable: true,
  91. });
  92. Object.defineProperty(AbstractMesh.prototype, "occlusionType", {
  93. get: function () {
  94. return this._occlusionDataStorage.occlusionType;
  95. },
  96. set: function (value) {
  97. this._occlusionDataStorage.occlusionType = value;
  98. },
  99. enumerable: true,
  100. configurable: true,
  101. });
  102. Object.defineProperty(AbstractMesh.prototype, "occlusionRetryCount", {
  103. get: function () {
  104. return this._occlusionDataStorage.occlusionRetryCount;
  105. },
  106. set: function (value) {
  107. this._occlusionDataStorage.occlusionRetryCount = value;
  108. },
  109. enumerable: true,
  110. configurable: true,
  111. });
  112. Object.defineProperty(AbstractMesh.prototype, "forceRenderingWhenOccluded", {
  113. get: function () {
  114. return this._occlusionDataStorage.forceRenderingWhenOccluded;
  115. },
  116. set: function (value) {
  117. this._occlusionDataStorage.forceRenderingWhenOccluded = value;
  118. },
  119. enumerable: true,
  120. configurable: true,
  121. });
  122. // We also need to update AbstractMesh as there is a portion of the code there
  123. AbstractMesh.prototype._checkOcclusionQuery = function () {
  124. const dataStorage = this._occlusionDataStorage;
  125. if (dataStorage.occlusionType === AbstractMesh.OCCLUSION_TYPE_NONE) {
  126. dataStorage.isOccluded = false;
  127. return false;
  128. }
  129. const engine = this.getEngine();
  130. if (!engine.getCaps().supportOcclusionQuery) {
  131. dataStorage.isOccluded = false;
  132. return false;
  133. }
  134. if (!engine.isQueryResultAvailable) {
  135. // Occlusion query where not referenced
  136. dataStorage.isOccluded = false;
  137. return false;
  138. }
  139. if (this.isOcclusionQueryInProgress && this._occlusionQuery !== null && this._occlusionQuery !== undefined) {
  140. const isOcclusionQueryAvailable = engine.isQueryResultAvailable(this._occlusionQuery);
  141. if (isOcclusionQueryAvailable) {
  142. const occlusionQueryResult = engine.getQueryResult(this._occlusionQuery);
  143. dataStorage.isOcclusionQueryInProgress = false;
  144. dataStorage.occlusionInternalRetryCounter = 0;
  145. dataStorage.isOccluded = occlusionQueryResult > 0 ? false : true;
  146. }
  147. else {
  148. dataStorage.occlusionInternalRetryCounter++;
  149. if (dataStorage.occlusionRetryCount !== -1 && dataStorage.occlusionInternalRetryCounter > dataStorage.occlusionRetryCount) {
  150. dataStorage.isOcclusionQueryInProgress = false;
  151. dataStorage.occlusionInternalRetryCounter = 0;
  152. // if optimistic set isOccluded to false regardless of the status of isOccluded. (Render in the current render loop)
  153. // if strict continue the last state of the object.
  154. dataStorage.isOccluded = dataStorage.occlusionType === AbstractMesh.OCCLUSION_TYPE_OPTIMISTIC ? false : dataStorage.isOccluded;
  155. }
  156. else {
  157. return dataStorage.occlusionType === AbstractMesh.OCCLUSION_TYPE_OPTIMISTIC ? false : dataStorage.isOccluded;
  158. }
  159. }
  160. }
  161. const scene = this.getScene();
  162. if (scene.getBoundingBoxRenderer) {
  163. const occlusionBoundingBoxRenderer = scene.getBoundingBoxRenderer();
  164. if (this._occlusionQuery === null) {
  165. this._occlusionQuery = engine.createQuery();
  166. }
  167. if (this._occlusionQuery && engine.beginOcclusionQuery(dataStorage.occlusionQueryAlgorithmType, this._occlusionQuery)) {
  168. occlusionBoundingBoxRenderer.renderOcclusionBoundingBox(this);
  169. engine.endOcclusionQuery(dataStorage.occlusionQueryAlgorithmType);
  170. this._occlusionDataStorage.isOcclusionQueryInProgress = true;
  171. }
  172. }
  173. return dataStorage.isOccluded;
  174. };
  175. //# sourceMappingURL=abstractEngine.query.js.map