Преглед изворни кода

Abstract object for physics

It is now possible to assign an impostor to each object with both
position and quaternion. Including particles.
Raanan Weber пре 10 година
родитељ
комит
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;