Преглед на файлове

Joint param settings

One step closer to a babylon native car.
Raanan Weber преди 9 години
родител
ревизия
af5dd9f8bb

+ 42 - 1
src/Physics/Plugins/babylon.cannonJSPlugin.ts

@@ -173,6 +173,7 @@
             }*/
             switch (impostorJoint.joint.type) {
                 case PhysicsJoint.HingeJoint:
+                case PhysicsJoint.Hinge2Joint:
                     constraint = new CANNON.HingeConstraint(mainBody, connectedBody, constraintData);
                     break;
                 case PhysicsJoint.DistanceJoint:
@@ -447,7 +448,47 @@
         public wakeUpBody(impostor: PhysicsImpostor) {
             impostor.physicsBody.wakeUp();
         }
-
+        
+        public updateDistanceJoint(joint: PhysicsJoint, maxDistance:number, minDistance?: number) {
+            joint.physicsJoint.distance = maxDistance;
+        }
+        
+        private enableMotor(joint: IMotorEnabledJoint, motorIndex?: number) {
+            if(!motorIndex) {
+                joint.physicsJoint.enableMotor();
+            }
+        }
+        
+        private disableMotor(joint: IMotorEnabledJoint, motorIndex?: number) {
+            if(!motorIndex) {
+                joint.physicsJoint.disableMotor();
+            }
+        }
+        
+        public setMotor(joint: IMotorEnabledJoint, speed?: number, maxForce?: number, motorIndex?: number) {
+            if(!motorIndex) {
+                joint.physicsJoint.enableMotor();
+                joint.physicsJoint.setMotorSpeed(speed);
+                if(maxForce) {
+                    this.setLimit(joint, maxForce);
+                }
+                //a hack for force application
+                /*var torque = new CANNON.Vec3();
+                var axis = joint.physicsJoint.axisB;
+                var body = joint.physicsJoint.bodyB;
+                var bodyTorque = body.torque;
+
+                axis.scale(force, torque);
+                body.vectorToWorldFrame(torque, torque);
+                bodyTorque.vadd(torque, bodyTorque);*/
+            }
+        }
+        
+        public setLimit(joint: IMotorEnabledJoint, upperLimit: number, lowerLimit?: number) {
+            joint.physicsJoint.motorEquation.maxForce = upperLimit;
+            joint.physicsJoint.motorEquation.minForce = lowerLimit || -upperLimit;
+        }        
+        
         public dispose() {
             //nothing to do, actually.
         }

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

@@ -25,7 +25,7 @@ module BABYLON {
 
         public executeStep(delta: number, impostors: Array<PhysicsImpostor>) {
 
-            impostors.forEach(function (impostor) {
+            impostors.forEach(function(impostor) {
                 impostor.beforeStep();
             });
 
@@ -36,7 +36,7 @@ module BABYLON {
                 //update the ordered impostors array
                 this._tmpImpostorsArray[impostor.mesh.uniqueId] = impostor;
             });
-            
+
             //check for collisions
             var contact = this.world.contacts;
 
@@ -103,7 +103,7 @@ module BABYLON {
 
                 var impostors = [impostor];
                 function addToArray(parent: AbstractMesh) {
-                    parent.getChildMeshes().forEach(function (m) {
+                    parent.getChildMeshes().forEach(function(m) {
                         if (m.physicsImpostor) {
                             impostors.push(m.physicsImpostor);
                             m.physicsImpostor._init();
@@ -117,7 +117,7 @@ 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 });
@@ -135,7 +135,7 @@ module BABYLON {
                         bodyConfig.pos.push(bbox.center.x);
                         bodyConfig.pos.push(bbox.center.y);
                         bodyConfig.pos.push(bbox.center.z);
-                        
+
                         //tmp solution
                         bodyConfig.rot.push(rot.x / (OIMO.degtorad || OIMO.TO_RAD));
                         bodyConfig.rot.push(rot.y / (OIMO.degtorad || OIMO.TO_RAD));
@@ -144,13 +144,13 @@ module BABYLON {
                         bodyConfig.pos.push(i.mesh.position.x);
                         bodyConfig.pos.push(i.mesh.position.y);
                         bodyConfig.pos.push(i.mesh.position.z);
-                        
+
                         //tmp solution until https://github.com/lo-th/Oimo.js/pull/37 is merged
                         bodyConfig.rot.push(0);
                         bodyConfig.rot.push(0);
                         bodyConfig.rot.push(0);
                     }
-                    
+
                     // register mesh
                     switch (i.type) {
                         case PhysicsEngine.SphereImpostor:
@@ -189,7 +189,7 @@ module BABYLON {
                             bodyConfig.size.push(sizeZ);
                             break;
                     }
-                    
+
                     //actually not needed, but hey...
                     i.mesh.rotationQuaternion = oldQuaternion;
                 });
@@ -237,7 +237,7 @@ module BABYLON {
                 max: options.max,
                 collision: options.collision || jointData.collision,
                 spring: options.spring,
-                
+
                 //supporting older version of Oimo
                 world: this.world
 
@@ -341,6 +341,27 @@ module BABYLON {
             impostor.physicsBody.awake();
         }
 
+        public updateDistanceJoint(joint: IMotorEnabledJoint, maxDistance: number, minDistance?: number) {
+            joint.physicsJoint.limitMotoe.upperLimit = maxDistance;
+            if (minDistance !== void 0) {
+                joint.physicsJoint.limitMotoe.lowerLimit = minDistance;
+            }
+        }
+
+        public setMotor(joint: IMotorEnabledJoint, force?: number, maxForce?: number, motorIndex?: number) {
+            var motor = motorIndex ? joint.physicsJoint.rotationalLimitMotor2 : joint.physicsJoint.rotationalLimitMotor2 || joint.physicsJoint.limitMotor;
+            if (motor) {
+                motor.setMotor(force, maxForce);
+            }
+        }
+
+        public setLimit(joint: IMotorEnabledJoint, upperLimit: number, lowerLimit?: number, motorIndex?: number) {
+            var motor = motorIndex ? joint.physicsJoint.rotationalLimitMotor2 : joint.physicsJoint.rotationalLimitMotor2 || joint.physicsJoint.limitMotor;
+            if (motor) {
+                motor.setLimit(upperLimit, lowerLimit || -upperLimit);
+            }
+        }
+
         public dispose() {
             this.world.clear();
         }

+ 5 - 0
src/Physics/babylon.physicsEngine.ts

@@ -95,6 +95,7 @@
                 connectedImpostor: connectedImpostor,
                 joint: joint
             }
+            joint.physicsPlugin = this._physicsPlugin;
             this._joints.push(impostorJoint);
             this._physicsPlugin.generateJoint(impostorJoint);
         }
@@ -166,6 +167,10 @@
         setBodyMass(impostor: PhysicsImpostor, mass: number);
         sleepBody(impostor: PhysicsImpostor);
         wakeUpBody(impostor: PhysicsImpostor);
+        //Joint Update
+        updateDistanceJoint(joint: DistanceJoint, maxDistance:number, minDistance?: number);
+        setMotor(joint: IMotorEnabledJoint, force?: number, maxForce?: number, motorIndex?: number);
+        setLimit(joint: IMotorEnabledJoint, upperLimit: number, lowerLimit?: number, motorIndex?: number);
         dispose();
     }
 }

+ 13 - 9
src/Physics/babylon.physicsImpostor.ts

@@ -31,15 +31,19 @@ module BABYLON {
         }>;
 
         constructor(private _mesh: AbstractMesh, public type: number, private _options: PhysicsImpostorParameters = { mass: 0 }) {
-            //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._physicsEngine = this._mesh.getScene().getPhysicsEngine();
-            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) {
-                this._init();
+            if (!this._physicsEngine) {
+                Tools.Error("Physics not enabled. Please use scene.enablePhysics(...) before creating impostors.")
+            } else {
+                //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) {
+                    this._init();
+                }
             }
         }
 
@@ -321,7 +325,7 @@ module BABYLON {
             if (this.parent) {
                 this.parent.forceUpdate();
             } else {
-                this.mesh.getChildMeshes().forEach(function (mesh) {
+                this.mesh.getChildMeshes().forEach(function(mesh) {
                     if (mesh.physicsImpostor) {
                         if (disposeChildren) {
                             mesh.physicsImpostor.dispose();

+ 59 - 5
src/Physics/babylon.physicsJoint.ts

@@ -6,7 +6,7 @@ module BABYLON {
         connectedPivot?: Vector3;
         mainAxis?: Vector3,
         connectedAxis?: Vector3,
-        collision?: boolean 
+        collision?: boolean
         //Native Oimo/Cannon/Energy data
         nativeParams?: any;
     }
@@ -14,6 +14,7 @@ module BABYLON {
     export class PhysicsJoint {
 
         private _physicsJoint;
+        protected _physicsPlugin: IPhysicsEnginePlugin;
 
         constructor(public type: number, public jointData: PhysicsJointData) {
             jointData.nativeParams = jointData.nativeParams || {};
@@ -31,10 +32,18 @@ module BABYLON {
 
             this._physicsJoint = newJoint;
         }
+
+        public set physicsPlugin(physicsPlugin: IPhysicsEnginePlugin) {
+            this._physicsPlugin = physicsPlugin;
+        }
         
-        
+        public executeNativeFunction(func : (physicsJoint:any) => void) {
+            func(this._physicsJoint)
+        }
+
+
         //TODO check if the native joints are the same
-        
+
         //Joint Types
         public static DistanceJoint = 0;
         public static HingeJoint = 1;
@@ -45,14 +54,59 @@ module BABYLON {
         public static PrismaticJoint = 5;
         //ENERGY FTW! (compare with this - http://ode-wiki.org/wiki/index.php?title=Manual:_Joint_Types_and_Functions)
         public static UniversalJoint = 6;
-        public static Hinge2Joint = 7;
+        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;
+    }
+
+    export class DistanceJoint extends PhysicsJoint {
+        constructor(jointData: DistanceJointData) {
+            super(PhysicsJoint.DistanceJoint, jointData);
+        }
+
+        public updateDistance(maxDistance: number, minDistance?: number) {
+            this._physicsPlugin.updateDistanceJoint(this, maxDistance, minDistance);
+        }
+    }
+
+    export class HingeJoint extends PhysicsJoint implements IMotorEnabledJoint {
+        
+        constructor(jointData:PhysicsJointData) {
+            super(PhysicsJoint.HingeJoint, jointData);
+        }
+        
+        public setMotor(force?: number, maxForce?: number) {
+            this._physicsPlugin.setMotor(this, force, maxForce);
+        }
+        
+        public setLimit(upperLimit: number, lowerLimit?: number) {
+            this._physicsPlugin.setLimit(this, upperLimit, lowerLimit);
+        }
+    }
+    
+    export class Hinge2Joint extends PhysicsJoint implements IMotorEnabledJoint {
+        
+        constructor(jointData:PhysicsJointData) {
+            super(PhysicsJoint.Hinge2Joint, jointData);
+        }
+        
+        public setMotor(force?: number, maxForce?: number, motorIndex: number = 0) {
+            this._physicsPlugin.setMotor(this, force, maxForce, motorIndex);
+        }
+        
+        public setLimit(upperLimit: number, lowerLimit?: number, motorIndex: number = 0) {
+            this._physicsPlugin.setLimit(this, upperLimit, lowerLimit, motorIndex);
+        }
+    }
 
+    export interface IMotorEnabledJoint {
+        physicsJoint: any;
+        setMotor(force?: number, maxForce?: number, motorIndex?: number);
+        setLimit(upperLimit: number, lowerLimit?: number, motorIndex?: number);
     }
 
     export interface DistanceJointData extends PhysicsJointData {
@@ -60,7 +114,7 @@ module BABYLON {
         //Oimo - minDistance
         //Cannon - maxForce
     }
-    
+
     export interface SpringJointData extends PhysicsJointData {
         length: number;
         stiffness: number;