فهرست منبع

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 سال پیش
والد
کامیت
36ffae5bf9
3فایلهای تغییر یافته به همراه39 افزوده شده و 10 حذف شده
  1. 17 0
      src/Math/babylon.math.ts
  2. 7 3
      src/Physics/Plugins/babylon.cannonJSPlugin.ts
  3. 15 7
      src/Physics/babylon.physicsImpostor.ts

+ 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