Sfoglia il codice sorgente

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 anni fa
parent
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 color = new Color4(1, 1, 1, 1);  // color
         public position = Vector3.Zero();       // position
         public position = Vector3.Zero();       // position
         public rotation = Vector3.Zero();       // rotation
         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 uvs = new Vector4(0, 0, 1, 1);   // uvs
         public velocity = Vector3.Zero();       // velocity
         public velocity = Vector3.Zero();       // velocity
         public alive = true;                    // alive
         public alive = true;                    // alive
@@ -22,6 +22,24 @@ module BABYLON {
             this.shapeId = shapeId;
             this.shapeId = shapeId;
             this.idxInShape = idxInShape;
             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 {
     export class ModelShape {

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

@@ -274,10 +274,10 @@
             this._copy.rotation.x = 0;
             this._copy.rotation.x = 0;
             this._copy.rotation.y = 0;
             this._copy.rotation.y = 0;
             this._copy.rotation.z = 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.x = 0;
             this._copy.uvs.y = 0;
             this._copy.uvs.y = 0;
             this._copy.uvs.z = 1;
             this._copy.uvs.z = 1;
@@ -296,11 +296,8 @@
                 options.positionFunction(this._copy, idx, idxInShape);
                 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 {
             } else {
                 this._yaw = this._copy.rotation.y;
                 this._yaw = this._copy.rotation.y;
                 this._pitch = this._copy.rotation.x;
                 this._pitch = this._copy.rotation.x;
@@ -318,9 +315,9 @@
                     options.vertexFunction(this._copy, this._vertex, i);
                     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);
                 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);
                 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);
                 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 {
             } else {
                 this._yaw = this._copy.rotation.y;
                 this._yaw = this._copy.rotation.y;
                 this._pitch = this._copy.rotation.x;
                 this._pitch = this._copy.rotation.x;
@@ -450,9 +444,9 @@
                     particle._model._vertexFunction(this._copy, this._vertex, pt); // recall to stored vertexFunction
                     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);
                 Vector3.TransformCoordinatesToRef(this._vertex, this._rotMatrix, this._rotated);
 
 
@@ -466,10 +460,10 @@
             particle.rotation.x = 0;
             particle.rotation.x = 0;
             particle.rotation.y = 0;
             particle.rotation.y = 0;
             particle.rotation.z = 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;
                     this._particle.rotation.y = 0.0;
                 }
                 }
                 if (this._computeParticleRotation) {
                 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 {
                     } else {
                         this._yaw = this._particle.rotation.y;
                         this._yaw = this._particle.rotation.y;
                         this._pitch = this._particle.rotation.x;
                         this._pitch = this._particle.rotation.x;
@@ -588,9 +579,9 @@
                     }
                     }
 
 
                     // positions
                     // 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._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;
                     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?
             //should a new body be created for this impostor?
             if (impostor.isBodyInitRequired()) {
             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);
                 var shape = this._createShape(impostor);
 
 
@@ -72,7 +69,7 @@
                 }
                 }
 
 
                 //create the body and material
                 //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 = {
                 var bodyCreationObject = {
                     mass: impostor.getParam("mass"),
                     mass: impostor.getParam("mass"),
@@ -107,7 +104,7 @@
         }
         }
 
 
         private _processChildMeshes(mainImpostor: PhysicsImpostor) {
         private _processChildMeshes(mainImpostor: PhysicsImpostor) {
-            var meshChildren = mainImpostor.mesh.getChildMeshes();
+            var meshChildren = mainImpostor.object.getChildMeshes ? mainImpostor.object.getChildMeshes() : [];
             if (meshChildren.length) {
             if (meshChildren.length) {
                 var processMesh = (localPosition: Vector3, mesh: AbstractMesh) => {
                 var processMesh = (localPosition: Vector3, mesh: AbstractMesh) => {
                     var childImpostor = mesh.getPhysicsImpostor();
                     var childImpostor = mesh.getPhysicsImpostor();
@@ -237,35 +234,25 @@
         }
         }
 
 
         private _createShape(impostor: PhysicsImpostor) {
         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 returnValue;
-            var bbox = mesh.getBoundingInfo().boundingBox;
+            var extendSize = impostor.getObjectExtendSize();
             switch (impostor.type) {
             switch (impostor.type) {
                 case PhysicsEngine.SphereImpostor:
                 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);
                     returnValue = new CANNON.Sphere(Math.max(this._checkWithEpsilon(radiusX), this._checkWithEpsilon(radiusY), this._checkWithEpsilon(radiusZ)) / 2);
 
 
                     break;
                     break;
                 //TMP also for cylinder - TODO Cannon supports cylinder natively.
                 //TMP also for cylinder - TODO Cannon supports cylinder natively.
                 case PhysicsImpostor.CylinderImpostor:
                 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;
                     break;
                 case PhysicsImpostor.BoxImpostor:
                 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)));
                     returnValue = new CANNON.Box(new CANNON.Vec3(this._checkWithEpsilon(box.x), this._checkWithEpsilon(box.y), this._checkWithEpsilon(box.z)));
                     break;
                     break;
                 case PhysicsImpostor.PlaneImpostor:
                 case PhysicsImpostor.PlaneImpostor:
@@ -273,37 +260,35 @@
                     returnValue = new CANNON.Plane();
                     returnValue = new CANNON.Plane();
                     break;
                     break;
                 case PhysicsImpostor.MeshImpostor:
                 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.");
                     Tools.Warn("MeshImpostor only collides against spheres.");
                     returnValue = new CANNON.Trimesh(rawVerts, rawFaces);
                     returnValue = new CANNON.Trimesh(rawVerts, rawFaces);
                     break;
                     break;
                 case PhysicsImpostor.HeightmapImpostor:
                 case PhysicsImpostor.HeightmapImpostor:
-                    returnValue = this._createHeightmap(mesh);
+                    returnValue = this._createHeightmap(object);
                     break;
                     break;
                 case PhysicsImpostor.ParticleImpostor:
                 case PhysicsImpostor.ParticleImpostor:
                     returnValue = new CANNON.Particle();
                     returnValue = new CANNON.Particle();
                     break;
                     break;
             }
             }
 
 
-            mesh.rotationQuaternion = oldQuaternion;
-
             return returnValue;
             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 = [];
             var matrix = [];
 
 
             //For now pointDepth will not be used and will be automatically calculated.
             //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.
             //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 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 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) {
             for (var i = 0; i < pos.length; i = i + 3) {
                 var x = Math.round((pos[i + 0]) / elementSize + arraySize / 2);
                 var x = Math.round((pos[i + 0]) / elementSize + arraySize / 2);
@@ -360,15 +345,15 @@
         private _tmpUnityRotation: Quaternion = new Quaternion();
         private _tmpUnityRotation: Quaternion = new Quaternion();
 
 
         private _updatePhysicsBodyTransformation(impostor: PhysicsImpostor) {
         private _updatePhysicsBodyTransformation(impostor: PhysicsImpostor) {
-            var mesh = impostor.mesh;
+            var object = impostor.object;
             //make sure it is updated...
             //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
             // 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.
             //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) {
             if (impostor.type === PhysicsImpostor.PlaneImpostor || impostor.type === PhysicsImpostor.HeightmapImpostor || impostor.type === PhysicsImpostor.CylinderImpostor) {
                 //-90 DEG in X, precalculated
                 //-90 DEG in X, precalculated
@@ -380,14 +365,14 @@
 
 
             //If it is a heightfield, if should be centered.
             //If it is a heightfield, if should be centered.
             if (impostor.type === PhysicsEngine.HeightmapImpostor) {
             if (impostor.type === PhysicsEngine.HeightmapImpostor) {
-
+                var mesh = <AbstractMesh>(<any>object);
                 //calculate the correct body position:
                 //calculate the correct body position:
                 var rotationQuaternion = mesh.rotationQuaternion;
                 var rotationQuaternion = mesh.rotationQuaternion;
                 mesh.rotationQuaternion = this._tmpUnityRotation;
                 mesh.rotationQuaternion = this._tmpUnityRotation;
                 mesh.computeWorldMatrix(true);
                 mesh.computeWorldMatrix(true);
 
 
                 //get original center with no rotation
                 //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);
                 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);
                 this._tmpPosition.copyFromFloats(translation.x, translation.y - mesh.getBoundingInfo().boundingBox.extendSize.y, translation.z);
                 //add it inverted to the delta 
                 //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;
                 this._tmpDeltaPosition.y += mesh.getBoundingInfo().boundingBox.extendSize.y;
 
 
                 mesh.setPivotMatrix(oldPivot);
                 mesh.setPivotMatrix(oldPivot);
                 mesh.computeWorldMatrix(true);
                 mesh.computeWorldMatrix(true);
             } else if (impostor.type === PhysicsEngine.MeshImpostor) {
             } else if (impostor.type === PhysicsEngine.MeshImpostor) {
                 this._tmpDeltaPosition.copyFromFloats(0, 0, 0);
                 this._tmpDeltaPosition.copyFromFloats(0, 0, 0);
-                this._tmpPosition.copyFrom(mesh.position);
+                this._tmpPosition.copyFrom(object.position);
             }
             }
 
 
             impostor.setDeltaPosition(this._tmpDeltaPosition);
             impostor.setDeltaPosition(this._tmpDeltaPosition);
@@ -421,8 +406,8 @@
         }
         }
 
 
         public setTransformationFromPhysicsBody(impostor: PhysicsImpostor) {
         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) {
         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) => {
             impostors.forEach((impostor) => {
                 impostor.afterStep();
                 impostor.afterStep();
                 //update the ordered impostors array
                 //update the ordered impostors array
-                this._tmpImpostorsArray[impostor.mesh.uniqueId] = impostor;
+                this._tmpImpostorsArray[impostor.uniqueId] = impostor;
             });
             });
 
 
             //check for collisions
             //check for collisions
@@ -80,16 +80,9 @@ module BABYLON {
                 return;
                 return;
             }
             }
 
 
-            impostor.mesh.computeWorldMatrix(true);
-
             if (impostor.isBodyInitRequired()) {
             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 = {
                 var bodyConfig: any = {
-                    name: impostor.mesh.uniqueId,
+                    name: impostor.uniqueId,
                     //Oimo must have mass, also for static objects.
                     //Oimo must have mass, also for static objects.
                     config: [impostor.getParam("mass") || 1, impostor.getParam("friction"), impostor.getParam("restitution")],
                     config: [impostor.getParam("mass") || 1, impostor.getParam("friction"), impostor.getParam("restitution")],
                     size: [],
                     size: [],
@@ -102,7 +95,8 @@ module BABYLON {
                 };
                 };
 
 
                 var impostors = [impostor];
                 var impostors = [impostor];
-                function addToArray(parent: AbstractMesh) {
+                function addToArray(parent: IPhysicsEnabledObject) {
+                    if(!parent.getChildMeshes) return;
                     parent.getChildMeshes().forEach(function(m) {
                     parent.getChildMeshes().forEach(function(m) {
                         if (m.physicsImpostor) {
                         if (m.physicsImpostor) {
                             impostors.push(m.physicsImpostor);
                             impostors.push(m.physicsImpostor);
@@ -110,7 +104,7 @@ module BABYLON {
                         }
                         }
                     });
                     });
                 }
                 }
-                addToArray(impostor.mesh)
+                addToArray(impostor.object)
 
 
                 function checkWithEpsilon(value: number): number {
                 function checkWithEpsilon(value: number): number {
                     return Math.max(value, PhysicsEngine.Epsilon);
                     return Math.max(value, PhysicsEngine.Epsilon);
@@ -119,31 +113,34 @@ module BABYLON {
                 impostors.forEach((i) => {
                 impostors.forEach((i) => {
 
 
                     //get the correct bounding box
                     //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) {
                     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
                         //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
                         //tmp solution
                         bodyConfig.rot.push(rot.x / (OIMO.degtorad || OIMO.TO_RAD));
                         bodyConfig.rot.push(rot.x / (OIMO.degtorad || OIMO.TO_RAD));
                         bodyConfig.rot.push(rot.y / (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));
                         bodyConfig.rot.push(rot.z / (OIMO.degtorad || OIMO.TO_RAD));
                     } else {
                     } 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
                         //tmp solution until https://github.com/lo-th/Oimo.js/pull/37 is merged
                         bodyConfig.rot.push(0);
                         bodyConfig.rot.push(0);
@@ -156,9 +153,9 @@ module BABYLON {
                         case PhysicsImpostor.ParticleImpostor:
                         case PhysicsImpostor.ParticleImpostor:
                             Tools.Warn("No Particle support in Oimo.js. using SphereImpostor instead");
                             Tools.Warn("No Particle support in Oimo.js. using SphereImpostor instead");
                         case PhysicsImpostor.SphereImpostor:
                         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(
                             var size = Math.max(
                                 checkWithEpsilon(radiusX),
                                 checkWithEpsilon(radiusX),
@@ -173,11 +170,8 @@ module BABYLON {
                             break;
                             break;
 
 
                         case PhysicsImpostor.CylinderImpostor:
                         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.type.push('cylinder');
                             bodyConfig.size.push(sizeX);
                             bodyConfig.size.push(sizeX);
                             bodyConfig.size.push(sizeY);
                             bodyConfig.size.push(sizeY);
@@ -188,12 +182,9 @@ module BABYLON {
                         case PhysicsImpostor.PlaneImpostor:
                         case PhysicsImpostor.PlaneImpostor:
                         case PhysicsImpostor.BoxImpostor:
                         case PhysicsImpostor.BoxImpostor:
                         default:
                         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.type.push('box');
                             bodyConfig.size.push(sizeX);
                             bodyConfig.size.push(sizeX);
@@ -203,7 +194,7 @@ module BABYLON {
                     }
                     }
 
 
                     //actually not needed, but hey...
                     //actually not needed, but hey...
-                    i.mesh.rotationQuaternion = oldQuaternion;
+                    i.object.rotationQuaternion = oldQuaternion;
                 });
                 });
 
 
                 impostor.physicsBody = new OIMO.Body(bodyConfig).body//this.world.add(bodyConfig);
                 impostor.physicsBody = new OIMO.Body(bodyConfig).body//this.world.add(bodyConfig);
@@ -299,14 +290,14 @@ module BABYLON {
                 //TODO check that
                 //TODO check that
                 if (impostor.physicsBody.shapes.next) {
                 if (impostor.physicsBody.shapes.next) {
                     var parentShape = this._getLastShape(impostor.physicsBody);
                     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 {
                 } 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
          * @param {PhysicsImpostor} impostor the impostor to add
          */
          */
         public addImpostor(impostor: PhysicsImpostor) {
         public addImpostor(impostor: PhysicsImpostor) {
-            this._impostors.push(impostor);
+            impostor.uniqueId = this._impostors.push(impostor);
             //if no parent, generate the body
             //if no parent, generate the body
             if (!impostor.parent) {
             if (!impostor.parent) {
                 this._physicsPlugin.generatePhysicsBody(impostor);
                 this._physicsPlugin.generatePhysicsBody(impostor);
@@ -154,6 +154,14 @@
         public getPhysicsPlugin(): IPhysicsEnginePlugin {
         public getPhysicsPlugin(): IPhysicsEnginePlugin {
             return this._physicsPlugin;
             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 {
         public getImpostorWithPhysicsBody(body: any): PhysicsImpostor {
             for (var i = 0; i < this._impostors.length; ++i) {
             for (var i = 0; i < this._impostors.length; ++i) {

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

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