/// module BABYLON { class GRIDMaterialDefines extends MaterialDefines { public TRANSPARENT = false; constructor() { super(); this._keys = Object.keys(this); } } /** * The grid materials allows you to wrap any shape with a grid. * Colors are customizable. */ export class GridMaterial extends BABYLON.Material { /** * Main color of the grid (e.g. between lines) */ @serializeAsColor3() public mainColor = Color3.White(); /** * Color of the grid lines. */ @serializeAsColor3() public lineColor = Color3.Black(); /** * The scale of the grid compared to unit. */ @serialize() public gridRatio = 1.0; /** * The frequency of thicker lines. */ @serialize() public majorUnitFrequency = 10; /** * The visibility of minor units in the grid. */ @serialize() public minorUnitVisibility = 0.33; /** * The grid opacity outside of the lines. */ @serialize() public opacity = 1.0; private _gridControl: Vector4 = new Vector4(this.gridRatio, this.majorUnitFrequency, this.minorUnitVisibility, this.opacity); private _renderId: number; private _defines = new GRIDMaterialDefines(); private _cachedDefines: GRIDMaterialDefines = new GRIDMaterialDefines(); /** * constructor * @param name The name given to the material in order to identify it afterwards. * @param scene The scene the material is used in. */ constructor(name: string, scene: Scene) { super(name, scene); // Forces cache to be different on first creation. this._cachedDefines.TRANSPARENT = true; } /** * Returns wehter or not the grid requires alpha blending. */ public needAlphaBlending(): boolean { return this.opacity < 1.0; } private _checkCache(scene: Scene, mesh?: AbstractMesh, useInstances?: boolean): boolean { if (!mesh) { return true; } if (mesh._materialDefines && mesh._materialDefines.isEqual(this._defines)) { return true; } return false; } public isReady(mesh?: AbstractMesh, useInstances?: boolean): boolean { if (this.checkReadyOnlyOnce) { if (this._wasPreviouslyReady) { return true; } } var scene = this.getScene(); if (!this.checkReadyOnEveryCall) { if (this._renderId === scene.getRenderId()) { if (this._checkCache(scene, mesh, useInstances)) { return true; } } } var engine = scene.getEngine(); var needNormals = true; this._defines.reset(); if (this.opacity < 1.0) { this._defines.TRANSPARENT = true; } // Get correct effect if (!this._defines.isEqual(this._cachedDefines)) { this._defines.cloneTo(this._cachedDefines); scene.resetCachedMaterial(); // Attributes var attribs = [VertexBuffer.PositionKind, VertexBuffer.NormalKind]; // Effect var shaderName = scene.getEngine().getCaps().standardDerivatives ? "grid" : "legacygrid"; // Defines var join = this._defines.toString(); this._effect = scene.getEngine().createEffect(shaderName, attribs, ["worldViewProjection", "mainColor", "lineColor", "gridControl"], [], join, null, this.onCompiled, this.onError); } if (!this._effect.isReady()) { return false; } this._renderId = scene.getRenderId(); this._wasPreviouslyReady = true; return true; } public bindOnlyWorldMatrix(world: Matrix): void { var scene = this.getScene(); this._effect.setMatrix("worldViewProjection", world.multiply(scene.getTransformMatrix())); } public bind(world: Matrix, mesh?: Mesh): void { var scene = this.getScene(); // Matrices this.bindOnlyWorldMatrix(world); // Uniforms if (scene.getCachedMaterial() !== (this)) { this._effect.setColor3("mainColor", this.mainColor); this._effect.setColor3("lineColor", this.lineColor); this._gridControl.x = this.gridRatio; this._gridControl.y = Math.round(this.majorUnitFrequency); this._gridControl.z = this.minorUnitVisibility; this._gridControl.w = this.opacity; this._effect.setVector4("gridControl", this._gridControl); } super.bind(world, mesh); } public dispose(forceDisposeEffect?: boolean): void { super.dispose(forceDisposeEffect); } public clone(name: string): GridMaterial { return SerializationHelper.Clone(() => new GridMaterial(name, this.getScene()), this); } public serialize(): any { var serializationObject = SerializationHelper.Serialize(this); serializationObject.customType = "BABYLON.GridMaterial"; return serializationObject; } public static Parse(source: any, scene: Scene, rootUrl: string): GridMaterial { return SerializationHelper.Parse(() => new GridMaterial(source.name, scene), source, scene, rootUrl); } } }