babylon.tools.js 9.8 KB

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