|
@@ -0,0 +1,194 @@
|
|
|
+/// <reference path="../../../dist/preview release/babylon.d.ts"/>
|
|
|
+
|
|
|
+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() !== (<BABYLON.Material>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 {
|
|
|
+ return SerializationHelper.Serialize(this);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static Parse(source: any, scene: Scene, rootUrl: string): GridMaterial {
|
|
|
+ return SerializationHelper.Parse(() => new GridMaterial(source.name, scene), source, scene, rootUrl);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|