Prechádzať zdrojové kódy

Merge pull request #1000 from RaananW/physics-bug-fixes

Physics Bug Fixing
David Catuhe 9 rokov pred
rodič
commit
4f46bae7d5

+ 17 - 0
src/Math/babylon.math.ts

@@ -1592,6 +1592,23 @@
 
             return this;
         }
+        
+        public conjugateToRef(ref: Quaternion) {
+            ref.copyFromFloats(-this.x, -this.y, -this.z, this.w);
+            return this;
+        }
+        
+        public conjugateInPlace() {
+            this.x *= -1;
+            this.y *= -1;
+            this.z *= -1;
+            return this;
+        }
+        
+        public conjugate() {
+            var result = new Quaternion(-this.x, -this.y, -this.z, this.w);
+            return result;
+        }
 
         public length(): number {
             return Math.sqrt((this.x * this.x) + (this.y * this.y) + (this.z * this.z) + (this.w * this.w));

+ 7 - 3
src/Physics/Plugins/babylon.cannonJSPlugin.ts

@@ -149,9 +149,11 @@
                 pivotB: jointData.connectedPivot ? new CANNON.Vec3().copy(jointData.connectedPivot) : null,
                 axisA: jointData.mainAxis ? new CANNON.Vec3().copy(jointData.mainAxis) : null,
                 axisB: jointData.connectedAxis ? new CANNON.Vec3().copy(jointData.connectedAxis) : null,
-                maxForce: jointData.nativeParams.maxForce
+                maxForce: jointData.nativeParams.maxForce,
+                collideConnected: !!jointData.collision
             };
-            if (!jointData.collision) {
+            //Not needed, Cannon has a collideConnected flag
+            /*if (!jointData.collision) {
                 //add 1st body to a collision group of its own, if it is not in 1
                 if (mainBody.collisionFilterGroup === 1) {
                     mainBody.collisionFilterGroup = this._currentCollisionGroup;
@@ -164,7 +166,7 @@
                 //add their mask to the collisionFilterMask of each other:
                 connectedBody.collisionFilterMask = connectedBody.collisionFilterMask | ~mainBody.collisionFilterGroup;
                 mainBody.collisionFilterMask = mainBody.collisionFilterMask | ~connectedBody.collisionFilterGroup;
-            }
+            }*/
             switch (impostorJoint.joint.type) {
                 case PhysicsJoint.HingeJoint:
                     constraint = new CANNON.HingeConstraint(mainBody, connectedBody, constraintData);
@@ -176,6 +178,8 @@
                     constraint = new CANNON.PointToPointConstraint(mainBody, constraintData.pivotA, connectedBody, constraintData.pivotA, constraintData.maxForce);
                     break;
             }
+            //set the collideConnected flag after the creation, since DistanceJoint ignores it.
+            constraint.collideConnected = !!jointData.collision
             impostorJoint.joint.physicsJoint = constraint;
             this.world.addConstraint(constraint);
         }

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

@@ -19,7 +19,8 @@ module BABYLON {
         private _onPhysicsCollideCallbacks: Array<{ callback: (collider: PhysicsImpostor, collidedAgainst: PhysicsImpostor) => void, otherImpostors: Array<PhysicsImpostor> }> = []
 
         private _deltaPosition: Vector3 = Vector3.Zero();
-        private _deltaRotation: Quaternion = new Quaternion();
+        private _deltaRotation: Quaternion;
+        private _deltaRotationConjugated: Quaternion;
         
         //If set, this is this impostor's parent
         private _parent: PhysicsImpostor;
@@ -185,12 +186,12 @@ module BABYLON {
          * register a function that will be executed when this impostor collides against a different body.
          */
         public registerOnPhysicsCollide(collideAgainst: PhysicsImpostor | Array<PhysicsImpostor>, func: (collider: PhysicsImpostor, collidedAgainst: PhysicsImpostor) => void): void {
-            var collidedAgainstList : Array<PhysicsImpostor> = collideAgainst instanceof Array ? <Array<PhysicsImpostor>> collideAgainst : [<PhysicsImpostor>collideAgainst]
+            var collidedAgainstList: Array<PhysicsImpostor> = collideAgainst instanceof Array ? <Array<PhysicsImpostor>>collideAgainst : [<PhysicsImpostor>collideAgainst]
             this._onPhysicsCollideCallbacks.push({ callback: func, otherImpostors: collidedAgainstList });
         }
 
         public unregisterOnPhysicsCollide(collideAgainst: PhysicsImpostor | Array<PhysicsImpostor>, func: (collider: PhysicsImpostor, collidedAgainst: PhysicsImpostor | Array<PhysicsImpostor>) => void): void {
-            var collidedAgainstList : Array<PhysicsImpostor> = collideAgainst instanceof Array ? <Array<PhysicsImpostor>> collideAgainst : [<PhysicsImpostor>collideAgainst]
+            var collidedAgainstList: Array<PhysicsImpostor> = collideAgainst instanceof Array ? <Array<PhysicsImpostor>>collideAgainst : [<PhysicsImpostor>collideAgainst]
             var index = this._onPhysicsCollideCallbacks.indexOf({ callback: func, otherImpostors: collidedAgainstList });
 
             if (index > -1) {
@@ -210,8 +211,9 @@ module BABYLON {
 
             this.mesh.position.subtractToRef(this._deltaPosition, this._tmpPositionWithDelta);
             //conjugate deltaRotation
-            this._tmpRotationWithDelta.copyFrom(this._deltaRotation);
-            this._tmpRotationWithDelta.multiplyInPlace(this.mesh.rotationQuaternion);
+            if (this._deltaRotationConjugated) {
+                this.mesh.rotationQuaternion.multiplyToRef(this._deltaRotationConjugated, this._tmpRotationWithDelta);
+            }
 
             this._physicsEngine.getPhysicsPlugin().setPhysicsBodyTransformation(this, this._tmpPositionWithDelta, this._tmpRotationWithDelta);
 
@@ -231,7 +233,9 @@ module BABYLON {
             this._physicsEngine.getPhysicsPlugin().setTransformationFromPhysicsBody(this);
 
             this.mesh.position.addInPlace(this._deltaPosition)
-            this.mesh.rotationQuaternion.multiplyInPlace(this._deltaRotation);
+            if(this._deltaRotation) {
+                this.mesh.rotationQuaternion.multiplyInPlace(this._deltaRotation);
+            }
         }
         
         //event and body object due to cannon's event-based architecture.
@@ -298,7 +302,7 @@ module BABYLON {
             if (this.parent) {
                 this.parent.forceUpdate();
             } else {
-                this.mesh.getChildMeshes().forEach(function (mesh) {
+                this.mesh.getChildMeshes().forEach(function(mesh) {
                     if (mesh.physicsImpostor) {
                         if (disposeChildren) {
                             mesh.physicsImpostor.dispose();
@@ -314,7 +318,11 @@ module BABYLON {
         }
 
         public setDeltaRotation(rotation: Quaternion) {
+            if(!this._deltaRotation) {
+                this._deltaRotation = new Quaternion();
+            }
             this._deltaRotation.copyFrom(rotation);
+            this._deltaRotationConjugated = this._deltaRotation.conjugate();
         }
         
         //Impostor types