|
@@ -1,17 +1,100 @@
|
|
module BABYLON {
|
|
module BABYLON {
|
|
- export class BoundingBoxRenderer {
|
|
|
|
|
|
+ export interface Scene {
|
|
|
|
+ /** @hidden (Backing field) */
|
|
|
|
+ _boundingBoxRenderer: BoundingBoxRenderer;
|
|
|
|
+
|
|
|
|
+ /** @hidden (Backing field) */
|
|
|
|
+ _forceShowBoundingBoxes: boolean;
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Gets or sets a boolean indicating if all bounding boxes must be rendered
|
|
|
|
+ */
|
|
|
|
+ forceShowBoundingBoxes: boolean;
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Gets the bounding box renderer associated with the scene
|
|
|
|
+ * @returns a BoundingBoxRenderer
|
|
|
|
+ */
|
|
|
|
+ getBoundingBoxRenderer(): BoundingBoxRenderer;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ Object.defineProperty(Scene.prototype, "forceShowBoundingBoxes", {
|
|
|
|
+ get: function (this:Scene) {
|
|
|
|
+ return this._forceShowBoundingBoxes || false;
|
|
|
|
+ },
|
|
|
|
+ set: function (this:Scene, value: boolean) {
|
|
|
|
+ this._forceShowBoundingBoxes = value;
|
|
|
|
+ // Lazyly creates a BB renderer if needed.
|
|
|
|
+ if (value) {
|
|
|
|
+ this.getBoundingBoxRenderer();
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ enumerable: true,
|
|
|
|
+ configurable: true
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ Scene.prototype.getBoundingBoxRenderer = function(): BoundingBoxRenderer {
|
|
|
|
+
|
|
|
|
+ if (!this._boundingBoxRenderer) {
|
|
|
|
+ this._boundingBoxRenderer = new BoundingBoxRenderer(this);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return this._boundingBoxRenderer;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ export class BoundingBoxRenderer implements ISceneComponent {
|
|
|
|
+ /**
|
|
|
|
+ * The component name helpfull to identify the component in the list of scene components.
|
|
|
|
+ */
|
|
|
|
+ public readonly name = SceneComponentConstants.NAME_BOUNDINGBOXRENDERER;
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * The scene the component belongs to.
|
|
|
|
+ */
|
|
|
|
+ public scene: Scene;
|
|
|
|
+
|
|
public frontColor = new Color3(1, 1, 1);
|
|
public frontColor = new Color3(1, 1, 1);
|
|
public backColor = new Color3(0.1, 0.1, 0.1);
|
|
public backColor = new Color3(0.1, 0.1, 0.1);
|
|
public showBackLines = true;
|
|
public showBackLines = true;
|
|
public renderList = new SmartArray<BoundingBox>(32);
|
|
public renderList = new SmartArray<BoundingBox>(32);
|
|
|
|
|
|
- private _scene: Scene;
|
|
|
|
private _colorShader: ShaderMaterial;
|
|
private _colorShader: ShaderMaterial;
|
|
private _vertexBuffers: { [key: string]: Nullable<VertexBuffer> } = {};
|
|
private _vertexBuffers: { [key: string]: Nullable<VertexBuffer> } = {};
|
|
private _indexBuffer: WebGLBuffer;
|
|
private _indexBuffer: WebGLBuffer;
|
|
|
|
|
|
constructor(scene: Scene) {
|
|
constructor(scene: Scene) {
|
|
- this._scene = scene;
|
|
|
|
|
|
+ this.scene = scene;
|
|
|
|
+ scene._addComponent(this);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Registers the component in a given scene
|
|
|
|
+ */
|
|
|
|
+ public register(): void {
|
|
|
|
+ this.scene._beforeEvaluateActiveMeshStage.registerStep(SceneComponentConstants.STEP_BEFOREEVALUATEACTIVEMESH_BOUNDINGBOXRENDERER, this, this.reset);
|
|
|
|
+
|
|
|
|
+ this.scene._activeMeshStage.registerStep(SceneComponentConstants.STEP_ACTIVEMESH_BOUNDINGBOXRENDERER, this, this._activeMesh);
|
|
|
|
+
|
|
|
|
+ this.scene._evaluateSubMeshStage.registerStep(SceneComponentConstants.STEP_EVALUATESUBMESH_BOUNDINGBOXRENDERER, this, this._evaluateSubMesh);
|
|
|
|
+
|
|
|
|
+ this.scene._afterCameraDrawStage.registerStep(SceneComponentConstants.STEP_AFTERCAMERADRAW_BOUNDINGBOXRENDERER, this, this.render);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private _evaluateSubMesh(mesh: AbstractMesh, subMesh: SubMesh): void {
|
|
|
|
+ if (mesh.showSubMeshesBoundingBox) {
|
|
|
|
+ const boundingInfo = subMesh.getBoundingInfo();
|
|
|
|
+ if (boundingInfo !== null && boundingInfo !== undefined) {
|
|
|
|
+ this.renderList.push(boundingInfo.boundingBox);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private _activeMesh(sourceMesh: AbstractMesh, mesh: AbstractMesh): void {
|
|
|
|
+ if (sourceMesh.showBoundingBox || this.scene.forceShowBoundingBoxes) {
|
|
|
|
+ let boundingInfo = sourceMesh.getBoundingInfo();
|
|
|
|
+
|
|
|
|
+ this.renderList.push(boundingInfo.boundingBox);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
private _prepareRessources(): void {
|
|
private _prepareRessources(): void {
|
|
@@ -19,25 +102,29 @@
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
- this._colorShader = new ShaderMaterial("colorShader", this._scene, "color",
|
|
|
|
|
|
+ this._colorShader = new ShaderMaterial("colorShader", this.scene, "color",
|
|
{
|
|
{
|
|
attributes: [VertexBuffer.PositionKind],
|
|
attributes: [VertexBuffer.PositionKind],
|
|
uniforms: ["world", "viewProjection", "color"]
|
|
uniforms: ["world", "viewProjection", "color"]
|
|
});
|
|
});
|
|
|
|
|
|
|
|
|
|
- var engine = this._scene.getEngine();
|
|
|
|
|
|
+ var engine = this.scene.getEngine();
|
|
var boxdata = VertexData.CreateBox({ size: 1.0 });
|
|
var boxdata = VertexData.CreateBox({ size: 1.0 });
|
|
this._vertexBuffers[VertexBuffer.PositionKind] = new VertexBuffer(engine, <FloatArray>boxdata.positions, VertexBuffer.PositionKind, false);
|
|
this._vertexBuffers[VertexBuffer.PositionKind] = new VertexBuffer(engine, <FloatArray>boxdata.positions, VertexBuffer.PositionKind, false);
|
|
this._createIndexBuffer();
|
|
this._createIndexBuffer();
|
|
}
|
|
}
|
|
|
|
|
|
private _createIndexBuffer(): void {
|
|
private _createIndexBuffer(): void {
|
|
- var engine = this._scene.getEngine();
|
|
|
|
|
|
+ var engine = this.scene.getEngine();
|
|
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]);
|
|
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]);
|
|
}
|
|
}
|
|
|
|
|
|
- public _rebuild(): void {
|
|
|
|
|
|
+ /**
|
|
|
|
+ * Rebuilds the elements related to this component in case of
|
|
|
|
+ * context lost for instance.
|
|
|
|
+ */
|
|
|
|
+ public rebuild(): void {
|
|
let vb = this._vertexBuffers[VertexBuffer.PositionKind];
|
|
let vb = this._vertexBuffers[VertexBuffer.PositionKind];
|
|
if (vb) {
|
|
if (vb) {
|
|
vb._rebuild();
|
|
vb._rebuild();
|
|
@@ -60,7 +147,7 @@
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
- var engine = this._scene.getEngine();
|
|
|
|
|
|
+ var engine = this.scene.getEngine();
|
|
engine.setDepthWrite(false);
|
|
engine.setDepthWrite(false);
|
|
this._colorShader._preBind();
|
|
this._colorShader._preBind();
|
|
for (var boundingBoxIndex = 0; boundingBoxIndex < this.renderList.length; boundingBoxIndex++) {
|
|
for (var boundingBoxIndex = 0; boundingBoxIndex < this.renderList.length; boundingBoxIndex++) {
|
|
@@ -80,7 +167,7 @@
|
|
if (this.showBackLines) {
|
|
if (this.showBackLines) {
|
|
// Back
|
|
// Back
|
|
engine.setDepthFunctionToGreaterOrEqual();
|
|
engine.setDepthFunctionToGreaterOrEqual();
|
|
- this._scene.resetCachedMaterial();
|
|
|
|
|
|
+ this.scene.resetCachedMaterial();
|
|
this._colorShader.setColor4("color", this.backColor.toColor4());
|
|
this._colorShader.setColor4("color", this.backColor.toColor4());
|
|
this._colorShader.bind(worldMatrix);
|
|
this._colorShader.bind(worldMatrix);
|
|
|
|
|
|
@@ -90,7 +177,7 @@
|
|
|
|
|
|
// Front
|
|
// Front
|
|
engine.setDepthFunctionToLess();
|
|
engine.setDepthFunctionToLess();
|
|
- this._scene.resetCachedMaterial();
|
|
|
|
|
|
+ this.scene.resetCachedMaterial();
|
|
this._colorShader.setColor4("color", this.frontColor.toColor4());
|
|
this._colorShader.setColor4("color", this.frontColor.toColor4());
|
|
this._colorShader.bind(worldMatrix);
|
|
this._colorShader.bind(worldMatrix);
|
|
|
|
|
|
@@ -110,7 +197,7 @@
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
- var engine = this._scene.getEngine();
|
|
|
|
|
|
+ var engine = this.scene.getEngine();
|
|
engine.setDepthWrite(false);
|
|
engine.setDepthWrite(false);
|
|
engine.setColorWrite(false);
|
|
engine.setColorWrite(false);
|
|
this._colorShader._preBind();
|
|
this._colorShader._preBind();
|
|
@@ -128,7 +215,7 @@
|
|
engine.bindBuffers(this._vertexBuffers, this._indexBuffer, <Effect>this._colorShader.getEffect());
|
|
engine.bindBuffers(this._vertexBuffers, this._indexBuffer, <Effect>this._colorShader.getEffect());
|
|
|
|
|
|
engine.setDepthFunctionToLess();
|
|
engine.setDepthFunctionToLess();
|
|
- this._scene.resetCachedMaterial();
|
|
|
|
|
|
+ this.scene.resetCachedMaterial();
|
|
this._colorShader.bind(worldMatrix);
|
|
this._colorShader.bind(worldMatrix);
|
|
|
|
|
|
engine.drawElementsType(Material.LineListDrawMode, 0, 24);
|
|
engine.drawElementsType(Material.LineListDrawMode, 0, 24);
|
|
@@ -153,7 +240,7 @@
|
|
buffer.dispose();
|
|
buffer.dispose();
|
|
this._vertexBuffers[VertexBuffer.PositionKind] = null;
|
|
this._vertexBuffers[VertexBuffer.PositionKind] = null;
|
|
}
|
|
}
|
|
- this._scene.getEngine()._releaseBuffer(this._indexBuffer);
|
|
|
|
|
|
+ this.scene.getEngine()._releaseBuffer(this._indexBuffer);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|