babylon.boundingBoxRenderer.ts 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  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]: Nullable<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, <FloatArray>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. let vb = this._vertexBuffers[VertexBuffer.PositionKind];
  34. if (vb) {
  35. vb._rebuild();
  36. }
  37. this._createIndexBuffer();
  38. }
  39. public reset(): void {
  40. this.renderList.reset();
  41. }
  42. public render(): void {
  43. if (this.renderList.length === 0) {
  44. return;
  45. }
  46. this._prepareRessources();
  47. if (!this._colorShader.isReady()) {
  48. return;
  49. }
  50. var engine = this._scene.getEngine();
  51. engine.setDepthWrite(false);
  52. this._colorShader._preBind();
  53. for (var boundingBoxIndex = 0; boundingBoxIndex < this.renderList.length; boundingBoxIndex++) {
  54. var boundingBox = this.renderList.data[boundingBoxIndex];
  55. var min = boundingBox.minimum;
  56. var max = boundingBox.maximum;
  57. var diff = max.subtract(min);
  58. var median = min.add(diff.scale(0.5));
  59. var worldMatrix = Matrix.Scaling(diff.x, diff.y, diff.z)
  60. .multiply(Matrix.Translation(median.x, median.y, median.z))
  61. .multiply(boundingBox.getWorldMatrix());
  62. // VBOs
  63. engine.bindBuffers(this._vertexBuffers, this._indexBuffer, <Effect>this._colorShader.getEffect());
  64. if (this.showBackLines) {
  65. // Back
  66. engine.setDepthFunctionToGreaterOrEqual();
  67. this._scene.resetCachedMaterial();
  68. this._colorShader.setColor4("color", this.backColor.toColor4());
  69. this._colorShader.bind(worldMatrix);
  70. // Draw order
  71. engine.draw(false, 0, 24);
  72. }
  73. // Front
  74. engine.setDepthFunctionToLess();
  75. this._scene.resetCachedMaterial();
  76. this._colorShader.setColor4("color", this.frontColor.toColor4());
  77. this._colorShader.bind(worldMatrix);
  78. // Draw order
  79. engine.draw(false, 0, 24);
  80. }
  81. this._colorShader.unbind();
  82. engine.setDepthFunctionToLessOrEqual();
  83. engine.setDepthWrite(true);
  84. }
  85. public renderOcclusionBoundingBox(mesh: AbstractMesh): void {
  86. this._prepareRessources();
  87. if (!this._colorShader.isReady() || !mesh._boundingInfo) {
  88. return;
  89. }
  90. var engine = this._scene.getEngine();
  91. engine.setDepthWrite(false);
  92. engine.setColorWrite(false);
  93. this._colorShader._preBind();
  94. var boundingBox = mesh._boundingInfo.boundingBox;
  95. var min = boundingBox.minimum;
  96. var max = boundingBox.maximum;
  97. var diff = max.subtract(min);
  98. var median = min.add(diff.scale(0.5));
  99. var worldMatrix = Matrix.Scaling(diff.x, diff.y, diff.z)
  100. .multiply(Matrix.Translation(median.x, median.y, median.z))
  101. .multiply(boundingBox.getWorldMatrix());
  102. engine.bindBuffers(this._vertexBuffers, this._indexBuffer, <Effect>this._colorShader.getEffect());
  103. engine.setDepthFunctionToLess();
  104. this._scene.resetCachedMaterial();
  105. this._colorShader.bind(worldMatrix);
  106. engine.draw(false, 0, 24);
  107. this._colorShader.unbind();
  108. engine.setDepthFunctionToLessOrEqual();
  109. engine.setDepthWrite(true);
  110. engine.setColorWrite(true);
  111. }
  112. public dispose(): void {
  113. if (!this._colorShader) {
  114. return;
  115. }
  116. this.renderList.dispose();
  117. this._colorShader.dispose();
  118. var buffer = this._vertexBuffers[VertexBuffer.PositionKind];
  119. if (buffer) {
  120. buffer.dispose();
  121. this._vertexBuffers[VertexBuffer.PositionKind] = null;
  122. }
  123. this._scene.getEngine()._releaseBuffer(this._indexBuffer);
  124. }
  125. }
  126. }