babylon.collisionCoordinator.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. var BABYLON;
  2. (function (BABYLON) {
  3. (function (WorkerTaskType) {
  4. WorkerTaskType[WorkerTaskType["INIT"] = 0] = "INIT";
  5. WorkerTaskType[WorkerTaskType["UPDATE"] = 1] = "UPDATE";
  6. WorkerTaskType[WorkerTaskType["COLLIDE"] = 2] = "COLLIDE";
  7. })(BABYLON.WorkerTaskType || (BABYLON.WorkerTaskType = {}));
  8. var WorkerTaskType = BABYLON.WorkerTaskType;
  9. (function (WorkerReplyType) {
  10. WorkerReplyType[WorkerReplyType["SUCCESS"] = 0] = "SUCCESS";
  11. WorkerReplyType[WorkerReplyType["UNKNOWN_ERROR"] = 1] = "UNKNOWN_ERROR";
  12. })(BABYLON.WorkerReplyType || (BABYLON.WorkerReplyType = {}));
  13. var WorkerReplyType = BABYLON.WorkerReplyType;
  14. var CollisionCoordinatorWorker = (function () {
  15. function CollisionCoordinatorWorker() {
  16. var _this = this;
  17. this._scaledPosition = BABYLON.Vector3.Zero();
  18. this._scaledVelocity = BABYLON.Vector3.Zero();
  19. this.onMeshUpdated = function (mesh) {
  20. _this._addUpdateMeshesList[mesh.uniqueId] = CollisionCoordinatorWorker.SerializeMesh(mesh);
  21. };
  22. this.onGeometryUpdated = function (geometry) {
  23. _this._addUpdateGeometriesList[geometry.id] = CollisionCoordinatorWorker.SerializeGeometry(geometry);
  24. };
  25. this._afterRender = function () {
  26. var payload = {
  27. updatedMeshes: _this._addUpdateMeshesList,
  28. updatedGeometries: _this._addUpdateGeometriesList,
  29. removedGeometries: _this._toRemoveGeometryArray,
  30. removedMeshes: _this._toRemoveMeshesArray
  31. };
  32. var message = {
  33. payload: payload,
  34. taskType: 1 /* UPDATE */
  35. };
  36. var serializable = [];
  37. for (var id in payload.updatedGeometries) {
  38. if (payload.updatedGeometries.hasOwnProperty(id)) {
  39. //prepare transferables
  40. serializable.push(message.payload.updatedGeometries[id].indices.buffer);
  41. serializable.push(message.payload.updatedGeometries[id].normals.buffer);
  42. serializable.push(message.payload.updatedGeometries[id].positions.buffer);
  43. }
  44. }
  45. //this variable is here only in case the update takes longer than a frame!
  46. _this._runningUpdated++;
  47. _this._worker.postMessage(message, serializable);
  48. _this._addUpdateMeshesList = {};
  49. _this._addUpdateGeometriesList = {};
  50. _this._toRemoveGeometryArray = [];
  51. _this._toRemoveMeshesArray = [];
  52. };
  53. this._onMessageFromWorker = function (e) {
  54. var returnData = e.data;
  55. switch (returnData.taskType) {
  56. case 0 /* INIT */:
  57. //TODO is init required after worker is done initializing?
  58. _this._init = true;
  59. break;
  60. case 1 /* UPDATE */:
  61. _this._runningUpdated--;
  62. break;
  63. case 2 /* COLLIDE */:
  64. _this._runningCollisionTask = false;
  65. var returnPayload = returnData.payload;
  66. if (!_this._collisionsCallbackArray[returnPayload.collisionId])
  67. return;
  68. _this._collisionsCallbackArray[returnPayload.collisionId](returnPayload.collisionId, BABYLON.Vector3.FromArray(returnPayload.newPosition), _this._scene.getMeshByUniqueID(returnPayload.collidedMeshUniqueId));
  69. //cleanup
  70. _this._collisionsCallbackArray[returnPayload.collisionId] = undefined;
  71. break;
  72. }
  73. };
  74. this._collisionsCallbackArray = [];
  75. this._init = false;
  76. this._runningUpdated = 0;
  77. this._runningCollisionTask = false;
  78. this._addUpdateMeshesList = {};
  79. this._addUpdateGeometriesList = {};
  80. this._toRemoveGeometryArray = [];
  81. this._toRemoveMeshesArray = [];
  82. }
  83. CollisionCoordinatorWorker.prototype.getNewPosition = function (position, velocity, collider, maximumRetry, excludedMesh, onNewPosition, collisionIndex) {
  84. if (this._collisionsCallbackArray[collisionIndex])
  85. return;
  86. position.divideToRef(collider.radius, this._scaledPosition);
  87. velocity.divideToRef(collider.radius, this._scaledVelocity);
  88. this._collisionsCallbackArray[collisionIndex] = onNewPosition;
  89. };
  90. CollisionCoordinatorWorker.prototype.init = function (scene) {
  91. this._scene = scene;
  92. this._scene.registerAfterRender(this._afterRender);
  93. //TODO init worker
  94. };
  95. CollisionCoordinatorWorker.prototype.destroy = function () {
  96. this._scene.unregisterAfterRender(this._afterRender);
  97. //TODO destroy worker
  98. };
  99. CollisionCoordinatorWorker.prototype.onMeshAdded = function (mesh) {
  100. mesh.registerAfterWorldMatrixUpdate(this.onMeshUpdated);
  101. this.onMeshUpdated(mesh);
  102. };
  103. CollisionCoordinatorWorker.prototype.onMeshRemoved = function (mesh) {
  104. this._toRemoveMeshesArray.push(mesh.uniqueId);
  105. };
  106. CollisionCoordinatorWorker.prototype.onGeometryAdded = function (geometry) {
  107. //TODO this will break if the user uses his own function. This should be an array on callbacks!
  108. geometry.onGeometryUpdated = this.onGeometryUpdated;
  109. this.onGeometryUpdated(geometry);
  110. };
  111. CollisionCoordinatorWorker.prototype.onGeometryDeleted = function (geometry) {
  112. this._toRemoveGeometryArray.push(geometry.id);
  113. };
  114. CollisionCoordinatorWorker.SerializeMesh = function (mesh) {
  115. var submeshes = [];
  116. if (mesh.subMeshes) {
  117. submeshes = mesh.subMeshes.map(function (sm, idx) {
  118. return {
  119. position: idx,
  120. verticesStart: sm.verticesStart,
  121. verticesCount: sm.verticesCount,
  122. indexStart: sm.indexStart,
  123. indexCount: sm.indexCount
  124. };
  125. });
  126. }
  127. var geometryId = mesh.geometry ? mesh.geometry.id : null;
  128. return {
  129. uniqueId: mesh.uniqueId,
  130. id: mesh.id,
  131. name: mesh.name,
  132. geometryId: geometryId,
  133. sphereCenter: mesh.getBoundingInfo().boundingSphere.centerWorld.asArray(),
  134. sphereRadius: mesh.getBoundingInfo().boundingSphere.radiusWorld,
  135. boxMinimum: mesh.getBoundingInfo().boundingBox.minimumWorld.asArray(),
  136. boxMaximum: mesh.getBoundingInfo().boundingBox.maximumWorld.asArray(),
  137. worldMatrixFromCache: mesh.worldMatrixFromCache.asArray(),
  138. subMeshes: submeshes,
  139. checkCollisions: mesh.checkCollisions
  140. };
  141. };
  142. CollisionCoordinatorWorker.SerializeGeometry = function (geometry) {
  143. return {
  144. id: geometry.id,
  145. positions: new Float32Array(geometry.getVerticesData(BABYLON.VertexBuffer.PositionKind) || []),
  146. normals: new Float32Array(geometry.getVerticesData(BABYLON.VertexBuffer.NormalKind) || []),
  147. indices: new Int32Array(geometry.getIndices() || []),
  148. };
  149. };
  150. return CollisionCoordinatorWorker;
  151. })();
  152. BABYLON.CollisionCoordinatorWorker = CollisionCoordinatorWorker;
  153. var CollisionCoordinatorLegacy = (function () {
  154. function CollisionCoordinatorLegacy() {
  155. this._scaledPosition = BABYLON.Vector3.Zero();
  156. this._scaledVelocity = BABYLON.Vector3.Zero();
  157. this._finalPosition = BABYLON.Vector3.Zero();
  158. }
  159. CollisionCoordinatorLegacy.prototype.getNewPosition = function (position, velocity, collider, maximumRetry, excludedMesh, onNewPosition, collisionIndex) {
  160. position.divideToRef(collider.radius, this._scaledPosition);
  161. velocity.divideToRef(collider.radius, this._scaledVelocity);
  162. collider.retry = 0;
  163. collider.initialVelocity = this._scaledVelocity;
  164. collider.initialPosition = this._scaledPosition;
  165. this._collideWithWorld(this._scaledPosition, this._scaledVelocity, collider, maximumRetry, this._finalPosition, excludedMesh);
  166. this._finalPosition.multiplyInPlace(collider.radius);
  167. //run the callback
  168. onNewPosition(collisionIndex, this._finalPosition, collider.collidedMesh);
  169. };
  170. CollisionCoordinatorLegacy.prototype.init = function (scene) {
  171. this._scene = scene;
  172. };
  173. CollisionCoordinatorLegacy.prototype.destroy = function () {
  174. //Legacy need no destruction method.
  175. };
  176. //No update in legacy mode
  177. CollisionCoordinatorLegacy.prototype.onMeshAdded = function (mesh) {
  178. };
  179. CollisionCoordinatorLegacy.prototype.onMeshUpdated = function (mesh) {
  180. };
  181. CollisionCoordinatorLegacy.prototype.onMeshRemoved = function (mesh) {
  182. };
  183. CollisionCoordinatorLegacy.prototype.onGeometryAdded = function (geometry) {
  184. };
  185. CollisionCoordinatorLegacy.prototype.onGeometryUpdated = function (geometry) {
  186. };
  187. CollisionCoordinatorLegacy.prototype.onGeometryDeleted = function (geometry) {
  188. };
  189. CollisionCoordinatorLegacy.prototype._collideWithWorld = function (position, velocity, collider, maximumRetry, finalPosition, excludedMesh) {
  190. if (excludedMesh === void 0) { excludedMesh = null; }
  191. var closeDistance = BABYLON.Engine.CollisionsEpsilon * 10.0;
  192. if (collider.retry >= maximumRetry) {
  193. finalPosition.copyFrom(position);
  194. return;
  195. }
  196. collider._initialize(position, velocity, closeDistance);
  197. for (var index = 0; index < this._scene.meshes.length; index++) {
  198. var mesh = this._scene.meshes[index];
  199. if (mesh.isEnabled() && mesh.checkCollisions && mesh.subMeshes && mesh !== excludedMesh) {
  200. mesh._checkCollision(collider);
  201. }
  202. }
  203. if (!collider.collisionFound) {
  204. position.addToRef(velocity, finalPosition);
  205. return;
  206. }
  207. if (velocity.x !== 0 || velocity.y !== 0 || velocity.z !== 0) {
  208. collider._getResponse(position, velocity);
  209. }
  210. if (velocity.length() <= closeDistance) {
  211. finalPosition.copyFrom(position);
  212. return;
  213. }
  214. collider.retry++;
  215. this._collideWithWorld(position, velocity, collider, maximumRetry, finalPosition, excludedMesh);
  216. };
  217. return CollisionCoordinatorLegacy;
  218. })();
  219. BABYLON.CollisionCoordinatorLegacy = CollisionCoordinatorLegacy;
  220. })(BABYLON || (BABYLON = {}));
  221. //# sourceMappingURL=babylon.collisionCoordinator.js.map