Raanan Weber 9 سال پیش
والد
کامیت
d86b240081

+ 6 - 0
src/Mesh/babylon.abstractMesh.js

@@ -682,7 +682,13 @@ var BABYLON;
          *  @Deprecated. Use new PhysicsImpostor instead.
          * */
         AbstractMesh.prototype.setPhysicsState = function (impostor, options) {
+            //legacy support
+            if (impostor.type) {
+                options = impostor;
+                impostor = impostor.type;
+            }
             this.physicsImpostor = new BABYLON.PhysicsImpostor(this, impostor, options);
+            return this.physicsImpostor.physicsBody;
         };
         AbstractMesh.prototype.getPhysicsImpostor = function () {
             return this.physicsImpostor;

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

@@ -537,7 +537,7 @@
                     this.rotation.copyFromFloats(0, 0, 0);
                 }
             }
-            
+
             if (this.rotationQuaternion) {
                 this.rotationQuaternion.toRotationMatrix(Tmp.Matrix[0]);
                 this._cache.rotationQuaternion.copyFrom(this.rotationQuaternion);
@@ -772,7 +772,13 @@
          *  @Deprecated. Use new PhysicsImpostor instead.
          * */
         public setPhysicsState(impostor?: any, options?: PhysicsImpostorParameters): any {
+            //legacy support
+            if (impostor.type) {
+                options = impostor;
+                impostor = impostor.type;
+            }
             this.physicsImpostor = new PhysicsImpostor(this, impostor, options);
+            return this.physicsImpostor.physicsBody;
         }
 
         public getPhysicsImpostor(): PhysicsImpostor {

+ 0 - 7
src/Mesh/babylon.mesh.js

@@ -1234,13 +1234,6 @@ var BABYLON;
                     mesh.numBoneInfluencers = parsedMesh.numBoneInfluencers;
                 }
             }
-            // Physics
-            if (parsedMesh.physicsImpostor) {
-                if (!scene.isPhysicsEnabled()) {
-                    scene.enablePhysics();
-                }
-                mesh.setPhysicsState({ impostor: parsedMesh.physicsImpostor, mass: parsedMesh.physicsMass, friction: parsedMesh.physicsFriction, restitution: parsedMesh.physicsRestitution });
-            }
             // Animations
             if (parsedMesh.animations) {
                 for (var animationIndex = 0; animationIndex < parsedMesh.animations.length; animationIndex++) {

+ 0 - 9
src/Mesh/babylon.mesh.ts

@@ -1458,15 +1458,6 @@
                 }
             }
 
-            // Physics
-            if (parsedMesh.physicsImpostor) {
-                if (!scene.isPhysicsEnabled()) {
-                    scene.enablePhysics();
-                }
-
-                mesh.setPhysicsState({ impostor: parsedMesh.physicsImpostor, mass: parsedMesh.physicsMass, friction: parsedMesh.physicsFriction, restitution: parsedMesh.physicsRestitution });
-            }
-
             // Animations
             if (parsedMesh.animations) {
                 for (var animationIndex = 0; animationIndex < parsedMesh.animations.length; animationIndex++) {

+ 5 - 2
src/Physics/Plugins/babylon.cannonJSPlugin.js

@@ -558,7 +558,7 @@ var BABYLON;
                 //unregister events, if body is being changed
                 var oldBody = impostor.physicsBody;
                 if (oldBody) {
-                    this.removePhysicsBody(oldBody);
+                    this.removePhysicsBody(impostor);
                 }
                 //create the body and material
                 var material = this._addMaterial(impostor.getOptions().friction, impostor.getOptions().restitution);
@@ -642,12 +642,15 @@ var BABYLON;
                 case BABYLON.PhysicsJoint.HingeJoint:
                     constraint = new CANNON.HingeConstraint(mainBody, connectedBody, constraintData);
                     break;
+                case BABYLON.PhysicsJoint.DistanceJoint:
+                    constraint = new CANNON.DistanceConstraint(mainBody, connectedBody, jointData.maxDistance || 2);
+                    break;
                 default:
                     constraint = new CANNON.PointToPointConstraint(mainBody, constraintData.pivotA, connectedBody, constraintData.pivotA, constraintData.maxForce);
                     break;
             }
+            impostorJoint.joint.physicsJoint = constraint;
             this.world.addConstraint(constraint);
-            return true;
         };
         CannonJSPlugin.prototype.removeJoint = function (joint) {
             //TODO

+ 14 - 12
src/Physics/Plugins/babylon.cannonJSPlugin.ts

@@ -564,7 +564,7 @@
                 //unregister events, if body is being changed
                 var oldBody = impostor.physicsBody;
                 if (oldBody) {
-                    this.removePhysicsBody(oldBody);
+                    this.removePhysicsBody(impostor);
                 }
                 
                 //create the body and material
@@ -654,13 +654,15 @@
                 case PhysicsJoint.HingeJoint:
                     constraint = new CANNON.HingeConstraint(mainBody, connectedBody, constraintData);
                     break;
+                case PhysicsJoint.DistanceJoint:
+                    constraint = new CANNON.DistanceConstraint(mainBody, connectedBody, (<DistanceJointData>jointData).maxDistance || 2)
+                    break;
                 default:
                     constraint = new CANNON.PointToPointConstraint(mainBody, constraintData.pivotA, connectedBody, constraintData.pivotA, constraintData.maxForce);
                     break;
             }
+            impostorJoint.joint.physicsJoint = constraint;
             this.world.addConstraint(constraint);
-
-            return true;
         }
 
         public removeJoint(joint: PhysicsImpostorJoint) {
@@ -807,14 +809,14 @@
 
             return shape;
         }
-        
+
         private _minus90X = new Quaternion(-0.7071067811865475, 0, 0, 0.7071067811865475);
         private _plus90X = new Quaternion(0.7071067811865475, 0, 0, 0.7071067811865475);
         private _tmpPosition: Vector3 = Vector3.Zero();
-        private _tmpQuaternion: Quaternion = new Quaternion();  
+        private _tmpQuaternion: Quaternion = new Quaternion();
         private _tmpDeltaPosition: Vector3 = Vector3.Zero();
-        private _tmpDeltaRotation: Quaternion = new Quaternion();   
-        private _tmpUnityRotation: Quaternion = new Quaternion();     
+        private _tmpDeltaRotation: Quaternion = new Quaternion();
+        private _tmpUnityRotation: Quaternion = new Quaternion();
 
         private _updatePhysicsBodyTransformation(impostor: PhysicsImpostor) {
             var mesh = impostor.mesh;
@@ -867,22 +869,22 @@
                 mesh.setPivotMatrix(oldPivot);
                 mesh.computeWorldMatrix(true);
             } else if (impostor.type === PhysicsEngine.MeshImpostor) {
-                this._tmpDeltaPosition.copyFromFloats(0,0,0);
+                this._tmpDeltaPosition.copyFromFloats(0, 0, 0);
                 this._tmpPosition.copyFrom(mesh.position);
             }
-            
+
             impostor.setDeltaPosition(this._tmpDeltaPosition);
             //Now update the impostor object
             impostor.physicsBody.position.copy(this._tmpPosition);
             impostor.physicsBody.quaternion.copy(quaternion);
         }
-        
+
         public setTransformationFromPhysicsBody(impostor: PhysicsImpostor) {
             impostor.mesh.position.copyFrom(impostor.physicsBody.position);
             impostor.mesh.rotationQuaternion.copyFrom(impostor.physicsBody.quaternion);
         }
-        
-        public setPhysicsBodyTransformation(impostor: PhysicsImpostor, newPosition:Vector3, newRotation: Quaternion) {
+
+        public setPhysicsBodyTransformation(impostor: PhysicsImpostor, newPosition: Vector3, newRotation: Quaternion) {
             impostor.physicsBody.position.copy(newPosition);
             impostor.physicsBody.quaternion.copy(newRotation);
         }

+ 19 - 14
src/Physics/Plugins/babylon.oimoJSPlugin.js

@@ -43,7 +43,8 @@ var BABYLON;
             }
         };
         OimoJSPlugin.prototype.applyImpulse = function (impostor, force, contactPoint) {
-            impostor.physicsBody.applyImpulse(contactPoint.scale(OIMO.INV_SCALE), force.scale(OIMO.INV_SCALE));
+            var mass = impostor.physicsBody.massInfo.mass;
+            impostor.physicsBody.applyImpulse(contactPoint.scale(OIMO.INV_SCALE), force.scale(OIMO.INV_SCALE * mass));
         };
         OimoJSPlugin.prototype.applyForce = function (impostor, force, contactPoint) {
             BABYLON.Tools.Warn("Oimo doesn't support applying force. Using impule instead.");
@@ -163,12 +164,25 @@ var BABYLON;
             var jointData = impostorJoint.joint.jointData;
             var options = jointData.nativeParams || {};
             var type;
+            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,
+                min: options.min,
+                max: options.max,
+                collision: options.collision,
+                spring: options.spring
+            };
             switch (impostorJoint.joint.type) {
                 case BABYLON.PhysicsJoint.BallAndSocketJoint:
                     type = "jointBall";
                     break;
                 case BABYLON.PhysicsJoint.DistanceJoint:
                     type = "jointDistance";
+                    nativeJointData.max = jointData.maxDistance;
                     break;
                 case BABYLON.PhysicsJoint.PrismaticJoint:
                     type = "jointPrisme";
@@ -184,19 +198,8 @@ var BABYLON;
                     type = "jointHinge";
                     break;
             }
-            impostorJoint.joint.physicsJoint = this.world.add({
-                type: type,
-                body1: mainBody.body,
-                body2: connectedBody.body,
-                min: options.min,
-                max: options.max,
-                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,
-                collision: options.collision,
-                spring: options.spring
-            });
+            nativeJointData.type = type;
+            impostorJoint.joint.physicsJoint = this.world.add(nativeJointData);
         };
         OimoJSPlugin.prototype.removeJoint = function (joint) {
             //TODO
@@ -222,9 +225,11 @@ 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();
         };
         OimoJSPlugin.prototype._getLastShape = function (body) {
             var lastShape = body.shapes;

+ 26 - 21
src/Physics/Plugins/babylon.oimoJSPlugin.ts

@@ -7,7 +7,7 @@ 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);
             this.world.clear();
             this.world.isNoStat = true;
         }
@@ -48,7 +48,7 @@ module BABYLON {
                     contact = contact.next;
                     continue;
                 }
-                
+
                 mainImpostor.onCollide({ body: collidingImpostor.physicsBody });
                 collidingImpostor.onCollide({ body: mainImpostor.physicsBody });
                 contact = contact.next;
@@ -57,8 +57,8 @@ module BABYLON {
         }
 
         public applyImpulse(impostor: PhysicsImpostor, force: Vector3, contactPoint: Vector3) {
-            impostor.physicsBody.applyImpulse(contactPoint.scale(OIMO.INV_SCALE), force.scale(OIMO.INV_SCALE));
-
+            var mass = impostor.physicsBody.massInfo.mass;
+            impostor.physicsBody.applyImpulse(contactPoint.scale(OIMO.INV_SCALE), force.scale(OIMO.INV_SCALE * mass));
         }
         public applyForce(impostor: PhysicsImpostor, force: Vector3, contactPoint: Vector3) {
             Tools.Warn("Oimo doesn't support applying force. Using impule instead.");
@@ -83,7 +83,7 @@ module BABYLON {
                 }
 
                 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.
@@ -205,12 +205,28 @@ module BABYLON {
             var jointData = impostorJoint.joint.jointData;
             var options = jointData.nativeParams || {};
             var type;
+            var nativeJointData: any = {
+                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,
+
+                min: options.min,
+                max: options.max,
+                collision: options.collision,
+                spring: options.spring
+
+            }
             switch (impostorJoint.joint.type) {
                 case PhysicsJoint.BallAndSocketJoint:
                     type = "jointBall";
                     break;
                 case PhysicsJoint.DistanceJoint:
                     type = "jointDistance";
+                    nativeJointData.max = (<DistanceJointData>jointData).maxDistance
                     break;
                 case PhysicsJoint.PrismaticJoint:
                     type = "jointPrisme";
@@ -226,19 +242,8 @@ module BABYLON {
                     type = "jointHinge";
                     break;
             }
-            impostorJoint.joint.physicsJoint = this.world.add({
-                type: type,
-                body1: mainBody.body,
-                body2: connectedBody.body,
-                min: options.min,
-                max: options.max,
-                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,
-                collision: options.collision,
-                spring: options.spring
-            });
+            nativeJointData.type = type;
+            impostorJoint.joint.physicsJoint = this.world.add(nativeJointData);
         }
 
         public removeJoint(joint: PhysicsImpostorJoint) {
@@ -267,12 +272,12 @@ module BABYLON {
 
         public setPhysicsBodyTransformation(impostor: PhysicsImpostor, newPosition: Vector3, newRotation: Quaternion) {
             var body = impostor.physicsBody;
-            
-            if(!newPosition.equalsWithEpsilon(impostor.mesh.position)) {
+
+            if (!newPosition.equalsWithEpsilon(impostor.mesh.position)) {
                 //Doesn't work as expected!
                 body.setPosition(newPosition);
             }
-            
+
             body.setQuaternion(newRotation);
             //body.awake();
         }

+ 8 - 2
src/Physics/babylon.physicsEngine.ts

@@ -60,6 +60,10 @@
 
         public addImpostor(impostor: PhysicsImpostor) {
             this._impostors.push(impostor);
+            //if no parent, generate the body
+            if(!impostor.parent) {
+                this._physicsPlugin.generatePhysicsBody(impostor);
+            }
         }
 
         public removeImpostor(impostor: PhysicsImpostor) {
@@ -74,11 +78,13 @@
         }
 
         public addJoint(mainImpostor: PhysicsImpostor, connectedImpostor: PhysicsImpostor, joint: PhysicsJoint) {
-            this._joints.push({
+            var impostorJoint = {
                 mainImpostor: mainImpostor,
                 connectedImpostor: connectedImpostor,
                 joint: joint
-            });
+            }
+            this._joints.push(impostorJoint);
+            this._physicsPlugin.generateJoint(impostorJoint);
         }
 
         public removeJoint(mainImpostor: PhysicsImpostor, connectedImpostor: PhysicsImpostor, joint: PhysicsJoint) {

+ 6 - 6
src/Physics/babylon.physicsImpostor.js

@@ -3,6 +3,7 @@ var BABYLON;
     var PhysicsImpostor = (function () {
         function PhysicsImpostor(_mesh, type, _options) {
             var _this = this;
+            if (_options === void 0) { _options = { mass: 0 }; }
             this._mesh = _mesh;
             this.type = type;
             this._options = _options;
@@ -42,9 +43,9 @@ var BABYLON;
                 }
             };
             //default options params
-            _options.mass = (_options.mass === void 0) ? 0 : _options.mass;
-            _options.friction = (_options.friction === void 0) ? 0.2 : _options.friction;
-            _options.restitution = (_options.restitution === void 0) ? 0.2 : _options.restitution;
+            this._options.mass = (_options.mass === void 0) ? 0 : _options.mass;
+            this._options.friction = (_options.friction === void 0) ? 0.2 : _options.friction;
+            this._options.restitution = (_options.restitution === void 0) ? 0.2 : _options.restitution;
             this._physicsEngine = this._mesh.getScene().getPhysicsEngine();
             this._joints = [];
             this._init();
@@ -54,7 +55,6 @@ var BABYLON;
             this._parent = this._parent || this._getPhysicsParent();
             if (!this.parent) {
                 this._physicsEngine.addImpostor(this);
-                this._bodyUpdateRequired = true;
             }
         };
         PhysicsImpostor.prototype._getPhysicsParent = function () {
@@ -85,11 +85,11 @@ var BABYLON;
         });
         Object.defineProperty(PhysicsImpostor.prototype, "physicsBody", {
             get: function () {
-                return this._physicsBody;
+                return this.parent ? this.parent.physicsBody : this._physicsBody;
             },
             set: function (physicsBody) {
                 if (this._physicsBody) {
-                    this._physicsEngine.getPhysicsPlugin().removePhysicsBody(this._physicsBody);
+                    this._physicsEngine.getPhysicsPlugin().removePhysicsBody(this);
                 }
                 this._physicsBody = physicsBody;
                 this.resetUpdateFlags();

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

@@ -29,11 +29,11 @@ module BABYLON {
             otherImpostor: PhysicsImpostor
         }>;
 
-        constructor(private _mesh: AbstractMesh, public type: number, private _options: PhysicsImpostorParameters) {
+        constructor(private _mesh: AbstractMesh, public type: number, private _options: PhysicsImpostorParameters = {mass: 0}) {
             //default options params
-            _options.mass = (_options.mass === void 0) ? 0 : _options.mass
-            _options.friction = (_options.friction === void 0) ? 0.2 : _options.friction
-            _options.restitution = (_options.restitution === void 0) ? 0.2 : _options.restitution
+            this._options.mass = (_options.mass === void 0) ? 0 : _options.mass
+            this._options.friction = (_options.friction === void 0) ? 0.2 : _options.friction
+            this._options.restitution = (_options.restitution === void 0) ? 0.2 : _options.restitution
             this._physicsEngine = this._mesh.getScene().getPhysicsEngine();
             this._joints = [];
             this._init();
@@ -44,7 +44,6 @@ module BABYLON {
             this._parent = this._parent || this._getPhysicsParent();
             if (!this.parent) {
                 this._physicsEngine.addImpostor(this);
-                this._bodyUpdateRequired = true;
             }
         }
 
@@ -76,7 +75,7 @@ module BABYLON {
         }
 
         public get physicsBody(): any {
-            return this._physicsBody;
+            return this.parent ? this.parent.physicsBody : this._physicsBody;
         }
 
         public get parent() {
@@ -85,7 +84,7 @@ module BABYLON {
 
         public set physicsBody(physicsBody: any) {
             if (this._physicsBody) {
-                this._physicsEngine.getPhysicsPlugin().removePhysicsBody(this._physicsBody);
+                this._physicsEngine.getPhysicsPlugin().removePhysicsBody(this);
             }
             this._physicsBody = physicsBody;
             this.resetUpdateFlags();