babylon.sceneOptimizer.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. var __extends = this.__extends || function (d, b) {
  2. for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
  3. function __() { this.constructor = d; }
  4. __.prototype = b.prototype;
  5. d.prototype = new __();
  6. };
  7. var BABYLON;
  8. (function (BABYLON) {
  9. // Standard optimizations
  10. var SceneOptimization = (function () {
  11. function SceneOptimization(priority) {
  12. if (priority === void 0) { priority = 0; }
  13. this.priority = priority;
  14. this.apply = function (scene) {
  15. return true; // Return true if everything that can be done was applied
  16. };
  17. }
  18. return SceneOptimization;
  19. })();
  20. BABYLON.SceneOptimization = SceneOptimization;
  21. var TextureOptimization = (function (_super) {
  22. __extends(TextureOptimization, _super);
  23. function TextureOptimization(priority, maximumSize) {
  24. var _this = this;
  25. if (priority === void 0) { priority = 0; }
  26. if (maximumSize === void 0) { maximumSize = 1024; }
  27. _super.call(this, priority);
  28. this.priority = priority;
  29. this.maximumSize = maximumSize;
  30. this.apply = function (scene) {
  31. var allDone = true;
  32. for (var index = 0; index < scene.textures.length; index++) {
  33. var texture = scene.textures[index];
  34. if (!texture.canRescale) {
  35. continue;
  36. }
  37. var currentSize = texture.getSize();
  38. var maxDimension = Math.max(currentSize.width, currentSize.height);
  39. if (maxDimension > _this.maximumSize) {
  40. texture.scale(0.5);
  41. allDone = false;
  42. }
  43. }
  44. return allDone;
  45. };
  46. }
  47. return TextureOptimization;
  48. })(SceneOptimization);
  49. BABYLON.TextureOptimization = TextureOptimization;
  50. var HardwareScalingOptimization = (function (_super) {
  51. __extends(HardwareScalingOptimization, _super);
  52. function HardwareScalingOptimization(priority, maximumScale) {
  53. var _this = this;
  54. if (priority === void 0) { priority = 0; }
  55. if (maximumScale === void 0) { maximumScale = 2; }
  56. _super.call(this, priority);
  57. this.priority = priority;
  58. this.maximumScale = maximumScale;
  59. this._currentScale = 1;
  60. this.apply = function (scene) {
  61. _this._currentScale++;
  62. scene.getEngine().setHardwareScalingLevel(_this._currentScale);
  63. return _this._currentScale >= _this.maximumScale;
  64. };
  65. }
  66. return HardwareScalingOptimization;
  67. })(SceneOptimization);
  68. BABYLON.HardwareScalingOptimization = HardwareScalingOptimization;
  69. var ShadowsOptimization = (function (_super) {
  70. __extends(ShadowsOptimization, _super);
  71. function ShadowsOptimization() {
  72. _super.apply(this, arguments);
  73. this.apply = function (scene) {
  74. scene.shadowsEnabled = false;
  75. return true;
  76. };
  77. }
  78. return ShadowsOptimization;
  79. })(SceneOptimization);
  80. BABYLON.ShadowsOptimization = ShadowsOptimization;
  81. var PostProcessesOptimization = (function (_super) {
  82. __extends(PostProcessesOptimization, _super);
  83. function PostProcessesOptimization() {
  84. _super.apply(this, arguments);
  85. this.apply = function (scene) {
  86. scene.postProcessesEnabled = false;
  87. return true;
  88. };
  89. }
  90. return PostProcessesOptimization;
  91. })(SceneOptimization);
  92. BABYLON.PostProcessesOptimization = PostProcessesOptimization;
  93. var LensFlaresOptimization = (function (_super) {
  94. __extends(LensFlaresOptimization, _super);
  95. function LensFlaresOptimization() {
  96. _super.apply(this, arguments);
  97. this.apply = function (scene) {
  98. scene.lensFlaresEnabled = false;
  99. return true;
  100. };
  101. }
  102. return LensFlaresOptimization;
  103. })(SceneOptimization);
  104. BABYLON.LensFlaresOptimization = LensFlaresOptimization;
  105. var ParticlesOptimization = (function (_super) {
  106. __extends(ParticlesOptimization, _super);
  107. function ParticlesOptimization() {
  108. _super.apply(this, arguments);
  109. this.apply = function (scene) {
  110. scene.particlesEnabled = false;
  111. return true;
  112. };
  113. }
  114. return ParticlesOptimization;
  115. })(SceneOptimization);
  116. BABYLON.ParticlesOptimization = ParticlesOptimization;
  117. var RenderTargetsOptimization = (function (_super) {
  118. __extends(RenderTargetsOptimization, _super);
  119. function RenderTargetsOptimization() {
  120. _super.apply(this, arguments);
  121. this.apply = function (scene) {
  122. scene.renderTargetsEnabled = false;
  123. return true;
  124. };
  125. }
  126. return RenderTargetsOptimization;
  127. })(SceneOptimization);
  128. BABYLON.RenderTargetsOptimization = RenderTargetsOptimization;
  129. var MergeMeshesOptimization = (function (_super) {
  130. __extends(MergeMeshesOptimization, _super);
  131. function MergeMeshesOptimization() {
  132. var _this = this;
  133. _super.apply(this, arguments);
  134. this._canBeMerged = function (abstractMesh) {
  135. if (!(abstractMesh instanceof BABYLON.Mesh)) {
  136. return false;
  137. }
  138. var mesh = abstractMesh;
  139. if (!mesh.isVisible || !mesh.isEnabled()) {
  140. return false;
  141. }
  142. if (mesh.instances.length > 0) {
  143. return false;
  144. }
  145. if (mesh.skeleton || mesh.hasLODLevels) {
  146. return false;
  147. }
  148. return true;
  149. };
  150. this.apply = function (scene) {
  151. var globalPool = scene.meshes.slice(0);
  152. var globalLength = globalPool.length;
  153. for (var index = 0; index < globalLength; index++) {
  154. var currentPool = new Array();
  155. var current = globalPool[index];
  156. // Checks
  157. if (!_this._canBeMerged(current)) {
  158. continue;
  159. }
  160. currentPool.push(current);
  161. // Find compatible meshes
  162. for (var subIndex = index + 1; subIndex < globalLength; subIndex++) {
  163. var otherMesh = globalPool[subIndex];
  164. if (!_this._canBeMerged(otherMesh)) {
  165. continue;
  166. }
  167. if (otherMesh.material !== current.material) {
  168. continue;
  169. }
  170. if (otherMesh.checkCollisions !== current.checkCollisions) {
  171. continue;
  172. }
  173. currentPool.push(otherMesh);
  174. globalLength--;
  175. globalPool.splice(subIndex, 1);
  176. subIndex--;
  177. }
  178. if (currentPool.length < 2) {
  179. continue;
  180. }
  181. // Merge meshes
  182. BABYLON.Mesh.MergeMeshes(currentPool);
  183. }
  184. return true;
  185. };
  186. }
  187. return MergeMeshesOptimization;
  188. })(SceneOptimization);
  189. BABYLON.MergeMeshesOptimization = MergeMeshesOptimization;
  190. // Options
  191. var SceneOptimizerOptions = (function () {
  192. function SceneOptimizerOptions(targetFrameRate, trackerDuration) {
  193. if (targetFrameRate === void 0) { targetFrameRate = 60; }
  194. if (trackerDuration === void 0) { trackerDuration = 2000; }
  195. this.targetFrameRate = targetFrameRate;
  196. this.trackerDuration = trackerDuration;
  197. this.optimizations = new Array();
  198. }
  199. SceneOptimizerOptions.LowDegradationAllowed = function (targetFrameRate) {
  200. var result = new SceneOptimizerOptions(targetFrameRate);
  201. var priority = 0;
  202. result.optimizations.push(new MergeMeshesOptimization(priority));
  203. result.optimizations.push(new ShadowsOptimization(priority));
  204. result.optimizations.push(new LensFlaresOptimization(priority));
  205. // Next priority
  206. priority++;
  207. result.optimizations.push(new PostProcessesOptimization(priority));
  208. result.optimizations.push(new ParticlesOptimization(priority));
  209. // Next priority
  210. priority++;
  211. result.optimizations.push(new TextureOptimization(priority, 1024));
  212. return result;
  213. };
  214. SceneOptimizerOptions.ModerateDegradationAllowed = function (targetFrameRate) {
  215. var result = new SceneOptimizerOptions(targetFrameRate);
  216. var priority = 0;
  217. result.optimizations.push(new MergeMeshesOptimization(priority));
  218. result.optimizations.push(new ShadowsOptimization(priority));
  219. result.optimizations.push(new LensFlaresOptimization(priority));
  220. // Next priority
  221. priority++;
  222. result.optimizations.push(new PostProcessesOptimization(priority));
  223. result.optimizations.push(new ParticlesOptimization(priority));
  224. // Next priority
  225. priority++;
  226. result.optimizations.push(new TextureOptimization(priority, 512));
  227. // Next priority
  228. priority++;
  229. result.optimizations.push(new RenderTargetsOptimization(priority));
  230. // Next priority
  231. priority++;
  232. result.optimizations.push(new HardwareScalingOptimization(priority, 2));
  233. return result;
  234. };
  235. SceneOptimizerOptions.HighDegradationAllowed = function (targetFrameRate) {
  236. var result = new SceneOptimizerOptions(targetFrameRate);
  237. var priority = 0;
  238. result.optimizations.push(new MergeMeshesOptimization(priority));
  239. result.optimizations.push(new ShadowsOptimization(priority));
  240. result.optimizations.push(new LensFlaresOptimization(priority));
  241. // Next priority
  242. priority++;
  243. result.optimizations.push(new PostProcessesOptimization(priority));
  244. result.optimizations.push(new ParticlesOptimization(priority));
  245. // Next priority
  246. priority++;
  247. result.optimizations.push(new TextureOptimization(priority, 256));
  248. // Next priority
  249. priority++;
  250. result.optimizations.push(new RenderTargetsOptimization(priority));
  251. // Next priority
  252. priority++;
  253. result.optimizations.push(new HardwareScalingOptimization(priority, 4));
  254. return result;
  255. };
  256. return SceneOptimizerOptions;
  257. })();
  258. BABYLON.SceneOptimizerOptions = SceneOptimizerOptions;
  259. // Scene optimizer tool
  260. var SceneOptimizer = (function () {
  261. function SceneOptimizer() {
  262. }
  263. SceneOptimizer._CheckCurrentState = function (scene, options, currentPriorityLevel, onSuccess, onFailure) {
  264. // TODO: add an epsilon
  265. if (scene.getEngine().getFps() >= options.targetFrameRate) {
  266. if (onSuccess) {
  267. onSuccess();
  268. }
  269. return;
  270. }
  271. // Apply current level of optimizations
  272. var allDone = true;
  273. var noOptimizationApplied = true;
  274. for (var index = 0; index < options.optimizations.length; index++) {
  275. var optimization = options.optimizations[index];
  276. if (optimization.priority === currentPriorityLevel) {
  277. noOptimizationApplied = false;
  278. allDone = allDone && optimization.apply(scene);
  279. }
  280. }
  281. // If no optimization was applied, this is a failure :(
  282. if (noOptimizationApplied) {
  283. if (onFailure) {
  284. onFailure();
  285. }
  286. return;
  287. }
  288. // If all optimizations were done, move to next level
  289. if (allDone) {
  290. currentPriorityLevel++;
  291. }
  292. // Let's the system running for a specific amount of time before checking FPS
  293. scene.executeWhenReady(function () {
  294. setTimeout(function () {
  295. SceneOptimizer._CheckCurrentState(scene, options, currentPriorityLevel, onSuccess, onFailure);
  296. }, options.trackerDuration);
  297. });
  298. };
  299. SceneOptimizer.OptimizeAsync = function (scene, options, onSuccess, onFailure) {
  300. if (!options) {
  301. options = SceneOptimizerOptions.ModerateDegradationAllowed();
  302. }
  303. // Let's the system running for a specific amount of time before checking FPS
  304. scene.executeWhenReady(function () {
  305. setTimeout(function () {
  306. SceneOptimizer._CheckCurrentState(scene, options, 0, onSuccess, onFailure);
  307. }, options.trackerDuration);
  308. });
  309. };
  310. return SceneOptimizer;
  311. })();
  312. BABYLON.SceneOptimizer = SceneOptimizer;
  313. })(BABYLON || (BABYLON = {}));
  314. //# sourceMappingURL=babylon.sceneOptimizer.js.map