浏览代码

Oimo Compound bug fix

Oimo has a bug in its body class (which I doubt will ever be fixed).
Rotation cannot be used correctly while creating a compound object.
Setting the rotation afterwards works correctly.
Raanan Weber 9 年之前
父节点
当前提交
9e4becfb79
共有 3 个文件被更改,包括 36 次插入10 次删除
  1. 12 5
      src/Physics/Plugins/babylon.oimoJSPlugin.js
  2. 14 5
      src/Physics/Plugins/babylon.oimoJSPlugin.ts
  3. 10 0
      src/babylon.scene.js

+ 12 - 5
src/Physics/Plugins/babylon.oimoJSPlugin.js

@@ -53,7 +53,7 @@ var BABYLON;
             // The delta between the mesh position and the mesh bounding box center
             var deltaPosition = mesh.position.subtract(bbox.center);
             //calculate rotation to fit Oimo's needs (Euler...)
-            var rot = OIMO.MatrixToEuler(mesh.getWorldMatrix().asArray());
+            var rot = OIMO.MatrixToEuler({ elements: mesh.getWorldMatrix().asArray() });
             var bodyConfig = {
                 pos: [bbox.center.x, bbox.center.y, bbox.center.z],
                 rot: rot,
@@ -103,13 +103,15 @@ var BABYLON;
         OimoJSPlugin.prototype.registerMeshesAsCompound = function (parts, options) {
             var types = [], sizes = [], positions = [], rotations = [];
             var initialMesh = parts[0].mesh;
+            if (!initialMesh.rotationQuaternion) {
+                initialMesh.rotationQuaternion = BABYLON.Quaternion.RotationYawPitchRoll(initialMesh.rotation.y, initialMesh.rotation.x, initialMesh.rotation.z);
+            }
             for (var index = 0; index < parts.length; index++) {
                 var part = parts[index];
                 var bodyParameters = this._createBodyAsCompound(part, options, initialMesh);
                 types.push(bodyParameters.type);
                 sizes.push.apply(sizes, bodyParameters.size);
                 positions.push.apply(positions, bodyParameters.pos);
-                //Hack for Oimo's rotation. Quaternion will be used later.
                 rotations.push.apply(rotations, bodyParameters.rot);
             }
             var body = new OIMO.Body({
@@ -121,6 +123,9 @@ var BABYLON;
                 config: [options.mass, options.friction, options.restitution],
                 world: this._world
             });
+            //Reset the body's rotation to be of the initial mesh's.
+            var rot = OIMO.MatrixToEuler({ elements: initialMesh.getWorldMatrix().asArray() });
+            body.resetRotation(rot.x, rot.y, rot.z);
             this._registeredMeshes.push({
                 mesh: initialMesh,
                 body: body
@@ -131,10 +136,12 @@ var BABYLON;
             var mesh = part.mesh;
             // We need the bounding box/sphere info to compute the physics body
             mesh.computeWorldMatrix();
-            var rot = OIMO.MatrixToEuler(mesh.getWorldMatrix().asArray());
+            var rot = OIMO.MatrixToEuler({ elements: mesh.getWorldMatrix().asArray() });
             var bodyParameters = {
                 pos: [mesh.position.x, mesh.position.y, mesh.position.z],
-                rot: rot
+                //A bug in Oimo (Body class) prevents us from using rot directly.
+                rot: [0, 0, 0],
+                realRot: rot
             };
             switch (part.impostor) {
                 case BABYLON.PhysicsEngine.SphereImpostor:
@@ -156,7 +163,7 @@ var BABYLON;
                     var sizeX = this._checkWithEpsilon(box.x);
                     var sizeY = this._checkWithEpsilon(box.y);
                     var sizeZ = this._checkWithEpsilon(box.z);
-                    bodyParameters.type = 'sphere';
+                    bodyParameters.type = 'box';
                     bodyParameters.size = [sizeX, sizeY, sizeZ];
                     break;
             }

+ 14 - 5
src/Physics/Plugins/babylon.oimoJSPlugin.ts

@@ -33,7 +33,7 @@ module BABYLON {
             var deltaPosition = mesh.position.subtract(bbox.center);
             
             //calculate rotation to fit Oimo's needs (Euler...)
-            var rot = OIMO.MatrixToEuler(mesh.getWorldMatrix().asArray());
+            var rot = OIMO.MatrixToEuler({elements:mesh.getWorldMatrix().asArray()});
 
             var bodyConfig : any = {
                 pos: [bbox.center.x, bbox.center.y, bbox.center.z],
@@ -102,6 +102,10 @@ module BABYLON {
                 rotations = [];
 
             var initialMesh = parts[0].mesh;
+            
+            if (!initialMesh.rotationQuaternion) {
+                initialMesh.rotationQuaternion = Quaternion.RotationYawPitchRoll(initialMesh.rotation.y, initialMesh.rotation.x, initialMesh.rotation.z);
+            }
 
             for (var index = 0; index < parts.length; index++) {
                 var part = parts[index];
@@ -109,7 +113,6 @@ module BABYLON {
                 types.push(bodyParameters.type);
                 sizes.push.apply(sizes, bodyParameters.size);
                 positions.push.apply(positions, bodyParameters.pos);
-                //Hack for Oimo's rotation. Quaternion will be used later.
                 rotations.push.apply(rotations, bodyParameters.rot);
             }
 
@@ -123,6 +126,10 @@ module BABYLON {
                 world: this._world
             });
             
+            //Reset the body's rotation to be of the initial mesh's.
+            var rot = OIMO.MatrixToEuler({ elements: initialMesh.getWorldMatrix().asArray() });
+
+            body.resetRotation(rot.x, rot.y, rot.z);
             
             this._registeredMeshes.push({
                 mesh: initialMesh,
@@ -137,11 +144,13 @@ module BABYLON {
             // We need the bounding box/sphere info to compute the physics body
             mesh.computeWorldMatrix();
 
-            var rot = OIMO.MatrixToEuler(mesh.getWorldMatrix().asArray());
+            var rot = OIMO.MatrixToEuler({elements:mesh.getWorldMatrix().asArray()});
             
             var bodyParameters : any = {
                 pos: [mesh.position.x, mesh.position.y, mesh.position.z],
-                rot: rot
+                //A bug in Oimo (Body class) prevents us from using rot directly.
+                rot: [0,0,0],
+                realRot: rot
             };
             
             switch (part.impostor) {
@@ -172,7 +181,7 @@ module BABYLON {
                     var sizeY = this._checkWithEpsilon(box.y);
                     var sizeZ = this._checkWithEpsilon(box.z);
                     
-                    bodyParameters.type = 'sphere';
+                    bodyParameters.type = 'box';
                     bodyParameters.size = [sizeX, sizeY, sizeZ];
                     
                     break;

+ 10 - 0
src/babylon.scene.js

@@ -1810,6 +1810,12 @@ var BABYLON;
         Scene.prototype.getPhysicsEngine = function () {
             return this._physicsEngine;
         };
+        /**
+         * Enables physics to the current scene
+         * @param {BABYLON.Vector3} [gravity] - the scene's gravity for the physics engine
+         * @param {BABYLON.IPhysicsEnginePlugin} [plugin] - The physics engine to be used. defaults to OimoJS.
+         * @return {boolean} was the physics engine initialized
+         */
         Scene.prototype.enablePhysics = function (gravity, plugin) {
             if (this._physicsEngine) {
                 return true;
@@ -1832,6 +1838,10 @@ var BABYLON;
         Scene.prototype.isPhysicsEnabled = function () {
             return this._physicsEngine !== undefined;
         };
+        /**
+         * Sets the gravity of the physics engine (and NOT of the scene)
+         * @param {BABYLON.Vector3} [gravity] - the new gravity to be used
+         */
         Scene.prototype.setGravity = function (gravity) {
             if (!this._physicsEngine) {
                 return;