瀏覽代碼

Some refactoring

Borut 7 年之前
父節點
當前提交
60ec64811d
共有 4 個文件被更改,包括 8016 次插入7850 次删除
  1. 2 1
      Tools/Gulp/config.json
  2. 7765 7722
      dist/preview release/babylon.d.ts
  3. 5 127
      src/Physics/babylon.physicsEngine.ts
  4. 244 0
      src/Physics/babylon.physicsHelper.ts

+ 2 - 1
Tools/Gulp/config.json

@@ -926,6 +926,7 @@
                 "../../src/Physics/babylon.physicsJoint.js",
                 "../../src/Physics/babylon.physicsImpostor.js",
                 "../../src/Physics/babylon.physicsEngine.js",
+                "../../src/Physics/babylon.physicsHelper.js",
                 "../../src/Physics/Plugins/babylon.cannonJSPlugin.js",
                 "../../src/Physics/Plugins/babylon.oimoJSPlugin.js"
             ],
@@ -1661,4 +1662,4 @@
             "distOutputDirectory": "/inspector/"
         }
     }
-}
+}

File diff suppressed because it is too large
+ 7765 - 7722
dist/preview release/babylon.d.ts


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

@@ -61,7 +61,7 @@
 
         private _impostors: Array<PhysicsImpostor> = [];
         private _joints: Array<PhysicsImpostorJoint> = [];
-
+        
         /**
          * Adding a new impostor for the impostor tracking.
          * This will be done by the impostor itself.
@@ -146,6 +146,10 @@
         public getPhysicsPlugin(): IPhysicsEnginePlugin {
             return this._physicsPlugin;
         }
+        
+        public getImpostors(): Array<PhysicsImpostor> {
+            return this._impostors;
+        }
 
         public getImpostorForPhysicsObject(object: IPhysicsEnabledObject): Nullable<PhysicsImpostor> {
             for (var i = 0; i < this._impostors.length; ++i) {
@@ -167,127 +171,6 @@
             return null;
         }
 
-        public applyRadialImpulse(origin: Vector3, radius: number, strength: number, falloff: PhysicsRadialImpulseFallof = PhysicsRadialImpulseFallof.Constant) {
-            if (this._impostors.length === 0) {
-                return null;
-            }
-
-            for (var i = 0; i < this._impostors.length; ++i) {
-                var impostor = this._impostors[i];
-                var impostorForceAndContactPoint = this.getImpostorForceAndContactPoint(
-                    impostor,
-                    origin,
-                    radius,
-                    strength,
-                    falloff
-                );
-                if (impostorForceAndContactPoint === false) {
-                    continue;
-                }
-
-                impostor.applyImpulse(
-                    impostorForceAndContactPoint.force,
-                    impostorForceAndContactPoint.contactPoint
-                );
-            }
-
-            return null;
-        }
-
-        public applyRadialForce(origin: Vector3, radius: number, strength: number, falloff: PhysicsRadialImpulseFallof = PhysicsRadialImpulseFallof.Constant) {
-            if (this._impostors.length === 0) {
-                return null;
-            }
-
-            for (var i = 0; i < this._impostors.length; ++i) {
-                var impostor = this._impostors[i];
-                var impostorForceAndContactPoint = this.getImpostorForceAndContactPoint(
-                    impostor,
-                    origin,
-                    radius,
-                    strength,
-                    falloff
-                );
-                if (impostorForceAndContactPoint === false) {
-                    continue;
-                }
-
-                impostor.applyForce(
-                    impostorForceAndContactPoint.force,
-                    impostorForceAndContactPoint.contactPoint
-                );
-            }
-
-            return null;
-        }
-
-        private getImpostorForceAndContactPoint(impostor: PhysicsImpostor, origin: Vector3, radius: number, strength: number, falloff: PhysicsRadialImpulseFallof) {
-            if (impostor.mass === 0) {
-                return false;
-            }
-
-            if (!this.intersectsWithRadialSphere(impostor, origin, radius)) {
-                return false;
-            }
-
-            var impostorObject = (<Mesh>impostor.object);
-            var impostorObjectCenter = impostor.getObjectCenter();
-            var direction = impostorObjectCenter.subtract(origin);
-
-            var ray = new Ray(origin, direction, radius);
-            var hit = ray.intersectsMesh(impostorObject);
-
-            var contactPoint = hit.pickedPoint;
-            if (!contactPoint) {
-                return false;
-            }
-
-            var distanceFromOrigin = BABYLON.Vector3.Distance(origin, contactPoint);
-            if (distanceFromOrigin > radius) {
-                return false;
-            }
-            
-            var multiplier = falloff === PhysicsRadialImpulseFallof.Constant
-                ? strength
-                : strength * (1 - (distanceFromOrigin / radius));
-
-            var force = direction.multiplyByFloats(multiplier, multiplier, multiplier);
-
-            return { force: force, contactPoint: contactPoint };
-        }
-
-        private _radialSphere: Mesh; // create a sphere, so we can get the intersecting meshes inside
-        private _prepareRadialSphere(scene: Scene) {
-            if (!this._radialSphere) {
-                this._radialSphere = BABYLON.Mesh.CreateSphere(
-                    "radialSphere",
-                    32,
-                    1,
-                    scene
-                );
-                this._radialSphere.isVisible = false;
-            }
-        }
-
-        private intersectsWithRadialSphere(impostor: PhysicsImpostor, origin: Vector3, radius: number): boolean {
-            var impostorObject = <Mesh>impostor.object;
-
-            this._prepareRadialSphere(impostorObject.getScene());
-
-            this._radialSphere.position = origin;
-            this._radialSphere.scaling = new Vector3(radius * 2, radius * 2, radius * 2);
-            this._radialSphere._updateBoundingInfo();
-            this._radialSphere.computeWorldMatrix(true);
-  
-            return this._radialSphere.intersectsMesh(
-                impostorObject,
-                true
-            );
-        }
-        
-        public getRadialSphere() {
-            return this._radialSphere;
-        }
     }
 
     export interface IPhysicsEnginePlugin {
@@ -328,9 +211,4 @@
         dispose(): void;
     }
     
-    export enum PhysicsRadialImpulseFallof {
-        Constant, // impulse is constant in strength across it's whole radius
-        Linear // impulse gets weaker if it's further from the origin
-    }
-    
 }

+ 244 - 0
src/Physics/babylon.physicsHelper.ts

@@ -0,0 +1,244 @@
+module BABYLON {
+    
+    /**
+     * The strenght of the force in correspondence to the distance of the affected object
+     */
+    export enum PhysicsRadialImpulseFallof {
+        Constant, // impulse is constant in strength across it's whole radius
+        Linear // impulse gets weaker if it's further from the origin
+    }
+    
+    export class PhysicsHelper {
+        
+        private _scene: Scene;
+        private _physicsEngine: Nullable<PhysicsEngine>;
+
+        public constructor(scene: Scene) {
+            this._scene = scene;
+            this._physicsEngine = this._scene.getPhysicsEngine();
+            
+            if (!this._physicsEngine) {
+                Tools.Warn('Physics engine not enabled. Please enable the physics before you call this method.');
+            }
+        }
+        
+        /**
+         * @param {Vector3} origin the origin of the explosion
+         * @param {number} radius the explosion radius
+         * @param {number} strength the explosion strength
+         * @param {PhysicsRadialImpulseFallof} falloff possible options: Constant & Linear. Defaults to Constant
+         */
+        public applyRadialExplosionImpulse(
+            origin: Vector3,
+            radius: number,
+            strength: number,
+            falloff: PhysicsRadialImpulseFallof = PhysicsRadialImpulseFallof.Constant
+        ) {
+            if (!this._physicsEngine) {
+                Tools.Warn('Physics engine not enabled. Please enable the physics before you call this method.');
+                return null;
+            }
+            
+            var impostors = this._physicsEngine.getImpostors();
+            if (impostors.length === 0) {
+                return null;
+            }
+
+            var event = new PhysicsRadialExplosionEvent(this._scene);
+
+            for (var i = 0; i < impostors.length; ++i) {
+                var impostor = impostors[i];
+                var impostorForceAndContactPoint = event.getImpostorForceAndContactPoint(
+                    impostor,
+                    origin,
+                    radius,
+                    strength,
+                    falloff
+                );
+                if (impostorForceAndContactPoint === false) {
+                    continue;
+                }
+
+                impostor.applyImpulse(
+                    impostorForceAndContactPoint.force,
+                    impostorForceAndContactPoint.contactPoint
+                );
+            }
+
+            return event;
+        }
+
+        /**
+         * @param {Vector3} origin the origin of the explosion
+         * @param {number} radius the explosion radius
+         * @param {number} strength the explosion strength
+         * @param {PhysicsRadialImpulseFallof} falloff possible options: Constant & Linear. Defaults to Constant
+         */
+        public applyRadialExplosionForce(
+            origin: Vector3,
+            radius: number,
+            strength: number,
+            falloff: PhysicsRadialImpulseFallof = PhysicsRadialImpulseFallof.Constant
+        ) {
+            if (!this._physicsEngine) {
+                Tools.Warn('Physics engine not enabled. Please enable the physics before you call the PhysicsHelper.');
+                return null;
+            }
+            
+            var impostors = this._physicsEngine.getImpostors();
+            if (impostors.length === 0) {
+                return null;
+            }
+
+            var event = new PhysicsRadialExplosionEvent(this._scene);
+
+            for (var i = 0; i < impostors.length; ++i) {
+                var impostor = impostors[i];
+                var impostorForceAndContactPoint = event.getImpostorForceAndContactPoint(
+                    impostor,
+                    origin,
+                    radius,
+                    strength,
+                    falloff
+                );
+                if (impostorForceAndContactPoint === false) {
+                    continue;
+                }
+
+                impostor.applyForce(
+                    impostorForceAndContactPoint.force,
+                    impostorForceAndContactPoint.contactPoint
+                );
+            }
+
+            return event;
+        }
+
+    }
+
+    /**
+     * All the stuff related to the radial explosion.
+     */
+    export class PhysicsRadialExplosionEvent {
+        
+        private _scene: Scene;
+        private _radialSphere: Mesh; // create a sphere, so we can get the intersecting meshes inside
+        private _rays: Array<Ray> = [];
+        private _rayHelpers: Array<RayHelper> = [];
+
+        constructor(scene: Scene) {
+            this._scene = scene;
+        }
+
+        public getImpostorForceAndContactPoint(impostor: PhysicsImpostor, origin: Vector3, radius: number, strength: number, falloff: PhysicsRadialImpulseFallof) {
+            if (impostor.mass === 0) {
+                return false;
+            }
+
+            if (!this._intersectsWithRadialSphere(impostor, origin, radius)) {
+                return false;
+            }
+
+            var impostorObject = (<Mesh>impostor.object);
+            var impostorObjectCenter = impostor.getObjectCenter();
+            var direction = impostorObjectCenter.subtract(origin);
+
+            var ray = new Ray(origin, direction, radius);
+            this._rays.push(ray);
+            var hit = ray.intersectsMesh(impostorObject);
+
+            var contactPoint = hit.pickedPoint;
+            if (!contactPoint) {
+                return false;
+            }
+
+            var distanceFromOrigin = BABYLON.Vector3.Distance(origin, contactPoint);
+            if (distanceFromOrigin > radius) {
+                return false;
+            }
+
+            var multiplier = falloff === PhysicsRadialImpulseFallof.Constant
+                ? strength
+                : strength * (1 - (distanceFromOrigin / radius));
+
+            var force = direction.multiplyByFloats(multiplier, multiplier, multiplier);
+
+            return { force: force, contactPoint: contactPoint };
+        }
+
+        /***** Debug *****/
+
+        /**
+         * Will show the radial sphere & rays.
+         * @param rayColor
+         */
+        public showDebug(rayColor: Color3 = new BABYLON.Color3(1, 1, 0)) {
+            if (this._radialSphere) {
+                this._radialSphere.isVisible = true;
+            }
+
+            if (this._rays.length) {
+                this._rayHelpers = [];
+                for (var i = 0; i < this._rays.length; i++) {
+                    var rayHelper = new RayHelper(this._rays[i]);
+                    rayHelper.show(this._scene, rayColor);
+                    this._rayHelpers.push(rayHelper);
+                }
+            }
+
+            return true;
+        }
+
+        public hideDebug() {
+            if (this._radialSphere) {
+                this._radialSphere.isVisible = false;
+            }
+
+            if (this._rayHelpers.length) {
+                for (var i = 0; i < this._rayHelpers.length; i++) {
+                    this._rayHelpers[i].hide();
+                }
+            }
+
+            return true;
+        }
+
+        /***** Helpers *****/
+
+        private _prepareRadialSphere() {
+            if (!this._radialSphere) {
+                this._radialSphere = BABYLON.Mesh.CreateSphere(
+                    "radialSphere",
+                    32,
+                    1,
+                    this._scene
+                );
+                this._radialSphere.isVisible = false;
+            }
+
+            if (!this._radialSphere.material) {
+                var radialSphereMaterial = new BABYLON.StandardMaterial("radialSphereMaterial", this._scene);
+                radialSphereMaterial.alpha = 0.5;
+                this._radialSphere.material = radialSphereMaterial;
+            }
+        }
+
+        private _intersectsWithRadialSphere(impostor: PhysicsImpostor, origin: Vector3, radius: number): boolean {
+            var impostorObject = <Mesh>impostor.object;
+
+            this._prepareRadialSphere();
+
+            this._radialSphere.position = origin;
+            this._radialSphere.scaling = new Vector3(radius * 2, radius * 2, radius * 2);
+            this._radialSphere._updateBoundingInfo();
+            this._radialSphere.computeWorldMatrix(true);
+
+            return this._radialSphere.intersectsMesh(
+                impostorObject,
+                true
+            );
+        }
+
+    }
+    
+}