Browse Source

Merge pull request #1050 from RaananW/physics.fix-and-particle

Physics Cylinder and Particles
David Catuhe 9 years ago
parent
commit
dfb695e53f

+ 45 - 39
src/Physics/Plugins/babylon.cannonJSPlugin.ts

@@ -64,13 +64,13 @@
                 }
 
                 var shape = this._createShape(impostor);
-                
+
                 //unregister events, if body is being changed
                 var oldBody = impostor.physicsBody;
                 if (oldBody) {
                     this.removePhysicsBody(impostor);
                 }
-                
+
                 //create the body and material
                 var material = this._addMaterial("mat-" + impostor.mesh.uniqueId, impostor.getParam("friction"), impostor.getParam("restitution"));
 
@@ -91,11 +91,11 @@
                 this.world.addEventListener("postStep", impostor.afterStep);
                 impostor.physicsBody.addShape(shape);
                 this.world.add(impostor.physicsBody);
-                
+
                 //try to keep the body moving in the right direction by taking old properties.
                 //Should be tested!
                 if (oldBody) {
-                    ['force', 'torque', 'velocity', 'angularVelocity'].forEach(function (param) {
+                    ['force', 'torque', 'velocity', 'angularVelocity'].forEach(function(param) {
                         impostor.physicsBody[param].copy(oldBody[param]);
                     });
                 }
@@ -189,6 +189,8 @@
                         localAnchorB: constraintData.pivotB
                     });
                     break;
+                case PhysicsJoint.PointToPointJoint:
+                case PhysicsJoint.BallAndSocketJoint:
                 default:
                     constraint = new CANNON.PointToPointConstraint(mainBody, constraintData.pivotA, connectedBody, constraintData.pivotA, constraintData.maxForce);
                     break;
@@ -200,7 +202,7 @@
             if (impostorJoint.joint.type !== PhysicsJoint.SpringJoint) {
                 this.world.addConstraint(constraint);
             } else {
-                impostorJoint.mainImpostor.registerAfterPhysicsStep(function () {
+                impostorJoint.mainImpostor.registerAfterPhysicsStep(function() {
                     constraint.applyForce();
                 });
             }
@@ -236,17 +238,16 @@
 
         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 returnValue;
-
+            var bbox = mesh.getBoundingInfo().boundingBox;
             switch (impostor.type) {
                 case PhysicsEngine.SphereImpostor:
-                    var bbox = mesh.getBoundingInfo().boundingBox;
                     var radiusX = bbox.maximumWorld.x - bbox.minimumWorld.x;
                     var radiusY = bbox.maximumWorld.y - bbox.minimumWorld.y;
                     var radiusZ = bbox.maximumWorld.z - bbox.minimumWorld.z;
@@ -255,29 +256,34 @@
 
                     break;
                 //TMP also for cylinder - TODO Cannon supports cylinder natively.
-                case PhysicsEngine.CylinderImpostor:
-                    Tools.Warn("CylinderImposter not yet implemented, using BoxImposter instead");
-                case PhysicsEngine.BoxImpostor:
-                    bbox = mesh.getBoundingInfo().boundingBox;
+                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);
+                    break;
+                case PhysicsImpostor.BoxImpostor:
                     var min = bbox.minimumWorld;
                     var max = bbox.maximumWorld;
                     var box = max.subtract(min).scale(0.5);
                     returnValue = new CANNON.Box(new CANNON.Vec3(this._checkWithEpsilon(box.x), this._checkWithEpsilon(box.y), this._checkWithEpsilon(box.z)));
                     break;
-                case PhysicsEngine.PlaneImpostor:
+                case PhysicsImpostor.PlaneImpostor:
                     Tools.Warn("Attention, PlaneImposter might not behave as you expect. Consider using BoxImposter instead");
                     returnValue = new CANNON.Plane();
                     break;
-                case PhysicsEngine.MeshImpostor:
+                case PhysicsImpostor.MeshImpostor:
                     var rawVerts = mesh.getVerticesData(VertexBuffer.PositionKind);
                     var rawFaces = mesh.getIndices();
                     Tools.Warn("MeshImpostor only collides against spheres.");
                     returnValue = new CANNON.Trimesh(rawVerts, rawFaces);
                     break;
-                case PhysicsEngine.HeightmapImpostor:
+                case PhysicsImpostor.HeightmapImpostor:
                     returnValue = this._createHeightmap(mesh);
                     break;
-
+                case PhysicsImpostor.ParticleImpostor:
+                    returnValue = new CANNON.Particle();
+                    break;
             }
 
             mesh.rotationQuaternion = oldQuaternion;
@@ -288,7 +294,7 @@
         private _createHeightmap(mesh: AbstractMesh, pointDepth?: number) {
             var pos = mesh.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);
@@ -338,7 +344,7 @@
             var shape = new CANNON.Heightfield(matrix, {
                 elementSize: elementSize
             });
-            
+
             //For future reference, needed for body transformation
             shape.minY = minY;
 
@@ -364,35 +370,35 @@
             var quaternion = mesh.rotationQuaternion;
             this._tmpPosition.copyFrom(mesh.getBoundingInfo().boundingBox.center);
             //is shape is a plane or a heightmap, it must be rotated 90 degs in the X axis.
-            if (impostor.type === PhysicsEngine.PlaneImpostor || impostor.type === PhysicsEngine.HeightmapImpostor) {
+            if (impostor.type === PhysicsImpostor.PlaneImpostor || impostor.type === PhysicsImpostor.HeightmapImpostor || impostor.type === PhysicsImpostor.CylinderImpostor) {
                 //-90 DEG in X, precalculated
                 quaternion = quaternion.multiply(this._minus90X);
                 //Invert! (Precalculated, 90 deg in X)
                 //No need to clone. this will never change.
                 impostor.setDeltaRotation(this._plus90X);
             }
-            
+
             //If it is a heightfield, if should be centered.
             if (impostor.type === PhysicsEngine.HeightmapImpostor) {
-                
+
                 //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 oldPivot = mesh.getPivotMatrix() || Matrix.Translation(0, 0, 0);
-                
+
                 //rotation is back
                 mesh.rotationQuaternion = rotationQuaternion;
-        
+
                 //calculate the new center using a pivot (since Cannon.js doesn't center height maps)
                 var p = Matrix.Translation(mesh.getBoundingInfo().boundingBox.extendSize.x, 0, -mesh.getBoundingInfo().boundingBox.extendSize.z);
                 mesh.setPivotMatrix(p);
                 mesh.computeWorldMatrix(true);
-        
+
                 //calculate the translation
                 var translation = mesh.getBoundingInfo().boundingBox.center.subtract(center).subtract(mesh.position).negate();
 
@@ -435,7 +441,7 @@
         public setAngularVelocity(impostor: PhysicsImpostor, velocity: Vector3) {
             impostor.physicsBody.angularVelocity.copy(velocity);
         }
-        
+
         public getLinearVelocity(impostor: PhysicsImpostor): Vector3 {
             var v = impostor.physicsBody.velocity;
             if (!v) return null;
@@ -459,28 +465,28 @@
         public wakeUpBody(impostor: PhysicsImpostor) {
             impostor.physicsBody.wakeUp();
         }
-        
-        public updateDistanceJoint(joint: PhysicsJoint, maxDistance:number, minDistance?: number) {
+
+        public updateDistanceJoint(joint: PhysicsJoint, maxDistance: number, minDistance?: number) {
             joint.physicsJoint.distance = maxDistance;
         }
-        
+
         private enableMotor(joint: IMotorEnabledJoint, motorIndex?: number) {
-            if(!motorIndex) {
+            if (!motorIndex) {
                 joint.physicsJoint.enableMotor();
             }
         }
-        
+
         private disableMotor(joint: IMotorEnabledJoint, motorIndex?: number) {
-            if(!motorIndex) {
+            if (!motorIndex) {
                 joint.physicsJoint.disableMotor();
             }
         }
-        
+
         public setMotor(joint: IMotorEnabledJoint, speed?: number, maxForce?: number, motorIndex?: number) {
-            if(!motorIndex) {
+            if (!motorIndex) {
                 joint.physicsJoint.enableMotor();
                 joint.physicsJoint.setMotorSpeed(speed);
-                if(maxForce) {
+                if (maxForce) {
                     this.setLimit(joint, maxForce);
                 }
                 //a hack for force application
@@ -494,12 +500,12 @@
                 bodyTorque.vadd(torque, bodyTorque);*/
             }
         }
-        
+
         public setLimit(joint: IMotorEnabledJoint, upperLimit: number, lowerLimit?: number) {
             joint.physicsJoint.motorEquation.maxForce = upperLimit;
-            joint.physicsJoint.motorEquation.minForce = lowerLimit || -upperLimit;
-        }        
-        
+            joint.physicsJoint.motorEquation.minForce = lowerLimit === void 0 ? -upperLimit : lowerLimit;
+        }
+
         public dispose() {
             //nothing to do, actually.
         }

+ 21 - 9
src/Physics/Plugins/babylon.oimoJSPlugin.ts

@@ -153,7 +153,9 @@ module BABYLON {
 
                     // register mesh
                     switch (i.type) {
-                        case PhysicsEngine.SphereImpostor:
+                        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;
@@ -170,12 +172,22 @@ module BABYLON {
                             bodyConfig.size.push(size);
                             break;
 
-                        case PhysicsEngine.PlaneImpostor:
-                        //TODO Oimo now supports cylinder!
-                        case PhysicsEngine.CylinderImpostor:
-                        case PhysicsEngine.BoxImpostor:
-                        default:
+                        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);
+                            bodyConfig.type.push('cylinder');
+                            bodyConfig.size.push(sizeX);
+                            bodyConfig.size.push(sizeY);
+                            //due to the way oimo works with compounds, add one more value.
+                            bodyConfig.size.push(sizeY);
+                            break;
 
+                        case PhysicsImpostor.PlaneImpostor:
+                        case PhysicsImpostor.BoxImpostor:
+                        default:
                             var min = bbox.minimumWorld;
                             var max = bbox.maximumWorld;
                             var box = max.subtract(min);
@@ -358,17 +370,17 @@ module BABYLON {
             }
         }
 
-        public setMotor(joint: IMotorEnabledJoint, force?: number, maxForce?: number, motorIndex?: number) {
+        public setMotor(joint: IMotorEnabledJoint, speed: number, maxForce?: number, motorIndex?: number) {
             var motor = motorIndex ? joint.physicsJoint.rotationalLimitMotor2 : joint.physicsJoint.rotationalLimitMotor1 || joint.physicsJoint.limitMotor;
             if (motor) {
-                motor.setMotor(force, maxForce);
+                motor.setMotor(speed, maxForce);
             }
         }
 
         public setLimit(joint: IMotorEnabledJoint, upperLimit: number, lowerLimit?: number, motorIndex?: number) {
             var motor = motorIndex ? joint.physicsJoint.rotationalLimitMotor2 : joint.physicsJoint.rotationalLimitMotor1 || joint.physicsJoint.limitMotor;
             if (motor) {
-                motor.setLimit(upperLimit, lowerLimit || -upperLimit);
+                motor.setLimit(upperLimit, lowerLimit === void 0 ? -upperLimit : lowerLimit);
             }
         }
 

+ 4 - 4
src/Physics/babylon.physicsEngine.ts

@@ -57,11 +57,11 @@
         public static BoxImpostor = PhysicsImpostor.BoxImpostor;
         public static PlaneImpostor = PhysicsImpostor.PlaneImpostor;
         public static MeshImpostor = PhysicsImpostor.MeshImpostor;
-        public static CapsuleImpostor = PhysicsImpostor.CapsuleImpostor;
-        public static ConeImpostor = PhysicsImpostor.ConeImpostor;
         public static CylinderImpostor = PhysicsImpostor.CylinderImpostor;
-        public static ConvexHullImpostor = PhysicsImpostor.ConvexHullImpostor;
         public static HeightmapImpostor = PhysicsImpostor.HeightmapImpostor;
+        public static CapsuleImpostor = -1;
+        public static ConeImpostor = -1;
+        public static ConvexHullImpostor = -1;
 
         public static Epsilon = 0.001;
         
@@ -188,7 +188,7 @@
         wakeUpBody(impostor: PhysicsImpostor);
         //Joint Update
         updateDistanceJoint(joint: DistanceJoint, maxDistance:number, minDistance?: number);
-        setMotor(joint: IMotorEnabledJoint, force?: number, maxForce?: number, motorIndex?: number);
+        setMotor(joint: IMotorEnabledJoint, speed: number, maxForce?: number, motorIndex?: number);
         setLimit(joint: IMotorEnabledJoint, upperLimit: number, lowerLimit?: number, motorIndex?: number);
         dispose();
     }

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

@@ -362,10 +362,8 @@ module BABYLON {
         public static BoxImpostor = 2;
         public static PlaneImpostor = 3;
         public static MeshImpostor = 4;
-        public static CapsuleImpostor = 5;
-        public static ConeImpostor = 6;
         public static CylinderImpostor = 7;
-        public static ConvexHullImpostor = 8;
+        public static ParticleImpostor = 8;
         public static HeightmapImpostor = 9;
     }
 

+ 0 - 1
src/Physics/babylon.physicsJoint.ts

@@ -66,7 +66,6 @@ module BABYLON {
         public static Hinge2Joint = PhysicsJoint.WheelJoint;
         //Cannon
         //Similar to a Ball-Joint. Different in params
-        //TODO check!!
         public static PointToPointJoint = 8;
         //Cannon only at the moment
         public static SpringJoint = 9;