Selaa lähdekoodia

Abstract object for physics

It is now possible to assign an impostor to each object with both
position and quaternion. Including particles.
Raanan Weber 9 vuotta sitten
vanhempi
commit
da1f7a8d5b

+ 20 - 2
src/Particles/babylon.solidParticle.ts

@@ -5,8 +5,8 @@ module BABYLON {
         public color = new Color4(1, 1, 1, 1);  // color
         public position = Vector3.Zero();       // position
         public rotation = Vector3.Zero();       // rotation
-        public quaternion: Vector4;             // quaternion, will overwrite rotation
-        public scale = new Vector3(1, 1, 1);    // scale
+        public rotationQuaternion: Quaternion;    // quaternion, will overwrite rotation
+        public scaling = new Vector3(1, 1, 1);  // scaling
         public uvs = new Vector4(0, 0, 1, 1);   // uvs
         public velocity = Vector3.Zero();       // velocity
         public alive = true;                    // alive
@@ -22,6 +22,24 @@ module BABYLON {
             this.shapeId = shapeId;
             this.idxInShape = idxInShape;
         }
+
+        //legacy support, changed scale to scaling
+        public get scale(): Vector3 {
+            return this.scaling;
+        }
+
+        public set scale(scale: Vector3) {
+            this.scaling = scale;
+        }
+
+        //legacy support, changed quaternion to rotationQuaternion
+        public get quaternion(): Quaternion {
+            return this.rotationQuaternion;
+        }
+
+        public set quaternion(q: Quaternion) {
+            this.rotationQuaternion = q;
+        }
     }
 
     export class ModelShape {

+ 23 - 32
src/Particles/babylon.solidParticleSystem.ts

@@ -274,10 +274,10 @@
             this._copy.rotation.x = 0;
             this._copy.rotation.y = 0;
             this._copy.rotation.z = 0;
-            this._copy.quaternion = null;
-            this._copy.scale.x = 1;
-            this._copy.scale.y = 1;
-            this._copy.scale.z = 1;
+            this._copy.rotationQuaternion = null;
+            this._copy.scaling.x = 1;
+            this._copy.scaling.y = 1;
+            this._copy.scaling.z = 1;
             this._copy.uvs.x = 0;
             this._copy.uvs.y = 0;
             this._copy.uvs.z = 1;
@@ -296,11 +296,8 @@
                 options.positionFunction(this._copy, idx, idxInShape);
             }
 
-            if (this._copy.quaternion) {
-                this._quaternion.x = this._copy.quaternion.x;
-                this._quaternion.y = this._copy.quaternion.y;
-                this._quaternion.z = this._copy.quaternion.z;
-                this._quaternion.w = this._copy.quaternion.w;
+            if (this._copy.rotationQuaternion) {
+                this._quaternion.copyFrom(this._copy.rotationQuaternion);
             } else {
                 this._yaw = this._copy.rotation.y;
                 this._pitch = this._copy.rotation.x;
@@ -318,9 +315,9 @@
                     options.vertexFunction(this._copy, this._vertex, i);
                 }
 
-                this._vertex.x *= this._copy.scale.x;
-                this._vertex.y *= this._copy.scale.y;
-                this._vertex.z *= this._copy.scale.z;
+                this._vertex.x *= this._copy.scaling.x;
+                this._vertex.y *= this._copy.scaling.y;
+                this._vertex.z *= this._copy.scaling.z;
 
                 Vector3.TransformCoordinatesToRef(this._vertex, this._rotMatrix, this._rotated);
                 positions.push(this._copy.position.x + this._rotated.x, this._copy.position.y + this._rotated.y, this._copy.position.z + this._rotated.z);
@@ -427,11 +424,8 @@
                 particle._model._positionFunction(this._copy, particle.idx, particle.idxInShape);
             }
 
-            if (this._copy.quaternion) {
-                this._quaternion.x = this._copy.quaternion.x;
-                this._quaternion.y = this._copy.quaternion.y;
-                this._quaternion.z = this._copy.quaternion.z;
-                this._quaternion.w = this._copy.quaternion.w;
+            if (this._copy.rotationQuaternion) {
+                this._quaternion.copyFrom(this._copy.rotationQuaternion);
             } else {
                 this._yaw = this._copy.rotation.y;
                 this._pitch = this._copy.rotation.x;
@@ -450,9 +444,9 @@
                     particle._model._vertexFunction(this._copy, this._vertex, pt); // recall to stored vertexFunction
                 }
 
-                this._vertex.x *= this._copy.scale.x;
-                this._vertex.y *= this._copy.scale.y;
-                this._vertex.z *= this._copy.scale.z;
+                this._vertex.x *= this._copy.scaling.x;
+                this._vertex.y *= this._copy.scaling.y;
+                this._vertex.z *= this._copy.scaling.z;
 
                 Vector3.TransformCoordinatesToRef(this._vertex, this._rotMatrix, this._rotated);
 
@@ -466,10 +460,10 @@
             particle.rotation.x = 0;
             particle.rotation.y = 0;
             particle.rotation.z = 0;
-            particle.quaternion = null;
-            particle.scale.x = 1;
-            particle.scale.y = 1;
-            particle.scale.z = 1;
+            particle.rotationQuaternion = null;
+            particle.scaling.x = 1;
+            particle.scaling.y = 1;
+            particle.scaling.z = 1;
         }
 
         /**
@@ -560,11 +554,8 @@
                     this._particle.rotation.y = 0.0;
                 }
                 if (this._computeParticleRotation) {
-                    if (this._particle.quaternion) {
-                        this._quaternion.x = this._particle.quaternion.x;
-                        this._quaternion.y = this._particle.quaternion.y;
-                        this._quaternion.z = this._particle.quaternion.z;
-                        this._quaternion.w = this._particle.quaternion.w;
+                    if (this._particle.rotationQuaternion) {
+                        this._quaternion.copyFrom(this._particle.rotationQuaternion);
                     } else {
                         this._yaw = this._particle.rotation.y;
                         this._pitch = this._particle.rotation.x;
@@ -588,9 +579,9 @@
                     }
 
                     // positions
-                    this._vertex.x *= this._particle.scale.x;
-                    this._vertex.y *= this._particle.scale.y;
-                    this._vertex.z *= this._particle.scale.z;
+                    this._vertex.x *= this._particle.scaling.x;
+                    this._vertex.y *= this._particle.scaling.y;
+                    this._vertex.z *= this._particle.scaling.z;
 
                     this._w = (this._vertex.x * this._rotMatrix.m[3]) + (this._vertex.y * this._rotMatrix.m[7]) + (this._vertex.z * this._rotMatrix.m[11]) + this._rotMatrix.m[15];
                     this._rotated.x = ((this._vertex.x * this._rotMatrix.m[0]) + (this._vertex.y * this._rotMatrix.m[4]) + (this._vertex.z * this._rotMatrix.m[8]) + this._rotMatrix.m[12]) / this._w;

+ 29 - 44
src/Physics/Plugins/babylon.cannonJSPlugin.ts

@@ -59,9 +59,6 @@
 
             //should a new body be created for this impostor?
             if (impostor.isBodyInitRequired()) {
-                if (!impostor.mesh.rotationQuaternion) {
-                    impostor.mesh.rotationQuaternion = Quaternion.RotationYawPitchRoll(impostor.mesh.rotation.y, impostor.mesh.rotation.x, impostor.mesh.rotation.z);
-                }
 
                 var shape = this._createShape(impostor);
 
@@ -72,7 +69,7 @@
                 }
 
                 //create the body and material
-                var material = this._addMaterial("mat-" + impostor.mesh.uniqueId, impostor.getParam("friction"), impostor.getParam("restitution"));
+                var material = this._addMaterial("mat-" + impostor.uniqueId, impostor.getParam("friction"), impostor.getParam("restitution"));
 
                 var bodyCreationObject = {
                     mass: impostor.getParam("mass"),
@@ -107,7 +104,7 @@
         }
 
         private _processChildMeshes(mainImpostor: PhysicsImpostor) {
-            var meshChildren = mainImpostor.mesh.getChildMeshes();
+            var meshChildren = mainImpostor.object.getChildMeshes ? mainImpostor.object.getChildMeshes() : [];
             if (meshChildren.length) {
                 var processMesh = (localPosition: Vector3, mesh: AbstractMesh) => {
                     var childImpostor = mesh.getPhysicsImpostor();
@@ -237,35 +234,25 @@
         }
 
         private _createShape(impostor: PhysicsImpostor) {
-            var mesh = impostor.mesh;
-
-            //get the correct bounding box
-            var oldQuaternion = mesh.rotationQuaternion;
-            mesh.rotationQuaternion = new Quaternion(0, 0, 0, 1);
-            mesh.computeWorldMatrix(true);
+            var object = impostor.object;
 
             var returnValue;
-            var bbox = mesh.getBoundingInfo().boundingBox;
+            var extendSize = impostor.getObjectExtendSize();
             switch (impostor.type) {
                 case PhysicsEngine.SphereImpostor:
-                    var radiusX = bbox.maximumWorld.x - bbox.minimumWorld.x;
-                    var radiusY = bbox.maximumWorld.y - bbox.minimumWorld.y;
-                    var radiusZ = bbox.maximumWorld.z - bbox.minimumWorld.z;
+                    var radiusX = extendSize.x;
+                    var radiusY = extendSize.y;
+                    var radiusZ = extendSize.z;
 
                     returnValue = new CANNON.Sphere(Math.max(this._checkWithEpsilon(radiusX), this._checkWithEpsilon(radiusY), this._checkWithEpsilon(radiusZ)) / 2);
 
                     break;
                 //TMP also for cylinder - TODO Cannon supports cylinder natively.
                 case PhysicsImpostor.CylinderImpostor:
-                    var min = bbox.minimumWorld;
-                    var max = bbox.maximumWorld;
-                    var box = max.subtract(min);
-                    returnValue = new CANNON.Cylinder(this._checkWithEpsilon(box.x) / 2, this._checkWithEpsilon(box.x) / 2, this._checkWithEpsilon(box.y), 16);
+                    returnValue = new CANNON.Cylinder(this._checkWithEpsilon(extendSize.x) / 2, this._checkWithEpsilon(extendSize.x) / 2, this._checkWithEpsilon(extendSize.y), 16);
                     break;
                 case PhysicsImpostor.BoxImpostor:
-                    var min = bbox.minimumWorld;
-                    var max = bbox.maximumWorld;
-                    var box = max.subtract(min).scale(0.5);
+                    var box = extendSize.scale(0.5);
                     returnValue = new CANNON.Box(new CANNON.Vec3(this._checkWithEpsilon(box.x), this._checkWithEpsilon(box.y), this._checkWithEpsilon(box.z)));
                     break;
                 case PhysicsImpostor.PlaneImpostor:
@@ -273,37 +260,35 @@
                     returnValue = new CANNON.Plane();
                     break;
                 case PhysicsImpostor.MeshImpostor:
-                    var rawVerts = mesh.getVerticesData(VertexBuffer.PositionKind);
-                    var rawFaces = mesh.getIndices();
+                    var rawVerts = object.getVerticesData ? object.getVerticesData(VertexBuffer.PositionKind) : [];
+                    var rawFaces = object.getIndices ? object.getIndices() : [];
                     Tools.Warn("MeshImpostor only collides against spheres.");
                     returnValue = new CANNON.Trimesh(rawVerts, rawFaces);
                     break;
                 case PhysicsImpostor.HeightmapImpostor:
-                    returnValue = this._createHeightmap(mesh);
+                    returnValue = this._createHeightmap(object);
                     break;
                 case PhysicsImpostor.ParticleImpostor:
                     returnValue = new CANNON.Particle();
                     break;
             }
 
-            mesh.rotationQuaternion = oldQuaternion;
-
             return returnValue;
         }
 
-        private _createHeightmap(mesh: AbstractMesh, pointDepth?: number) {
-            var pos = mesh.getVerticesData(VertexBuffer.PositionKind);
+        private _createHeightmap(object: IPhysicsEnabledObject, pointDepth?: number) {
+            var pos = object.getVerticesData(VertexBuffer.PositionKind);
             var matrix = [];
 
             //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);
 
-            var dim = Math.min(mesh.getBoundingInfo().boundingBox.extendSize.x, mesh.getBoundingInfo().boundingBox.extendSize.z);
+            var dim = Math.min(object.getBoundingInfo().boundingBox.extendSize.x, object.getBoundingInfo().boundingBox.extendSize.z);
 
             var elementSize = dim * 2 / arraySize;
 
-            var minY = mesh.getBoundingInfo().boundingBox.extendSize.y;
+            var minY = object.getBoundingInfo().boundingBox.extendSize.y;
 
             for (var i = 0; i < pos.length; i = i + 3) {
                 var x = Math.round((pos[i + 0]) / elementSize + arraySize / 2);
@@ -360,15 +345,15 @@
         private _tmpUnityRotation: Quaternion = new Quaternion();
 
         private _updatePhysicsBodyTransformation(impostor: PhysicsImpostor) {
-            var mesh = impostor.mesh;
+            var object = impostor.object;
             //make sure it is updated...
-            impostor.mesh.computeWorldMatrix(true);
+            object.computeWorldMatrix && object.computeWorldMatrix(true);
             // The delta between the mesh position and the mesh bounding box center
-            var bbox = mesh.getBoundingInfo().boundingBox;
-            this._tmpDeltaPosition.copyFrom(mesh.position.subtract(bbox.center));
-
-            var quaternion = mesh.rotationQuaternion;
-            this._tmpPosition.copyFrom(mesh.getBoundingInfo().boundingBox.center);
+            var center = impostor.getObjectCenter();
+            var extendSize = impostor.getObjectExtendSize();
+            this._tmpDeltaPosition.copyFrom(object.position.subtract(center));
+            this._tmpPosition.copyFrom(center);
+            var quaternion = object.rotationQuaternion;
             //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
@@ -380,14 +365,14 @@
 
             //If it is a heightfield, if should be centered.
             if (impostor.type === PhysicsEngine.HeightmapImpostor) {
-
+                var mesh = <AbstractMesh>(<any>object);
                 //calculate the correct body position:
                 var rotationQuaternion = mesh.rotationQuaternion;
                 mesh.rotationQuaternion = this._tmpUnityRotation;
                 mesh.computeWorldMatrix(true);
 
                 //get original center with no rotation
-                var center = mesh.getBoundingInfo().boundingBox.center.clone();
+                var c = center.clone();
 
                 var oldPivot = mesh.getPivotMatrix() || Matrix.Translation(0, 0, 0);
 
@@ -404,14 +389,14 @@
 
                 this._tmpPosition.copyFromFloats(translation.x, translation.y - mesh.getBoundingInfo().boundingBox.extendSize.y, translation.z);
                 //add it inverted to the delta 
-                this._tmpDeltaPosition.copyFrom(mesh.getBoundingInfo().boundingBox.center.subtract(center));
+                this._tmpDeltaPosition.copyFrom(mesh.getBoundingInfo().boundingBox.center.subtract(c));
                 this._tmpDeltaPosition.y += mesh.getBoundingInfo().boundingBox.extendSize.y;
 
                 mesh.setPivotMatrix(oldPivot);
                 mesh.computeWorldMatrix(true);
             } else if (impostor.type === PhysicsEngine.MeshImpostor) {
                 this._tmpDeltaPosition.copyFromFloats(0, 0, 0);
-                this._tmpPosition.copyFrom(mesh.position);
+                this._tmpPosition.copyFrom(object.position);
             }
 
             impostor.setDeltaPosition(this._tmpDeltaPosition);
@@ -421,8 +406,8 @@
         }
 
         public setTransformationFromPhysicsBody(impostor: PhysicsImpostor) {
-            impostor.mesh.position.copyFrom(impostor.physicsBody.position);
-            impostor.mesh.rotationQuaternion.copyFrom(impostor.physicsBody.quaternion);
+            impostor.object.position.copyFrom(impostor.physicsBody.position);
+            impostor.object.rotationQuaternion.copyFrom(impostor.physicsBody.quaternion);
         }
 
         public setPhysicsBodyTransformation(impostor: PhysicsImpostor, newPosition: Vector3, newRotation: Quaternion) {

+ 34 - 43
src/Physics/Plugins/babylon.oimoJSPlugin.ts

@@ -34,7 +34,7 @@ module BABYLON {
             impostors.forEach((impostor) => {
                 impostor.afterStep();
                 //update the ordered impostors array
-                this._tmpImpostorsArray[impostor.mesh.uniqueId] = impostor;
+                this._tmpImpostorsArray[impostor.uniqueId] = impostor;
             });
 
             //check for collisions
@@ -80,16 +80,9 @@ module BABYLON {
                 return;
             }
 
-            impostor.mesh.computeWorldMatrix(true);
-
             if (impostor.isBodyInitRequired()) {
-                if (!impostor.mesh.rotationQuaternion) {
-                    impostor.mesh.rotationQuaternion = Quaternion.RotationYawPitchRoll(impostor.mesh.rotation.y, impostor.mesh.rotation.x, impostor.mesh.rotation.z);
-                }
-
-
                 var bodyConfig: any = {
-                    name: impostor.mesh.uniqueId,
+                    name: impostor.uniqueId,
                     //Oimo must have mass, also for static objects.
                     config: [impostor.getParam("mass") || 1, impostor.getParam("friction"), impostor.getParam("restitution")],
                     size: [],
@@ -102,7 +95,8 @@ module BABYLON {
                 };
 
                 var impostors = [impostor];
-                function addToArray(parent: AbstractMesh) {
+                function addToArray(parent: IPhysicsEnabledObject) {
+                    if(!parent.getChildMeshes) return;
                     parent.getChildMeshes().forEach(function(m) {
                         if (m.physicsImpostor) {
                             impostors.push(m.physicsImpostor);
@@ -110,7 +104,7 @@ module BABYLON {
                         }
                     });
                 }
-                addToArray(impostor.mesh)
+                addToArray(impostor.object)
 
                 function checkWithEpsilon(value: number): number {
                     return Math.max(value, PhysicsEngine.Epsilon);
@@ -119,31 +113,34 @@ module BABYLON {
                 impostors.forEach((i) => {
 
                     //get the correct bounding box
-                    var oldQuaternion = i.mesh.rotationQuaternion;
-                    var rot = new OIMO.Euler().setFromQuaternion({ x: impostor.mesh.rotationQuaternion.x, y: impostor.mesh.rotationQuaternion.y, z: impostor.mesh.rotationQuaternion.z, s: impostor.mesh.rotationQuaternion.w });
+                    var oldQuaternion = i.object.rotationQuaternion;
+                    var rot = new OIMO.Euler().setFromQuaternion({ 
+                        x: impostor.object.rotationQuaternion.x, 
+                        y: impostor.object.rotationQuaternion.y, 
+                        z: impostor.object.rotationQuaternion.z, 
+                        s: impostor.object.rotationQuaternion.w });
 
-                    i.mesh.rotationQuaternion = new Quaternion(0, 0, 0, 1);
-                    i.mesh.computeWorldMatrix(true);
 
-                    var bbox = i.mesh.getBoundingInfo().boundingBox;
+                    var extendSize = i.getObjectExtendSize();
 
                     if (i === impostor) {
+                        var center = impostor.getObjectCenter();
 
-                        impostor.mesh.position.subtractToRef(impostor.mesh.getBoundingInfo().boundingBox.center, this._tmpPositionVector);
+                        impostor.object.position.subtractToRef(center, this._tmpPositionVector);
 
                         //Can also use Array.prototype.push.apply
-                        bodyConfig.pos.push(bbox.center.x);
-                        bodyConfig.pos.push(bbox.center.y);
-                        bodyConfig.pos.push(bbox.center.z);
+                        bodyConfig.pos.push(center.x);
+                        bodyConfig.pos.push(center.y);
+                        bodyConfig.pos.push(center.z);
 
                         //tmp solution
                         bodyConfig.rot.push(rot.x / (OIMO.degtorad || OIMO.TO_RAD));
                         bodyConfig.rot.push(rot.y / (OIMO.degtorad || OIMO.TO_RAD));
                         bodyConfig.rot.push(rot.z / (OIMO.degtorad || OIMO.TO_RAD));
                     } else {
-                        bodyConfig.pos.push(i.mesh.position.x);
-                        bodyConfig.pos.push(i.mesh.position.y);
-                        bodyConfig.pos.push(i.mesh.position.z);
+                        bodyConfig.pos.push(i.object.position.x);
+                        bodyConfig.pos.push(i.object.position.y);
+                        bodyConfig.pos.push(i.object.position.z);
 
                         //tmp solution until https://github.com/lo-th/Oimo.js/pull/37 is merged
                         bodyConfig.rot.push(0);
@@ -156,9 +153,9 @@ module BABYLON {
                         case PhysicsImpostor.ParticleImpostor:
                             Tools.Warn("No Particle support in Oimo.js. using SphereImpostor instead");
                         case PhysicsImpostor.SphereImpostor:
-                            var radiusX = bbox.maximumWorld.x - bbox.minimumWorld.x;
-                            var radiusY = bbox.maximumWorld.y - bbox.minimumWorld.y;
-                            var radiusZ = bbox.maximumWorld.z - bbox.minimumWorld.z;
+                            var radiusX = extendSize.x;
+                            var radiusY = extendSize.y;
+                            var radiusZ = extendSize.z;
 
                             var size = Math.max(
                                 checkWithEpsilon(radiusX),
@@ -173,11 +170,8 @@ module BABYLON {
                             break;
 
                         case PhysicsImpostor.CylinderImpostor:
-                            var min = bbox.minimumWorld;
-                            var max = bbox.maximumWorld;
-                            var box = max.subtract(min);
-                            var sizeX = checkWithEpsilon(box.x) / 2;
-                            var sizeY = checkWithEpsilon(box.y);
+                            var sizeX = checkWithEpsilon(extendSize.x) / 2;
+                            var sizeY = checkWithEpsilon(extendSize.y);
                             bodyConfig.type.push('cylinder');
                             bodyConfig.size.push(sizeX);
                             bodyConfig.size.push(sizeY);
@@ -188,12 +182,9 @@ module BABYLON {
                         case PhysicsImpostor.PlaneImpostor:
                         case PhysicsImpostor.BoxImpostor:
                         default:
-                            var min = bbox.minimumWorld;
-                            var max = bbox.maximumWorld;
-                            var box = max.subtract(min);
-                            var sizeX = checkWithEpsilon(box.x);
-                            var sizeY = checkWithEpsilon(box.y);
-                            var sizeZ = checkWithEpsilon(box.z);
+                            var sizeX = checkWithEpsilon(extendSize.x);
+                            var sizeY = checkWithEpsilon(extendSize.y);
+                            var sizeZ = checkWithEpsilon(extendSize.z);
 
                             bodyConfig.type.push('box');
                             bodyConfig.size.push(sizeX);
@@ -203,7 +194,7 @@ module BABYLON {
                     }
 
                     //actually not needed, but hey...
-                    i.mesh.rotationQuaternion = oldQuaternion;
+                    i.object.rotationQuaternion = oldQuaternion;
                 });
 
                 impostor.physicsBody = new OIMO.Body(bodyConfig).body//this.world.add(bodyConfig);
@@ -299,14 +290,14 @@ module BABYLON {
                 //TODO check that
                 if (impostor.physicsBody.shapes.next) {
                     var parentShape = this._getLastShape(impostor.physicsBody);
-                    impostor.mesh.position.x = parentShape.position.x * OIMO.WORLD_SCALE;
-                    impostor.mesh.position.y = parentShape.position.y * OIMO.WORLD_SCALE;
-                    impostor.mesh.position.z = parentShape.position.z * OIMO.WORLD_SCALE;
+                    impostor.object.position.x = parentShape.position.x * OIMO.WORLD_SCALE;
+                    impostor.object.position.y = parentShape.position.y * OIMO.WORLD_SCALE;
+                    impostor.object.position.z = parentShape.position.z * OIMO.WORLD_SCALE;
                 } else {
-                    impostor.mesh.position.copyFrom(impostor.physicsBody.getPosition());
+                    impostor.object.position.copyFrom(impostor.physicsBody.getPosition());
 
                 }
-                impostor.mesh.rotationQuaternion.copyFrom(impostor.physicsBody.getQuaternion());
+                impostor.object.rotationQuaternion.copyFrom(impostor.physicsBody.getQuaternion());
             }
         }
 

+ 9 - 1
src/Physics/babylon.physicsEngine.ts

@@ -76,7 +76,7 @@
          * @param {PhysicsImpostor} impostor the impostor to add
          */
         public addImpostor(impostor: PhysicsImpostor) {
-            this._impostors.push(impostor);
+            impostor.uniqueId = this._impostors.push(impostor);
             //if no parent, generate the body
             if (!impostor.parent) {
                 this._physicsPlugin.generatePhysicsBody(impostor);
@@ -154,6 +154,14 @@
         public getPhysicsPlugin(): IPhysicsEnginePlugin {
             return this._physicsPlugin;
         }
+        
+        public getImpostorForPhysicsObject(object: IPhysicsEnabledObject) {
+            for (var i = 0; i < this._impostors.length; ++i) {
+                if (this._impostors[i].object === object) {
+                    return this._impostors[i];
+                }
+            }
+        }
 
         public getImpostorWithPhysicsBody(body: any): PhysicsImpostor {
             for (var i = 0; i < this._impostors.length; ++i) {

+ 74 - 30
src/Physics/babylon.physicsImpostor.ts

@@ -7,8 +7,23 @@ module BABYLON {
         nativeOptions?: any;
     }
 
+    export interface IPhysicsEnabledObject {
+        position: Vector3;
+        rotationQuaternion: Quaternion;
+        scaling: Vector3;
+        rotation?: Vector3;
+        parent?: any;
+        getBoundingInfo?(): BoundingInfo;
+        computeWorldMatrix?(force: boolean): void;
+        getChildMeshes?(): Array<AbstractMesh>;
+        getVerticesData?(kind: string): Array<number> | Float32Array;
+        getIndices?(): Array<number>| Int32Array;
+    }
+
     export class PhysicsImpostor {
 
+        public static DEFAULT_OBJECT_SIZE: Vector3 = new BABYLON.Vector3(1, 1, 1);
+
         private _physicsEngine: PhysicsEngine;
         //The native cannon/oimo/energy physics body object.
         private _physicsBody: any;
@@ -21,27 +36,39 @@ module BABYLON {
         private _deltaPosition: Vector3 = Vector3.Zero();
         private _deltaRotation: Quaternion;
         private _deltaRotationConjugated: Quaternion;
-        
+
         //If set, this is this impostor's parent
         private _parent: PhysicsImpostor;
 
+        //set by the physics engine when adding this impostor to the array.
+        public uniqueId: number;
+
         private _joints: Array<{
             joint: PhysicsJoint,
             otherImpostor: PhysicsImpostor
         }>;
 
-        constructor(private _mesh: AbstractMesh, public type: number, private _options: PhysicsImpostorParameters = { mass: 0 }) {
-            this._physicsEngine = this._mesh.getScene().getPhysicsEngine();
+        constructor(public object: IPhysicsEnabledObject, public type: number, private _options: PhysicsImpostorParameters = { mass: 0 }, private _scene: Scene) {
+            this._physicsEngine = this._scene.getPhysicsEngine();
             if (!this._physicsEngine) {
                 Tools.Error("Physics not enabled. Please use scene.enablePhysics(...) before creating impostors.")
             } else {
+                //set the object's quaternion, if not set
+                if (!this.object.rotationQuaternion) {
+                    if (this.object.rotation) {
+                        this.object.rotationQuaternion = Quaternion.RotationYawPitchRoll(this.object.rotation.y, this.object.rotation.x, this.object.rotation.z);
+                    } else {
+                        this.object.rotationQuaternion = new Quaternion();
+                    }
+
+                }
                 //default options params
                 this._options.mass = (_options.mass === void 0) ? 0 : _options.mass
                 this._options.friction = (_options.friction === void 0) ? 0.2 : _options.friction
                 this._options.restitution = (_options.restitution === void 0) ? 0.2 : _options.restitution
                 this._joints = [];
                 //If the mesh has a parent, don't initialize the physicsBody. Instead wait for the parent to do that.
-                if (!this._mesh.parent) {
+                if (!this.object.parent) {
                     this._init();
                 }
             }
@@ -63,9 +90,9 @@ module BABYLON {
         }
 
         private _getPhysicsParent(): PhysicsImpostor {
-            if (this.mesh.parent instanceof AbstractMesh) {
-                var parentMesh: AbstractMesh = <AbstractMesh>this.mesh.parent;
-                return parentMesh.getPhysicsImpostor();
+            if (this.object.parent instanceof AbstractMesh) {
+                var parentMesh: AbstractMesh = <AbstractMesh>this.object.parent;
+                return parentMesh.physicsImpostor;
             }
             return;
         }
@@ -92,9 +119,9 @@ module BABYLON {
             }
         }
 
-        public get mesh(): AbstractMesh {
+        /*public get mesh(): AbstractMesh {
             return this._mesh;
-        }
+        }*/
 
         /**
          * Gets the body that holds this impostor. Either its own, or its parent.
@@ -122,6 +149,23 @@ module BABYLON {
             this._bodyUpdateRequired = false;
         }
 
+        public getObjectExtendSize(): Vector3 {
+            if (this.object.getBoundingInfo) {
+                this.object.computeWorldMatrix && this.object.computeWorldMatrix(true);
+                return this.object.getBoundingInfo().boundingBox.extendSize.scale(2).multiply(this.object.scaling)
+            } else {
+                return PhysicsImpostor.DEFAULT_OBJECT_SIZE;
+            }
+        }
+        
+        public getObjectCenter(): Vector3 {
+            if (this.object.getBoundingInfo) {
+                return this.object.getBoundingInfo().boundingBox.center;
+            } else {
+                return this.object.position;
+            }
+        }
+
         /**
          * Get a specific parametes from the options parameter.
          */
@@ -136,7 +180,7 @@ module BABYLON {
             this._options[paramName] = value;
             this._bodyUpdateRequired = true;
         }
-        
+
         /**
          * Specifically change the body's mass option. Won't recreate the physics body object
          */
@@ -146,9 +190,9 @@ module BABYLON {
             }
             this._physicsEngine.getPhysicsPlugin().setBodyMass(this, mass);
         }
-        
-        public getLinearVelocity() : Vector3 {
-            return this._physicsEngine.getPhysicsPlugin().getLinearVelocity(this);    
+
+        public getLinearVelocity(): Vector3 {
+            return this._physicsEngine.getPhysicsPlugin().getLinearVelocity(this);
         }
 
         /**
@@ -157,18 +201,18 @@ module BABYLON {
         public setLinearVelocity(velocity: Vector3) {
             this._physicsEngine.getPhysicsPlugin().setLinearVelocity(this, velocity);
         }
-        
-        public getAngularVelocity() : Vector3 {
-             return this._physicsEngine.getPhysicsPlugin().getAngularVelocity(this);    
+
+        public getAngularVelocity(): Vector3 {
+            return this._physicsEngine.getPhysicsPlugin().getAngularVelocity(this);
         }
-        
+
         /**
          * Set the body's linear velocity.
          */
         public setAngularVelocity(velocity: Vector3) {
             this._physicsEngine.getPhysicsPlugin().setAngularVelocity(this, velocity);
         }
-        
+
         /**
          * Execute a function with the physics plugin native code.
          * Provide a function the will have two variables - the world object and the physics body object.
@@ -238,12 +282,12 @@ module BABYLON {
          */
         public beforeStep = () => {
 
-            this.mesh.position.subtractToRef(this._deltaPosition, this._tmpPositionWithDelta);
+            this.object.position.subtractToRef(this._deltaPosition, this._tmpPositionWithDelta);
             //conjugate deltaRotation
             if (this._deltaRotationConjugated) {
-                this.mesh.rotationQuaternion.multiplyToRef(this._deltaRotationConjugated, this._tmpRotationWithDelta);
+                this.object.rotationQuaternion.multiplyToRef(this._deltaRotationConjugated, this._tmpRotationWithDelta);
             } else {
-                this._tmpRotationWithDelta.copyFrom(this.mesh.rotationQuaternion);
+                this._tmpRotationWithDelta.copyFrom(this.object.rotationQuaternion);
             }
 
             this._physicsEngine.getPhysicsPlugin().setPhysicsBodyTransformation(this, this._tmpPositionWithDelta, this._tmpRotationWithDelta);
@@ -263,12 +307,12 @@ module BABYLON {
 
             this._physicsEngine.getPhysicsPlugin().setTransformationFromPhysicsBody(this);
 
-            this.mesh.position.addInPlace(this._deltaPosition)
+            this.object.position.addInPlace(this._deltaPosition)
             if (this._deltaRotation) {
-                this.mesh.rotationQuaternion.multiplyInPlace(this._deltaRotation);
+                this.object.rotationQuaternion.multiplyInPlace(this._deltaRotation);
             }
         }
-        
+
         //event and body object due to cannon's event-based architecture.
         public onCollide = (e: { body: any }) => {
             var otherImpostor = this._physicsEngine.getImpostorWithPhysicsBody(e.body);
@@ -313,14 +357,14 @@ module BABYLON {
             })
             this._physicsEngine.addJoint(this, otherImpostor, joint);
         }
-        
+
         /**
          * Will keep this body still, in a sleep mode.
          */
         public sleep() {
             this._physicsEngine.getPhysicsPlugin().sleepBody(this);
         }
-        
+
         /**
          * Wake the body up.
          */
@@ -328,19 +372,19 @@ module BABYLON {
             this._physicsEngine.getPhysicsPlugin().wakeUpBody(this);
         }
 
-        public dispose(disposeChildren: boolean = true) {
+        public dispose(/*disposeChildren: boolean = true*/) {
             this.physicsBody = null;
             if (this.parent) {
                 this.parent.forceUpdate();
             } else {
-                this.mesh.getChildMeshes().forEach(function(mesh) {
+                /*this._object.getChildMeshes().forEach(function(mesh) {
                     if (mesh.physicsImpostor) {
                         if (disposeChildren) {
                             mesh.physicsImpostor.dispose();
                             mesh.physicsImpostor = null;
                         }
                     }
-                })
+                })*/
             }
         }
 
@@ -355,7 +399,7 @@ module BABYLON {
             this._deltaRotation.copyFrom(rotation);
             this._deltaRotationConjugated = this._deltaRotation.conjugate();
         }
-        
+
         //Impostor types
         public static NoImpostor = 0;
         public static SphereImpostor = 1;