babylon.collisionWorker.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. var BABYLON;
  2. (function (BABYLON) {
  3. var CollisionWorker;
  4. (function (CollisionWorker) {
  5. var CollisionCache = (function () {
  6. function CollisionCache() {
  7. this._meshes = {};
  8. this._geometries = {};
  9. }
  10. CollisionCache.prototype.getMeshes = function () {
  11. return this._meshes;
  12. };
  13. CollisionCache.prototype.getGeometries = function () {
  14. return this._geometries;
  15. };
  16. CollisionCache.prototype.getMesh = function (id) {
  17. return this._meshes[id];
  18. };
  19. CollisionCache.prototype.addMesh = function (mesh) {
  20. this._meshes[mesh.uniqueId] = mesh;
  21. };
  22. CollisionCache.prototype.getGeometry = function (id) {
  23. return this._geometries[id];
  24. };
  25. CollisionCache.prototype.addGeometry = function (geometry) {
  26. this._geometries[geometry.id] = geometry;
  27. };
  28. return CollisionCache;
  29. })();
  30. CollisionWorker.CollisionCache = CollisionCache;
  31. var CollideWorker = (function () {
  32. function CollideWorker(collider, _collisionCache, finalPosition) {
  33. this.collider = collider;
  34. this._collisionCache = _collisionCache;
  35. this.finalPosition = finalPosition;
  36. this.collisionsScalingMatrix = BABYLON.Matrix.Zero();
  37. this.collisionTranformationMatrix = BABYLON.Matrix.Zero();
  38. }
  39. CollideWorker.prototype.collideWithWorld = function (position, velocity, maximumRetry, excludedMeshUniqueId) {
  40. var closeDistance = BABYLON.Engine.CollisionsEpsilon * 10.0;
  41. //is initializing here correct? A quick look - looks like it is fine.
  42. if (this.collider.retry >= maximumRetry) {
  43. this.finalPosition.copyFrom(position);
  44. return;
  45. }
  46. this.collider._initialize(position, velocity, closeDistance);
  47. // Check all meshes
  48. var meshes = this._collisionCache.getMeshes();
  49. for (var uniqueId in meshes) {
  50. if (meshes.hasOwnProperty(uniqueId) && parseInt(uniqueId) != excludedMeshUniqueId) {
  51. var mesh = meshes[uniqueId];
  52. if (mesh.checkCollisions)
  53. this.checkCollision(mesh);
  54. }
  55. }
  56. if (!this.collider.collisionFound) {
  57. position.addToRef(velocity, this.finalPosition);
  58. return;
  59. }
  60. if (velocity.x !== 0 || velocity.y !== 0 || velocity.z !== 0) {
  61. this.collider._getResponse(position, velocity);
  62. }
  63. if (velocity.length() <= closeDistance) {
  64. //console.log("webworker collision with " + this.collider.collidedMesh);
  65. this.finalPosition.copyFrom(position);
  66. return;
  67. }
  68. this.collider.retry++;
  69. this.collideWithWorld(position, velocity, maximumRetry, excludedMeshUniqueId);
  70. };
  71. CollideWorker.prototype.checkCollision = function (mesh) {
  72. if (!this.collider._canDoCollision(BABYLON.Vector3.FromArray(mesh.sphereCenter), mesh.sphereRadius, BABYLON.Vector3.FromArray(mesh.boxMinimum), BABYLON.Vector3.FromArray(mesh.boxMaximum))) {
  73. return;
  74. }
  75. ;
  76. // Transformation matrix
  77. BABYLON.Matrix.ScalingToRef(1.0 / this.collider.radius.x, 1.0 / this.collider.radius.y, 1.0 / this.collider.radius.z, this.collisionsScalingMatrix);
  78. var worldFromCache = BABYLON.Matrix.FromArray(mesh.worldMatrixFromCache);
  79. worldFromCache.multiplyToRef(this.collisionsScalingMatrix, this.collisionTranformationMatrix);
  80. this.processCollisionsForSubMeshes(this.collisionTranformationMatrix, mesh);
  81. //return colTransMat;
  82. };
  83. CollideWorker.prototype.processCollisionsForSubMeshes = function (transformMatrix, mesh) {
  84. var len;
  85. // No Octrees for now
  86. //if (this._submeshesOctree && this.useOctreeForCollisions) {
  87. // var radius = collider.velocityWorldLength + Math.max(collider.radius.x, collider.radius.y, collider.radius.z);
  88. // var intersections = this._submeshesOctree.intersects(collider.basePointWorld, radius);
  89. // len = intersections.length;
  90. // subMeshes = intersections.data;
  91. //} else {
  92. // subMeshes = this.subMeshes;
  93. // len = subMeshes.length;
  94. //}
  95. if (!mesh.geometryId) {
  96. console.log("no mesh geometry id");
  97. return;
  98. }
  99. var meshGeometry = this._collisionCache.getGeometry(mesh.geometryId);
  100. if (!meshGeometry) {
  101. console.log("couldn't find geometry", mesh.geometryId);
  102. return;
  103. }
  104. for (var index = 0; index < mesh.subMeshes.length; index++) {
  105. var subMesh = mesh.subMeshes[index];
  106. // Bounding test
  107. if (len > 1 && !this.checkSubmeshCollision(subMesh))
  108. continue;
  109. subMesh['getMesh'] = function () {
  110. return mesh.uniqueId;
  111. };
  112. this.collideForSubMesh(subMesh, transformMatrix, meshGeometry);
  113. }
  114. };
  115. CollideWorker.prototype.collideForSubMesh = function (subMesh, transformMatrix, meshGeometry) {
  116. var positionsArray = [];
  117. for (var i = 0; i < meshGeometry.positions.length; i = i + 3) {
  118. var p = BABYLON.Vector3.FromArray([meshGeometry.positions[i], meshGeometry.positions[i + 1], meshGeometry.positions[i + 2]]);
  119. positionsArray.push(p);
  120. }
  121. subMesh['_lastColliderTransformMatrix'] = transformMatrix.clone();
  122. subMesh['_lastColliderWorldVertices'] = [];
  123. subMesh['_trianglePlanes'] = [];
  124. var start = subMesh.verticesStart;
  125. var end = (subMesh.verticesStart + subMesh.verticesCount);
  126. for (var i = start; i < end; i++) {
  127. subMesh['_lastColliderWorldVertices'].push(BABYLON.Vector3.TransformCoordinates(positionsArray[i], transformMatrix));
  128. }
  129. subMesh['getMaterial'] = function () {
  130. return true;
  131. };
  132. //}
  133. // Collide
  134. this.collider._collide(subMesh, subMesh['_lastColliderWorldVertices'], meshGeometry.indices, subMesh.indexStart, subMesh.indexStart + subMesh.indexCount, subMesh.verticesStart);
  135. };
  136. //TODO - this! :-)
  137. CollideWorker.prototype.checkSubmeshCollision = function (subMesh) {
  138. return true;
  139. };
  140. return CollideWorker;
  141. })();
  142. CollisionWorker.CollideWorker = CollideWorker;
  143. var CollisionDetectorTransferable = (function () {
  144. function CollisionDetectorTransferable() {
  145. }
  146. CollisionDetectorTransferable.prototype.onInit = function (payload) {
  147. this._collisionCache = new CollisionCache();
  148. var reply = {
  149. error: 0 /* SUCCESS */,
  150. taskType: 0 /* INIT */
  151. };
  152. postMessage(reply, undefined);
  153. };
  154. CollisionDetectorTransferable.prototype.onUpdate = function (payload) {
  155. for (var id in payload.updatedGeometries) {
  156. if (payload.updatedGeometries.hasOwnProperty(id)) {
  157. this._collisionCache.addGeometry(payload.updatedGeometries[id]);
  158. }
  159. }
  160. for (var uniqueId in payload.updatedMeshes) {
  161. if (payload.updatedMeshes.hasOwnProperty(uniqueId)) {
  162. this._collisionCache.addMesh(payload.updatedMeshes[uniqueId]);
  163. }
  164. }
  165. var replay = {
  166. error: 0 /* SUCCESS */,
  167. taskType: 1 /* UPDATE */
  168. };
  169. console.log("updated");
  170. postMessage(replay, undefined);
  171. };
  172. CollisionDetectorTransferable.prototype.onCollision = function (payload) {
  173. var finalPosition = BABYLON.Vector3.Zero();
  174. //create a new collider
  175. var collider = new BABYLON.Collider();
  176. collider.radius = BABYLON.Vector3.FromArray(payload.collider.radius);
  177. var colliderWorker = new CollideWorker(collider, this._collisionCache, finalPosition);
  178. colliderWorker.collideWithWorld(BABYLON.Vector3.FromArray(payload.collider.position), BABYLON.Vector3.FromArray(payload.collider.velocity), payload.maximumRetry, payload.excludedMeshUniqueId);
  179. var replyPayload = {
  180. collidedMeshUniqueId: collider.collidedMesh,
  181. collisionId: payload.collisionId,
  182. newPosition: finalPosition.asArray()
  183. };
  184. var reply = {
  185. error: 0 /* SUCCESS */,
  186. taskType: 2 /* COLLIDE */,
  187. payload: replyPayload
  188. };
  189. postMessage(reply, undefined);
  190. };
  191. return CollisionDetectorTransferable;
  192. })();
  193. CollisionWorker.CollisionDetectorTransferable = CollisionDetectorTransferable;
  194. //check if we are in a web worker, as this code should NOT run on the main UI thread
  195. if (self && !self.document) {
  196. var collisionDetector = new CollisionDetectorTransferable();
  197. var onNewMessage = function (event) {
  198. var message = event.data;
  199. switch (message.taskType) {
  200. case 0 /* INIT */:
  201. collisionDetector.onInit(message.payload);
  202. break;
  203. case 2 /* COLLIDE */:
  204. collisionDetector.onCollision(message.payload);
  205. break;
  206. case 1 /* UPDATE */:
  207. collisionDetector.onUpdate(message.payload);
  208. break;
  209. }
  210. };
  211. self.onmessage = onNewMessage;
  212. }
  213. })(CollisionWorker = BABYLON.CollisionWorker || (BABYLON.CollisionWorker = {}));
  214. })(BABYLON || (BABYLON = {}));
  215. //# sourceMappingURL=babylon.collisionWorker.js.map