David Catuhe преди 7 години
родител
ревизия
3c201c7f53

BIN
Playground/textures/mercator.jpg


Файловите разлики са ограничени, защото са твърде много
+ 5183 - 5183
dist/preview release/babylon.d.ts


Файловите разлики са ограничени, защото са твърде много
+ 1 - 1
dist/preview release/babylon.js


Файловите разлики са ограничени, защото са твърде много
+ 2 - 2
dist/preview release/babylon.max.js


Файловите разлики са ограничени, защото са твърде много
+ 2 - 2
dist/preview release/babylon.no-module.max.js


Файловите разлики са ограничени, защото са твърде много
+ 2 - 2
dist/preview release/es6.js


+ 10 - 1
dist/preview release/gui/babylon.gui.d.ts

@@ -2426,6 +2426,8 @@ declare module BABYLON.GUI {
             };
             protected _scene: BABYLON.Scene;
             protected _blockRefresh: boolean;
+            /** BABYLON.Observable raised when a refresh was done */
+            onRefreshObservable: BABYLON.Observable<Chart>;
             /** BABYLON.Observable raised when a new element is created */
             onElementCreatedObservable: BABYLON.Observable<BABYLON.Mesh>;
             /**
@@ -2542,14 +2544,21 @@ declare module BABYLON.GUI {
         * @see http://doc.babylonjs.com/how_to/chart3d#mapgraph
         */
     export class MapGraph extends Chart {
+            /** Gets or sets the radius of each cylinder */
+            cylinderRadius: number;
+            /** Gets or sets the size of the world map (this will define the width) */
+            worldMapSize: number;
             /**
                 * Creates a new MapGraph
                 * @param name defines the name of the graph
                 * @param scene defines the hosting scene
                 */
             constructor(name: string, mapUrl: string, scene?: BABYLON.Nullable<BABYLON.Scene>);
-            protected _createBarMesh(name: string, scene: BABYLON.Scene): BABYLON.Mesh;
+            protected _createCylinderMesh(name: string, scene: BABYLON.Scene): BABYLON.Mesh;
+            protected _createDefaultMaterial(scene: BABYLON.Scene): BABYLON.Material;
             refresh(): MapGraph;
             protected _clean(): void;
+            /** Clean associated resources */
+            dispose(): void;
     }
 }

Файловите разлики са ограничени, защото са твърде много
+ 1 - 1
dist/preview release/gui/babylon.gui.js


Файловите разлики са ограничени, защото са твърде много
+ 1 - 1
dist/preview release/gui/babylon.gui.min.js


Файловите разлики са ограничени, защото са твърде много
+ 1 - 1
dist/preview release/gui/babylon.gui.min.js.map


+ 21 - 3
dist/preview release/gui/babylon.gui.module.d.ts

@@ -2642,6 +2642,8 @@ declare module 'babylonjs-gui/3D/charting/chart' {
             };
             protected _scene: Scene;
             protected _blockRefresh: boolean;
+            /** Observable raised when a refresh was done */
+            onRefreshObservable: Observable<Chart>;
             /** Observable raised when a new element is created */
             onElementCreatedObservable: Observable<Mesh>;
             /**
@@ -2758,21 +2760,28 @@ declare module 'babylonjs-gui/3D/charting/barGraph' {
 
 declare module 'babylonjs-gui/3D/charting/mapGraph' {
     import { Chart } from "babylonjs-gui/3D/charting";
-    import { Scene, Nullable, Mesh } from "babylonjs";
+    import { Scene, Nullable, Mesh, Material } from "babylonjs";
     /**
         * Class used to render bar graphs
         * @see http://doc.babylonjs.com/how_to/chart3d#mapgraph
         */
     export class MapGraph extends Chart {
+            /** Gets or sets the radius of each cylinder */
+            cylinderRadius: number;
+            /** Gets or sets the size of the world map (this will define the width) */
+            worldMapSize: number;
             /**
                 * Creates a new MapGraph
                 * @param name defines the name of the graph
                 * @param scene defines the hosting scene
                 */
             constructor(name: string, mapUrl: string, scene?: Nullable<Scene>);
-            protected _createBarMesh(name: string, scene: Scene): Mesh;
+            protected _createCylinderMesh(name: string, scene: Scene): Mesh;
+            protected _createDefaultMaterial(scene: Scene): Material;
             refresh(): MapGraph;
             protected _clean(): void;
+            /** Clean associated resources */
+            dispose(): void;
     }
 }
 
@@ -5205,6 +5214,8 @@ declare module BABYLON.GUI {
             };
             protected _scene: BABYLON.Scene;
             protected _blockRefresh: boolean;
+            /** BABYLON.Observable raised when a refresh was done */
+            onRefreshObservable: BABYLON.Observable<Chart>;
             /** BABYLON.Observable raised when a new element is created */
             onElementCreatedObservable: BABYLON.Observable<BABYLON.Mesh>;
             /**
@@ -5321,14 +5332,21 @@ declare module BABYLON.GUI {
         * @see http://doc.babylonjs.com/how_to/chart3d#mapgraph
         */
     export class MapGraph extends Chart {
+            /** Gets or sets the radius of each cylinder */
+            cylinderRadius: number;
+            /** Gets or sets the size of the world map (this will define the width) */
+            worldMapSize: number;
             /**
                 * Creates a new MapGraph
                 * @param name defines the name of the graph
                 * @param scene defines the hosting scene
                 */
             constructor(name: string, mapUrl: string, scene?: BABYLON.Nullable<BABYLON.Scene>);
-            protected _createBarMesh(name: string, scene: BABYLON.Scene): BABYLON.Mesh;
+            protected _createCylinderMesh(name: string, scene: BABYLON.Scene): BABYLON.Mesh;
+            protected _createDefaultMaterial(scene: BABYLON.Scene): BABYLON.Material;
             refresh(): MapGraph;
             protected _clean(): void;
+            /** Clean associated resources */
+            dispose(): void;
     }
 }

+ 19 - 5
dist/preview release/viewer/babylon.viewer.d.ts

@@ -168,11 +168,11 @@ declare module BabylonViewer {
                 * Mainly used for help and errors
                 * @param subScreen the name of the subScreen. Those can be defined in the configuration object
                 */
-            showOverlayScreen(subScreen: string): Promise<string> | Promise<Template>;
+            showOverlayScreen(subScreen: string): Promise<Template> | Promise<string>;
             /**
                 * Hide the overlay screen.
                 */
-            hideOverlayScreen(): Promise<string> | Promise<Template>;
+            hideOverlayScreen(): Promise<Template> | Promise<string>;
             /**
                 * show the viewer (in case it was hidden)
                 *
@@ -189,11 +189,11 @@ declare module BabylonViewer {
                 * Show the loading screen.
                 * The loading screen can be configured using the configuration object
                 */
-            showLoadingScreen(): Promise<string> | Promise<Template>;
+            showLoadingScreen(): Promise<Template> | Promise<string>;
             /**
                 * Hide the loading screen
                 */
-            hideLoadingScreen(): Promise<string> | Promise<Template>;
+            hideLoadingScreen(): Promise<Template> | Promise<string>;
             dispose(): void;
             protected _onConfigurationLoaded(configuration: ViewerConfiguration): void;
     }
@@ -916,7 +916,7 @@ declare module BabylonViewer {
       * @param name the name of the custom optimizer configuration
       * @param upgrade set to true if you want to upgrade optimizer and false if you want to degrade
       */
-    export function getCustomOptimizerByName(name: string, upgrade?: boolean): (sceneManager: SceneManager) => boolean;
+    export function getCustomOptimizerByName(name: string, upgrade?: boolean): typeof extendedUpgrade;
     export function registerCustomOptimizer(name: string, optimizer: (sceneManager: SceneManager) => boolean): void;
 }
 declare module BabylonViewer {
@@ -1542,6 +1542,20 @@ declare module BabylonViewer {
     export function addLoaderPlugin(name: string, plugin: ILoaderPlugin): void;
 }
 declare module BabylonViewer {
+    /**
+        * A custom upgrade-oriented function configuration for the scene optimizer.
+        *
+        * @param viewer the viewer to optimize
+        */
+    export function extendedUpgrade(sceneManager: SceneManager): boolean;
+    /**
+        * A custom degrade-oriented function configuration for the scene optimizer.
+        *
+        * @param viewer the viewer to optimize
+        */
+    export function extendedDegrade(sceneManager: SceneManager): boolean;
+}
+declare module BabylonViewer {
 }
 declare module BabylonViewer {
     export interface IEnvironmentMapConfiguration {

Файловите разлики са ограничени, защото са твърде много
+ 1 - 1
dist/preview release/viewer/babylon.viewer.js


Файловите разлики са ограничени, защото са твърде много
+ 1 - 1
dist/preview release/viewer/babylon.viewer.max.js


+ 22 - 5
dist/preview release/viewer/babylon.viewer.module.d.ts

@@ -200,11 +200,11 @@ declare module 'babylonjs-viewer/viewer/defaultViewer' {
                 * Mainly used for help and errors
                 * @param subScreen the name of the subScreen. Those can be defined in the configuration object
                 */
-            showOverlayScreen(subScreen: string): Promise<string> | Promise<Template>;
+            showOverlayScreen(subScreen: string): Promise<Template> | Promise<string>;
             /**
                 * Hide the overlay screen.
                 */
-            hideOverlayScreen(): Promise<string> | Promise<Template>;
+            hideOverlayScreen(): Promise<Template> | Promise<string>;
             /**
                 * show the viewer (in case it was hidden)
                 *
@@ -221,11 +221,11 @@ declare module 'babylonjs-viewer/viewer/defaultViewer' {
                 * Show the loading screen.
                 * The loading screen can be configured using the configuration object
                 */
-            showLoadingScreen(): Promise<string> | Promise<Template>;
+            showLoadingScreen(): Promise<Template> | Promise<string>;
             /**
                 * Hide the loading screen
                 */
-            hideLoadingScreen(): Promise<string> | Promise<Template>;
+            hideLoadingScreen(): Promise<Template> | Promise<string>;
             dispose(): void;
             protected _onConfigurationLoaded(configuration: ViewerConfiguration): void;
     }
@@ -977,13 +977,14 @@ declare module 'babylonjs-viewer/templating/viewerTemplatePlugin' {
 }
 
 declare module 'babylonjs-viewer/optimizer/custom' {
+    import { extendedUpgrade } from "babylonjs-viewer/optimizer/custom/extended";
     import { SceneManager } from "babylonjs-viewer/managers/sceneManager";
     /**
       *
       * @param name the name of the custom optimizer configuration
       * @param upgrade set to true if you want to upgrade optimizer and false if you want to degrade
       */
-    export function getCustomOptimizerByName(name: string, upgrade?: boolean): (sceneManager: SceneManager) => boolean;
+    export function getCustomOptimizerByName(name: string, upgrade?: boolean): typeof extendedUpgrade;
     export function registerCustomOptimizer(name: string, optimizer: (sceneManager: SceneManager) => boolean): void;
 }
 
@@ -1646,6 +1647,22 @@ declare module 'babylonjs-viewer/loader/plugins' {
     export function addLoaderPlugin(name: string, plugin: ILoaderPlugin): void;
 }
 
+declare module 'babylonjs-viewer/optimizer/custom/extended' {
+    import { SceneManager } from 'babylonjs-viewer/managers/sceneManager';
+    /**
+        * A custom upgrade-oriented function configuration for the scene optimizer.
+        *
+        * @param viewer the viewer to optimize
+        */
+    export function extendedUpgrade(sceneManager: SceneManager): boolean;
+    /**
+        * A custom degrade-oriented function configuration for the scene optimizer.
+        *
+        * @param viewer the viewer to optimize
+        */
+    export function extendedDegrade(sceneManager: SceneManager): boolean;
+}
+
 declare module 'babylonjs-viewer/configuration/interfaces' {
     export * from 'babylonjs-viewer/configuration/interfaces/cameraConfiguration';
     export * from 'babylonjs-viewer/configuration/interfaces/colorGradingConfiguration';

+ 1 - 0
dist/preview release/what's new.md

@@ -5,6 +5,7 @@
 - Added new `MixMaterial` to the Materials Library allowing to mix up to 8 textures ([julien-moreau](https://github.com/julien-moreau))
 - Added new `PhotoDome` object to display 360 photos. [Demo](https://www.babylonjs-playground.com/#14KRGG#0) ([SzeyinLee](https://github.com/SzeyinLee))
 - New GUI 3D controls toolset. [Complete doc + demos](http://doc.babylonjs.com/how_to/gui3d) ([Deltakosh](https://github.com/deltakosh))
+- New 3D chart controls. [Complete doc + demos](http://doc.babylonjs.com/how_to/chart3d) ([Deltakosh](https://github.com/deltakosh))
 - Added [Environment Texture Tools](https://doc.babylonjs.com/how_to/physically_based_rendering#creating-a-compressed-environment-texture) to reduce the size of the usual .DDS file ([sebavan](http://www.github.com/sebavan))
 - New GUI control: the [Grid](http://doc.babylonjs.com/how_to/gui#grid) ([Deltakosh](https://github.com/deltakosh))
 - Gizmo Support ([TrevorDev](https://github.com/TrevorDev))

+ 6 - 4
gui/src/3D/charting/barGraph.ts

@@ -1,4 +1,4 @@
-import { Nullable, Scene, Mesh, StandardMaterial, Material, Animation, Observer, Vector3, GlowLayer, Engine, AbstractMesh } from "babylonjs";
+import { Nullable, Scene, Mesh, StandardMaterial, Material, Animation, Observer, Vector3, GlowLayer, Engine, AbstractMesh, Matrix } from "babylonjs";
 import { Chart } from ".";
 import { AdvancedDynamicTexture, DisplayGrid } from "../../2D";
 import { FluentMaterial } from "../materials";
@@ -204,7 +204,7 @@ export class BarGraph extends Chart {
      */
     protected _createBarMesh(name: string, scene: Scene): Mesh {
         var box = Mesh.CreateBox(name, 1, scene);
-        box.setPivotPoint(new BABYLON.Vector3(0, -0.5, 0));
+        box.setPivotMatrix(Matrix.Translation(0, 0.5, 0), false);
 
         return box;
     }
@@ -270,7 +270,7 @@ export class BarGraph extends Chart {
             // Axis
             this._backgroundMesh = BABYLON.Mesh.CreatePlane("background", 1, scene);
             this._backgroundMesh.parent = this._rootNode;            
-            this._backgroundMesh.setPivotPoint(new BABYLON.Vector3(0, -0.5, 0));
+            this._backgroundMesh.setPivotMatrix(Matrix.Translation(0, 0.5, 0), false);
 
             this._backgroundADT = AdvancedDynamicTexture.CreateForMesh(this._backgroundMesh, this._backgroundResolution, this._backgroundResolution, false);
 
@@ -293,7 +293,7 @@ export class BarGraph extends Chart {
                 var label = (max / this._backgroundTickCount) * tickIndex + "";
                 var ticklabel = this._addLabel(label, this._barWidth, false);
                 ticklabel.position.x = left - this._barWidth;
-                ticklabel.position.y = (this.maxBarHeight * (tickIndex - 0.25)) / this._backgroundTickCount;
+                ticklabel.position.y = (this.maxBarHeight * tickIndex) / this._backgroundTickCount;
                 ticklabel.position.z = this._barWidth;
             }
         }
@@ -336,6 +336,8 @@ export class BarGraph extends Chart {
             label.position.z -= this.barWidth;
         });
 
+        this.onRefreshObservable.notifyObservers(this);
+
         return this;
     }
 

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

@@ -16,6 +16,9 @@ export abstract class Chart {
     private _labelMeshes = new Array<Mesh>();
     protected _blockRefresh = false;
 
+    /** Observable raised when a refresh was done */
+    public onRefreshObservable  = new Observable<Chart>();
+
     /** Observable raised when a new element is created */
     public onElementCreatedObservable  = new Observable<Mesh>();
 

+ 105 - 31
gui/src/3D/charting/mapGraph.ts

@@ -1,5 +1,6 @@
 import { Chart } from ".";
-import { Engine, Scene, Nullable, Mesh, Animation, StandardMaterial, Texture } from "babylonjs";
+import { Engine, Scene, Nullable, Mesh, Animation, StandardMaterial, Texture, Matrix, Material, Observer, Vector3 } from "babylonjs";
+import { FluentMaterial } from "../materials";
 
 /** 
  * Class used to render bar graphs 
@@ -7,11 +8,44 @@ import { Engine, Scene, Nullable, Mesh, Animation, StandardMaterial, Texture } f
  */
 export class MapGraph extends Chart {
 
-    private _barMeshes: Nullable<Array<Mesh>>;
-    private _barWidth = 0.5;    
-    private _maxBarHeight = 10;
+    private _cylinderMeshes: Nullable<Array<Mesh>>;
+    private _cylinderRadius = 0.5;    
+    private _maxCylinderHeight = 10;
     private _worldMap: Nullable<Mesh>;
     private _mercatorMaterial: Nullable<StandardMaterial>;
+    private _worldMapSize = 40;   
+    private _pickedPointObserver: Nullable<Observer<Vector3>>;    
+    private _defaultMaterial: Nullable<Material>;
+
+    /** Gets or sets the radius of each cylinder */
+    public get cylinderRadius(): number {
+        return this._cylinderRadius;
+    }
+
+    public set cylinderRadius(value: number) {
+        if (this._cylinderRadius === value) {
+            return;
+        }
+
+        this._cylinderRadius = value;
+
+        this.refresh();
+    }
+    
+    /** Gets or sets the size of the world map (this will define the width) */
+    public get worldMapSize(): number {
+        return this._worldMapSize;
+    }
+
+    public set worldMapSize(value: number) {
+        if (this._worldMapSize === value) {
+            return;
+        }
+
+        this._worldMapSize = value;
+
+        this.refresh();
+    }    
     
     /**
      * Creates a new MapGraph
@@ -22,19 +56,41 @@ export class MapGraph extends Chart {
         super(name, scene);
 
         this._mercatorMaterial = new StandardMaterial("WorldMap", scene!);
-        this._mercatorMaterial.emissiveTexture = new Texture(mapUrl, scene);
+        this._mercatorMaterial.emissiveTexture = new Texture(mapUrl, scene, false, true, Texture.LINEAR_LINEAR_MIPLINEAR, () => {
+            this.refresh();
+        });
         this._mercatorMaterial.disableLighting = true;
+        this._mercatorMaterial.backFaceCulling = false;
     }
 
-    protected _createBarMesh(name: string, scene: Scene): Mesh {
-        var box = Mesh.CreateBox(name, 1, scene);
-        box.setPivotPoint(new BABYLON.Vector3(0, -0.5, 0));
+    protected _createCylinderMesh(name: string, scene: Scene): Mesh {
+        var cylinder = Mesh.CreateCylinder(name, 1, 1, 1, 16, 1, scene);
+        cylinder.setPivotMatrix(Matrix.Translation(0, 0.5, 0), false);
 
-        return box;
+        return cylinder;
+    }
+
+    protected _createDefaultMaterial(scene: Scene): Material {
+        var result = new FluentMaterial("fluent", scene);
+        result.albedoColor = this._dataSource!.color.scale(0.5);
+        result.innerGlowColorIntensity = 0.6;
+        result.renderHoverLight = true;
+        result.hoverRadius = 5;
+
+        this._pickedPointObserver = this.onPickedPointChangedObservable.add(pickedPoint => {
+            if (pickedPoint) {
+                result.hoverPosition = pickedPoint;
+                result.hoverColor.a = 1.0;
+            } else {
+                result.hoverColor.a = 0;
+            }
+        });
+
+        return result;
     }
 
     public refresh(): MapGraph {
-        if (this._blockRefresh) {
+        if (this._blockRefresh || !this._mercatorMaterial || !this._mercatorMaterial.emissiveTexture!.isReady()) {
             return this;
         }
 
@@ -48,10 +104,10 @@ export class MapGraph extends Chart {
         let createMesh = false;
 
         // Do we need to create new graph or animate the current one
-        if (!this._barMeshes || this._barMeshes.length !== data.length) {
+        if (!this._cylinderMeshes || this._cylinderMeshes.length !== data.length) {
             this._clean();
             createMesh = true;
-            this._barMeshes = [];
+            this._cylinderMeshes = [];
         }      
 
         // Scan data
@@ -69,10 +125,11 @@ export class MapGraph extends Chart {
             }
         });
 
-        let ratio = this._maxBarHeight / (max - min);     
+        let ratio = this._maxCylinderHeight / (max - min);     
         
-        const worldMapWidth = 40;
-        const worldMapHeight = 20;
+        const worldMaptextureSize = this._mercatorMaterial.emissiveTexture!.getSize();
+        const worldMapWidth = this._worldMapSize;
+        const worldMapHeight = worldMapWidth * worldMaptextureSize.height / worldMaptextureSize.width;
 
         if (this._worldMap) {
             this._worldMap.dispose();
@@ -81,24 +138,30 @@ export class MapGraph extends Chart {
         this._worldMap = Mesh.CreateGround("WorldMap", worldMapWidth, worldMapHeight, 1, scene);
         this._worldMap.parent = this._rootNode;
         this._worldMap.material = this._mercatorMaterial;
+
+        // Default material
+        if (!this._defaultMaterial) {
+            this._defaultMaterial = this._createDefaultMaterial(scene);
+        }        
         
-        // We will generate one bar per entry
+        // We will generate one cylinder per entry
         let index = 0;
         data.forEach(entry => {
 
-            var barMesh: Mesh;
+            var cylinderMesh: Mesh;
             if (createMesh) {
-                barMesh = this._createBarMesh(this.name + "_box_" + index++, scene);
-                barMesh.enablePointerMoveEvents = true;
-                this._barMeshes!.push(barMesh);
+                cylinderMesh = this._createCylinderMesh(this.name + "_cylinder_" + index++, scene);
+                cylinderMesh.enablePointerMoveEvents = true;
+                this._cylinderMeshes!.push(cylinderMesh);
             } else {
-                barMesh = this._barMeshes![index++];
+                cylinderMesh = this._cylinderMeshes![index++];
             }
 
-            barMesh.metadata = entry;
-            barMesh.parent = this._worldMap;
-            let currentScalingYState = barMesh.scaling.y;
-            barMesh.scaling.set(this._barWidth, 0, this._barWidth);
+            cylinderMesh.material = this._defaultMaterial;
+            cylinderMesh.metadata = entry;
+            cylinderMesh.parent = this._rootNode;
+            let currentScalingYState = cylinderMesh.scaling.y;
+            cylinderMesh.scaling.set(this._cylinderRadius, 0, this._cylinderRadius);
 
             // Lat/long convertion
             const latitude: number = entry.latitude;
@@ -107,20 +170,31 @@ export class MapGraph extends Chart {
             const latRad = latitude * Math.PI / 180;
             const mercN = Math.log(Math.tan(Math.PI / 4 + latRad / 2));
             const z = worldMapWidth * mercN / (2 * Math.PI);
-            barMesh.position.set(x, 0, z);
+            cylinderMesh.position.set(x, 0, z);
 
             var easing = new BABYLON.CircleEase();
-            Animation.CreateAndStartAnimation("entryScale", barMesh, "scaling.y", 30, 30, currentScalingYState, entry.value * ratio, 0, easing);
+            Animation.CreateAndStartAnimation("entryScale", cylinderMesh, "scaling.y", 30, 30, currentScalingYState, entry.value * ratio, 0, easing);
 
-            this.onElementCreatedObservable.notifyObservers(barMesh);
+            this.onElementCreatedObservable.notifyObservers(cylinderMesh);
         });
+
+        this.onRefreshObservable.notifyObservers(this);
     
         return this;
     }
 
-
     protected _clean(): void {
         super._clean();
-        this._barMeshes = null;
-    }    
+        this._worldMap = null;
+        this._cylinderMeshes = null;
+    }
+    
+    /** Clean associated resources */
+    public dispose() {
+        super.dispose();
+        if (this._pickedPointObserver) {
+            this.onPickedPointChangedObservable.remove(this._pickedPointObserver);
+            this._pickedPointObserver = null;
+        }
+    }
 }