Prechádzať zdrojové kódy

Physics Bug Fixing

Delta rotation should be conjugated, otherwise the body will keep on
constantly flipping (is deltaRotation is set).
cannonJS collision of joined objects improved.
Added Conjugate function to the quaternion class.
Raanan Weber 9 rokov pred
rodič
commit
36ffae5bf9

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

@@ -1592,6 +1592,23 @@
 
 
             return this;
             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 {
         public length(): number {
             return Math.sqrt((this.x * this.x) + (this.y * this.y) + (this.z * this.z) + (this.w * this.w));
             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,
                 pivotB: jointData.connectedPivot ? new CANNON.Vec3().copy(jointData.connectedPivot) : null,
                 axisA: jointData.mainAxis ? new CANNON.Vec3().copy(jointData.mainAxis) : null,
                 axisA: jointData.mainAxis ? new CANNON.Vec3().copy(jointData.mainAxis) : null,
                 axisB: jointData.connectedAxis ? new CANNON.Vec3().copy(jointData.connectedAxis) : 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
                 //add 1st body to a collision group of its own, if it is not in 1
                 if (mainBody.collisionFilterGroup === 1) {
                 if (mainBody.collisionFilterGroup === 1) {
                     mainBody.collisionFilterGroup = this._currentCollisionGroup;
                     mainBody.collisionFilterGroup = this._currentCollisionGroup;
@@ -164,7 +166,7 @@
                 //add their mask to the collisionFilterMask of each other:
                 //add their mask to the collisionFilterMask of each other:
                 connectedBody.collisionFilterMask = connectedBody.collisionFilterMask | ~mainBody.collisionFilterGroup;
                 connectedBody.collisionFilterMask = connectedBody.collisionFilterMask | ~mainBody.collisionFilterGroup;
                 mainBody.collisionFilterMask = mainBody.collisionFilterMask | ~connectedBody.collisionFilterGroup;
                 mainBody.collisionFilterMask = mainBody.collisionFilterMask | ~connectedBody.collisionFilterGroup;
-            }
+            }*/
             switch (impostorJoint.joint.type) {
             switch (impostorJoint.joint.type) {
                 case PhysicsJoint.HingeJoint:
                 case PhysicsJoint.HingeJoint:
                     constraint = new CANNON.HingeConstraint(mainBody, connectedBody, constraintData);
                     constraint = new CANNON.HingeConstraint(mainBody, connectedBody, constraintData);
@@ -176,6 +178,8 @@
                     constraint = new CANNON.PointToPointConstraint(mainBody, constraintData.pivotA, connectedBody, constraintData.pivotA, constraintData.maxForce);
                     constraint = new CANNON.PointToPointConstraint(mainBody, constraintData.pivotA, connectedBody, constraintData.pivotA, constraintData.maxForce);
                     break;
                     break;
             }
             }
+            //set the collideConnected flag after the creation, since DistanceJoint ignores it.
+            constraint.collideConnected = !!jointData.collision
             impostorJoint.joint.physicsJoint = constraint;
             impostorJoint.joint.physicsJoint = constraint;
             this.world.addConstraint(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 _onPhysicsCollideCallbacks: Array<{ callback: (collider: PhysicsImpostor, collidedAgainst: PhysicsImpostor) => void, otherImpostors: Array<PhysicsImpostor> }> = []
 
 
         private _deltaPosition: Vector3 = Vector3.Zero();
         private _deltaPosition: Vector3 = Vector3.Zero();
-        private _deltaRotation: Quaternion = new Quaternion();
+        private _deltaRotation: Quaternion;
+        private _deltaRotationConjugated: Quaternion;
         
         
         //If set, this is this impostor's parent
         //If set, this is this impostor's parent
         private _parent: PhysicsImpostor;
         private _parent: PhysicsImpostor;
@@ -185,12 +186,12 @@ module BABYLON {
          * register a function that will be executed when this impostor collides against a different body.
          * 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 {
         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 });
             this._onPhysicsCollideCallbacks.push({ callback: func, otherImpostors: collidedAgainstList });
         }
         }
 
 
         public unregisterOnPhysicsCollide(collideAgainst: PhysicsImpostor | Array<PhysicsImpostor>, func: (collider: PhysicsImpostor, collidedAgainst: PhysicsImpostor | Array<PhysicsImpostor>) => void): void {
         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 });
             var index = this._onPhysicsCollideCallbacks.indexOf({ callback: func, otherImpostors: collidedAgainstList });
 
 
             if (index > -1) {
             if (index > -1) {
@@ -210,8 +211,9 @@ module BABYLON {
 
 
             this.mesh.position.subtractToRef(this._deltaPosition, this._tmpPositionWithDelta);
             this.mesh.position.subtractToRef(this._deltaPosition, this._tmpPositionWithDelta);
             //conjugate deltaRotation
             //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);
             this._physicsEngine.getPhysicsPlugin().setPhysicsBodyTransformation(this, this._tmpPositionWithDelta, this._tmpRotationWithDelta);
 
 
@@ -231,7 +233,9 @@ module BABYLON {
             this._physicsEngine.getPhysicsPlugin().setTransformationFromPhysicsBody(this);
             this._physicsEngine.getPhysicsPlugin().setTransformationFromPhysicsBody(this);
 
 
             this.mesh.position.addInPlace(this._deltaPosition)
             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.
         //event and body object due to cannon's event-based architecture.
@@ -298,7 +302,7 @@ module BABYLON {
             if (this.parent) {
             if (this.parent) {
                 this.parent.forceUpdate();
                 this.parent.forceUpdate();
             } else {
             } else {
-                this.mesh.getChildMeshes().forEach(function (mesh) {
+                this.mesh.getChildMeshes().forEach(function(mesh) {
                     if (mesh.physicsImpostor) {
                     if (mesh.physicsImpostor) {
                         if (disposeChildren) {
                         if (disposeChildren) {
                             mesh.physicsImpostor.dispose();
                             mesh.physicsImpostor.dispose();
@@ -314,7 +318,11 @@ module BABYLON {
         }
         }
 
 
         public setDeltaRotation(rotation: Quaternion) {
         public setDeltaRotation(rotation: Quaternion) {
+            if(!this._deltaRotation) {
+                this._deltaRotation = new Quaternion();
+            }
             this._deltaRotation.copyFrom(rotation);
             this._deltaRotation.copyFrom(rotation);
+            this._deltaRotationConjugated = this._deltaRotation.conjugate();
         }
         }
         
         
         //Impostor types
         //Impostor types