소스 검색

whats new

Trevor Baron 6 년 전
부모
커밋
0e62f97d15
3개의 변경된 파일32개의 추가작업 그리고 41개의 파일을 삭제
  1. 1 0
      dist/preview release/what's new.md
  2. 30 40
      src/Physics/Plugins/babylon.ammoJSPlugin.ts
  3. 1 1
      src/Physics/babylon.physicsImpostor.ts

+ 1 - 0
dist/preview release/what's new.md

@@ -70,6 +70,7 @@
 - Added support for overriding the mesh used for the world matrix for a mesh with a skeleton ([bghgary](https://github.com/bghgary))
 - Added support for linking a bone to a transform node ([bghgary](https://github.com/bghgary))
 - Factored out `setDirection` function from `lookAt` for transform node ([bghgary](https://github.com/bghgary))
+- Added support for AmmoJS physics plugin ([TrevorDev](https://github.com/TrevorDev))
 
 ### glTF Loader
 

+ 30 - 40
src/Physics/Plugins/babylon.ammoJSPlugin.ts

@@ -33,6 +33,7 @@ module BABYLON {
                 return;
             }
 
+            // Initialize the physics world
             this._collisionConfiguration  = new this.BJSAMMO.btDefaultCollisionConfiguration();
             this._dispatcher              = new this.BJSAMMO.btCollisionDispatcher(this._collisionConfiguration);
             this._overlappingPairCache    = new this.BJSAMMO.btDbvtBroadphase();
@@ -40,6 +41,7 @@ module BABYLON {
             this.world           = new this.BJSAMMO.btDiscreteDynamicsWorld(this._dispatcher, this._overlappingPairCache, this._solver, this._collisionConfiguration);
             this._tmpAmmoConcreteContactResultCallback = new this.BJSAMMO.ConcreteContactResultCallback();
 
+            // Create temp ammo variables
             this._tmpAmmoTransform = new this.BJSAMMO.btTransform();
             this._tmpAmmoTransform.setIdentity();
             this._tmpAmmoQuaternion = new this.BJSAMMO.btQuaternion(0, 0, 0, 1);
@@ -62,7 +64,7 @@ module BABYLON {
         }
 
         // Ammo's contactTest and contactPairTest take a callback that runs synchronously, wrap them so that they are easier to consume
-        private _contactTest(impostor: PhysicsImpostor) {
+        private _isImpostorInContact(impostor: PhysicsImpostor) {
             var result = false;
             this._tmpAmmoConcreteContactResultCallback.addSingleResult = function() { result = true; };
             this.world.contactTest(impostor.physicsBody, this._tmpAmmoConcreteContactResultCallback);
@@ -71,7 +73,7 @@ module BABYLON {
         // Ammo's collision events have some weird quirks
         // contactPairTest fires too many events as it fires events even when objects are close together but contactTest does not
         // so only fire event if both contactTest and contactPairTest have a hit
-        private _contactPairTest(impostorA: PhysicsImpostor, impostorB: PhysicsImpostor) {
+        private _isImpostorPairInContact(impostorA: PhysicsImpostor, impostorB: PhysicsImpostor) {
             var result = false;
             this._tmpAmmoConcreteContactResultCallback.addSingleResult = function() { result = true; };
             this.world.contactPairTest(impostorA.physicsBody, impostorB.physicsBody, this._tmpAmmoConcreteContactResultCallback);
@@ -80,20 +82,23 @@ module BABYLON {
 
         public executeStep(delta: number, impostors: Array<PhysicsImpostor>): void {
             impostors.forEach(function(impostor) {
+                // Update physics world objects to match babylon world
                 impostor.beforeStep();
             });
+
             this.world.stepSimulation(this._fixedTimeStep, this._useDeltaForWorldStep ? delta : 0, 3);
 
             impostors.forEach((mainImpostor) => {
+                // After physics update make babylon world objects match physics world objects
                 mainImpostor.afterStep();
 
-                // Handle collision
+                // Handle collision event
                 if (mainImpostor._onPhysicsCollideCallbacks.length > 0) {
-                    if (this._contactTest(mainImpostor)) {
+                    if (this._isImpostorInContact(mainImpostor)) {
                         mainImpostor._onPhysicsCollideCallbacks.forEach((c) => {
                             c.otherImpostors.forEach((otherImpostor) => {
                                 if (mainImpostor.physicsBody.isActive() || otherImpostor.physicsBody.isActive()) {
-                                    if (this._contactPairTest(mainImpostor, otherImpostor)) {
+                                    if (this._isImpostorPairInContact(mainImpostor, otherImpostor)) {
                                         mainImpostor.onCollide({ body: otherImpostor.physicsBody });
                                         otherImpostor.onCollide({ body: mainImpostor.physicsBody });
                                     }
@@ -124,7 +129,7 @@ module BABYLON {
         }
 
         public generatePhysicsBody(impostor: PhysicsImpostor) {
-            impostor._pluginData = {toDispose: []}
+            impostor._pluginData = {toDispose: []};
 
             //parent-child relationship
             if (impostor.parent) {
@@ -145,16 +150,16 @@ module BABYLON {
                 if (mass !== 0) {
                     colShape.calculateLocalInertia(mass, localInertia);
                 }
-                this._tmpAmmoVectorA.setValue(impostor.object.position.x, impostor.object.position.y, impostor.object.position.z)
-                this._tmpAmmoQuaternion.setValue(impostor.object.rotationQuaternion!.x, impostor.object.rotationQuaternion!.y, impostor.object.rotationQuaternion!.z, impostor.object.rotationQuaternion!.w)
+                this._tmpAmmoVectorA.setValue(impostor.object.position.x, impostor.object.position.y, impostor.object.position.z);
+                this._tmpAmmoQuaternion.setValue(impostor.object.rotationQuaternion!.x, impostor.object.rotationQuaternion!.y, impostor.object.rotationQuaternion!.z, impostor.object.rotationQuaternion!.w);
                 startTransform.setOrigin(this._tmpAmmoVectorA);
                 startTransform.setRotation(this._tmpAmmoQuaternion);
                 var myMotionState = new Ammo.btDefaultMotionState(startTransform);
                 var rbInfo        = new Ammo.btRigidBodyConstructionInfo(mass, myMotionState, colShape, localInertia);
                 var body          = new Ammo.btRigidBody(rbInfo);
 
-                // Make objects kinematic
-                if(mass === 0){
+                // Make objects kinematic if it's mass is 0
+                if (mass === 0) {
                     body.setCollisionFlags(body.getCollisionFlags() | AmmoJSPlugin.KINEMATIC_FLAG);
                     body.setActivationState(AmmoJSPlugin.DISABLE_DEACTIVATION_FLAG);
                 }
@@ -162,8 +167,8 @@ module BABYLON {
                 body.setRestitution(impostor.getParam("restitution"));
                 this.world.addRigidBody(body);
                 impostor.physicsBody = body;
-                
-                impostor._pluginData.toDispose.concat([body, rbInfo, myMotionState, startTransform, localInertia, colShape])
+
+                impostor._pluginData.toDispose.concat([body, rbInfo, myMotionState, startTransform, localInertia, colShape]);
             }
         }
 
@@ -171,9 +176,9 @@ module BABYLON {
             if (this.world) {
                 this.world.removeRigidBody(impostor.physicsBody);
 
-                impostor._pluginData.toDispose.forEach((d:any)=>{
+                impostor._pluginData.toDispose.forEach((d: any) => {
                     this.BJSAMMO.destroy(d);
-                })
+                });
             }
         }
 
@@ -197,29 +202,20 @@ module BABYLON {
                 case PhysicsJoint.BallAndSocketJoint:
                     joint = new Ammo.btPoint2PointConstraint(mainBody, connectedBody, new Ammo.btVector3(jointData.mainPivot.x, jointData.mainPivot.y, jointData.mainPivot.z), new Ammo.btVector3(jointData.connectedPivot.x, jointData.connectedPivot.y, jointData.connectedPivot.z));
                     break;
-                // case PhysicsJoint.SpringJoint:
-                //     break;
-                // case PhysicsJoint.DistanceJoint:
-                //     break;
-                // case PhysicsJoint.PrismaticJoint:
-                //     break;
-                // case PhysicsJoint.SliderJoint:
-                //     break;
-                // case PhysicsJoint.WheelJoint:
-                //     break;
-                // case PhysicsJoint.HingeJoint:
-                //     joint = new Ammo.btHingeConstraint(mainBody, connectedBody, new Ammo.btVector3(jointData.mainPivot.x, jointData.mainPivot.y, jointData.mainPivot.z), new Ammo.btVector3(jointData.connectedPivot.x, jointData.connectedPivot.y, jointData.connectedPivot.z));
-                //     break;
                 default:
+                    Tools.Warn("JointType not currently supported by the Ammo plugin, falling back to PhysicsJoint.BallAndSocketJoint");
                     joint = new Ammo.btPoint2PointConstraint(mainBody, connectedBody, new Ammo.btVector3(jointData.mainPivot.x, jointData.mainPivot.y, jointData.mainPivot.z), new Ammo.btVector3(jointData.connectedPivot.x, jointData.connectedPivot.y, jointData.connectedPivot.z));
                     break;
             }
             this.world.addConstraint(joint, true);
+            impostorJoint.joint.physicsJoint = joint;
         }
 
         public removeJoint(impostorJoint: PhysicsImpostorJoint) {
+            this.world.removeConstraint(impostorJoint.joint.physicsJoint);
         }
 
+        // adds all verticies (including child verticies) to the triangle mesh
         private _addMeshVerts(btTriangleMesh: any, topLevelObject: IPhysicsEnabledObject, object: IPhysicsEnabledObject) {
             var triangleCount = 0;
             if (object && object.getIndices && object.getWorldMatrix && object.getChildMeshes) {
@@ -315,18 +311,14 @@ module BABYLON {
                     returnValue = new Ammo.btBoxShape(this._tmpAmmoVectorA);
                     break;
                 case PhysicsImpostor.MeshImpostor:
-
                     var tetraMesh = new Ammo.btTriangleMesh();
                     impostor._pluginData.toDispose.concat([tetraMesh]);
-
                     var triangeCount = this._addMeshVerts(tetraMesh, object, object);
-
                     if (triangeCount == 0) {
                         returnValue = new Ammo.btCompoundShape();
                     }else {
                         returnValue = new Ammo.btBvhTriangleMeshShape(tetraMesh);
                     }
-
                     break;
             }
 
@@ -334,7 +326,6 @@ module BABYLON {
         }
 
         public setTransformationFromPhysicsBody(impostor: PhysicsImpostor) {
-
             impostor.physicsBody.getMotionState().getWorldTransform(this._tmpAmmoTransform);
             impostor.object.position.set(this._tmpAmmoTransform.getOrigin().x(), this._tmpAmmoTransform.getOrigin().y(), this._tmpAmmoTransform.getOrigin().z());
 
@@ -349,7 +340,6 @@ module BABYLON {
         }
 
         public setPhysicsBodyTransformation(impostor: PhysicsImpostor, newPosition: Vector3, newRotation: Quaternion) {
-
             var trans = impostor.physicsBody.getWorldTransform();
 
             // If rotation/position has changed update and activate riged body
@@ -362,20 +352,20 @@ module BABYLON {
                 trans.getRotation().z() != newRotation.z ||
                 trans.getRotation().w() != newRotation.w
             ) {
-                this._tmpAmmoVectorA.setValue(newPosition.x,newPosition.y,newPosition.z)
-                trans.setOrigin(this._tmpAmmoVectorA)
+                this._tmpAmmoVectorA.setValue(newPosition.x, newPosition.y, newPosition.z);
+                trans.setOrigin(this._tmpAmmoVectorA);
 
                 this._tmpAmmoQuaternion.setValue(newRotation.x, newRotation.y, newRotation.z, newRotation.w);
                 trans.setRotation(this._tmpAmmoQuaternion);
                 impostor.physicsBody.setWorldTransform(trans);
 
-                if(impostor.mass == 0){
+                if (impostor.mass == 0) {
                     // Kinematic objects must be updated using motion state
-                    var motionState = impostor.physicsBody.getMotionState()
-                    if(motionState){
-                        motionState.setWorldTransform(trans)
+                    var motionState = impostor.physicsBody.getMotionState();
+                    if (motionState) {
+                        motionState.setWorldTransform(trans);
                     }
-                }else{
+                }else {
                     impostor.physicsBody.activate();
                 }
             }

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

@@ -150,7 +150,7 @@ module BABYLON {
         public static IDENTITY_QUATERNION = Quaternion.Identity();
 
         /** @hidden */
-        public _pluginData:any;
+        public _pluginData: any;
 
         private _physicsEngine: Nullable<IPhysicsEngine>;
         //The native cannon/oimo/energy physics body object.