Browse Source

created Debug.PhysicsViewer

Adam Bowman 8 years ago
parent
commit
fb8abde16d

+ 7 - 6
Babylon.csproj

@@ -138,6 +138,7 @@
     <TypeScriptCompile Include="src\Debug\babylon.boneAxesViewer.ts" />
     <TypeScriptCompile Include="src\Debug\babylon.skeletonViewer.ts" />
     <TypeScriptCompile Include="src\Debug\babylon.debugLayer.ts" />
+    <TypeScriptCompile Include="src\Debug\babylon.physicsViewer.ts" />
     <TypeScriptCompile Include="src\Layer\babylon.highlightlayer.ts" />
     <TypeScriptCompile Include="src\Loading\babylon.sceneLoader.ts" />
     <TypeScriptCompile Include="src\Loading\Plugins\babylon.babylonFileLoader.ts" />
@@ -562,11 +563,11 @@
     <PostBuildEvent>
     </PostBuildEvent>
   </PropertyGroup>
-  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
-       Other similar extension points exist, see Microsoft.Common.targets.
-  <Target Name="BeforeBuild">
-  </Target>
-  <Target Name="AfterBuild">
-  </Target>
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
   -->
 </Project>

+ 1 - 0
Tools/Gulp/config.json

@@ -807,6 +807,7 @@
                 "../../src/Debug/babylon.boneAxesViewer.js",
                 "../../src/Debug/babylon.rayHelper.js",
                 "../../src/Debug/babylon.debugLayer.js",
+                "../../src/Debug/babylon.physicsViewer.js",
                 "../../src/Rendering/babylon.boundingBoxRenderer.js"
             ],
             "dependUpon" : [

+ 99 - 0
src/Debug/babylon.physicsViewer.ts

@@ -0,0 +1,99 @@
+module BABYLON.Debug {
+
+    export class PhysicsViewer {
+        
+        protected _imposters:Array<PhysicsImpostor> = [];
+        protected _meshes:Array<AbstractMesh> = [];
+        protected _scene:Scene;
+        protected _numMeshes = 0;
+        protected _physicsEnginePlugin:IPhysicsEnginePlugin;
+        private _renderFunction: () => void;
+
+        constructor(scene:Scene){
+
+            this._scene = scene || Engine.LastCreatedScene;
+            this._physicsEnginePlugin = this._scene.getPhysicsEngine().getPhysicsPlugin();
+
+        }
+
+        protected _updateDebugMeshes():void{
+
+            var plugin = this._physicsEnginePlugin;
+
+            for (var i = 0; i < this._numMeshes; i++){
+                if(this._imposters[i].isDisposed){
+                    this.hideImposter(this._imposters[i--]);
+                }else{
+                    plugin.syncMeshWithImposter(this._meshes[i], this._imposters[i]);
+                }
+            }
+
+        }
+
+        public showImposter(imposter:PhysicsImpostor):void{
+
+            for (var i = 0; i < this._numMeshes; i++){
+                if(this._imposters[i] == imposter){
+                    return;
+                }
+            }
+
+            var debugMesh = this._physicsEnginePlugin.getDebugMesh(imposter, this._scene);
+
+            if(debugMesh){
+                this._imposters[this._numMeshes] = imposter;
+                this._meshes[this._numMeshes] = debugMesh;
+
+                if(this._numMeshes == 0){
+                    this._renderFunction = this._updateDebugMeshes.bind(this);
+                    this._scene.registerBeforeRender(this._renderFunction);
+                }
+
+                this._numMeshes++;
+            }
+
+        }
+
+        public hideImposter(imposter:PhysicsImpostor){
+
+            var removed = false;
+
+            for (var i = 0; i < this._numMeshes; i++){
+                if(this._imposters[i] == imposter){
+                    this._scene.removeMesh(this._meshes[i]);
+                    this._meshes[i].dispose();
+                    this._numMeshes--;
+                    if(this._numMeshes > 0){
+                        this._meshes[i] = this._meshes[this._numMeshes];
+                        this._imposters[i] = this._imposters[this._numMeshes];
+                        this._meshes[this._numMeshes] = null;
+                        this._imposters[this._numMeshes] = null;
+                    }else{
+                        this._meshes[0] = null;
+                        this._imposters[0] = null;
+                    }
+                    removed = true;
+                    break;
+                }
+            }
+
+            if(removed && this._numMeshes == 0){
+                this._scene.registerBeforeRender(this._renderFunction);
+            }
+
+        }
+
+        public dispose(){
+            
+            for (var i = 0; i < this._numMeshes; i++){
+                this.hideImposter(this._imposters[i]);
+            }
+
+            this._imposters.length = 0;
+            this._scene = null;
+            this._physicsEnginePlugin = null;
+            
+        }
+
+    }
+}

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

@@ -10,6 +10,9 @@
         //See https://github.com/schteppe/cannon.js/blob/gh-pages/demos/collisionFilter.html
         private _currentCollisionGroup = 2;
 
+        private _debugBoxMesh:Mesh;
+        private _debugSphereMesh:Mesh;
+
         public constructor(private _useDeltaForWorldStep: boolean = true, iterations: number = 10) {
             if (!this.isSupported()) {
                 Tools.Error("CannonJS is not available. Please make sure you included the js file.");
@@ -469,8 +472,65 @@
             joint.physicsJoint.motorEquation.minForce = lowerLimit === void 0 ? -upperLimit : lowerLimit;
         }
 
+        public getDebugMesh(imposter:PhysicsImpostor, scene:Scene):AbstractMesh{
+
+            var body = imposter.physicsBody;
+            var shape = body.shapes[0];
+            var mesh:InstancedMesh;
+            
+            if (shape.halfExtents) {
+                if(!this._debugBoxMesh){
+                    this._debugBoxMesh = MeshBuilder.CreateBox('physicsBodyBoxViewMesh', { size: 1 }, scene); 
+                    this._debugBoxMesh.renderingGroupId = 1;
+                    this._debugBoxMesh.rotationQuaternion = Quaternion.Identity();
+                    this._debugBoxMesh.material = new StandardMaterial('', scene);
+                    this._debugBoxMesh.material.wireframe = true;
+                    scene.removeMesh(this._debugBoxMesh);             
+                }
+                mesh = this._debugBoxMesh.createInstance('physicsBodyBoxViewInstance');
+                mesh.scaling.x = shape.halfExtents.x * 2;
+                mesh.scaling.y = shape.halfExtents.y * 2;
+                mesh.scaling.z = shape.halfExtents.z * 2;
+            } else if(shape.boundingSphereRadius){	
+                if(!this._debugSphereMesh){
+                    this._debugSphereMesh = MeshBuilder.CreateSphere('physicsBodySphereViewMesh', { diameter: 1 }, scene); 
+                    this._debugSphereMesh.renderingGroupId = 1;
+                    this._debugSphereMesh.rotationQuaternion = Quaternion.Identity();
+                    this._debugSphereMesh.material = new StandardMaterial('', scene);
+                    this._debugSphereMesh.material.wireframe = true;
+                    scene.removeMesh(this._debugSphereMesh);
+                }	
+                mesh = this._debugSphereMesh.createInstance('physicsBodySphereViewInstance');            
+                mesh.scaling.x = shape.boundingSphereRadius * 2;
+                mesh.scaling.y = shape.boundingSphereRadius * 2;
+                mesh.scaling.z = shape.boundingSphereRadius * 2;	
+            }
+
+            return mesh;
+        }
+
+        public syncMeshWithImposter(mesh:AbstractMesh, imposter:PhysicsImpostor){
+
+            var body = imposter.physicsBody;
+
+            mesh.position.x = body.position.x;
+            mesh.position.y = body.position.y;
+            mesh.position.z = body.position.z;
+            
+            mesh.rotationQuaternion.x = body.quaternion.x;
+            mesh.rotationQuaternion.y = body.quaternion.y;
+            mesh.rotationQuaternion.z = body.quaternion.z;
+            mesh.rotationQuaternion.w = body.quaternion.w;
+
+        }
+
         public dispose() {
-            //nothing to do, actually.
+            if(this._debugBoxMesh){
+                this._debugBoxMesh.dispose();
+            }
+            if(this._debugSphereMesh){
+                this._debugSphereMesh.dispose();
+            }
         }
     }
 }

+ 61 - 0
src/Physics/Plugins/babylon.oimoJSPlugin.ts

@@ -6,6 +6,9 @@ module BABYLON {
         public world: any;
         public name: string = "OimoJSPlugin";
 
+        private _debugBoxMesh:Mesh;
+        private _debugSphereMesh:Mesh;
+        
         constructor(iterations?: number) {
             this.world = new OIMO.World(1 / 60, 2, iterations, true);
             this.world.worldscale(1);
@@ -388,7 +391,65 @@ module BABYLON {
             }
         }
 
+        public getDebugMesh(imposter:PhysicsImpostor, scene:Scene):AbstractMesh{
+
+            var body = imposter.physicsBody;
+            var shape = body.shapes;
+            var mesh:InstancedMesh;
+            
+            if (shape.halfWidth) {
+                if(!this._debugBoxMesh){
+                    this._debugBoxMesh = MeshBuilder.CreateBox('physicsBodyBoxViewMesh', { size: 1 }, scene); 
+                    this._debugBoxMesh.renderingGroupId = 1;
+                    this._debugBoxMesh.rotationQuaternion = Quaternion.Identity();
+                    this._debugBoxMesh.material = new StandardMaterial('', scene);
+                    this._debugBoxMesh.material.wireframe = true;
+                    scene.removeMesh(this._debugBoxMesh);             
+                }
+                mesh = this._debugBoxMesh.createInstance('physicsBodyBoxViewInstance');
+                mesh.scaling.x = shape.halfWidth * 2;
+                mesh.scaling.y = shape.halfHeight * 2;
+                mesh.scaling.z = shape.halfDepth * 2;
+            } else if(shape.radius){	
+                if(!this._debugSphereMesh){
+                    this._debugSphereMesh = MeshBuilder.CreateSphere('physicsBodySphereViewMesh', { diameter: 1 }, scene); 
+                    this._debugSphereMesh.renderingGroupId = 1;
+                    this._debugSphereMesh.rotationQuaternion = Quaternion.Identity();
+                    this._debugSphereMesh.material = new StandardMaterial('', scene);
+                    this._debugSphereMesh.material.wireframe = true;
+                    scene.removeMesh(this._debugSphereMesh);
+                }	
+                mesh = this._debugSphereMesh.createInstance('physicsBodySphereViewInstance');            
+                mesh.scaling.x = shape.radius * 2;
+                mesh.scaling.y = shape.radius * 2;
+                mesh.scaling.z = shape.radius * 2;	
+            }
+
+            return mesh;
+        }
+
+        public syncMeshWithImposter(mesh:AbstractMesh, imposter:PhysicsImpostor){
+
+            var body = imposter.physicsBody;
+
+            mesh.position.x = body.position.x;
+            mesh.position.y = body.position.y;
+            mesh.position.z = body.position.z;
+            
+            mesh.rotationQuaternion.x = body.orientation.x;
+            mesh.rotationQuaternion.y = body.orientation.y;
+            mesh.rotationQuaternion.z = body.orientation.z;
+            mesh.rotationQuaternion.w = body.orientation.s;
+
+        }
+
         public dispose() {
+            if(this._debugBoxMesh){
+                this._debugBoxMesh.dispose();
+            }
+            if(this._debugSphereMesh){
+                this._debugSphereMesh.dispose();
+            }
             this.world.clear();
         }
     }

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

@@ -183,6 +183,8 @@
         updateDistanceJoint(joint: PhysicsJoint, maxDistance:number, minDistance?: number);
         setMotor(joint: IMotorEnabledJoint, speed: number, maxForce?: number, motorIndex?: number);
         setLimit(joint: IMotorEnabledJoint, upperLimit: number, lowerLimit?: number, motorIndex?: number);
+        getDebugMesh(imposter:PhysicsImpostor, scene:Scene);
+        syncMeshWithImposter(mesh:AbstractMesh, imposter:PhysicsImpostor);
         dispose();
     }
 }

+ 8 - 0
src/Physics/babylon.physicsImpostor.ts

@@ -44,6 +44,12 @@ module BABYLON {
         //If set, this is this impostor's parent
         private _parent: PhysicsImpostor;
 
+        private _isDisposed = false;
+
+        get isDisposed():boolean{
+            return this._isDisposed;
+        }
+
         //set by the physics engine when adding this impostor to the array.
         public uniqueId: number;
 
@@ -436,6 +442,8 @@ module BABYLON {
                     }
                 })*/
             }
+
+            this._isDisposed = true;
         }
 
         public setDeltaPosition(position: Vector3) {