babylon.boundingBoxRenderer.ts 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. module BABYLON {
  2. export class BoundingBoxRenderer {
  3. public frontColor = new Color3(1, 1, 1);
  4. public backColor = new Color3(0.1, 0.1, 0.1);
  5. public showBackLines = true;
  6. public renderList = new SmartArray<BoundingBox>(32);
  7. private _scene: Scene;
  8. private _colorShader: ShaderMaterial;
  9. private _vertexBuffers: { [key: string]: VertexBuffer } = {};
  10. private _indexBuffer: WebGLBuffer;
  11. constructor(scene: Scene) {
  12. this._scene = scene;
  13. }
  14. private _prepareRessources(): void {
  15. if (this._colorShader) {
  16. return;
  17. }
  18. this._colorShader = new ShaderMaterial("colorShader", this._scene, "color",
  19. {
  20. attributes: [VertexBuffer.PositionKind],
  21. uniforms: ["world", "viewProjection", "color"]
  22. });
  23. var engine = this._scene.getEngine();
  24. var boxdata = VertexData.CreateBox({ size: 1.0 });
  25. this._vertexBuffers[VertexBuffer.PositionKind] = new VertexBuffer(engine, boxdata.positions, VertexBuffer.PositionKind, false);
  26. this._createIndexBuffer();
  27. }
  28. private _createIndexBuffer(): void {
  29. var engine = this._scene.getEngine();
  30. this._indexBuffer = engine.createIndexBuffer([0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 7, 1, 6, 2, 5, 3, 4]);
  31. }
  32. public _rebuild(): void {
  33. this._vertexBuffers[VertexBuffer.PositionKind]._rebuild();
  34. this._createIndexBuffer();
  35. }
  36. public reset(): void {
  37. this.renderList.reset();
  38. }
  39. public render(): void {
  40. if (this.renderList.length === 0) {
  41. return;
  42. }
  43. this._prepareRessources();
  44. if (!this._colorShader.isReady()) {
  45. return;
  46. }
  47. var engine = this._scene.getEngine();
  48. engine.setDepthWrite(false);
  49. this._colorShader._preBind();
  50. for (var boundingBoxIndex = 0; boundingBoxIndex < this.renderList.length; boundingBoxIndex++) {
  51. var boundingBox = this.renderList.data[boundingBoxIndex];
  52. var min = boundingBox.minimum;
  53. var max = boundingBox.maximum;
  54. var diff = max.subtract(min);
  55. var median = min.add(diff.scale(0.5));
  56. var worldMatrix = Matrix.Scaling(diff.x, diff.y, diff.z)
  57. .multiply(Matrix.Translation(median.x, median.y, median.z))
  58. .multiply(boundingBox.getWorldMatrix());
  59. // VBOs
  60. engine.bindBuffers(this._vertexBuffers, this._indexBuffer, this._colorShader.getEffect());
  61. if (this.showBackLines) {
  62. // Back
  63. engine.setDepthFunctionToGreaterOrEqual();
  64. this._scene.resetCachedMaterial();
  65. this._colorShader.setColor4("color", this.backColor.toColor4());
  66. this._colorShader.bind(worldMatrix);
  67. // Draw order
  68. engine.draw(false, 0, 24);
  69. }
  70. // Front
  71. engine.setDepthFunctionToLess();
  72. this._scene.resetCachedMaterial();
  73. this._colorShader.setColor4("color", this.frontColor.toColor4());
  74. this._colorShader.bind(worldMatrix);
  75. // Draw order
  76. engine.draw(false, 0, 24);
  77. }
  78. this._colorShader.unbind();
  79. engine.setDepthFunctionToLessOrEqual();
  80. engine.setDepthWrite(true);
  81. }
  82. public renderOcclusionBoundingBox(mesh: AbstractMesh): void {
  83. this._prepareRessources();
  84. if (!this._colorShader.isReady()) {
  85. return;
  86. }
  87. var engine = this._scene.getEngine();
  88. engine.setDepthWrite(false);
  89. engine.setColorWrite(false);
  90. this._colorShader._preBind();
  91. var boundingBox = mesh._boundingInfo.boundingBox;
  92. var min = boundingBox.minimum;
  93. var max = boundingBox.maximum;
  94. var diff = max.subtract(min);
  95. var median = min.add(diff.scale(0.5));
  96. var worldMatrix = Matrix.Scaling(diff.x, diff.y, diff.z)
  97. .multiply(Matrix.Translation(median.x, median.y, median.z))
  98. .multiply(boundingBox.getWorldMatrix());
  99. engine.bindBuffers(this._vertexBuffers, this._indexBuffer, this._colorShader.getEffect());
  100. engine.setDepthFunctionToLess();
  101. this._scene.resetCachedMaterial();
  102. this._colorShader.bind(worldMatrix);
  103. engine.draw(false, 0, 24);
  104. this._colorShader.unbind();
  105. engine.setDepthFunctionToLessOrEqual();
  106. engine.setDepthWrite(true);
  107. engine.setColorWrite(true);
  108. }
  109. public dispose(): void {
  110. if (!this._colorShader) {
  111. return;
  112. }
  113. this.renderList.dispose();
  114. this._colorShader.dispose();
  115. var buffer = this._vertexBuffers[VertexBuffer.PositionKind];
  116. if (buffer) {
  117. buffer.dispose();
  118. this._vertexBuffers[VertexBuffer.PositionKind] = null;
  119. }
  120. this._scene.getEngine()._releaseBuffer(this._indexBuffer);
  121. }
  122. }
  123. }