浏览代码

Changes to parenting system and bug fixes

Raanan Weber 9 年之前
父节点
当前提交
d618f3767a

+ 2 - 1
src/Mesh/babylon.abstractMesh.js

@@ -735,7 +735,8 @@ var BABYLON;
             }
             this.physicsImpostor.createJoint(otherMesh.physicsImpostor, BABYLON.PhysicsJoint.HingeJoint, {
                 mainPivot: pivot1,
-                connectedPivot: pivot2
+                connectedPivot: pivot2,
+                nativeParams: options
             });
         };
         /**

+ 2 - 1
src/Mesh/babylon.abstractMesh.ts

@@ -837,7 +837,8 @@
 
             this.physicsImpostor.createJoint(otherMesh.physicsImpostor, PhysicsJoint.HingeJoint, {
                 mainPivot: pivot1,
-                connectedPivot: pivot2
+                connectedPivot: pivot2,
+                nativeParams: options
             })
         }
 

+ 37 - 23
src/Physics/Plugins/babylon.oimoJSPlugin.js

@@ -5,8 +5,9 @@ var BABYLON;
             this.name = "OimoJSPlugin";
             this._tmpImpostorsArray = [];
             this._tmpPositionVector = BABYLON.Vector3.Zero();
-            this.world = new OIMO.World(1 / 60, 2, iterations);
+            this.world = new OIMO.World(1 / 60, 2, iterations, true);
             this.world.clear();
+            //making sure no stats are calculated
             this.world.isNoStat = true;
         }
         OimoJSPlugin.prototype.setGravity = function (gravity) {
@@ -51,6 +52,7 @@ var BABYLON;
             this.applyImpulse(impostor, force, contactPoint);
         };
         OimoJSPlugin.prototype.generatePhysicsBody = function (impostor) {
+            var _this = this;
             //parent-child relationship. Does this impostor has a parent impostor?
             if (impostor.parent) {
                 if (impostor.physicsBody) {
@@ -65,7 +67,6 @@ var BABYLON;
                 if (!impostor.mesh.rotationQuaternion) {
                     impostor.mesh.rotationQuaternion = BABYLON.Quaternion.RotationYawPitchRoll(impostor.mesh.rotation.y, impostor.mesh.rotation.x, impostor.mesh.rotation.z);
                 }
-                impostor.mesh.position.subtractToRef(impostor.mesh.getBoundingInfo().boundingBox.center, this._tmpPositionVector);
                 var bodyConfig = {
                     name: impostor.mesh.uniqueId,
                     //Oimo must have mass, also for static objects.
@@ -74,13 +75,16 @@ var BABYLON;
                     type: [],
                     pos: [],
                     rot: [],
-                    move: impostor.getParam("mass") !== 0
+                    move: impostor.getParam("mass") !== 0,
+                    //Supporting older versions of Oimo
+                    world: this.world
                 };
                 var impostors = [impostor];
                 function addToArray(parent) {
                     parent.getChildMeshes().forEach(function (m) {
                         if (m.physicsImpostor) {
                             impostors.push(m.physicsImpostor);
+                            m.physicsImpostor._init();
                         }
                         addToArray(m);
                     });
@@ -97,19 +101,25 @@ var BABYLON;
                     i.mesh.computeWorldMatrix(true);
                     var bbox = i.mesh.getBoundingInfo().boundingBox;
                     if (i === impostor) {
+                        impostor.mesh.position.subtractToRef(impostor.mesh.getBoundingInfo().boundingBox.center, _this._tmpPositionVector);
                         //Can also use Array.prototype.push.apply
                         bodyConfig.pos.push(bbox.center.x);
                         bodyConfig.pos.push(bbox.center.y);
                         bodyConfig.pos.push(bbox.center.z);
+                        //tmp solution
+                        bodyConfig.rot.push(rot.x / (OIMO.degtorad || OIMO.TO_RAD));
+                        bodyConfig.rot.push(rot.y / (OIMO.degtorad || OIMO.TO_RAD));
+                        bodyConfig.rot.push(rot.z / (OIMO.degtorad || OIMO.TO_RAD));
                     }
                     else {
                         bodyConfig.pos.push(i.mesh.position.x);
                         bodyConfig.pos.push(i.mesh.position.y);
                         bodyConfig.pos.push(i.mesh.position.z);
+                        //tmp solution until https://github.com/lo-th/Oimo.js/pull/37 is merged
+                        bodyConfig.rot.push(0);
+                        bodyConfig.rot.push(0);
+                        bodyConfig.rot.push(0);
                     }
-                    bodyConfig.rot.push(rot.x / OIMO.degtorad);
-                    bodyConfig.rot.push(rot.y / OIMO.degtorad);
-                    bodyConfig.rot.push(rot.z / OIMO.degtorad);
                     // register mesh
                     switch (i.type) {
                         case BABYLON.PhysicsEngine.SphereImpostor:
@@ -143,16 +153,18 @@ var BABYLON;
                     //actually not needed, but hey...
                     i.mesh.rotationQuaternion = oldQuaternion;
                 });
-                impostor.physicsBody = this.world.add(bodyConfig);
-                impostor.setDeltaPosition(this._tmpPositionVector);
+                impostor.physicsBody = new OIMO.Body(bodyConfig).body; //this.world.add(bodyConfig);
             }
             else {
                 this._tmpPositionVector.copyFromFloats(0, 0, 0);
             }
-            this._tmpPositionVector.addInPlace(impostor.mesh.getBoundingInfo().boundingBox.center);
-            this.setPhysicsBodyTransformation(impostor, this._tmpPositionVector, impostor.mesh.rotationQuaternion);
+            impostor.setDeltaPosition(this._tmpPositionVector);
+            //this._tmpPositionVector.addInPlace(impostor.mesh.getBoundingInfo().boundingBox.center);
+            //this.setPhysicsBodyTransformation(impostor, this._tmpPositionVector, impostor.mesh.rotationQuaternion);
         };
         OimoJSPlugin.prototype.removePhysicsBody = function (impostor) {
+            //impostor.physicsBody.dispose();
+            //Same as : (older oimo versions)
             this.world.removeRigidBody(impostor.physicsBody);
         };
         OimoJSPlugin.prototype.generateJoint = function (impostorJoint) {
@@ -167,14 +179,16 @@ var BABYLON;
             var nativeJointData = {
                 body1: mainBody,
                 body2: connectedBody,
-                axe1: jointData.mainAxis ? jointData.mainAxis.asArray() : null,
-                axe2: jointData.connectedAxis ? jointData.connectedAxis.asArray() : null,
-                pos1: jointData.mainPivot ? jointData.mainPivot.asArray() : null,
-                pos2: jointData.connectedPivot ? jointData.connectedPivot.asArray() : null,
+                axe1: options.axe1 || (jointData.mainAxis ? jointData.mainAxis.asArray() : null),
+                axe2: options.axe2 || (jointData.connectedAxis ? jointData.connectedAxis.asArray() : null),
+                pos1: options.pos1 || (jointData.mainPivot ? jointData.mainPivot.asArray() : null),
+                pos2: options.pos2 || (jointData.connectedPivot ? jointData.connectedPivot.asArray() : null),
                 min: options.min,
                 max: options.max,
                 collision: options.collision,
-                spring: options.spring
+                spring: options.spring,
+                //supporting older version of Oimo
+                world: this.world
             };
             switch (impostorJoint.joint.type) {
                 case BABYLON.PhysicsJoint.BallAndSocketJoint:
@@ -199,10 +213,10 @@ var BABYLON;
                     break;
             }
             nativeJointData.type = type;
-            impostorJoint.joint.physicsJoint = this.world.add(nativeJointData);
+            impostorJoint.joint.physicsJoint = new OIMO.Link(nativeJointData).joint; //this.world.add(nativeJointData);
         };
         OimoJSPlugin.prototype.removeJoint = function (joint) {
-            //TODO
+            joint.joint.physicsJoint.dispose();
         };
         OimoJSPlugin.prototype.isSupported = function () {
             return OIMO !== undefined;
@@ -224,12 +238,12 @@ var BABYLON;
         };
         OimoJSPlugin.prototype.setPhysicsBodyTransformation = function (impostor, newPosition, newRotation) {
             var body = impostor.physicsBody;
-            if (!newPosition.equalsWithEpsilon(impostor.mesh.position)) {
-                //Doesn't work as expected!
-                body.setPosition(newPosition);
-            }
-            body.setQuaternion(newRotation);
-            //body.awake();
+            //if (!newPosition.equalsWithEpsilon(impostor.mesh.position)) {
+            body.position.init(newPosition.x * OIMO.INV_SCALE, newPosition.y * OIMO.INV_SCALE, newPosition.z * OIMO.INV_SCALE);
+            //}
+            body.orientation.init(newRotation.w, newRotation.x, newRotation.y, newRotation.z);
+            body.syncShapes();
+            body.awake();
         };
         OimoJSPlugin.prototype._getLastShape = function (body) {
             var lastShape = body.shapes;

+ 48 - 30
src/Physics/Plugins/babylon.oimoJSPlugin.ts

@@ -7,8 +7,9 @@ module BABYLON {
         public name: string = "OimoJSPlugin";
 
         constructor(iterations?: number) {
-            this.world = new OIMO.World(1 / 60, 2, iterations);
+            this.world = new OIMO.World(1 / 60, 2, iterations, true);
             this.world.clear();
+            //making sure no stats are calculated
             this.world.isNoStat = true;
         }
 
@@ -82,8 +83,7 @@ module BABYLON {
                     impostor.mesh.rotationQuaternion = Quaternion.RotationYawPitchRoll(impostor.mesh.rotation.y, impostor.mesh.rotation.x, impostor.mesh.rotation.z);
                 }
 
-                impostor.mesh.position.subtractToRef(impostor.mesh.getBoundingInfo().boundingBox.center, this._tmpPositionVector);
-
+                
                 var bodyConfig: any = {
                     name: impostor.mesh.uniqueId,
                     //Oimo must have mass, also for static objects.
@@ -92,7 +92,9 @@ module BABYLON {
                     type: [],
                     pos: [],
                     rot: [],
-                    move: impostor.getParam("mass") !== 0
+                    move: impostor.getParam("mass") !== 0,
+                    //Supporting older versions of Oimo
+                    world: this.world
                 };
 
                 var impostors = [impostor];
@@ -100,6 +102,7 @@ module BABYLON {
                     parent.getChildMeshes().forEach(function(m) {
                         if (m.physicsImpostor) {
                             impostors.push(m.physicsImpostor);
+                            m.physicsImpostor._init();
                         }
                         addToArray(m);
                     });
@@ -110,7 +113,7 @@ module BABYLON {
                     return Math.max(value, PhysicsEngine.Epsilon);
                 }
 
-                impostors.forEach(function(i) {
+                impostors.forEach((i) => {
                     
                     //get the correct bounding box
                     var oldQuaternion = i.mesh.rotationQuaternion;
@@ -118,23 +121,32 @@ module BABYLON {
 
                     i.mesh.rotationQuaternion = new Quaternion(0, 0, 0, 1);
                     i.mesh.computeWorldMatrix(true);
-
-                    var bbox = i.mesh.getBoundingInfo().boundingBox;
                     
+                    var bbox = i.mesh.getBoundingInfo().boundingBox;
+
                     if (i === impostor) {
+                        
+                        impostor.mesh.position.subtractToRef(impostor.mesh.getBoundingInfo().boundingBox.center, this._tmpPositionVector);
+
                         //Can also use Array.prototype.push.apply
                         bodyConfig.pos.push(bbox.center.x);
                         bodyConfig.pos.push(bbox.center.y);
                         bodyConfig.pos.push(bbox.center.z);
+                        
+                        //tmp solution
+                        bodyConfig.rot.push(rot.x / (OIMO.degtorad || OIMO.TO_RAD));
+                        bodyConfig.rot.push(rot.y / (OIMO.degtorad || OIMO.TO_RAD));
+                        bodyConfig.rot.push(rot.z / (OIMO.degtorad || OIMO.TO_RAD));
                     } else {
                         bodyConfig.pos.push(i.mesh.position.x);
                         bodyConfig.pos.push(i.mesh.position.y);
                         bodyConfig.pos.push(i.mesh.position.z);
+                        
+                        //tmp solution until https://github.com/lo-th/Oimo.js/pull/37 is merged
+                        bodyConfig.rot.push(0);
+                        bodyConfig.rot.push(0);
+                        bodyConfig.rot.push(0);
                     }
-
-                    bodyConfig.rot.push(rot.x / OIMO.degtorad);
-                    bodyConfig.rot.push(rot.y / OIMO.degtorad);
-                    bodyConfig.rot.push(rot.z / OIMO.degtorad);
                     
                     // register mesh
                     switch (i.type) {
@@ -179,20 +191,23 @@ module BABYLON {
                     i.mesh.rotationQuaternion = oldQuaternion;
                 });
 
-                impostor.physicsBody = this.world.add(bodyConfig);
-
-                impostor.setDeltaPosition(this._tmpPositionVector);
+                impostor.physicsBody = new OIMO.Body(bodyConfig).body//this.world.add(bodyConfig);
 
             } else {
                 this._tmpPositionVector.copyFromFloats(0, 0, 0);
             }
-            this._tmpPositionVector.addInPlace(impostor.mesh.getBoundingInfo().boundingBox.center);
-            this.setPhysicsBodyTransformation(impostor, this._tmpPositionVector, impostor.mesh.rotationQuaternion);
+            
+            impostor.setDeltaPosition(this._tmpPositionVector);
+
+            //this._tmpPositionVector.addInPlace(impostor.mesh.getBoundingInfo().boundingBox.center);
+            //this.setPhysicsBodyTransformation(impostor, this._tmpPositionVector, impostor.mesh.rotationQuaternion);
         }
 
         private _tmpPositionVector: Vector3 = Vector3.Zero();
 
         public removePhysicsBody(impostor: PhysicsImpostor) {
+            //impostor.physicsBody.dispose();
+            //Same as : (older oimo versions)
             this.world.removeRigidBody(impostor.physicsBody);
         }
 
@@ -210,15 +225,18 @@ module BABYLON {
                 body1: mainBody,
                 body2: connectedBody,
 
-                axe1: jointData.mainAxis ? jointData.mainAxis.asArray() : null,
-                axe2: jointData.connectedAxis ? jointData.connectedAxis.asArray() : null,
-                pos1: jointData.mainPivot ? jointData.mainPivot.asArray() : null,
-                pos2: jointData.connectedPivot ? jointData.connectedPivot.asArray() : null,
+                axe1: options.axe1 || (jointData.mainAxis ? jointData.mainAxis.asArray() : null),
+                axe2: options.axe2 || (jointData.connectedAxis ? jointData.connectedAxis.asArray() : null),
+                pos1: options.pos1 || (jointData.mainPivot ? jointData.mainPivot.asArray() : null),
+                pos2: options.pos2 || (jointData.connectedPivot ? jointData.connectedPivot.asArray() : null),
 
                 min: options.min,
                 max: options.max,
                 collision: options.collision,
-                spring: options.spring
+                spring: options.spring,
+                
+                //supporting older version of Oimo
+                world: this.world
 
             }
             switch (impostorJoint.joint.type) {
@@ -244,11 +262,11 @@ module BABYLON {
                     break;
             }
             nativeJointData.type = type;
-            impostorJoint.joint.physicsJoint = this.world.add(nativeJointData);
+            impostorJoint.joint.physicsJoint = new OIMO.Link(nativeJointData).joint//this.world.add(nativeJointData);
         }
 
         public removeJoint(joint: PhysicsImpostorJoint) {
-            //TODO
+            joint.joint.physicsJoint.dispose();
         }
 
         public isSupported(): boolean {
@@ -274,13 +292,13 @@ module BABYLON {
         public setPhysicsBodyTransformation(impostor: PhysicsImpostor, newPosition: Vector3, newRotation: Quaternion) {
             var body = impostor.physicsBody;
 
-            if (!newPosition.equalsWithEpsilon(impostor.mesh.position)) {
-                //Doesn't work as expected!
-                body.setPosition(newPosition);
-            }
-
-            body.setQuaternion(newRotation);
-            //body.awake();
+            //if (!newPosition.equalsWithEpsilon(impostor.mesh.position)) {
+            body.position.init(newPosition.x * OIMO.INV_SCALE, newPosition.y * OIMO.INV_SCALE, newPosition.z * OIMO.INV_SCALE);
+            //}
+            
+            body.orientation.init(newRotation.w, newRotation.x, newRotation.y, newRotation.z);
+            body.syncShapes();
+            body.awake();
         }
 
         private _getLastShape(body: any): any {

+ 13 - 8
src/Physics/babylon.physicsEngine.js

@@ -29,6 +29,10 @@ var BABYLON;
         };
         PhysicsEngine.prototype.addImpostor = function (impostor) {
             this._impostors.push(impostor);
+            //if no parent, generate the body
+            if (!impostor.parent) {
+                this._physicsPlugin.generatePhysicsBody(impostor);
+            }
         };
         PhysicsEngine.prototype.removeImpostor = function (impostor) {
             var index = this._impostors.indexOf(impostor);
@@ -36,16 +40,19 @@ var BABYLON;
                 var removed = this._impostors.splice(index, 1);
                 //Is it needed?
                 if (removed.length) {
-                    this._physicsPlugin.removePhysicsBody(removed[0]);
+                    //this will also remove it from the world.
+                    removed[0].physicsBody = null;
                 }
             }
         };
         PhysicsEngine.prototype.addJoint = function (mainImpostor, connectedImpostor, joint) {
-            this._joints.push({
+            var impostorJoint = {
                 mainImpostor: mainImpostor,
                 connectedImpostor: connectedImpostor,
                 joint: joint
-            });
+            };
+            this._joints.push(impostorJoint);
+            this._physicsPlugin.generateJoint(impostorJoint);
         };
         PhysicsEngine.prototype.removeJoint = function (mainImpostor, connectedImpostor, joint) {
             var matchingJoints = this._joints.filter(function (impostorJoint) {
@@ -57,6 +64,9 @@ var BABYLON;
                 this._physicsPlugin.removeJoint(matchingJoints[0]);
             }
         };
+        /**
+         * Called by the scene. no need to call it.
+         */
         PhysicsEngine.prototype._step = function (delta) {
             var _this = this;
             //check if any mesh has no body / requires an update
@@ -102,9 +112,4 @@ var BABYLON;
         return PhysicsEngine;
     }());
     BABYLON.PhysicsEngine = PhysicsEngine;
-    (function (PhysicsFeature) {
-        PhysicsFeature[PhysicsFeature["PIVOT_IN_JOINT"] = 0] = "PIVOT_IN_JOINT";
-        PhysicsFeature[PhysicsFeature["TRIMESH"] = 1] = "TRIMESH";
-    })(BABYLON.PhysicsFeature || (BABYLON.PhysicsFeature = {}));
-    var PhysicsFeature = BABYLON.PhysicsFeature;
 })(BABYLON || (BABYLON = {}));

+ 1 - 1
src/Physics/babylon.physicsEngine.ts

@@ -72,7 +72,7 @@
                 var removed = this._impostors.splice(index, 1);
                 //Is it needed?
                 if(removed.length) {
-                    this._physicsPlugin.removePhysicsBody(removed[0]);
+                    //this will also remove it from the world.
                     removed[0].physicsBody = null;
                 }
             }

+ 3 - 4
src/Physics/babylon.physicsImpostor.js

@@ -48,7 +48,9 @@ var BABYLON;
             this._options.restitution = (_options.restitution === void 0) ? 0.2 : _options.restitution;
             this._physicsEngine = this._mesh.getScene().getPhysicsEngine();
             this._joints = [];
-            this._init();
+            if (!this._mesh.parent) {
+                this._init();
+            }
         }
         PhysicsImpostor.prototype._init = function () {
             this._physicsEngine.removeImpostor(this);
@@ -57,9 +59,6 @@ var BABYLON;
             if (!this.parent) {
                 this._physicsEngine.addImpostor(this);
             }
-            else {
-                this.parent.forceUpdate();
-            }
         };
         PhysicsImpostor.prototype._getPhysicsParent = function () {
             if (this.mesh.parent instanceof BABYLON.AbstractMesh) {

+ 6 - 5
src/Physics/babylon.physicsImpostor.ts

@@ -36,18 +36,19 @@ module BABYLON {
             this._options.restitution = (_options.restitution === void 0) ? 0.2 : _options.restitution
             this._physicsEngine = this._mesh.getScene().getPhysicsEngine();
             this._joints = [];
-            this._init();
+            //If the mesh has a parent, don't initialize the physicsBody. Instead wait for the parent to do that.
+            if(!this._mesh.parent) {
+                this._init();
+            }
         }
 
-        private _init() {
+        public _init() {
             this._physicsEngine.removeImpostor(this);
             this.physicsBody = null;
             this._parent = this._parent || this._getPhysicsParent();
             if (!this.parent) {
                 this._physicsEngine.addImpostor(this);
-            } else {
-                this.parent.forceUpdate();
-            }
+            } 
         }
 
         private _getPhysicsParent(): PhysicsImpostor {

+ 1 - 1
src/Physics/babylon.physicsJoint.js

@@ -35,6 +35,6 @@ var BABYLON;
         //TODO check!!
         PhysicsJoint.PointToPointJoint = 8;
         return PhysicsJoint;
-    })();
+    }());
     BABYLON.PhysicsJoint = PhysicsJoint;
 })(BABYLON || (BABYLON = {}));

+ 1 - 0
src/babylon.scene.js

@@ -2043,6 +2043,7 @@ var BABYLON;
                 }
                 mesh.physicsImpostor = new BABYLON.PhysicsImpostor(mesh, parts[index].impostor, options);
             }
+            mainMesh.physicsImpostor.forceUpdate();
         };
         Scene.prototype.deleteCompoundImpostor = function (compound) {
             var mesh = compound.parts[0].mesh;