David Catuhe преди 7 години
родител
ревизия
ab3d4529fa
променени са 6 файла, в които са добавени 183 реда и са изтрити 71 реда
  1. 0 19
      gui/src/3D/charting/IGraph.ts
  2. 51 46
      gui/src/3D/charting/barGraph.ts
  3. 43 0
      gui/src/3D/charting/chart.ts
  4. 82 0
      gui/src/3D/charting/glassBarGraph.ts
  5. 3 2
      gui/src/3D/charting/index.ts
  6. 4 4
      src/Mesh/babylon.mesh.ts

+ 0 - 19
gui/src/3D/charting/IGraph.ts

@@ -1,19 +0,0 @@
-import { DataSeries } from "./dataSeries";
-import { TransformNode } from "babylonjs";
-
-export interface IGraph {
-    /** Gets the root node associated with this graph */
-    rootNode: TransformNode;
-
-    /** Gets or sets the data source used by the graph */
-    dataSource: DataSeries;
-
-    /** Gets or sets the name of the graph */
-    name: string;
-
-    /** 
-     * Force the graph to redraw itself
-     * @returns the current graph 
-     */
-    refresh(): IGraph;
-}

+ 51 - 46
gui/src/3D/charting/barGraph.ts

@@ -1,40 +1,16 @@
-import { DataSeries } from "./dataSeries";
-import { Nullable, TransformNode, Scene, Mesh, Observable, PBRMaterial, CubeTexture } from "babylonjs";
+import { Nullable, Scene, Mesh, Observable, StandardMaterial, Material, Color3, Animation, Animatable } from "babylonjs";
+import { Chart } from ".";
 
 /** Class used to render bar graphs */
-export class BarGraph {
-    private _dataSource: Nullable<DataSeries>;
-    private _rootNode: TransformNode;
+export class BarGraph extends Chart {
     private _margin = 1;
     private _barWidth = 2
     private _maxBarHeight = 10;
-    private _defaultMaterial: PBRMaterial;
+    private _defaultMaterial: Nullable<Material>;
+    protected _ownDefaultMaterial = false;
 
     public onElementCreated = new Observable<Mesh>();
 
-    /** Gets or sets the data source used by the graph */
-    public get dataSource(): Nullable<DataSeries> {
-        return this._dataSource;
-    }
-
-    public set dataSource(value: Nullable<DataSeries>) {
-        if (this._dataSource === value) {
-            return;
-        }
-
-        this._dataSource = value;
-
-        this.refresh();
-    }
-
-    /** Gets the root node associated with this graph */
-    public get rootNode(): TransformNode {
-        return this._rootNode;
-    }
-
-    /** Gets or sets the name of the graph */
-    public name: string; 
-
     /** Gets or sets the margin between bars */
     public get margin(): number {
         return this._margin;
@@ -81,11 +57,11 @@ export class BarGraph {
     }
 
     /** Gets or sets the material used by bar meshes */
-    public get defaultMaterial(): PBRMaterial {
+    public get defaultMaterial(): Nullable<Material> {
         return this._defaultMaterial;
     }
 
-    public set defaultMaterial(value: PBRMaterial) {
+    public set defaultMaterial(value: Nullable<Material>) {
         if (this._defaultMaterial === value) {
             return;
         }
@@ -100,13 +76,36 @@ export class BarGraph {
      * @param name defines the name of the graph
      */
     constructor(name: string, scene?: Scene) {
-        this.name = name;
-        this._rootNode = new TransformNode(name, scene);
+        super(name, scene);
+    }
+
+    protected _createDefaultMaterial(scene: Scene): Material {
+        var result = new StandardMaterial("Plastic", scene);
+
+        result.diffuseColor = this._dataSource!.color;
+        result.specularColor = Color3.Black();
+
+        return result;
+    }
+
+    /**
+     * Children class can override this function to provide a new mesh (as long as it stays inside a 1x1x1 box)
+     * @param name defines the mesh name
+     * @param scene defines the hosting scene
+     * @returns a new mesh used to represent the current bar
+     */
+    protected _createBarMesh(name: string, scene: Scene): Mesh {
+        var box = Mesh.CreateBox(name, 1, scene);
+        box.setPivotPoint(new BABYLON.Vector3(0, -0.5, 0));
+
+        return box;
     }
 
     /** Force the graph to redraw itself */
     public refresh(): BarGraph {
-        // TODO: clean current meshes
+        // Cleanup
+        var descendants = this._rootNode.getDescendants();
+        descendants.forEach(n => n.dispose());
 
         if (!this._dataSource) {
             return this;
@@ -116,11 +115,7 @@ export class BarGraph {
 
         // Default material
         if (!this._defaultMaterial) {
-            this._defaultMaterial = new BABYLON.PBRMaterial("plastic", scene);
-            this._defaultMaterial.microSurface = 0.96;
-            this._defaultMaterial.alpha = 0.8;
-            this._defaultMaterial.albedoColor = this._dataSource.color;
-            this._defaultMaterial.reflectivityColor = new BABYLON.Color3(0.003, 0.003, 0.003);
+            this._defaultMaterial = this._createDefaultMaterial(scene);
         }
 
         // Scan data
@@ -143,16 +138,17 @@ export class BarGraph {
         let index = 0;
         this._dataSource.data.forEach(entry => {
 
-            var box = Mesh.CreateBox(this.name + "_box_" + index++, 1, scene);
-            box.setPivotPoint(new BABYLON.Vector3(0, -0.5, 0));
+            var barMesh = this._createBarMesh(this.name + "_box_" + index++, scene);
+
+            barMesh.parent = this._rootNode;
+            barMesh.position.x += left;
+            barMesh.scaling.set(this.barWidth, 0, this._barWidth);
 
-            box.parent = this._rootNode;
-            box.position.x += left;
-            box.scaling.set(this.barWidth, entry.value * ratio, this._barWidth);
+            Animation.CreateAndStartAnimation("entryScale", barMesh, "scaling.y", 30, 30, 0, entry.value * ratio, 0);
 
-            box.material = this._defaultMaterial;
+            barMesh.material = this._defaultMaterial;
 
-            this.onElementCreated.notifyObservers(box);
+            this.onElementCreated.notifyObservers(barMesh);
 
             left += this.barWidth + this.margin;
         });
@@ -160,4 +156,13 @@ export class BarGraph {
 
         return this;
     }
+
+    public dispose() {
+        if (this._ownDefaultMaterial && this._defaultMaterial) {
+            this._defaultMaterial.dispose();
+            this._defaultMaterial = null;
+        }
+
+        this._rootNode.dispose();
+    }
 }

+ 43 - 0
gui/src/3D/charting/chart.ts

@@ -0,0 +1,43 @@
+import { DataSeries } from ".";
+import { Nullable, TransformNode, Scene } from "babylonjs";
+
+/** base class for all chart controls*/
+export abstract class Chart {
+    protected _dataSource: Nullable<DataSeries>;
+    protected _rootNode: TransformNode;
+
+    /** Gets or sets the data source used by the graph */
+    public get dataSource(): Nullable<DataSeries> {
+        return this._dataSource;
+    }
+
+    public set dataSource(value: Nullable<DataSeries>) {
+        if (this._dataSource === value) {
+            return;
+        }
+
+        this._dataSource = value;
+
+        this.refresh();
+    }
+
+    /** Gets the root node associated with this graph */
+    public get rootNode(): TransformNode {
+        return this._rootNode;
+    }
+
+    /** Gets or sets the name of the graph */
+    public name: string; 
+
+    /**
+     * Creates a new BarGraph
+     * @param name defines the name of the graph
+     */
+    constructor(name: string, scene?: Scene) {
+        this.name = name;
+        this._rootNode = new TransformNode(name, scene);
+    }
+
+    /** Force the graph to redraw itself */
+    public abstract refresh(): Chart;
+}

+ 82 - 0
gui/src/3D/charting/glassBarGraph.ts

@@ -0,0 +1,82 @@
+import { BarGraph } from "./barGraph";
+import { Scene, Material, PBRMaterial, Mesh, Vector3 } from "babylonjs";
+
+/** Class used to render bar graphs */
+export class GlassBarGraph extends BarGraph {
+    private _innerMaterial: PBRMaterial;
+
+    /**
+     * Creates a new GlassBarGraph
+     * @param name defines the name of the graph
+     */
+    constructor(name: string, scene?: Scene) {
+        super(name, scene);
+
+        this.onElementCreated.add(mesh => {
+            // Clone the mesh
+            var innerMesh = mesh.clone("Inner", mesh);
+            innerMesh.material = this._innerMaterial;
+
+            innerMesh.scaling = new Vector3(1, 1, 1);
+            innerMesh.position = Vector3.Zero();
+
+            mesh.alphaIndex = 0;
+            innerMesh.alphaIndex = 1;
+        });
+    }
+
+    protected _createBarMesh(name: string, scene: Scene): Mesh {
+        var path = [
+            new BABYLON.Vector3(0, 0, 0),
+            new BABYLON.Vector3(0, 1.0, 0.0),
+        ];        
+
+        var tube = BABYLON.MeshBuilder.CreateTube("tube", {
+            path: path, 
+            tessellation:16, 
+            cap: Mesh.CAP_ALL,
+            radius: 0.5}, scene);
+
+        return tube;
+    }    
+
+    protected _createDefaultMaterial(scene: Scene): Material {
+        var result = new PBRMaterial("OuterGlass", scene);
+        const dataSource = this.dataSource;
+        
+        let reflectionTexture = scene.environmentTexture;
+        if (!reflectionTexture) {
+            reflectionTexture = BABYLON.CubeTexture.CreateFromPrefilteredData("https://assets.babylonjs.com/environments/environmentSpecular.env", scene);
+        }
+
+        // Outside material
+        result.alphaMode = BABYLON.Engine.ALPHA_SCREENMODE;
+        result.reflectionTexture = reflectionTexture;
+        result.alpha = 0.0;
+        result.directIntensity = 1.0;
+        result.environmentIntensity = 1.0;
+        result.microSurface = 1;
+        result.useAlphaFresnel = true;
+        result.reflectivityColor = new BABYLON.Color3(0.01, 0.01, 0.01);
+        result.albedoColor = new BABYLON.Color3(0, 0, 0);
+
+        this._innerMaterial = new PBRMaterial("InnerGlass", scene);;
+        this._innerMaterial.alphaMode = BABYLON.Engine.ALPHA_MULTIPLY;
+        this._innerMaterial.alpha = 0;
+        this._innerMaterial.directIntensity = 1.0;
+        this._innerMaterial.environmentIntensity = 1.0;
+        this._innerMaterial.microSurface = 0.0;
+        this._innerMaterial.reflectivityColor = new BABYLON.Color3(0, 0, 0);
+
+        if (dataSource) {
+            this._innerMaterial.albedoColor = dataSource.color;
+        }
+
+        return result;
+    }
+
+    public dispose() {
+        super.dispose();
+        this._innerMaterial.dispose();
+    }
+}

+ 3 - 2
gui/src/3D/charting/index.ts

@@ -1,3 +1,4 @@
 export * from "./dataSeries";
-export * from "./IGraph";
-export * from "./barGraph";
+export * from "./chart";
+export * from "./barGraph";
+export * from "./glassBarGraph";

+ 4 - 4
src/Mesh/babylon.mesh.ts

@@ -2671,7 +2671,7 @@
         /**
          * Creates a ribbon mesh.   
          * Please consider using the same method from the MeshBuilder class instead.   
-         * The ribbon is a parametric shape :  http://doc.babylonjs.com/tutorials/Parametric_Shapes.  It has no predefined shape. Its final shape will depend on the input parameters.    
+         * The ribbon is a parametric shape :  http://doc.babylonjs.com/how_to/parametric_shapes.  It has no predefined shape. Its final shape will depend on the input parameters.    
          *
          * Please read this full tutorial to understand how to design a ribbon : http://doc.babylonjs.com/tutorials/Ribbon_Tutorial    
          * The parameter `pathArray` is a required array of paths, what are each an array of successive Vector3. The pathArray parameter depicts the ribbon geometry.    
@@ -2916,7 +2916,7 @@
 
         /**
          * Creates an extruded shape mesh.    
-         * The extrusion is a parametric shape :  http://doc.babylonjs.com/tutorials/Parametric_Shapes.  It has no predefined shape. Its final shape will depend on the input parameters.  
+         * The extrusion is a parametric shape :  http://doc.babylonjs.com/how_to/parametric_shapes.  It has no predefined shape. Its final shape will depend on the input parameters.  
          * Please consider using the same method from the MeshBuilder class instead.    
          *
          * Please read this full tutorial to understand how to design an extruded shape : http://doc.babylonjs.com/how_to/parametric_shapes#extruded-shapes     
@@ -2948,7 +2948,7 @@
         }
         /**
          * Creates an custom extruded shape mesh.    
-         * The custom extrusion is a parametric shape :  http://doc.babylonjs.com/tutorials/Parametric_Shapes.  It has no predefined shape. Its final shape will depend on the input parameters.  
+         * The custom extrusion is a parametric shape :  http://doc.babylonjs.com/how_to/parametric_shapes.  It has no predefined shape. Its final shape will depend on the input parameters.  
          * Please consider using the same method from the MeshBuilder class instead.    
          *
          * Please read this full tutorial to understand how to design a custom extruded shape : http://doc.babylonjs.com/how_to/parametric_shapes#extruded-shapes     
@@ -3113,7 +3113,7 @@
         }
         /**
          * Creates a tube mesh.    
-         * The tube is a parametric shape :  http://doc.babylonjs.com/tutorials/Parametric_Shapes.  It has no predefined shape. Its final shape will depend on the input parameters.    
+         * The tube is a parametric shape :  http://doc.babylonjs.com/how_to/parametric_shapes.  It has no predefined shape. Its final shape will depend on the input parameters.    
          * Please consider using the same method from the MeshBuilder class instead.    
          * The parameter `path` is a required array of successive Vector3. It is the curve used as the axis of the tube.        
          * The parameter `radius` (positive float, default 1) sets the tube radius size.