babylon.tools.js 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. var BABYLON = BABYLON || {};
  2. (function () {
  3. BABYLON.Tools = {};
  4. BABYLON.Tools.ExtractMinAndMax = function (positions, start, count) {
  5. var minimum = new BABYLON.Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);
  6. var maximum = new BABYLON.Vector3(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);
  7. for (var index = start; index < start + count; index++) {
  8. var current = new BABYLON.Vector3(positions[index * 3], positions[index * 3 + 1], positions[index * 3 + 2]);
  9. minimum = BABYLON.Vector3.Minimize(current, minimum);
  10. maximum = BABYLON.Vector3.Maximize(current, maximum);
  11. }
  12. return {
  13. minimum: minimum,
  14. maximum: maximum
  15. };
  16. };
  17. // Smart array
  18. BABYLON.Tools.SmartArray = function(capacity) {
  19. this.data = new Array(capacity);
  20. this.length = 0;
  21. };
  22. BABYLON.Tools.SmartArray.prototype.push = function(value) {
  23. this.data[this.length++] = value;
  24. if (this.length > this.data.length) {
  25. this.data.length *= 2;
  26. }
  27. };
  28. BABYLON.Tools.SmartArray.prototype.pushNoDuplicate = function(value) {
  29. if (this.indexOf(value) > -1) {
  30. return;
  31. }
  32. this.push(value);
  33. };
  34. BABYLON.Tools.SmartArray.prototype.sort = function (compareFn) {
  35. this.data.sort(compareFn);
  36. };
  37. BABYLON.Tools.SmartArray.prototype.reset = function() {
  38. this.length = 0;
  39. };
  40. BABYLON.Tools.SmartArray.prototype.concat = function (array) {
  41. if (array.length === 0) {
  42. return;
  43. }
  44. if (this.length + array.length > this.data.length) {
  45. this.data.length = (this.length + array.length) * 2;
  46. }
  47. for (var index = 0; index < array.length; index++) {
  48. this.data[this.length++] = (array.data || array)[index];
  49. }
  50. };
  51. BABYLON.Tools.SmartArray.prototype.concatWithNoDuplicate = function (array) {
  52. if (array.length === 0) {
  53. return;
  54. }
  55. if (this.length + array.length > this.data.length) {
  56. this.data.length = (this.length + array.length) * 2;
  57. }
  58. for (var index = 0; index < array.length; index++) {
  59. var item = (array.data || array)[index];
  60. var pos = this.data.indexOf(item);
  61. if (pos === -1 ||pos >= this.length) {
  62. this.data[this.length++] = item;
  63. }
  64. }
  65. };
  66. BABYLON.Tools.SmartArray.prototype.indexOf = function (value) {
  67. var position = this.data.indexOf(value);
  68. if (position >= this.length) {
  69. return -1;
  70. }
  71. return position;
  72. };
  73. // Misc.
  74. BABYLON.Tools.GetPointerPrefix = function() {
  75. var eventPrefix = "pointer";
  76. // Check if hand.js is referenced or if the browser natively supports pointer events
  77. if (!navigator.pointerEnabled) {
  78. eventPrefix = "mouse";
  79. }
  80. return eventPrefix;
  81. };
  82. BABYLON.Tools.QueueNewFrame = function (func) {
  83. if (window.requestAnimationFrame)
  84. window.requestAnimationFrame(func);
  85. else if (window.msRequestAnimationFrame)
  86. window.msRequestAnimationFrame(func);
  87. else if (window.webkitRequestAnimationFrame)
  88. window.webkitRequestAnimationFrame(func);
  89. else if (window.mozRequestAnimationFrame)
  90. window.mozRequestAnimationFrame(func);
  91. else if (window.oRequestAnimationFrame)
  92. window.oRequestAnimationFrame(func);
  93. else {
  94. window.setTimeout(func, 16);
  95. }
  96. };
  97. BABYLON.Tools.RequestFullscreen = function (element) {
  98. if (element.requestFullscreen)
  99. element.requestFullscreen();
  100. else if (element.msRequestFullscreen)
  101. element.msRequestFullscreen();
  102. else if (element.webkitRequestFullscreen)
  103. element.webkitRequestFullscreen();
  104. else if (element.mozRequestFullScreen)
  105. element.mozRequestFullScreen();
  106. };
  107. BABYLON.Tools.ExitFullscreen = function () {
  108. if (document.exitFullscreen) {
  109. document.exitFullscreen();
  110. }
  111. else if (document.mozCancelFullScreen) {
  112. document.mozCancelFullScreen();
  113. }
  114. else if (document.webkitCancelFullScreen) {
  115. document.webkitCancelFullScreen();
  116. }
  117. else if (document.msCancelFullScreen) {
  118. document.msCancelFullScreen();
  119. }
  120. };
  121. // External files
  122. BABYLON.Tools.BaseUrl = "";
  123. BABYLON.Tools.LoadImage = function (url, onload, onerror, database) {
  124. var img = new Image();
  125. img.onload = function () {
  126. onload(img);
  127. };
  128. img.onerror = function (err) {
  129. onerror(img, err);
  130. };
  131. var noIndexedDB = function () {
  132. img.src = url;
  133. };
  134. var loadFromIndexedDB = function () {
  135. database.loadImageFromDB(url, img);
  136. };
  137. if (database && database.enableTexturesOffline && BABYLON.Database.isUASupportingBlobStorage) {
  138. database.openAsync(loadFromIndexedDB, noIndexedDB);
  139. }
  140. else {
  141. noIndexedDB();
  142. }
  143. return img;
  144. };
  145. BABYLON.Tools.LoadFile = function (url, callback, progressCallBack, database) {
  146. var noIndexedDB = function () {
  147. var request = new XMLHttpRequest();
  148. var loadUrl = BABYLON.Tools.BaseUrl + url;
  149. request.open('GET', loadUrl, true);
  150. request.onprogress = progressCallBack;
  151. request.onreadystatechange = function () {
  152. if (request.readyState == 4) {
  153. if (request.status == 200) {
  154. callback(request.responseText);
  155. } else { // Failed
  156. throw new Error(request.status, "Unable to load " + loadUrl);
  157. }
  158. }
  159. };
  160. request.send(null);
  161. };
  162. var loadFromIndexedDB = function () {
  163. database.loadSceneFromDB(url, callback, progressCallBack, noIndexedDB);
  164. };
  165. // Caching only scenes files
  166. if (database && url.indexOf(".babylon") !== -1 && (database.enableSceneOffline)) {
  167. database.openAsync(loadFromIndexedDB, noIndexedDB);
  168. }
  169. else {
  170. noIndexedDB();
  171. }
  172. };
  173. // Misc.
  174. BABYLON.Tools.isIE = function () {
  175. return window.ActiveXObject !== undefined;
  176. };
  177. BABYLON.Tools.WithinEpsilon = function (a, b) {
  178. var num = a - b;
  179. return -1.401298E-45 <= num && num <= 1.401298E-45;
  180. };
  181. var cloneValue = function (source, destinationObject) {
  182. if (!source)
  183. return null;
  184. if (source instanceof BABYLON.Mesh) {
  185. return null;
  186. }
  187. if (source instanceof BABYLON.SubMesh) {
  188. return source.clone(destinationObject);
  189. } else if (source.clone) {
  190. return source.clone();
  191. }
  192. return null;
  193. };
  194. BABYLON.Tools.DeepCopy = function (source, destination, doNotCopyList, mustCopyList) {
  195. for (var prop in source) {
  196. if (prop[0] === "_" && (!mustCopyList || mustCopyList.indexOf(prop) === -1)) {
  197. continue;
  198. }
  199. if (doNotCopyList && doNotCopyList.indexOf(prop) !== -1) {
  200. continue;
  201. }
  202. var sourceValue = source[prop];
  203. var typeOfSourceValue = typeof sourceValue;
  204. if (typeOfSourceValue == "function") {
  205. continue;
  206. }
  207. if (typeOfSourceValue == "object") {
  208. if (sourceValue instanceof Array) {
  209. destination[prop] = [];
  210. if (sourceValue.length > 0) {
  211. if (typeof sourceValue[0] == "object") {
  212. for (var index = 0; index < sourceValue.length; index++) {
  213. var clonedValue = cloneValue(sourceValue[index], destination);
  214. if (destination[prop].indexOf(clonedValue) === -1) { // Test if auto inject was not done
  215. destination[prop].push(clonedValue);
  216. }
  217. }
  218. } else {
  219. destination[prop] = sourceValue.slice(0);
  220. }
  221. }
  222. } else {
  223. destination[prop] = cloneValue(sourceValue, destination);
  224. }
  225. } else {
  226. destination[prop] = sourceValue;
  227. }
  228. }
  229. };
  230. // FPS
  231. var fpsRange = 60;
  232. var previousFramesDuration = [];
  233. var fps = 60;
  234. var deltaTime = 0;
  235. BABYLON.Tools.GetFps = function () {
  236. return fps;
  237. };
  238. BABYLON.Tools.GetDeltaTime = function () {
  239. return deltaTime;
  240. };
  241. BABYLON.Tools._MeasureFps = function () {
  242. previousFramesDuration.push((new Date).getTime());
  243. var length = previousFramesDuration.length;
  244. if (length >= 2) {
  245. deltaTime = previousFramesDuration[length - 1] - previousFramesDuration[length - 2];
  246. }
  247. if (length >= fpsRange) {
  248. if (length > fpsRange) {
  249. previousFramesDuration.splice(0, 1);
  250. length = previousFramesDuration.length;
  251. }
  252. var sum = 0;
  253. for (var id = 0; id < length - 1; id++) {
  254. sum += previousFramesDuration[id + 1] - previousFramesDuration[id];
  255. }
  256. fps = 1000.0 / (sum / (length - 1));
  257. }
  258. };
  259. })();