Trevor Baron 6 gadi atpakaļ
vecāks
revīzija
0e931ef599
1 mainītis faili ar 182 papildinājumiem un 478 dzēšanām
  1. 182 478
      src/Physics/Plugins/babylon.ammoJSPlugin.ts

+ 182 - 478
src/Physics/Plugins/babylon.ammoJSPlugin.ts

@@ -1,32 +1,38 @@
 module BABYLON {
-    //declare var require: any;
-    declare var CANNON: any;
+    declare var Ammo: any;
 
     /** @hidden */
-    export class CannonJSPlugin implements IPhysicsEnginePlugin {
-
+    export class AmmoJSPlugin implements IPhysicsEnginePlugin {
+        public BJSAMMO:any;
         public world: any;
-        public name: string = "CannonJSPlugin";
-        private _physicsMaterials = new Array();
+        public name: string = "AmmoJSPlugin";
+
         private _fixedTimeStep: number = 1 / 60;
-        //See https://github.com/schteppe/CANNON.js/blob/gh-pages/demos/collisionFilter.html
-        public BJSCANNON = CANNON;
+        private _tmpQuaternion = new BABYLON.Quaternion();
+        private _tmpAmmoTransform:any;
+        private _tmpAmmoQuaternion:any;
 
         public constructor(private _useDeltaForWorldStep: boolean = true, iterations: number = 10) {
+            if(typeof Ammo === "function"){
+                Ammo();
+            }
+            this.BJSAMMO = Ammo;
             if (!this.isSupported()) {
-                Tools.Error("CannonJS is not available. Please make sure you included the js file.");
+                Tools.Error("AmmoJS is not available. Please make sure you included the js file.");
                 return;
             }
 
-            this._extendNamespace();
-
-            this.world = new this.BJSCANNON.World();
-            this.world.broadphase = new this.BJSCANNON.NaiveBroadphase();
-            this.world.solver.iterations = iterations;
+            var collisionConfiguration  = new this.BJSAMMO.btDefaultCollisionConfiguration();
+            var dispatcher              = new this.BJSAMMO.btCollisionDispatcher(collisionConfiguration);
+            var overlappingPairCache    = new this.BJSAMMO.btDbvtBroadphase();
+            var solver                  = new this.BJSAMMO.btSequentialImpulseConstraintSolver();
+            this.world           = new this.BJSAMMO.btDiscreteDynamicsWorld(dispatcher, overlappingPairCache, solver, collisionConfiguration);
+            this._tmpAmmoTransform = new this.BJSAMMO.btTransform();
+            this._tmpAmmoQuaternion = new this.BJSAMMO.btQuaternion(0,0,0,1);
         }
 
         public setGravity(gravity: Vector3): void {
-            this.world.gravity.copy(gravity);
+            this.world.setGravity(new this.BJSAMMO.btVector3(gravity.x, gravity.y, gravity.z));
         }
 
         public setTimeStep(timeStep: number) {
@@ -38,119 +44,62 @@ module BABYLON {
         }
 
         public executeStep(delta: number, impostors: Array<PhysicsImpostor>): void {
-            this.world.step(this._fixedTimeStep, this._useDeltaForWorldStep ? delta : 0, 3);
+            impostors.forEach(function(impostor) {
+                impostor.beforeStep();
+            });
+            this.world.stepSimulation(this._fixedTimeStep, this._useDeltaForWorldStep ? delta : 0, 3);
+            impostors.forEach((impostor) => {
+                impostor.afterStep();
+            });
         }
 
         public applyImpulse(impostor: PhysicsImpostor, force: Vector3, contactPoint: Vector3) {
-            var worldPoint = new this.BJSCANNON.Vec3(contactPoint.x, contactPoint.y, contactPoint.z);
-            var impulse = new this.BJSCANNON.Vec3(force.x, force.y, force.z);
+            var worldPoint = new this.BJSAMMO.btVector3(contactPoint.x, contactPoint.y, contactPoint.z);
+            var impulse = new this.BJSAMMO.btVector3(force.x, force.y, force.z);
 
             impostor.physicsBody.applyImpulse(impulse, worldPoint);
         }
 
         public applyForce(impostor: PhysicsImpostor, force: Vector3, contactPoint: Vector3) {
-            var worldPoint = new this.BJSCANNON.Vec3(contactPoint.x, contactPoint.y, contactPoint.z);
-            var impulse = new this.BJSCANNON.Vec3(force.x, force.y, force.z);
+            var worldPoint = new this.BJSAMMO.btVector3(contactPoint.x, contactPoint.y, contactPoint.z);
+            var impulse = new this.BJSAMMO.btVector3(force.x, force.y, force.z);
 
             impostor.physicsBody.applyForce(impulse, worldPoint);
         }
 
         public generatePhysicsBody(impostor: PhysicsImpostor) {
-            //parent-child relationship. Does this impostor has a parent impostor?
+            //parent-child relationship
             if (impostor.parent) {
                 if (impostor.physicsBody) {
                     this.removePhysicsBody(impostor);
-                    //TODO is that needed?
                     impostor.forceUpdate();
                 }
                 return;
             }
 
-            //should a new body be created for this impostor?
             if (impostor.isBodyInitRequired()) {
-
-                var shape = this._createShape(impostor);
-
-                //unregister events, if body is being changed
-                var oldBody = impostor.physicsBody;
-                if (oldBody) {
-                    this.removePhysicsBody(impostor);
-                }
-
-                //create the body and material
-                var material = this._addMaterial("mat-" + impostor.uniqueId, impostor.getParam("friction"), impostor.getParam("restitution"));
-
-                var bodyCreationObject = {
-                    mass: impostor.getParam("mass"),
-                    material: material
-                };
-                // A simple extend, in case native options were used.
-                var nativeOptions = impostor.getParam("nativeOptions");
-                for (var key in nativeOptions) {
-                    if (nativeOptions.hasOwnProperty(key)) {
-                        (<any>bodyCreationObject)[key] = nativeOptions[key];
-                    }
-                }
-                impostor.physicsBody = new this.BJSCANNON.Body(bodyCreationObject);
-                impostor.physicsBody.addEventListener("collide", impostor.onCollide);
-                this.world.addEventListener("preStep", impostor.beforeStep);
-                this.world.addEventListener("postStep", impostor.afterStep);
-                impostor.physicsBody.addShape(shape);
-                this.world.add(impostor.physicsBody);
-
-                //try to keep the body moving in the right direction by taking old properties.
-                //Should be tested!
-                if (oldBody) {
-                    ['force', 'torque', 'velocity', 'angularVelocity'].forEach(function(param) {
-                        impostor.physicsBody[param].copy(oldBody[param]);
-                    });
+                var colShape = this._createShape(impostor);
+                var mass          = impostor.getParam("mass")
+                var isDynamic     = (mass !== 0)
+                var localInertia  = new Ammo.btVector3(0, 0, 0);
+                var startTransform  = new Ammo.btTransform();
+                startTransform.setIdentity();
+                if (isDynamic){
+                    colShape.calculateLocalInertia(mass,localInertia);
                 }
-                this._processChildMeshes(impostor);
+                startTransform.setOrigin(new Ammo.btVector3(impostor.object.position.x, impostor.object.position.y, impostor.object.position.z));
+                var myMotionState = new Ammo.btDefaultMotionState(startTransform)
+                var rbInfo        = new Ammo.btRigidBodyConstructionInfo(mass, myMotionState, colShape, localInertia)
+                var body          = new Ammo.btRigidBody(rbInfo);
+                body.setRestitution(impostor.getParam("restitution"));
+                this.world.addRigidBody(body);
+                impostor.physicsBody = body;
             }
-
-            //now update the body's transformation
-            this._updatePhysicsBodyTransformation(impostor);
         }
 
-        private _processChildMeshes(mainImpostor: PhysicsImpostor) {
-            var meshChildren = mainImpostor.object.getChildMeshes ? mainImpostor.object.getChildMeshes(true) : [];
-            let currentRotation: Nullable<Quaternion> = mainImpostor.object.rotationQuaternion;
-            if (meshChildren.length) {
-                var processMesh = (localPosition: Vector3, mesh: AbstractMesh) => {
-
-                    if (!currentRotation || !mesh.rotationQuaternion) {
-                        return;
-                    }
-
-                    var childImpostor = mesh.getPhysicsImpostor();
-                    if (childImpostor) {
-                        var parent = childImpostor.parent;
-                        if (parent !== mainImpostor) {
-                            var pPosition = mesh.getAbsolutePosition().subtract(mainImpostor.object.getAbsolutePosition());
-                            let localRotation = mesh.rotationQuaternion.multiply(Quaternion.Inverse(currentRotation));
-                            if (childImpostor.physicsBody) {
-                                this.removePhysicsBody(childImpostor);
-                                childImpostor.physicsBody = null;
-                            }
-                            childImpostor.parent = mainImpostor;
-                            childImpostor.resetUpdateFlags();
-                            mainImpostor.physicsBody.addShape(this._createShape(childImpostor), new this.BJSCANNON.Vec3(pPosition.x, pPosition.y, pPosition.z), new this.BJSCANNON.Quaternion(localRotation.x, localRotation.y, localRotation.z, localRotation.w));
-                            //Add the mass of the children.
-                            mainImpostor.physicsBody.mass += childImpostor.getParam("mass");
-                        }
-                    }
-                    currentRotation.multiplyInPlace(mesh.rotationQuaternion);
-                    mesh.getChildMeshes(true).filter((m) => !!m.physicsImpostor).forEach(processMesh.bind(this, mesh.getAbsolutePosition()));
-                };
-                meshChildren.filter((m) => !!m.physicsImpostor).forEach(processMesh.bind(this, mainImpostor.object.getAbsolutePosition()));
-            }
-        }
 
         public removePhysicsBody(impostor: PhysicsImpostor) {
-            impostor.physicsBody.removeEventListener("collide", impostor.onCollide);
-            this.world.removeEventListener("preStep", impostor.beforeStep);
-            this.world.removeEventListener("postStep", impostor.afterStep);
-            this.world.remove(impostor.physicsBody);
+            this.world.removeRigidBody(impostor.physicsBody);
         }
 
         public generateJoint(impostorJoint: PhysicsImpostorJoint) {
@@ -159,90 +108,51 @@ module BABYLON {
             if (!mainBody || !connectedBody) {
                 return;
             }
-            var constraint: any;
+            
             var jointData = impostorJoint.joint.jointData;
-            //TODO - https://github.com/schteppe/this.BJSCANNON.js/blob/gh-pages/demos/collisionFilter.html
-            var constraintData = {
-                pivotA: jointData.mainPivot ? new this.BJSCANNON.Vec3().copy(jointData.mainPivot) : null,
-                pivotB: jointData.connectedPivot ? new this.BJSCANNON.Vec3().copy(jointData.connectedPivot) : null,
-                axisA: jointData.mainAxis ? new this.BJSCANNON.Vec3().copy(jointData.mainAxis) : null,
-                axisB: jointData.connectedAxis ? new this.BJSCANNON.Vec3().copy(jointData.connectedAxis) : null,
-                maxForce: jointData.nativeParams.maxForce,
-                collideConnected: !!jointData.collision
-            };
+            if(!jointData.mainPivot){
+                jointData.mainPivot = new Vector3(0,0,0);
+            }
+            if(!jointData.connectedPivot){
+                jointData.connectedPivot = new Vector3(0,0,0);
+            }
+
+            var joint:any;
             switch (impostorJoint.joint.type) {
-                case PhysicsJoint.HingeJoint:
-                case PhysicsJoint.Hinge2Joint:
-                    constraint = new this.BJSCANNON.HingeConstraint(mainBody, connectedBody, constraintData);
-                    break;
-                case PhysicsJoint.DistanceJoint:
-                    constraint = new this.BJSCANNON.DistanceConstraint(mainBody, connectedBody, (<DistanceJointData>jointData).maxDistance || 2);
-                    break;
-                case PhysicsJoint.SpringJoint:
-                    var springData = <SpringJointData>jointData;
-                    constraint = new this.BJSCANNON.Spring(mainBody, connectedBody, {
-                        restLength: springData.length,
-                        stiffness: springData.stiffness,
-                        damping: springData.damping,
-                        localAnchorA: constraintData.pivotA,
-                        localAnchorB: constraintData.pivotB
-                    });
+                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.LockJoint:
-                    constraint = new this.BJSCANNON.LockConstraint(mainBody, connectedBody, constraintData);
+                // case PhysicsJoint.SpringJoint:
+                //     Tools.Warn("OIMO.js doesn't support Spring Constraint. Simulating using DistanceJoint instead");
+                //     var springData = <SpringJointData>jointData;
+                //     nativeJointData.min = springData.length || nativeJointData.min;
+                //     //Max should also be set, just make sure it is at least min
+                //     nativeJointData.max = Math.max(nativeJointData.min, nativeJointData.max);
+                // case PhysicsJoint.DistanceJoint:
+                //     type = "jointDistance";
+                //     nativeJointData.max = (<DistanceJointData>jointData).maxDistance;
+                //     break;
+                // case PhysicsJoint.PrismaticJoint:
+                //     type = "jointPrisme";
+                //     break;
+                // case PhysicsJoint.SliderJoint:
+                //     type = "jointSlide";
+                //     break;
+                // case PhysicsJoint.WheelJoint:
+                //     type = "jointWheel";
+                //     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;
-                case PhysicsJoint.PointToPointJoint:
-                case PhysicsJoint.BallAndSocketJoint:
                 default:
-                    constraint = new this.BJSCANNON.PointToPointConstraint(mainBody, constraintData.pivotA, connectedBody, constraintData.pivotA, constraintData.maxForce);
+                    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;
             }
-            //set the collideConnected flag after the creation, since DistanceJoint ignores it.
-            constraint.collideConnected = !!jointData.collision;
-            impostorJoint.joint.physicsJoint = constraint;
-            //don't add spring as constraint, as it is not one.
-            if (impostorJoint.joint.type !== PhysicsJoint.SpringJoint) {
-                this.world.addConstraint(constraint);
-            } else {
-                (<SpringJointData>impostorJoint.joint.jointData).forceApplicationCallback = (<SpringJointData>impostorJoint.joint.jointData).forceApplicationCallback || function() {
-                    constraint.applyForce();
-                };
-                impostorJoint.mainImpostor.registerAfterPhysicsStep((<SpringJointData>impostorJoint.joint.jointData).forceApplicationCallback);
-            }
+            this.world.addConstraint(joint, true);
         }
 
         public removeJoint(impostorJoint: PhysicsImpostorJoint) {
-            if (impostorJoint.joint.type !== PhysicsJoint.SpringJoint) {
-                this.world.removeConstraint(impostorJoint.joint.physicsJoint);
-            } else {
-                impostorJoint.mainImpostor.unregisterAfterPhysicsStep((<SpringJointData>impostorJoint.joint.jointData).forceApplicationCallback);
-            }
-
-        }
-
-        private _addMaterial(name: string, friction: number, restitution: number) {
-            var index;
-            var mat;
-
-            for (index = 0; index < this._physicsMaterials.length; index++) {
-                mat = this._physicsMaterials[index];
-
-                if (mat.friction === friction && mat.restitution === restitution) {
-                    return mat;
-                }
-            }
-
-            var currentMat = new this.BJSCANNON.Material(name);
-            currentMat.friction = friction;
-            currentMat.restitution = restitution;
-
-            this._physicsMaterials.push(currentMat);
-            return currentMat;
-        }
-
-        private _checkWithEpsilon(value: number): number {
-            return value < PhysicsEngine.Epsilon ? PhysicsEngine.Epsilon : value;
-        }
+        }      
 
         private _createShape(impostor: PhysicsImpostor) {
             var object = impostor.object;
@@ -251,269 +161,121 @@ module BABYLON {
             var extendSize = impostor.getObjectExtendSize();
             switch (impostor.type) {
                 case PhysicsImpostor.SphereImpostor:
-                    var radiusX = extendSize.x;
-                    var radiusY = extendSize.y;
-                    var radiusZ = extendSize.z;
-
-                    returnValue = new this.BJSCANNON.Sphere(Math.max(this._checkWithEpsilon(radiusX), this._checkWithEpsilon(radiusY), this._checkWithEpsilon(radiusZ)) / 2);
-
+                    returnValue = new this.BJSAMMO.btSphereShape(extendSize.x/2);
                     break;
-                //TMP also for cylinder - TODO Cannon supports cylinder natively.
                 case PhysicsImpostor.CylinderImpostor:
-                    returnValue = new this.BJSCANNON.Cylinder(this._checkWithEpsilon(extendSize.x) / 2, this._checkWithEpsilon(extendSize.x) / 2, this._checkWithEpsilon(extendSize.y), 16);
-                    break;
-                case PhysicsImpostor.BoxImpostor:
-                    var box = extendSize.scale(0.5);
-                    returnValue = new this.BJSCANNON.Box(new this.BJSCANNON.Vec3(this._checkWithEpsilon(box.x), this._checkWithEpsilon(box.y), this._checkWithEpsilon(box.z)));
+                    returnValue = new this.BJSAMMO.btCylinderShape(new this.BJSAMMO.btVector3(extendSize.x/2,extendSize.y/2,extendSize.z/2));
                     break;
                 case PhysicsImpostor.PlaneImpostor:
-                    Tools.Warn("Attention, PlaneImposter might not behave as you expect. Consider using BoxImposter instead");
-                    returnValue = new this.BJSCANNON.Plane();
+                case PhysicsImpostor.BoxImpostor:
+                    returnValue = new this.BJSAMMO.btBoxShape(new this.BJSAMMO.btVector3(extendSize.x/2,extendSize.y/2,extendSize.z/2));
                     break;
                 case PhysicsImpostor.MeshImpostor:
-                    // should transform the vertex data to world coordinates!!
-                    var rawVerts = object.getVerticesData ? object.getVerticesData(VertexBuffer.PositionKind) : [];
-                    var rawFaces = object.getIndices ? object.getIndices() : [];
-                    if (!rawVerts) { return; }
-                    // get only scale! so the object could transform correctly.
-                    let oldPosition = object.position.clone();
-                    let oldRotation = object.rotation && object.rotation.clone();
-                    let oldQuaternion = object.rotationQuaternion && object.rotationQuaternion.clone();
-                    object.position.copyFromFloats(0, 0, 0);
-                    object.rotation && object.rotation.copyFromFloats(0, 0, 0);
-                    object.rotationQuaternion && object.rotationQuaternion.copyFrom(impostor.getParentsRotation());
-
-                    object.rotationQuaternion && object.parent && object.rotationQuaternion.conjugateInPlace();
-
-                    let transform = object.computeWorldMatrix(true);
-                    // convert rawVerts to object space
-                    var temp = new Array<number>();
-                    var index: number;
-                    for (index = 0; index < rawVerts.length; index += 3) {
-                        Vector3.TransformCoordinates(Vector3.FromArray(rawVerts, index), transform).toArray(temp, index);
-                    }
+                    var tetraMesh = new this.BJSAMMO.btTriangleMesh();
+                    // Create mesh impostor from triangles which makeup the mesh
+                    if(object && object.getIndices && object.getWorldMatrix){
+                        var ind = object.getIndices()
+                        if(!ind){
+                            ind = [];
+                        }
 
-                    Tools.Warn("MeshImpostor only collides against spheres.");
-                    returnValue = new this.BJSCANNON.Trimesh(temp, <number[]>rawFaces);
-                    //now set back the transformation!
-                    object.position.copyFrom(oldPosition);
-                    oldRotation && object.rotation && object.rotation.copyFrom(oldRotation);
-                    oldQuaternion && object.rotationQuaternion && object.rotationQuaternion.copyFrom(oldQuaternion);
-                    break;
-                case PhysicsImpostor.HeightmapImpostor:
-                    let oldPosition2 = object.position.clone();
-                    let oldRotation2 = object.rotation && object.rotation.clone();
-                    let oldQuaternion2 = object.rotationQuaternion && object.rotationQuaternion.clone();
-                    object.position.copyFromFloats(0, 0, 0);
-                    object.rotation && object.rotation.copyFromFloats(0, 0, 0);
-                    object.rotationQuaternion && object.rotationQuaternion.copyFrom(impostor.getParentsRotation());
-                    object.rotationQuaternion && object.parent && object.rotationQuaternion.conjugateInPlace();
-                    object.rotationQuaternion && object.rotationQuaternion.multiplyInPlace(this._minus90X);
-
-                    returnValue = this._createHeightmap(object);
-                    object.position.copyFrom(oldPosition2);
-                    oldRotation2 && object.rotation && object.rotation.copyFrom(oldRotation2);
-                    oldQuaternion2 && object.rotationQuaternion && object.rotationQuaternion.copyFrom(oldQuaternion2);
-                    object.computeWorldMatrix(true);
-                    break;
-                case PhysicsImpostor.ParticleImpostor:
-                    returnValue = new this.BJSCANNON.Particle();
+                        var p = object.getVerticesData(BABYLON.VertexBuffer.PositionKind)
+                        if(!p){
+                            p = [];
+                        }
+                        object.computeWorldMatrix(false);
+                        var faceCount = ind.length/3;
+                        for(var i =0;i<faceCount;i++){
+                            var triPoints = [];
+                            for(var point = 0;point<3;point++){
+                                
+                                triPoints.push(new this.BJSAMMO.btVector3(
+                                    object.scaling.x*p[(ind[(i*3)+point]*3)+0],
+                                    object.scaling.y*p[(ind[(i*3)+point]*3)+1],
+                                    object.scaling.z*p[(ind[(i*3)+point]*3)+2]
+                                ));
+                            }
+                            tetraMesh.addTriangle(triPoints[0], triPoints[1], triPoints[2]);
+                        }
+                    }else{
+                        throw "Unable to create MeshImpostor from object";
+                    }
+                    returnValue = new this.BJSAMMO.btBvhTriangleMeshShape(tetraMesh);
                     break;
             }
 
             return returnValue;
         }
-
-        private _createHeightmap(object: IPhysicsEnabledObject, pointDepth?: number) {
-            var pos = <FloatArray>(object.getVerticesData(VertexBuffer.PositionKind));
-            let transform = object.computeWorldMatrix(true);
-            // convert rawVerts to object space
-            var temp = new Array<number>();
-            var index: number;
-            for (index = 0; index < pos.length; index += 3) {
-                Vector3.TransformCoordinates(Vector3.FromArray(pos, index), transform).toArray(temp, index);
-            }
-            pos = temp;
-            var matrix = new Array<Array<any>>();
-
-            //For now pointDepth will not be used and will be automatically calculated.
-            //Future reference - try and find the best place to add a reference to the pointDepth variable.
-            var arraySize = pointDepth || ~~(Math.sqrt(pos.length / 3) - 1);
-            let boundingInfo = object.getBoundingInfo();
-            var dim = Math.min(boundingInfo.boundingBox.extendSizeWorld.x, boundingInfo.boundingBox.extendSizeWorld.y);
-            var minY = boundingInfo.boundingBox.extendSizeWorld.z;
-
-            var elementSize = dim * 2 / arraySize;
-
-            for (var i = 0; i < pos.length; i = i + 3) {
-                var x = Math.round((pos[i + 0]) / elementSize + arraySize / 2);
-                var z = Math.round(((pos[i + 1]) / elementSize - arraySize / 2) * -1);
-                var y = -pos[i + 2] + minY;
-                if (!matrix[x]) {
-                    matrix[x] = [];
-                }
-                if (!matrix[x][z]) {
-                    matrix[x][z] = y;
-                }
-                matrix[x][z] = Math.max(y, matrix[x][z]);
-            }
-
-            for (var x = 0; x <= arraySize; ++x) {
-                if (!matrix[x]) {
-                    var loc = 1;
-                    while (!matrix[(x + loc) % arraySize]) {
-                        loc++;
-                    }
-                    matrix[x] = matrix[(x + loc) % arraySize].slice();
-                    //console.log("missing x", x);
-                }
-                for (var z = 0; z <= arraySize; ++z) {
-                    if (!matrix[x][z]) {
-                        var loc = 1;
-                        var newValue;
-                        while (newValue === undefined) {
-                            newValue = matrix[x][(z + loc++) % arraySize];
-                        }
-                        matrix[x][z] = newValue;
-
-                    }
+        
+        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());
+
+            if(!impostor.object.rotationQuaternion){
+                if(impostor.object.rotation){
+                    this._tmpQuaternion.set(this._tmpAmmoTransform.getRotation().x(),this._tmpAmmoTransform.getRotation().y(),this._tmpAmmoTransform.getRotation().z(),this._tmpAmmoTransform.getRotation().w());
+                    this._tmpQuaternion.toEulerAnglesToRef(impostor.object.rotation);  
                 }
+            }else{
+                impostor.object.rotationQuaternion.set(this._tmpAmmoTransform.getRotation().x(),this._tmpAmmoTransform.getRotation().y(),this._tmpAmmoTransform.getRotation().z(),this._tmpAmmoTransform.getRotation().w());
             }
-
-            var shape = new this.BJSCANNON.Heightfield(matrix, {
-                elementSize: elementSize
-            });
-
-            //For future reference, needed for body transformation
-            shape.minY = minY;
-
-            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 _tmpDeltaPosition: Vector3 = Vector3.Zero();
-        private _tmpUnityRotation: Quaternion = new Quaternion();
-
-        private _updatePhysicsBodyTransformation(impostor: PhysicsImpostor) {
-            var object = impostor.object;
-            //make sure it is updated...
-            object.computeWorldMatrix && object.computeWorldMatrix(true);
-            // The delta between the mesh position and the mesh bounding box center
-            let bInfo = object.getBoundingInfo();
-            if (!bInfo) { return; }
-            var center = impostor.getObjectCenter();
-            //m.getAbsolutePosition().subtract(m.getBoundingInfo().boundingBox.centerWorld)
-            this._tmpDeltaPosition.copyFrom(object.getAbsolutePivotPoint().subtract(center));
-            this._tmpDeltaPosition.divideInPlace(impostor.object.scaling);
-            this._tmpPosition.copyFrom(center);
-            var quaternion = object.rotationQuaternion;
-
-            if (!quaternion) {
-                return;
-            }
-
-            //is shape is a plane or a heightmap, it must be rotated 90 degs in the X axis.
-            if (impostor.type === PhysicsImpostor.PlaneImpostor || impostor.type === PhysicsImpostor.HeightmapImpostor || impostor.type === PhysicsImpostor.CylinderImpostor) {
-                //-90 DEG in X, precalculated
-                quaternion = quaternion.multiply(this._minus90X);
-                //Invert! (Precalculated, 90 deg in X)
-                //No need to clone. this will never change.
-                impostor.setDeltaRotation(this._plus90X);
-            }
-
-            //If it is a heightfield, if should be centered.
-            if (impostor.type === PhysicsImpostor.HeightmapImpostor) {
-                var mesh = <AbstractMesh>(<any>object);
-                let boundingInfo = mesh.getBoundingInfo();
-                //calculate the correct body position:
-                var rotationQuaternion = mesh.rotationQuaternion;
-                mesh.rotationQuaternion = this._tmpUnityRotation;
-                mesh.computeWorldMatrix(true);
-
-                //get original center with no rotation
-                var c = center.clone();
-
-                var oldPivot = mesh.getPivotMatrix();
-                if (oldPivot) {
-                    // create a copy the pivot Matrix as it is modified in place
-                    oldPivot = oldPivot.clone();
-                }
-                else {
-                    oldPivot = Matrix.Identity();
-                }
-
-                //calculate the new center using a pivot (since this.BJSCANNON.js doesn't center height maps)
-                var p = Matrix.Translation(boundingInfo.boundingBox.extendSizeWorld.x, 0, -boundingInfo.boundingBox.extendSizeWorld.z);
-                mesh.setPreTransformMatrix(p);
-                mesh.computeWorldMatrix(true);
-
-                //calculate the translation
-                var translation = boundingInfo.boundingBox.centerWorld.subtract(center).subtract(mesh.position).negate();
-
-                this._tmpPosition.copyFromFloats(translation.x, translation.y - boundingInfo.boundingBox.extendSizeWorld.y, translation.z);
-                //add it inverted to the delta
-                this._tmpDeltaPosition.copyFrom(boundingInfo.boundingBox.centerWorld.subtract(c));
-                this._tmpDeltaPosition.y += boundingInfo.boundingBox.extendSizeWorld.y;
-                //rotation is back
-                mesh.rotationQuaternion = rotationQuaternion;
-
-                mesh.setPreTransformMatrix(oldPivot);
-                mesh.computeWorldMatrix(true);
-            } else if (impostor.type === PhysicsImpostor.MeshImpostor) {
-                this._tmpDeltaPosition.copyFromFloats(0, 0, 0);
-                //this._tmpPosition.copyFrom(object.position);
-            }
-
-            impostor.setDeltaPosition(this._tmpDeltaPosition);
-            //Now update the impostor object
-            impostor.physicsBody.position.copy(this._tmpPosition);
-            impostor.physicsBody.quaternion.copy(quaternion);
-        }
+        public setPhysicsBodyTransformation(impostor: PhysicsImpostor, newPosition: Vector3, newRotation: Quaternion) {
 
-        public setTransformationFromPhysicsBody(impostor: PhysicsImpostor) {
-            impostor.object.position.copyFrom(impostor.physicsBody.position);
-            if (impostor.object.rotationQuaternion) {
-                impostor.object.rotationQuaternion.copyFrom(impostor.physicsBody.quaternion);
+            var trans = impostor.physicsBody.getWorldTransform();
+
+            // If rotation/position has changed update and activate riged body
+            if( 
+                trans.getOrigin().x() != newPosition.x || 
+                trans.getOrigin().y() != newPosition.y || 
+                trans.getOrigin().z() != newPosition.z || 
+                trans.getRotation().x() != newRotation.x || 
+                trans.getRotation().y() != newRotation.y || 
+                trans.getRotation().z() != newRotation.z || 
+                trans.getRotation().w() != newRotation.w
+            ){
+                trans.getOrigin().setX(newPosition.x);
+                trans.getOrigin().setY(newPosition.y);
+                trans.getOrigin().setZ(newPosition.z);
+                
+                this._tmpAmmoQuaternion.setValue(newRotation.x,newRotation.y,newRotation.z,newRotation.w)
+                trans.setRotation(this._tmpAmmoQuaternion);
+                impostor.physicsBody.setWorldTransform(trans);
+                impostor.physicsBody.activate();
             }
         }
 
-        public setPhysicsBodyTransformation(impostor: PhysicsImpostor, newPosition: Vector3, newRotation: Quaternion) {
-            impostor.physicsBody.position.copy(newPosition);
-            impostor.physicsBody.quaternion.copy(newRotation);
-        }
-
         public isSupported(): boolean {
-            return this.BJSCANNON !== undefined;
+            return this.BJSAMMO !== undefined;
         }
 
         public setLinearVelocity(impostor: PhysicsImpostor, velocity: Vector3) {
-            impostor.physicsBody.velocity.copy(velocity);
+            impostor.physicsBody.setLinearVelocity(new this.BJSAMMO.btVector3(velocity.x, velocity.y, velocity.z));
         }
 
         public setAngularVelocity(impostor: PhysicsImpostor, velocity: Vector3) {
-            impostor.physicsBody.angularVelocity.copy(velocity);
+            impostor.physicsBody.setAngularVelocity(new this.BJSAMMO.btVector3(velocity.x, velocity.y, velocity.z));
         }
 
         public getLinearVelocity(impostor: PhysicsImpostor): Nullable<Vector3> {
-            var v = impostor.physicsBody.velocity;
+            var v = impostor.physicsBody.getLinearVelocity();
             if (!v) {
                 return null;
             }
-            return new Vector3(v.x, v.y, v.z);
+            return new Vector3(v.x(), v.y(), v.z());
         }
         public getAngularVelocity(impostor: PhysicsImpostor): Nullable<Vector3> {
-            var v = impostor.physicsBody.angularVelocity;
+            var v = impostor.physicsBody.getAngularVelocity();
             if (!v) {
                 return null;
             }
-            return new Vector3(v.x, v.y, v.z);
+            return new Vector3(v.x(), v.y(), v.z());
         }
 
         public setBodyMass(impostor: PhysicsImpostor, mass: number) {
-            impostor.physicsBody.mass = mass;
-            impostor.physicsBody.updateMassProperties();
+            impostor.physicsBody.setMassProps(mass);
         }
 
         public getBodyMass(impostor: PhysicsImpostor): number {
@@ -521,130 +283,72 @@ module BABYLON {
         }
 
         public getBodyFriction(impostor: PhysicsImpostor): number {
-            return impostor.physicsBody.material.friction;
+            return impostor.physicsBody.getFriction();
         }
 
         public setBodyFriction(impostor: PhysicsImpostor, friction: number) {
-            impostor.physicsBody.material.friction = friction;
+            impostor.physicsBody.setFriction(friction);
         }
 
         public getBodyRestitution(impostor: PhysicsImpostor): number {
-            return impostor.physicsBody.material.restitution;
+            return impostor.physicsBody.getRestitution();
         }
 
         public setBodyRestitution(impostor: PhysicsImpostor, restitution: number) {
-            impostor.physicsBody.material.restitution = restitution;
+            impostor.physicsBody.setRestitution(restitution);
         }
 
         public sleepBody(impostor: PhysicsImpostor) {
-            impostor.physicsBody.sleep();
+            Tools.Warn("sleepBody is not currently supported by the Ammo physics plugin")
         }
 
         public wakeUpBody(impostor: PhysicsImpostor) {
-            impostor.physicsBody.wakeUp();
+            impostor.physicsBody.activate();
         }
 
         public updateDistanceJoint(joint: PhysicsJoint, maxDistance: number, minDistance?: number) {
-            joint.physicsJoint.distance = maxDistance;
+            Tools.Warn("updateDistanceJoint is not currently supported by the Ammo physics plugin")
         }
 
-        // private enableMotor(joint: IMotorEnabledJoint, motorIndex?: number) {
-        //     if (!motorIndex) {
-        //         joint.physicsJoint.enableMotor();
-        //     }
-        // }
-
-        // private disableMotor(joint: IMotorEnabledJoint, motorIndex?: number) {
-        //     if (!motorIndex) {
-        //         joint.physicsJoint.disableMotor();
-        //     }
-        // }
-
         public setMotor(joint: IMotorEnabledJoint, speed?: number, maxForce?: number, motorIndex?: number) {
-            if (!motorIndex) {
-                joint.physicsJoint.enableMotor();
-                joint.physicsJoint.setMotorSpeed(speed);
-                if (maxForce) {
-                    this.setLimit(joint, maxForce);
-                }
-            }
+            Tools.Warn("setMotor is not currently supported by the Ammo physics plugin")
         }
 
         public setLimit(joint: IMotorEnabledJoint, upperLimit: number, lowerLimit?: number) {
-            joint.physicsJoint.motorEquation.maxForce = upperLimit;
-            joint.physicsJoint.motorEquation.minForce = lowerLimit === void 0 ? -upperLimit : lowerLimit;
+            Tools.Warn("setLimit is not currently supported by the Ammo physics plugin")
         }
 
         public syncMeshWithImpostor(mesh: AbstractMesh, impostor: PhysicsImpostor) {
             var body = impostor.physicsBody;
 
-            mesh.position.x = body.position.x;
-            mesh.position.y = body.position.y;
-            mesh.position.z = body.position.z;
+            body.getMotionState().getWorldTransform(this._tmpAmmoTransform)
+
+            mesh.position.x = this._tmpAmmoTransform.getOrigin().x();
+            mesh.position.y = this._tmpAmmoTransform.getOrigin().y();
+            mesh.position.z = this._tmpAmmoTransform.getOrigin().z();
 
             if (mesh.rotationQuaternion) {
-                mesh.rotationQuaternion.x = body.quaternion.x;
-                mesh.rotationQuaternion.y = body.quaternion.y;
-                mesh.rotationQuaternion.z = body.quaternion.z;
-                mesh.rotationQuaternion.w = body.quaternion.w;
+                mesh.rotationQuaternion.x = this._tmpAmmoTransform.getRotation().x();
+                mesh.rotationQuaternion.y = this._tmpAmmoTransform.getRotation().y();
+                mesh.rotationQuaternion.z = this._tmpAmmoTransform.getRotation().z();
+                mesh.rotationQuaternion.w = this._tmpAmmoTransform.getRotation().w();
             }
         }
 
         public getRadius(impostor: PhysicsImpostor): number {
-            var shape = impostor.physicsBody.shapes[0];
-            return shape.boundingSphereRadius;
+            var exntend = impostor.getObjectExtendSize();
+            return exntend.x;
         }
 
         public getBoxSizeToRef(impostor: PhysicsImpostor, result: Vector3): void {
-            var shape = impostor.physicsBody.shapes[0];
-            result.x = shape.halfExtents.x * 2;
-            result.y = shape.halfExtents.y * 2;
-            result.z = shape.halfExtents.z * 2;
+            var exntend = impostor.getObjectExtendSize();
+            result.x = exntend.x;
+            result.y = exntend.y;
+            result.z = exntend.z;
         }
 
         public dispose() {
 
         }
-
-        private _extendNamespace() {
-
-            //this will force cannon to execute at least one step when using interpolation
-            let step_tmp1 = new this.BJSCANNON.Vec3();
-            let Engine = this.BJSCANNON;
-            this.BJSCANNON.World.prototype.step = function(dt: number, timeSinceLastCalled: number, maxSubSteps: number) {
-                maxSubSteps = maxSubSteps || 10;
-                timeSinceLastCalled = timeSinceLastCalled || 0;
-                if (timeSinceLastCalled === 0) {
-                    this.internalStep(dt);
-                    this.time += dt;
-                } else {
-                    var internalSteps = Math.floor((this.time + timeSinceLastCalled) / dt) - Math.floor(this.time / dt);
-                    internalSteps = Math.min(internalSteps, maxSubSteps) || 1;
-                    var t0 = performance.now();
-                    for (var i = 0; i !== internalSteps; i++) {
-                        this.internalStep(dt);
-                        if (performance.now() - t0 > dt * 1000) {
-                            break;
-                        }
-                    }
-                    this.time += timeSinceLastCalled;
-                    var h = this.time % dt;
-                    var h_div_dt = h / dt;
-                    var interpvelo = step_tmp1;
-                    var bodies = this.bodies;
-                    for (var j = 0; j !== bodies.length; j++) {
-                        var b = bodies[j];
-                        if (b.type !== Engine.Body.STATIC && b.sleepState !== Engine.Body.SLEEPING) {
-                            b.position.vsub(b.previousPosition, interpvelo);
-                            interpvelo.scale(h_div_dt, interpvelo);
-                            b.position.vadd(interpvelo, b.interpolatedPosition);
-                        } else {
-                            b.interpolatedPosition.copy(b.position);
-                            b.interpolatedQuaternion.copy(b.quaternion);
-                        }
-                    }
-                }
-            };
-        }
     }
 }