babylon.physicsViewer.ts 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. module BABYLON.Debug {
  2. export class PhysicsViewer {
  3. protected _impostors: Array<Nullable<PhysicsImpostor>> = [];
  4. protected _meshes: Array<Nullable<AbstractMesh>> = [];
  5. protected _scene: Nullable<Scene>;
  6. protected _numMeshes = 0;
  7. protected _physicsEnginePlugin: Nullable<IPhysicsEnginePlugin>;
  8. private _renderFunction: () => void;
  9. private _debugBoxMesh:Mesh;
  10. private _debugSphereMesh:Mesh;
  11. private _debugMaterial:StandardMaterial;
  12. constructor(scene:Scene){
  13. this._scene = scene || Engine.LastCreatedScene;
  14. let physicEngine = this._scene.getPhysicsEngine();
  15. if (physicEngine) {
  16. this._physicsEnginePlugin = physicEngine.getPhysicsPlugin();
  17. }
  18. }
  19. protected _updateDebugMeshes(): void{
  20. var plugin = this._physicsEnginePlugin;
  21. for (var i = 0; i < this._numMeshes; i++) {
  22. let impostor = this._impostors[i];
  23. if (!impostor) {
  24. continue;
  25. }
  26. if (impostor.isDisposed) {
  27. this.hideImpostor(this._impostors[i--]);
  28. } else {
  29. let mesh = this._meshes[i];
  30. if (mesh && plugin) {
  31. plugin.syncMeshWithImpostor(mesh, impostor);
  32. }
  33. }
  34. }
  35. }
  36. public showImpostor(impostor:PhysicsImpostor):void {
  37. if (!this._scene) {
  38. return;
  39. }
  40. for (var i = 0; i < this._numMeshes; i++){
  41. if(this._impostors[i] == impostor){
  42. return;
  43. }
  44. }
  45. var debugMesh = this._getDebugMesh(impostor, this._scene);
  46. if(debugMesh){
  47. this._impostors[this._numMeshes] = impostor;
  48. this._meshes[this._numMeshes] = debugMesh;
  49. if(this._numMeshes === 0){
  50. this._renderFunction = this._updateDebugMeshes.bind(this);
  51. this._scene.registerBeforeRender(this._renderFunction);
  52. }
  53. this._numMeshes++;
  54. }
  55. }
  56. public hideImpostor(impostor: Nullable<PhysicsImpostor>){
  57. if (!impostor || !this._scene) {
  58. return;
  59. }
  60. var removed = false;
  61. for (var i = 0; i < this._numMeshes; i++){
  62. if(this._impostors[i] == impostor){
  63. let mesh = this._meshes[i];
  64. if (!mesh) {
  65. continue;
  66. }
  67. this._scene.removeMesh(mesh);
  68. mesh.dispose();
  69. this._numMeshes--;
  70. if(this._numMeshes > 0){
  71. this._meshes[i] = this._meshes[this._numMeshes];
  72. this._impostors[i] = this._impostors[this._numMeshes];
  73. this._meshes[this._numMeshes] = null;
  74. this._impostors[this._numMeshes] = null;
  75. }else{
  76. this._meshes[0] = null;
  77. this._impostors[0] = null;
  78. }
  79. removed = true;
  80. break;
  81. }
  82. }
  83. if(removed && this._numMeshes === 0){
  84. this._scene.unregisterBeforeRender(this._renderFunction);
  85. }
  86. }
  87. private _getDebugMaterial(scene:Scene):Material{
  88. if(!this._debugMaterial){
  89. this._debugMaterial = new StandardMaterial('', scene);
  90. this._debugMaterial.wireframe = true;
  91. }
  92. return this._debugMaterial;
  93. }
  94. private _getDebugBoxMesh(scene:Scene):AbstractMesh{
  95. if(!this._debugBoxMesh){
  96. this._debugBoxMesh = MeshBuilder.CreateBox('physicsBodyBoxViewMesh', { size: 1 }, scene);
  97. this._debugBoxMesh.renderingGroupId = 1;
  98. this._debugBoxMesh.rotationQuaternion = Quaternion.Identity();
  99. this._debugBoxMesh.material = this._getDebugMaterial(scene);
  100. scene.removeMesh(this._debugBoxMesh);
  101. }
  102. return this._debugBoxMesh.createInstance('physicsBodyBoxViewInstance');
  103. }
  104. private _getDebugSphereMesh(scene:Scene):AbstractMesh{
  105. if(!this._debugSphereMesh){
  106. this._debugSphereMesh = MeshBuilder.CreateSphere('physicsBodySphereViewMesh', { diameter: 1 }, scene);
  107. this._debugSphereMesh.renderingGroupId = 1;
  108. this._debugSphereMesh.rotationQuaternion = Quaternion.Identity();
  109. this._debugSphereMesh.material = this._getDebugMaterial(scene);
  110. scene.removeMesh(this._debugSphereMesh);
  111. }
  112. return this._debugSphereMesh.createInstance('physicsBodyBoxViewInstance');
  113. }
  114. private _getDebugMesh(impostor:PhysicsImpostor, scene:Scene): Nullable<AbstractMesh> {
  115. var mesh: Nullable<AbstractMesh> = null;
  116. if (impostor.type == PhysicsImpostor.BoxImpostor) {
  117. mesh = this._getDebugBoxMesh(scene);
  118. impostor.getBoxSizeToRef(mesh.scaling);
  119. } else if(impostor.type == PhysicsImpostor.SphereImpostor){
  120. mesh = this._getDebugSphereMesh(scene);
  121. var radius = impostor.getRadius();
  122. mesh.scaling.x = radius * 2;
  123. mesh.scaling.y = radius * 2;
  124. mesh.scaling.z = radius * 2;
  125. }
  126. return mesh;
  127. }
  128. public dispose(){
  129. for (var i = 0; i < this._numMeshes; i++){
  130. this.hideImpostor(this._impostors[i]);
  131. }
  132. if(this._debugBoxMesh){
  133. this._debugBoxMesh.dispose();
  134. }
  135. if(this._debugSphereMesh){
  136. this._debugSphereMesh.dispose();
  137. }
  138. if(this._debugMaterial){
  139. this._debugMaterial.dispose();
  140. }
  141. this._impostors.length = 0;
  142. this._scene = null;
  143. this._physicsEnginePlugin = null;
  144. }
  145. }
  146. }