babylon.oimoJSPlugin.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. var BABYLON;
  2. (function (BABYLON) {
  3. var OimoJSPlugin = (function () {
  4. function OimoJSPlugin() {
  5. this._registeredMeshes = [];
  6. /**
  7. * Update the body position according to the mesh position
  8. * @param mesh
  9. */
  10. this.updateBodyPosition = function (mesh) {
  11. for (var index = 0; index < this._registeredMeshes.length; index++) {
  12. var registeredMesh = this._registeredMeshes[index];
  13. if (registeredMesh.mesh === mesh || registeredMesh.mesh === mesh.parent) {
  14. var body = registeredMesh.body.body;
  15. body.setPosition(mesh.position.x, mesh.position.y, mesh.position.z);
  16. body.setOrientation(mesh.rotation.x, mesh.rotation.y, mesh.rotation.z);
  17. return;
  18. }
  19. }
  20. };
  21. this.createLink = function (mesh1, mesh2, pivot1, pivot2, options) {
  22. var body1 = null, body2 = null;
  23. for (var index = 0; index < this._registeredMeshes.length; index++) {
  24. var registeredMesh = this._registeredMeshes[index];
  25. if (registeredMesh.mesh === mesh1) {
  26. body1 = registeredMesh.body.body;
  27. } else if (registeredMesh.mesh === mesh2) {
  28. body2 = registeredMesh.body.body;
  29. }
  30. }
  31. if (!body1 || !body2) {
  32. return false;
  33. }
  34. if (!options) {
  35. options = {};
  36. }
  37. new OIMO.Link({
  38. type: options.type,
  39. body1: body1,
  40. body2: body2,
  41. min: options.min,
  42. max: options.max,
  43. axe1: options.axe1,
  44. axe2: options.axe2,
  45. pos1: [pivot1.x, pivot1.y, pivot1.z],
  46. collision: options.collision,
  47. spring: options.spring,
  48. world: this.world
  49. });
  50. return true;
  51. };
  52. }
  53. OimoJSPlugin.prototype.initialize = function (iterations) {
  54. this._world = new OIMO.World();
  55. this._world.clear();
  56. };
  57. OimoJSPlugin.prototype.setGravity = function (gravity) {
  58. this._world.gravity = gravity;
  59. };
  60. OimoJSPlugin.prototype.registerMesh = function (mesh, impostor, options) {
  61. var body = null;
  62. this.unregisterMesh(mesh);
  63. mesh.computeWorldMatrix(true);
  64. switch (impostor) {
  65. case BABYLON.PhysicsEngine.SphereImpostor:
  66. var bsphere = mesh.getBoundingInfo().boundingSphere;
  67. var size = bsphere.maximum.subtract(bsphere.minimum).scale(0.5).multiply(mesh.scaling);
  68. body = new OIMO.Body({
  69. type: 'sphere',
  70. size: [size.x],
  71. pos: [mesh.position.x, mesh.position.y, mesh.position.z],
  72. rot: [mesh.rotation.x / OIMO.TO_RAD, mesh.rotation.y / OIMO.TO_RAD, mesh.rotation.z / OIMO.TO_RAD],
  73. move: options.mass != 0,
  74. config: [options.mass, options.friction, options.restitution],
  75. world: this._world
  76. });
  77. this._registeredMeshes.push({
  78. mesh: mesh,
  79. body: body
  80. });
  81. break;
  82. case BABYLON.PhysicsEngine.PlaneImpostor:
  83. case BABYLON.PhysicsEngine.BoxImpostor:
  84. var bbox = mesh.getBoundingInfo().boundingBox;
  85. size = bbox.extends.scale(2).multiply(mesh.scaling);
  86. body = new OIMO.Body({
  87. type: 'box',
  88. size: [size.x || 0.1, size.y || 0.1, size.z || 0.1],
  89. pos: [mesh.position.x, mesh.position.y, mesh.position.z],
  90. rot: [mesh.rotation.x / OIMO.TO_RAD, mesh.rotation.y / OIMO.TO_RAD, mesh.rotation.z / OIMO.TO_RAD],
  91. move: options.mass != 0,
  92. config: [options.mass, options.friction, options.restitution],
  93. world: this._world
  94. });
  95. this._registeredMeshes.push({
  96. mesh: mesh,
  97. body: body
  98. });
  99. break;
  100. }
  101. return body;
  102. };
  103. OimoJSPlugin.prototype.registerMeshesAsCompound = function (parts, options) {
  104. var types = [], sizes = [], positions = [], rotations = [];
  105. var initialMesh = parts[0].mesh;
  106. for (var index = 0; index < parts.length; index++) {
  107. var part = parts[index];
  108. var bodyParameters = this._createBodyAsCompound(part, options, initialMesh);
  109. types.push(bodyParameters.type);
  110. sizes.push.apply(sizes, bodyParameters.size);
  111. positions.push.apply(positions, bodyParameters.pos);
  112. rotations.push.apply(rotations, bodyParameters.rot);
  113. }
  114. var body = new OIMO.Body({
  115. type: types,
  116. size: sizes,
  117. pos: positions,
  118. rot: rotations,
  119. move: options.mass != 0,
  120. config: [options.mass, options.friction, options.restitution],
  121. world: this._world
  122. });
  123. this._registeredMeshes.push({
  124. mesh: initialMesh,
  125. body: body
  126. });
  127. return body;
  128. };
  129. OimoJSPlugin.prototype._createBodyAsCompound = function (part, options, initialMesh) {
  130. var bodyParameters = null;
  131. var mesh = part.mesh;
  132. switch (part.impostor) {
  133. case BABYLON.PhysicsEngine.SphereImpostor:
  134. var bsphere = mesh.getBoundingInfo().boundingSphere;
  135. var size = bsphere.maximum.subtract(bsphere.minimum).scale(0.5).multiply(mesh.scaling);
  136. bodyParameters = {
  137. type: 'sphere',
  138. /* bug with oimo : sphere needs 3 sizes in this case */
  139. size: [size.x, -1, -1],
  140. pos: [mesh.position.x, mesh.position.y, mesh.position.z],
  141. rot: [mesh.rotation.x / OIMO.TO_RAD, mesh.rotation.y / OIMO.TO_RAD, mesh.rotation.z / OIMO.TO_RAD]
  142. };
  143. break;
  144. case BABYLON.PhysicsEngine.PlaneImpostor:
  145. case BABYLON.PhysicsEngine.BoxImpostor:
  146. var bbox = part.mesh.getBoundingInfo().boundingBox;
  147. size = bbox.extends.scale(2).multiply(mesh.scaling);
  148. var relativePosition = mesh.position;
  149. bodyParameters = {
  150. type: 'box',
  151. size: [size.x || 0.1, size.y || 0.1, size.z || 0.1],
  152. pos: [relativePosition.x, relativePosition.y, relativePosition.z],
  153. rot: [mesh.rotation.x / OIMO.TO_RAD, mesh.rotation.y / OIMO.TO_RAD, mesh.rotation.z / OIMO.TO_RAD]
  154. };
  155. break;
  156. }
  157. return bodyParameters;
  158. };
  159. OimoJSPlugin.prototype.unregisterMesh = function (mesh) {
  160. for (var index = 0; index < this._registeredMeshes.length; index++) {
  161. var registeredMesh = this._registeredMeshes[index];
  162. if (registeredMesh.mesh === mesh || registeredMesh.mesh === mesh.parent) {
  163. if (registeredMesh.body) {
  164. this._world.removeRigidBody(registeredMesh.body.body);
  165. this._unbindBody(registeredMesh.body);
  166. }
  167. this._registeredMeshes.splice(index, 1);
  168. return;
  169. }
  170. }
  171. };
  172. OimoJSPlugin.prototype._unbindBody = function (body) {
  173. for (var index = 0; index < this._registeredMeshes.length; index++) {
  174. var registeredMesh = this._registeredMeshes[index];
  175. if (registeredMesh.body === body) {
  176. registeredMesh.body = null;
  177. }
  178. }
  179. };
  180. OimoJSPlugin.prototype.applyImpulse = function (mesh, force, contactPoint) {
  181. for (var index = 0; index < this._registeredMeshes.length; index++) {
  182. var registeredMesh = this._registeredMeshes[index];
  183. if (registeredMesh.mesh === mesh || registeredMesh.mesh === mesh.parent) {
  184. registeredMesh.body.body.applyImpulse(contactPoint.scale(OIMO.INV_SCALE), force.scale(OIMO.INV_SCALE * 0.01));
  185. return;
  186. }
  187. }
  188. };
  189. OimoJSPlugin.prototype.dispose = function () {
  190. this._world.clear();
  191. while (this._registeredMeshes.length) {
  192. this.unregisterMesh(this._registeredMeshes[0].mesh);
  193. }
  194. };
  195. OimoJSPlugin.prototype.isSupported = function () {
  196. return OIMO !== undefined;
  197. };
  198. OimoJSPlugin.prototype._getLastShape = function (body) {
  199. var lastShape = body.shapes;
  200. while (lastShape.next) {
  201. lastShape = lastShape.next;
  202. }
  203. return lastShape;
  204. };
  205. OimoJSPlugin.prototype.runOneStep = function (time) {
  206. this._world.step();
  207. // Update the position of all registered meshes
  208. var i = this._registeredMeshes.length;
  209. var m;
  210. while (i--) {
  211. var body = this._registeredMeshes[i].body.body;
  212. var mesh = this._registeredMeshes[i].mesh;
  213. if (!body.sleeping) {
  214. if (body.shapes.next) {
  215. var parentShape = this._getLastShape(body);
  216. mesh.position.x = parentShape.position.x * OIMO.WORLD_SCALE;
  217. mesh.position.y = parentShape.position.y * OIMO.WORLD_SCALE;
  218. mesh.position.z = parentShape.position.z * OIMO.WORLD_SCALE;
  219. var mtx = BABYLON.Matrix.FromArray(body.getMatrix());
  220. if (!mesh.rotationQuaternion) {
  221. mesh.rotationQuaternion = new BABYLON.Quaternion(0, 0, 0, 1);
  222. }
  223. mesh.rotationQuaternion.fromRotationMatrix(mtx);
  224. } else {
  225. m = body.getMatrix();
  226. mtx = BABYLON.Matrix.FromArray(m);
  227. mesh.position.x = mtx.m[12];
  228. mesh.position.y = mtx.m[13];
  229. mesh.position.z = mtx.m[14];
  230. if (!mesh.rotationQuaternion) {
  231. mesh.rotationQuaternion = new BABYLON.Quaternion(0, 0, 0, 1);
  232. }
  233. mesh.rotationQuaternion.fromRotationMatrix(mtx);
  234. }
  235. }
  236. }
  237. };
  238. return OimoJSPlugin;
  239. })();
  240. BABYLON.OimoJSPlugin = OimoJSPlugin;
  241. })(BABYLON || (BABYLON = {}));
  242. //# sourceMappingURL=babylon.oimoJSPlugin.js.map