David Catuhe 7 年之前
父節點
當前提交
b5d84bb759

文件差異過大導致無法顯示
+ 9068 - 9068
Playground/babylon.d.txt


+ 7 - 0
Tools/Gulp/config.json

@@ -139,6 +139,13 @@
             "picking",
             "backgroundMaterial",
             "videoDome"
+        ],
+        "glTFViewer": [
+            "arcRotateCamera",
+            "imageProcessing",
+            "backgroundMaterial",
+            "pbrMaterial",
+            "hdr"        
         ]
     },
     "workloads": {

文件差異過大導致無法顯示
+ 3848 - 3144
dist/preview release/babylon.d.ts


文件差異過大導致無法顯示
+ 1 - 1
dist/preview release/babylon.js


+ 28 - 10
dist/preview release/babylon.max.js

@@ -62812,6 +62812,16 @@ var BABYLON;
              * How much of the attached particles speed should be added to the sub emitted particle (default: 0)
              */
             this.inheritedVelocityAmount = 0;
+            // Create mesh as emitter to support rotation
+            if (!particleSystem.emitter || !particleSystem.emitter.dispose) {
+                particleSystem.emitter = new BABYLON.AbstractMesh("SubemitterSystemEmitter", particleSystem.getScene());
+            }
+            // Automatically dispose of subemitter when system is disposed
+            particleSystem.onDisposeObservable.add(function () {
+                if (particleSystem.emitter && particleSystem.emitter.dispose) {
+                    particleSystem.emitter.dispose();
+                }
+            });
         }
         /**
          * Clones the sub emitter
@@ -101630,10 +101640,12 @@ var BABYLON;
          * @param gizmoLayer The utility layer the gizmo will be added to
          * @param planeNormal The normal of the plane which the gizmo will be able to rotate on
          * @param color The color of the gizmo
+         * @param tessellation Amount of tessellation to be used when creating rotation circles
          */
-        function PlaneRotationGizmo(planeNormal, color, gizmoLayer) {
+        function PlaneRotationGizmo(planeNormal, color, gizmoLayer, tessellation) {
             if (color === void 0) { color = BABYLON.Color3.Gray(); }
             if (gizmoLayer === void 0) { gizmoLayer = BABYLON.UtilityLayerRenderer.DefaultUtilityLayer; }
+            if (tessellation === void 0) { tessellation = 32; }
             var _this = _super.call(this, gizmoLayer) || this;
             _this._pointerObserver = null;
             /**
@@ -101655,7 +101667,6 @@ var BABYLON;
             // Build mesh on root node
             var parentMesh = new BABYLON.AbstractMesh("", gizmoLayer.utilityLayerScene);
             // Create circle out of lines
-            var tessellation = 20;
             var radius = 0.8;
             var points = new Array();
             for (var i = 0; i < tessellation; i++) {
@@ -101914,13 +101925,15 @@ var BABYLON;
         /**
          * Creates a RotationGizmo
          * @param gizmoLayer The utility layer the gizmo will be added to
+         * @param tessellation Amount of tessellation to be used when creating rotation circles
          */
-        function RotationGizmo(gizmoLayer) {
+        function RotationGizmo(gizmoLayer, tessellation) {
             if (gizmoLayer === void 0) { gizmoLayer = BABYLON.UtilityLayerRenderer.DefaultUtilityLayer; }
+            if (tessellation === void 0) { tessellation = 32; }
             var _this = _super.call(this, gizmoLayer) || this;
-            _this.xGizmo = new BABYLON.PlaneRotationGizmo(new BABYLON.Vector3(1, 0, 0), BABYLON.Color3.Red().scale(0.5), gizmoLayer);
-            _this.yGizmo = new BABYLON.PlaneRotationGizmo(new BABYLON.Vector3(0, 1, 0), BABYLON.Color3.Green().scale(0.5), gizmoLayer);
-            _this.zGizmo = new BABYLON.PlaneRotationGizmo(new BABYLON.Vector3(0, 0, 1), BABYLON.Color3.Blue().scale(0.5), gizmoLayer);
+            _this.xGizmo = new BABYLON.PlaneRotationGizmo(new BABYLON.Vector3(1, 0, 0), BABYLON.Color3.Red().scale(0.5), gizmoLayer, tessellation);
+            _this.yGizmo = new BABYLON.PlaneRotationGizmo(new BABYLON.Vector3(0, 1, 0), BABYLON.Color3.Green().scale(0.5), gizmoLayer, tessellation);
+            _this.zGizmo = new BABYLON.PlaneRotationGizmo(new BABYLON.Vector3(0, 0, 1), BABYLON.Color3.Blue().scale(0.5), gizmoLayer, tessellation);
             _this.attachedMesh = null;
             return _this;
         }
@@ -102644,6 +102657,9 @@ var BABYLON;
              * If pointer events should perform attaching/detaching a gizmo, if false this can be done manually via attachToMesh. (Default: true)
              */
             this.usePointerToAttachGizmos = true;
+            this._defaultKeepDepthUtilityLayer = new BABYLON.UtilityLayerRenderer(scene);
+            this._defaultKeepDepthUtilityLayer.utilityLayerScene.autoClearDepthAndStencil = false;
+            this._defaultUtilityLayer = new BABYLON.UtilityLayerRenderer(scene);
             this.gizmos = { positionGizmo: null, rotationGizmo: null, scaleGizmo: null, boundingBoxGizmo: null };
             // Instatiate/dispose gizmos based on pointer actions
             this._pointerObserver = scene.onPointerObservable.add(function (pointerInfo, state) {
@@ -102714,7 +102730,7 @@ var BABYLON;
             set: function (value) {
                 if (value) {
                     if (!this.gizmos.positionGizmo) {
-                        this.gizmos.positionGizmo = new BABYLON.PositionGizmo();
+                        this.gizmos.positionGizmo = new BABYLON.PositionGizmo(this._defaultUtilityLayer);
                     }
                     this.gizmos.positionGizmo.attachedMesh = this._attachedMesh;
                 }
@@ -102736,7 +102752,7 @@ var BABYLON;
             set: function (value) {
                 if (value) {
                     if (!this.gizmos.rotationGizmo) {
-                        this.gizmos.rotationGizmo = new BABYLON.RotationGizmo();
+                        this.gizmos.rotationGizmo = new BABYLON.RotationGizmo(this._defaultUtilityLayer);
                     }
                     this.gizmos.rotationGizmo.attachedMesh = this._attachedMesh;
                 }
@@ -102757,7 +102773,7 @@ var BABYLON;
              */
             set: function (value) {
                 if (value) {
-                    this.gizmos.scaleGizmo = this.gizmos.scaleGizmo || new BABYLON.ScaleGizmo();
+                    this.gizmos.scaleGizmo = this.gizmos.scaleGizmo || new BABYLON.ScaleGizmo(this._defaultUtilityLayer);
                     this.gizmos.scaleGizmo.attachedMesh = this._attachedMesh;
                 }
                 else if (this.gizmos.scaleGizmo) {
@@ -102777,7 +102793,7 @@ var BABYLON;
              */
             set: function (value) {
                 if (value) {
-                    this.gizmos.boundingBoxGizmo = this.gizmos.boundingBoxGizmo || new BABYLON.BoundingBoxGizmo(this._boundingBoxColor);
+                    this.gizmos.boundingBoxGizmo = this.gizmos.boundingBoxGizmo || new BABYLON.BoundingBoxGizmo(this._boundingBoxColor, this._defaultKeepDepthUtilityLayer);
                     this.gizmos.boundingBoxGizmo.attachedMesh = this._attachedMesh;
                     if (this._attachedMesh) {
                         this._attachedMesh.removeBehavior(this.boundingBoxDragBehavior);
@@ -102803,6 +102819,8 @@ var BABYLON;
                     gizmo.dispose();
                 }
             }
+            this._defaultKeepDepthUtilityLayer.dispose();
+            this._defaultUtilityLayer.dispose();
             this.boundingBoxDragBehavior.detach();
         };
         return GizmoManager;

+ 28 - 10
dist/preview release/babylon.no-module.max.js

@@ -62779,6 +62779,16 @@ var BABYLON;
              * How much of the attached particles speed should be added to the sub emitted particle (default: 0)
              */
             this.inheritedVelocityAmount = 0;
+            // Create mesh as emitter to support rotation
+            if (!particleSystem.emitter || !particleSystem.emitter.dispose) {
+                particleSystem.emitter = new BABYLON.AbstractMesh("SubemitterSystemEmitter", particleSystem.getScene());
+            }
+            // Automatically dispose of subemitter when system is disposed
+            particleSystem.onDisposeObservable.add(function () {
+                if (particleSystem.emitter && particleSystem.emitter.dispose) {
+                    particleSystem.emitter.dispose();
+                }
+            });
         }
         /**
          * Clones the sub emitter
@@ -101597,10 +101607,12 @@ var BABYLON;
          * @param gizmoLayer The utility layer the gizmo will be added to
          * @param planeNormal The normal of the plane which the gizmo will be able to rotate on
          * @param color The color of the gizmo
+         * @param tessellation Amount of tessellation to be used when creating rotation circles
          */
-        function PlaneRotationGizmo(planeNormal, color, gizmoLayer) {
+        function PlaneRotationGizmo(planeNormal, color, gizmoLayer, tessellation) {
             if (color === void 0) { color = BABYLON.Color3.Gray(); }
             if (gizmoLayer === void 0) { gizmoLayer = BABYLON.UtilityLayerRenderer.DefaultUtilityLayer; }
+            if (tessellation === void 0) { tessellation = 32; }
             var _this = _super.call(this, gizmoLayer) || this;
             _this._pointerObserver = null;
             /**
@@ -101622,7 +101634,6 @@ var BABYLON;
             // Build mesh on root node
             var parentMesh = new BABYLON.AbstractMesh("", gizmoLayer.utilityLayerScene);
             // Create circle out of lines
-            var tessellation = 20;
             var radius = 0.8;
             var points = new Array();
             for (var i = 0; i < tessellation; i++) {
@@ -101881,13 +101892,15 @@ var BABYLON;
         /**
          * Creates a RotationGizmo
          * @param gizmoLayer The utility layer the gizmo will be added to
+         * @param tessellation Amount of tessellation to be used when creating rotation circles
          */
-        function RotationGizmo(gizmoLayer) {
+        function RotationGizmo(gizmoLayer, tessellation) {
             if (gizmoLayer === void 0) { gizmoLayer = BABYLON.UtilityLayerRenderer.DefaultUtilityLayer; }
+            if (tessellation === void 0) { tessellation = 32; }
             var _this = _super.call(this, gizmoLayer) || this;
-            _this.xGizmo = new BABYLON.PlaneRotationGizmo(new BABYLON.Vector3(1, 0, 0), BABYLON.Color3.Red().scale(0.5), gizmoLayer);
-            _this.yGizmo = new BABYLON.PlaneRotationGizmo(new BABYLON.Vector3(0, 1, 0), BABYLON.Color3.Green().scale(0.5), gizmoLayer);
-            _this.zGizmo = new BABYLON.PlaneRotationGizmo(new BABYLON.Vector3(0, 0, 1), BABYLON.Color3.Blue().scale(0.5), gizmoLayer);
+            _this.xGizmo = new BABYLON.PlaneRotationGizmo(new BABYLON.Vector3(1, 0, 0), BABYLON.Color3.Red().scale(0.5), gizmoLayer, tessellation);
+            _this.yGizmo = new BABYLON.PlaneRotationGizmo(new BABYLON.Vector3(0, 1, 0), BABYLON.Color3.Green().scale(0.5), gizmoLayer, tessellation);
+            _this.zGizmo = new BABYLON.PlaneRotationGizmo(new BABYLON.Vector3(0, 0, 1), BABYLON.Color3.Blue().scale(0.5), gizmoLayer, tessellation);
             _this.attachedMesh = null;
             return _this;
         }
@@ -102611,6 +102624,9 @@ var BABYLON;
              * If pointer events should perform attaching/detaching a gizmo, if false this can be done manually via attachToMesh. (Default: true)
              */
             this.usePointerToAttachGizmos = true;
+            this._defaultKeepDepthUtilityLayer = new BABYLON.UtilityLayerRenderer(scene);
+            this._defaultKeepDepthUtilityLayer.utilityLayerScene.autoClearDepthAndStencil = false;
+            this._defaultUtilityLayer = new BABYLON.UtilityLayerRenderer(scene);
             this.gizmos = { positionGizmo: null, rotationGizmo: null, scaleGizmo: null, boundingBoxGizmo: null };
             // Instatiate/dispose gizmos based on pointer actions
             this._pointerObserver = scene.onPointerObservable.add(function (pointerInfo, state) {
@@ -102681,7 +102697,7 @@ var BABYLON;
             set: function (value) {
                 if (value) {
                     if (!this.gizmos.positionGizmo) {
-                        this.gizmos.positionGizmo = new BABYLON.PositionGizmo();
+                        this.gizmos.positionGizmo = new BABYLON.PositionGizmo(this._defaultUtilityLayer);
                     }
                     this.gizmos.positionGizmo.attachedMesh = this._attachedMesh;
                 }
@@ -102703,7 +102719,7 @@ var BABYLON;
             set: function (value) {
                 if (value) {
                     if (!this.gizmos.rotationGizmo) {
-                        this.gizmos.rotationGizmo = new BABYLON.RotationGizmo();
+                        this.gizmos.rotationGizmo = new BABYLON.RotationGizmo(this._defaultUtilityLayer);
                     }
                     this.gizmos.rotationGizmo.attachedMesh = this._attachedMesh;
                 }
@@ -102724,7 +102740,7 @@ var BABYLON;
              */
             set: function (value) {
                 if (value) {
-                    this.gizmos.scaleGizmo = this.gizmos.scaleGizmo || new BABYLON.ScaleGizmo();
+                    this.gizmos.scaleGizmo = this.gizmos.scaleGizmo || new BABYLON.ScaleGizmo(this._defaultUtilityLayer);
                     this.gizmos.scaleGizmo.attachedMesh = this._attachedMesh;
                 }
                 else if (this.gizmos.scaleGizmo) {
@@ -102744,7 +102760,7 @@ var BABYLON;
              */
             set: function (value) {
                 if (value) {
-                    this.gizmos.boundingBoxGizmo = this.gizmos.boundingBoxGizmo || new BABYLON.BoundingBoxGizmo(this._boundingBoxColor);
+                    this.gizmos.boundingBoxGizmo = this.gizmos.boundingBoxGizmo || new BABYLON.BoundingBoxGizmo(this._boundingBoxColor, this._defaultKeepDepthUtilityLayer);
                     this.gizmos.boundingBoxGizmo.attachedMesh = this._attachedMesh;
                     if (this._attachedMesh) {
                         this._attachedMesh.removeBehavior(this.boundingBoxDragBehavior);
@@ -102770,6 +102786,8 @@ var BABYLON;
                     gizmo.dispose();
                 }
             }
+            this._defaultKeepDepthUtilityLayer.dispose();
+            this._defaultUtilityLayer.dispose();
             this.boundingBoxDragBehavior.detach();
         };
         return GizmoManager;

文件差異過大導致無法顯示
+ 1 - 1
dist/preview release/babylon.worker.js


+ 28 - 10
dist/preview release/es6.js

@@ -62779,6 +62779,16 @@ var BABYLON;
              * How much of the attached particles speed should be added to the sub emitted particle (default: 0)
              */
             this.inheritedVelocityAmount = 0;
+            // Create mesh as emitter to support rotation
+            if (!particleSystem.emitter || !particleSystem.emitter.dispose) {
+                particleSystem.emitter = new BABYLON.AbstractMesh("SubemitterSystemEmitter", particleSystem.getScene());
+            }
+            // Automatically dispose of subemitter when system is disposed
+            particleSystem.onDisposeObservable.add(function () {
+                if (particleSystem.emitter && particleSystem.emitter.dispose) {
+                    particleSystem.emitter.dispose();
+                }
+            });
         }
         /**
          * Clones the sub emitter
@@ -101597,10 +101607,12 @@ var BABYLON;
          * @param gizmoLayer The utility layer the gizmo will be added to
          * @param planeNormal The normal of the plane which the gizmo will be able to rotate on
          * @param color The color of the gizmo
+         * @param tessellation Amount of tessellation to be used when creating rotation circles
          */
-        function PlaneRotationGizmo(planeNormal, color, gizmoLayer) {
+        function PlaneRotationGizmo(planeNormal, color, gizmoLayer, tessellation) {
             if (color === void 0) { color = BABYLON.Color3.Gray(); }
             if (gizmoLayer === void 0) { gizmoLayer = BABYLON.UtilityLayerRenderer.DefaultUtilityLayer; }
+            if (tessellation === void 0) { tessellation = 32; }
             var _this = _super.call(this, gizmoLayer) || this;
             _this._pointerObserver = null;
             /**
@@ -101622,7 +101634,6 @@ var BABYLON;
             // Build mesh on root node
             var parentMesh = new BABYLON.AbstractMesh("", gizmoLayer.utilityLayerScene);
             // Create circle out of lines
-            var tessellation = 20;
             var radius = 0.8;
             var points = new Array();
             for (var i = 0; i < tessellation; i++) {
@@ -101881,13 +101892,15 @@ var BABYLON;
         /**
          * Creates a RotationGizmo
          * @param gizmoLayer The utility layer the gizmo will be added to
+         * @param tessellation Amount of tessellation to be used when creating rotation circles
          */
-        function RotationGizmo(gizmoLayer) {
+        function RotationGizmo(gizmoLayer, tessellation) {
             if (gizmoLayer === void 0) { gizmoLayer = BABYLON.UtilityLayerRenderer.DefaultUtilityLayer; }
+            if (tessellation === void 0) { tessellation = 32; }
             var _this = _super.call(this, gizmoLayer) || this;
-            _this.xGizmo = new BABYLON.PlaneRotationGizmo(new BABYLON.Vector3(1, 0, 0), BABYLON.Color3.Red().scale(0.5), gizmoLayer);
-            _this.yGizmo = new BABYLON.PlaneRotationGizmo(new BABYLON.Vector3(0, 1, 0), BABYLON.Color3.Green().scale(0.5), gizmoLayer);
-            _this.zGizmo = new BABYLON.PlaneRotationGizmo(new BABYLON.Vector3(0, 0, 1), BABYLON.Color3.Blue().scale(0.5), gizmoLayer);
+            _this.xGizmo = new BABYLON.PlaneRotationGizmo(new BABYLON.Vector3(1, 0, 0), BABYLON.Color3.Red().scale(0.5), gizmoLayer, tessellation);
+            _this.yGizmo = new BABYLON.PlaneRotationGizmo(new BABYLON.Vector3(0, 1, 0), BABYLON.Color3.Green().scale(0.5), gizmoLayer, tessellation);
+            _this.zGizmo = new BABYLON.PlaneRotationGizmo(new BABYLON.Vector3(0, 0, 1), BABYLON.Color3.Blue().scale(0.5), gizmoLayer, tessellation);
             _this.attachedMesh = null;
             return _this;
         }
@@ -102611,6 +102624,9 @@ var BABYLON;
              * If pointer events should perform attaching/detaching a gizmo, if false this can be done manually via attachToMesh. (Default: true)
              */
             this.usePointerToAttachGizmos = true;
+            this._defaultKeepDepthUtilityLayer = new BABYLON.UtilityLayerRenderer(scene);
+            this._defaultKeepDepthUtilityLayer.utilityLayerScene.autoClearDepthAndStencil = false;
+            this._defaultUtilityLayer = new BABYLON.UtilityLayerRenderer(scene);
             this.gizmos = { positionGizmo: null, rotationGizmo: null, scaleGizmo: null, boundingBoxGizmo: null };
             // Instatiate/dispose gizmos based on pointer actions
             this._pointerObserver = scene.onPointerObservable.add(function (pointerInfo, state) {
@@ -102681,7 +102697,7 @@ var BABYLON;
             set: function (value) {
                 if (value) {
                     if (!this.gizmos.positionGizmo) {
-                        this.gizmos.positionGizmo = new BABYLON.PositionGizmo();
+                        this.gizmos.positionGizmo = new BABYLON.PositionGizmo(this._defaultUtilityLayer);
                     }
                     this.gizmos.positionGizmo.attachedMesh = this._attachedMesh;
                 }
@@ -102703,7 +102719,7 @@ var BABYLON;
             set: function (value) {
                 if (value) {
                     if (!this.gizmos.rotationGizmo) {
-                        this.gizmos.rotationGizmo = new BABYLON.RotationGizmo();
+                        this.gizmos.rotationGizmo = new BABYLON.RotationGizmo(this._defaultUtilityLayer);
                     }
                     this.gizmos.rotationGizmo.attachedMesh = this._attachedMesh;
                 }
@@ -102724,7 +102740,7 @@ var BABYLON;
              */
             set: function (value) {
                 if (value) {
-                    this.gizmos.scaleGizmo = this.gizmos.scaleGizmo || new BABYLON.ScaleGizmo();
+                    this.gizmos.scaleGizmo = this.gizmos.scaleGizmo || new BABYLON.ScaleGizmo(this._defaultUtilityLayer);
                     this.gizmos.scaleGizmo.attachedMesh = this._attachedMesh;
                 }
                 else if (this.gizmos.scaleGizmo) {
@@ -102744,7 +102760,7 @@ var BABYLON;
              */
             set: function (value) {
                 if (value) {
-                    this.gizmos.boundingBoxGizmo = this.gizmos.boundingBoxGizmo || new BABYLON.BoundingBoxGizmo(this._boundingBoxColor);
+                    this.gizmos.boundingBoxGizmo = this.gizmos.boundingBoxGizmo || new BABYLON.BoundingBoxGizmo(this._boundingBoxColor, this._defaultKeepDepthUtilityLayer);
                     this.gizmos.boundingBoxGizmo.attachedMesh = this._attachedMesh;
                     if (this._attachedMesh) {
                         this._attachedMesh.removeBehavior(this.boundingBoxDragBehavior);
@@ -102770,6 +102786,8 @@ var BABYLON;
                     gizmo.dispose();
                 }
             }
+            this._defaultKeepDepthUtilityLayer.dispose();
+            this._defaultUtilityLayer.dispose();
             this.boundingBoxDragBehavior.detach();
         };
         return GizmoManager;

文件差異過大導致無法顯示
+ 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


+ 198 - 272
dist/preview release/viewer/babylon.viewer.d.ts

@@ -123,80 +123,6 @@ declare module BabylonViewer {
     export let viewerManager: ViewerManager;
 }
 declare module BabylonViewer {
-    /**
-        * The Default viewer is the default implementation of the AbstractViewer.
-        * It uses the templating system to render a new canvas and controls.
-        */
-    export class DefaultViewer extends AbstractViewer {
-            containerElement: HTMLElement;
-            fullscreenElement?: HTMLElement;
-            /**
-                * Create a new default viewer
-                * @param containerElement the element in which the templates will be rendered
-                * @param initialConfiguration the initial configuration. Defaults to extending the default configuration
-                */
-            constructor(containerElement: HTMLElement, initialConfiguration?: ViewerConfiguration);
-            registerTemplatePlugin(plugin: IViewerTemplatePlugin): void;
-            /**
-                * This will be executed when the templates initialize.
-                */
-            protected _onTemplatesLoaded(): Promise<AbstractViewer>;
-            protected _initVR(): void;
-            /**
-                * Toggle fullscreen of the entire viewer
-                */
-            toggleFullscreen: () => void;
-            /**
-                * Preparing the container element to present the viewer
-                */
-            protected _prepareContainerElement(): void;
-            /**
-                * This function will configure the templates and update them after a model was loaded
-                * It is mainly responsible to changing the title and subtitle etc'.
-                * @param model the model to be used to configure the templates by
-                */
-            protected _configureTemplate(model?: ViewerModel): void;
-            /**
-                * This will load a new model to the default viewer
-                * overriding the AbstractViewer's loadModel.
-                * The scene will automatically be cleared of the old models, if exist.
-                * @param model the configuration object (or URL) to load.
-                */
-            loadModel(model?: string | File | IModelConfiguration): Promise<ViewerModel>;
-            /**
-                * Show the overlay and the defined sub-screen.
-                * 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>;
-            /**
-                * Hide the overlay screen.
-                */
-            hideOverlayScreen(): Promise<string> | Promise<Template>;
-            /**
-                * show the viewer (in case it was hidden)
-                *
-                * @param visibilityFunction an optional function to execute in order to show the container
-                */
-            show(visibilityFunction?: ((template: Template) => Promise<Template>)): Promise<Template>;
-            /**
-                * hide the viewer (in case it is visible)
-                *
-                * @param visibilityFunction an optional function to execute in order to hide the container
-                */
-            hide(visibilityFunction?: ((template: Template) => Promise<Template>)): Promise<Template>;
-            /**
-                * Show the loading screen.
-                * The loading screen can be configured using the configuration object
-                */
-            showLoadingScreen(): Promise<string> | Promise<Template>;
-            /**
-                * Hide the loading screen
-                */
-            hideLoadingScreen(): Promise<string> | Promise<Template>;
-            dispose(): void;
-            protected _onConfigurationLoaded(configuration: ViewerConfiguration): void;
-    }
 }
 declare module BabylonViewer {
     /**
@@ -1018,171 +944,6 @@ declare module BabylonViewer {
     }
 }
 declare module BabylonViewer {
-    /**
-        * The object sent when an event is triggered
-        */
-    export interface EventCallback {
-            event: Event;
-            template: Template;
-            selector: string;
-            payload?: any;
-    }
-    /**
-        * The template manager, a member of the viewer class, will manage the viewer's templates and generate the HTML.
-        * The template manager managers a single viewer and can be seen as the collection of all sub-templates of the viewer.
-        */
-    export class TemplateManager {
-            containerElement: HTMLElement;
-            /**
-                * Will be triggered when any template is initialized
-                */
-            onTemplateInit: BABYLON.Observable<Template>;
-            /**
-                * Will be triggered when any template is fully loaded
-                */
-            onTemplateLoaded: BABYLON.Observable<Template>;
-            /**
-                * Will be triggered when a template state changes
-                */
-            onTemplateStateChange: BABYLON.Observable<Template>;
-            /**
-                * Will be triggered when all templates finished loading
-                */
-            onAllLoaded: BABYLON.Observable<TemplateManager>;
-            /**
-                * Will be triggered when any event on any template is triggered.
-                */
-            onEventTriggered: BABYLON.Observable<EventCallback>;
-            /**
-                * This template manager's event manager. In charge of callback registrations to native event types
-                */
-            eventManager: EventManager;
-            constructor(containerElement: HTMLElement);
-            /**
-                * Initialize the template(s) for the viewer. Called bay the Viewer class
-                * @param templates the templates to be used to initialize the main template
-                */
-            initTemplate(templates: {
-                    [key: string]: ITemplateConfiguration;
-            }): Promise<void>;
-            /**
-                * Get the canvas in the template tree.
-                * There must be one and only one canvas inthe template.
-                */
-            getCanvas(): HTMLCanvasElement | null;
-            /**
-                * Get a specific template from the template tree
-                * @param name the name of the template to load
-                */
-            getTemplate(name: string): Template | undefined;
-            /**
-                * Dispose the template manager
-                */
-            dispose(): void;
-    }
-    /**
-        * This class represents a single template in the viewer's template tree.
-        * An example for a template is a single canvas, an overlay (containing sub-templates) or the navigation bar.
-        * A template is injected using the template manager in the correct position.
-        * The template is rendered using Handlebars and can use Handlebars' features (such as parameter injection)
-        *
-        * For further information please refer to the documentation page, https://doc.babylonjs.com
-        */
-    export class Template {
-            name: string;
-            /**
-                * Will be triggered when the template is loaded
-                */
-            onLoaded: BABYLON.Observable<Template>;
-            /**
-                * will be triggered when the template is appended to the tree
-                */
-            onAppended: BABYLON.Observable<Template>;
-            /**
-                * Will be triggered when the template's state changed (shown, hidden)
-                */
-            onStateChange: BABYLON.Observable<Template>;
-            /**
-                * Will be triggered when an event is triggered on ths template.
-                * The event is a native browser event (like mouse or pointer events)
-                */
-            onEventTriggered: BABYLON.Observable<EventCallback>;
-            onParamsUpdated: BABYLON.Observable<Template>;
-            onHTMLRendered: BABYLON.Observable<Template>;
-            /**
-                * is the template loaded?
-                */
-            isLoaded: boolean;
-            /**
-                * This is meant to be used to track the show and hide functions.
-                * This is NOT (!!) a flag to check if the element is actually visible to the user.
-                */
-            isShown: boolean;
-            /**
-                * Is this template a part of the HTML tree (the template manager injected it)
-                */
-            isInHtmlTree: boolean;
-            /**
-                * The HTML element containing this template
-                */
-            parent: HTMLElement;
-            /**
-                * A promise that is fulfilled when the template finished loading.
-                */
-            initPromise: Promise<Template>;
-            constructor(name: string, _configuration: ITemplateConfiguration);
-            /**
-                * Some templates have parameters (like background color for example).
-                * The parameters are provided to Handlebars which in turn generates the template.
-                * This function will update the template with the new parameters
-                *
-                * Note that when updating parameters the events will be registered again (after being cleared).
-                *
-                * @param params the new template parameters
-                */
-            updateParams(params: {
-                    [key: string]: string | number | boolean | object;
-            }, append?: boolean): void;
-            redraw(): void;
-            /**
-                * Get the template'S configuration
-                */
-            readonly configuration: ITemplateConfiguration;
-            /**
-                * A template can be a parent element for other templates or HTML elements.
-                * This function will deliver all child HTML elements of this template.
-                */
-            getChildElements(): Array<string>;
-            /**
-                * Appending the template to a parent HTML element.
-                * If a parent is already set and you wish to replace the old HTML with new one, forceRemove should be true.
-                * @param parent the parent to which the template is added
-                * @param forceRemove if the parent already exists, shoud the template be removed from it?
-                */
-            appendTo(parent: HTMLElement, forceRemove?: boolean): void;
-            /**
-                * Show the template using the provided visibilityFunction, or natively using display: flex.
-                * The provided function returns a promise that should be fullfilled when the element is shown.
-                * Since it is a promise async operations are more than possible.
-                * See the default viewer for an opacity example.
-                * @param visibilityFunction The function to execute to show the template.
-                */
-            show(visibilityFunction?: (template: Template) => Promise<Template>): Promise<Template>;
-            /**
-                * Hide the template using the provided visibilityFunction, or natively using display: none.
-                * The provided function returns a promise that should be fullfilled when the element is hidden.
-                * Since it is a promise async operations are more than possible.
-                * See the default viewer for an opacity example.
-                * @param visibilityFunction The function to execute to show the template.
-                */
-            hide(visibilityFunction?: (template: Template) => Promise<Template>): Promise<Template>;
-            /**
-                * Dispose this template
-                */
-            dispose(): void;
-    }
-}
-declare module BabylonViewer {
     export class ConfigurationContainer {
         configuration: ViewerConfiguration;
         viewerId: string;
@@ -1459,6 +1220,171 @@ declare module BabylonViewer {
     }
 }
 declare module BabylonViewer {
+    /**
+        * The object sent when an event is triggered
+        */
+    export interface EventCallback {
+            event: Event;
+            template: Template;
+            selector: string;
+            payload?: any;
+    }
+    /**
+        * The template manager, a member of the viewer class, will manage the viewer's templates and generate the HTML.
+        * The template manager managers a single viewer and can be seen as the collection of all sub-templates of the viewer.
+        */
+    export class TemplateManager {
+            containerElement: HTMLElement;
+            /**
+                * Will be triggered when any template is initialized
+                */
+            onTemplateInit: BABYLON.Observable<Template>;
+            /**
+                * Will be triggered when any template is fully loaded
+                */
+            onTemplateLoaded: BABYLON.Observable<Template>;
+            /**
+                * Will be triggered when a template state changes
+                */
+            onTemplateStateChange: BABYLON.Observable<Template>;
+            /**
+                * Will be triggered when all templates finished loading
+                */
+            onAllLoaded: BABYLON.Observable<TemplateManager>;
+            /**
+                * Will be triggered when any event on any template is triggered.
+                */
+            onEventTriggered: BABYLON.Observable<EventCallback>;
+            /**
+                * This template manager's event manager. In charge of callback registrations to native event types
+                */
+            eventManager: EventManager;
+            constructor(containerElement: HTMLElement);
+            /**
+                * Initialize the template(s) for the viewer. Called bay the Viewer class
+                * @param templates the templates to be used to initialize the main template
+                */
+            initTemplate(templates: {
+                    [key: string]: ITemplateConfiguration;
+            }): Promise<void>;
+            /**
+                * Get the canvas in the template tree.
+                * There must be one and only one canvas inthe template.
+                */
+            getCanvas(): HTMLCanvasElement | null;
+            /**
+                * Get a specific template from the template tree
+                * @param name the name of the template to load
+                */
+            getTemplate(name: string): Template | undefined;
+            /**
+                * Dispose the template manager
+                */
+            dispose(): void;
+    }
+    /**
+        * This class represents a single template in the viewer's template tree.
+        * An example for a template is a single canvas, an overlay (containing sub-templates) or the navigation bar.
+        * A template is injected using the template manager in the correct position.
+        * The template is rendered using Handlebars and can use Handlebars' features (such as parameter injection)
+        *
+        * For further information please refer to the documentation page, https://doc.babylonjs.com
+        */
+    export class Template {
+            name: string;
+            /**
+                * Will be triggered when the template is loaded
+                */
+            onLoaded: BABYLON.Observable<Template>;
+            /**
+                * will be triggered when the template is appended to the tree
+                */
+            onAppended: BABYLON.Observable<Template>;
+            /**
+                * Will be triggered when the template's state changed (shown, hidden)
+                */
+            onStateChange: BABYLON.Observable<Template>;
+            /**
+                * Will be triggered when an event is triggered on ths template.
+                * The event is a native browser event (like mouse or pointer events)
+                */
+            onEventTriggered: BABYLON.Observable<EventCallback>;
+            onParamsUpdated: BABYLON.Observable<Template>;
+            onHTMLRendered: BABYLON.Observable<Template>;
+            /**
+                * is the template loaded?
+                */
+            isLoaded: boolean;
+            /**
+                * This is meant to be used to track the show and hide functions.
+                * This is NOT (!!) a flag to check if the element is actually visible to the user.
+                */
+            isShown: boolean;
+            /**
+                * Is this template a part of the HTML tree (the template manager injected it)
+                */
+            isInHtmlTree: boolean;
+            /**
+                * The HTML element containing this template
+                */
+            parent: HTMLElement;
+            /**
+                * A promise that is fulfilled when the template finished loading.
+                */
+            initPromise: Promise<Template>;
+            constructor(name: string, _configuration: ITemplateConfiguration);
+            /**
+                * Some templates have parameters (like background color for example).
+                * The parameters are provided to Handlebars which in turn generates the template.
+                * This function will update the template with the new parameters
+                *
+                * Note that when updating parameters the events will be registered again (after being cleared).
+                *
+                * @param params the new template parameters
+                */
+            updateParams(params: {
+                    [key: string]: string | number | boolean | object;
+            }, append?: boolean): void;
+            redraw(): void;
+            /**
+                * Get the template'S configuration
+                */
+            readonly configuration: ITemplateConfiguration;
+            /**
+                * A template can be a parent element for other templates or HTML elements.
+                * This function will deliver all child HTML elements of this template.
+                */
+            getChildElements(): Array<string>;
+            /**
+                * Appending the template to a parent HTML element.
+                * If a parent is already set and you wish to replace the old HTML with new one, forceRemove should be true.
+                * @param parent the parent to which the template is added
+                * @param forceRemove if the parent already exists, shoud the template be removed from it?
+                */
+            appendTo(parent: HTMLElement, forceRemove?: boolean): void;
+            /**
+                * Show the template using the provided visibilityFunction, or natively using display: flex.
+                * The provided function returns a promise that should be fullfilled when the element is shown.
+                * Since it is a promise async operations are more than possible.
+                * See the default viewer for an opacity example.
+                * @param visibilityFunction The function to execute to show the template.
+                */
+            show(visibilityFunction?: (template: Template) => Promise<Template>): Promise<Template>;
+            /**
+                * Hide the template using the provided visibilityFunction, or natively using display: none.
+                * The provided function returns a promise that should be fullfilled when the element is hidden.
+                * Since it is a promise async operations are more than possible.
+                * See the default viewer for an opacity example.
+                * @param visibilityFunction The function to execute to show the template.
+                */
+            hide(visibilityFunction?: (template: Template) => Promise<Template>): Promise<Template>;
+            /**
+                * Dispose this template
+                */
+            dispose(): void;
+    }
+}
+declare module BabylonViewer {
     export interface IModelConfiguration {
             id?: string;
             url?: string;
@@ -1579,39 +1505,6 @@ declare module BabylonViewer {
 }
 declare module BabylonViewer {
     /**
-        * The EventManager is in charge of registering user interctions with the viewer.
-        * It is used in the TemplateManager
-        */
-    export class EventManager {
-            constructor(_templateManager: TemplateManager);
-            /**
-                * Register a new callback to a specific template.
-                * The best example for the usage can be found in the DefaultViewer
-                *
-                * @param templateName the templateName to register the event to
-                * @param callback The callback to be executed
-                * @param eventType the type of event to register
-                * @param selector an optional selector. if not defined the parent object in the template will be selected
-                */
-            registerCallback(templateName: string, callback: (eventData: EventCallback) => void, eventType?: string, selector?: string): void;
-            /**
-                * This will remove a registered event from the defined template.
-                * Each one of the variables apart from the template name are optional, but one must be provided.
-                *
-                * @param templateName the templateName
-                * @param callback the callback to remove (optional)
-                * @param eventType the event type to remove (optional)
-                * @param selector the selector from which to remove the event (optional)
-                */
-            unregisterCallback(templateName: string, callback: (eventData: EventCallback) => void, eventType?: string, selector?: string): void;
-            /**
-                * Dispose the event manager
-                */
-            dispose(): void;
-    }
-}
-declare module BabylonViewer {
-    /**
         * The ViewerLabs class will hold functions that are not (!) backwards compatible.
         * The APIs in all labs-related classes and configuration  might change.
         * Once stable, lab features will be moved to the publis API and configuration object.
@@ -1660,6 +1553,39 @@ declare module BabylonViewer {
 }
 declare module BabylonViewer {
     /**
+        * The EventManager is in charge of registering user interctions with the viewer.
+        * It is used in the TemplateManager
+        */
+    export class EventManager {
+            constructor(_templateManager: TemplateManager);
+            /**
+                * Register a new callback to a specific template.
+                * The best example for the usage can be found in the DefaultViewer
+                *
+                * @param templateName the templateName to register the event to
+                * @param callback The callback to be executed
+                * @param eventType the type of event to register
+                * @param selector an optional selector. if not defined the parent object in the template will be selected
+                */
+            registerCallback(templateName: string, callback: (eventData: EventCallback) => void, eventType?: string, selector?: string): void;
+            /**
+                * This will remove a registered event from the defined template.
+                * Each one of the variables apart from the template name are optional, but one must be provided.
+                *
+                * @param templateName the templateName
+                * @param callback the callback to remove (optional)
+                * @param eventType the event type to remove (optional)
+                * @param selector the selector from which to remove the event (optional)
+                */
+            unregisterCallback(templateName: string, callback: (eventData: EventCallback) => void, eventType?: string, selector?: string): void;
+            /**
+                * Dispose the event manager
+                */
+            dispose(): void;
+    }
+}
+declare module BabylonViewer {
+    /**
         * Defines an animation to be applied to a model (translation, scale or rotation).
         */
     export interface IModelAnimationConfiguration {

文件差異過大導致無法顯示
+ 1 - 1
dist/preview release/viewer/babylon.viewer.js


文件差異過大導致無法顯示
+ 4 - 0
dist/preview release/viewer/babylon.viewer.max.js


+ 205 - 283
dist/preview release/viewer/babylon.viewer.module.d.ts

@@ -150,85 +150,7 @@ declare module 'babylonjs-viewer/viewer/viewerManager' {
 }
 
 declare module 'babylonjs-viewer/viewer/defaultViewer' {
-    import { ViewerConfiguration, IModelConfiguration } from 'babylonjs-viewer/configuration';
-    import { Template } from 'babylonjs-viewer/templating/templateManager';
-    import { AbstractViewer } from 'babylonjs-viewer/viewer/viewer';
-    import { ViewerModel } from 'babylonjs-viewer/model/viewerModel';
-    import { IViewerTemplatePlugin } from 'babylonjs-viewer/templating/viewerTemplatePlugin';
-    /**
-        * The Default viewer is the default implementation of the AbstractViewer.
-        * It uses the templating system to render a new canvas and controls.
-        */
-    export class DefaultViewer extends AbstractViewer {
-            containerElement: HTMLElement;
-            fullscreenElement?: HTMLElement;
-            /**
-                * Create a new default viewer
-                * @param containerElement the element in which the templates will be rendered
-                * @param initialConfiguration the initial configuration. Defaults to extending the default configuration
-                */
-            constructor(containerElement: HTMLElement, initialConfiguration?: ViewerConfiguration);
-            registerTemplatePlugin(plugin: IViewerTemplatePlugin): void;
-            /**
-                * This will be executed when the templates initialize.
-                */
-            protected _onTemplatesLoaded(): Promise<AbstractViewer>;
-            protected _initVR(): void;
-            /**
-                * Toggle fullscreen of the entire viewer
-                */
-            toggleFullscreen: () => void;
-            /**
-                * Preparing the container element to present the viewer
-                */
-            protected _prepareContainerElement(): void;
-            /**
-                * This function will configure the templates and update them after a model was loaded
-                * It is mainly responsible to changing the title and subtitle etc'.
-                * @param model the model to be used to configure the templates by
-                */
-            protected _configureTemplate(model?: ViewerModel): void;
-            /**
-                * This will load a new model to the default viewer
-                * overriding the AbstractViewer's loadModel.
-                * The scene will automatically be cleared of the old models, if exist.
-                * @param model the configuration object (or URL) to load.
-                */
-            loadModel(model?: string | File | IModelConfiguration): Promise<ViewerModel>;
-            /**
-                * Show the overlay and the defined sub-screen.
-                * 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>;
-            /**
-                * Hide the overlay screen.
-                */
-            hideOverlayScreen(): Promise<string> | Promise<Template>;
-            /**
-                * show the viewer (in case it was hidden)
-                *
-                * @param visibilityFunction an optional function to execute in order to show the container
-                */
-            show(visibilityFunction?: ((template: Template) => Promise<Template>)): Promise<Template>;
-            /**
-                * hide the viewer (in case it is visible)
-                *
-                * @param visibilityFunction an optional function to execute in order to hide the container
-                */
-            hide(visibilityFunction?: ((template: Template) => Promise<Template>)): Promise<Template>;
-            /**
-                * Show the loading screen.
-                * The loading screen can be configured using the configuration object
-                */
-            showLoadingScreen(): Promise<string> | Promise<Template>;
-            /**
-                * Hide the loading screen
-                */
-            hideLoadingScreen(): Promise<string> | Promise<Template>;
-            dispose(): void;
-            protected _onConfigurationLoaded(configuration: ViewerConfiguration): void;
-    }
+    
 }
 
 declare module 'babylonjs-viewer/viewer/viewer' {
@@ -1094,175 +1016,6 @@ declare module 'babylonjs-viewer/configuration/configuration' {
     }
 }
 
-declare module 'babylonjs-viewer/templating/templateManager' {
-    import { Observable } from 'babylonjs';
-    import { EventManager } from 'babylonjs-viewer/templating/eventManager';
-    import { ITemplateConfiguration } from 'babylonjs-viewer/configuration/interfaces';
-    /**
-        * The object sent when an event is triggered
-        */
-    export interface EventCallback {
-            event: Event;
-            template: Template;
-            selector: string;
-            payload?: any;
-    }
-    /**
-        * The template manager, a member of the viewer class, will manage the viewer's templates and generate the HTML.
-        * The template manager managers a single viewer and can be seen as the collection of all sub-templates of the viewer.
-        */
-    export class TemplateManager {
-            containerElement: HTMLElement;
-            /**
-                * Will be triggered when any template is initialized
-                */
-            onTemplateInit: Observable<Template>;
-            /**
-                * Will be triggered when any template is fully loaded
-                */
-            onTemplateLoaded: Observable<Template>;
-            /**
-                * Will be triggered when a template state changes
-                */
-            onTemplateStateChange: Observable<Template>;
-            /**
-                * Will be triggered when all templates finished loading
-                */
-            onAllLoaded: Observable<TemplateManager>;
-            /**
-                * Will be triggered when any event on any template is triggered.
-                */
-            onEventTriggered: Observable<EventCallback>;
-            /**
-                * This template manager's event manager. In charge of callback registrations to native event types
-                */
-            eventManager: EventManager;
-            constructor(containerElement: HTMLElement);
-            /**
-                * Initialize the template(s) for the viewer. Called bay the Viewer class
-                * @param templates the templates to be used to initialize the main template
-                */
-            initTemplate(templates: {
-                    [key: string]: ITemplateConfiguration;
-            }): Promise<void>;
-            /**
-                * Get the canvas in the template tree.
-                * There must be one and only one canvas inthe template.
-                */
-            getCanvas(): HTMLCanvasElement | null;
-            /**
-                * Get a specific template from the template tree
-                * @param name the name of the template to load
-                */
-            getTemplate(name: string): Template | undefined;
-            /**
-                * Dispose the template manager
-                */
-            dispose(): void;
-    }
-    /**
-        * This class represents a single template in the viewer's template tree.
-        * An example for a template is a single canvas, an overlay (containing sub-templates) or the navigation bar.
-        * A template is injected using the template manager in the correct position.
-        * The template is rendered using Handlebars and can use Handlebars' features (such as parameter injection)
-        *
-        * For further information please refer to the documentation page, https://doc.babylonjs.com
-        */
-    export class Template {
-            name: string;
-            /**
-                * Will be triggered when the template is loaded
-                */
-            onLoaded: Observable<Template>;
-            /**
-                * will be triggered when the template is appended to the tree
-                */
-            onAppended: Observable<Template>;
-            /**
-                * Will be triggered when the template's state changed (shown, hidden)
-                */
-            onStateChange: Observable<Template>;
-            /**
-                * Will be triggered when an event is triggered on ths template.
-                * The event is a native browser event (like mouse or pointer events)
-                */
-            onEventTriggered: Observable<EventCallback>;
-            onParamsUpdated: Observable<Template>;
-            onHTMLRendered: Observable<Template>;
-            /**
-                * is the template loaded?
-                */
-            isLoaded: boolean;
-            /**
-                * This is meant to be used to track the show and hide functions.
-                * This is NOT (!!) a flag to check if the element is actually visible to the user.
-                */
-            isShown: boolean;
-            /**
-                * Is this template a part of the HTML tree (the template manager injected it)
-                */
-            isInHtmlTree: boolean;
-            /**
-                * The HTML element containing this template
-                */
-            parent: HTMLElement;
-            /**
-                * A promise that is fulfilled when the template finished loading.
-                */
-            initPromise: Promise<Template>;
-            constructor(name: string, _configuration: ITemplateConfiguration);
-            /**
-                * Some templates have parameters (like background color for example).
-                * The parameters are provided to Handlebars which in turn generates the template.
-                * This function will update the template with the new parameters
-                *
-                * Note that when updating parameters the events will be registered again (after being cleared).
-                *
-                * @param params the new template parameters
-                */
-            updateParams(params: {
-                    [key: string]: string | number | boolean | object;
-            }, append?: boolean): void;
-            redraw(): void;
-            /**
-                * Get the template'S configuration
-                */
-            readonly configuration: ITemplateConfiguration;
-            /**
-                * A template can be a parent element for other templates or HTML elements.
-                * This function will deliver all child HTML elements of this template.
-                */
-            getChildElements(): Array<string>;
-            /**
-                * Appending the template to a parent HTML element.
-                * If a parent is already set and you wish to replace the old HTML with new one, forceRemove should be true.
-                * @param parent the parent to which the template is added
-                * @param forceRemove if the parent already exists, shoud the template be removed from it?
-                */
-            appendTo(parent: HTMLElement, forceRemove?: boolean): void;
-            /**
-                * Show the template using the provided visibilityFunction, or natively using display: flex.
-                * The provided function returns a promise that should be fullfilled when the element is shown.
-                * Since it is a promise async operations are more than possible.
-                * See the default viewer for an opacity example.
-                * @param visibilityFunction The function to execute to show the template.
-                */
-            show(visibilityFunction?: (template: Template) => Promise<Template>): Promise<Template>;
-            /**
-                * Hide the template using the provided visibilityFunction, or natively using display: none.
-                * The provided function returns a promise that should be fullfilled when the element is hidden.
-                * Since it is a promise async operations are more than possible.
-                * See the default viewer for an opacity example.
-                * @param visibilityFunction The function to execute to show the template.
-                */
-            hide(visibilityFunction?: (template: Template) => Promise<Template>): Promise<Template>;
-            /**
-                * Dispose this template
-                */
-            dispose(): void;
-    }
-}
-
 declare module 'babylonjs-viewer/configuration/configurationContainer' {
     import { ViewerConfiguration } from 'babylonjs-viewer/configuration/configuration';
     import { Color3, Scene } from 'babylonjs';
@@ -1555,6 +1308,175 @@ declare module 'babylonjs-viewer/managers/sceneManager' {
     }
 }
 
+declare module 'babylonjs-viewer/templating/templateManager' {
+    import { Observable } from 'babylonjs';
+    import { EventManager } from 'babylonjs-viewer/templating/eventManager';
+    import { ITemplateConfiguration } from 'babylonjs-viewer/configuration/interfaces';
+    /**
+        * The object sent when an event is triggered
+        */
+    export interface EventCallback {
+            event: Event;
+            template: Template;
+            selector: string;
+            payload?: any;
+    }
+    /**
+        * The template manager, a member of the viewer class, will manage the viewer's templates and generate the HTML.
+        * The template manager managers a single viewer and can be seen as the collection of all sub-templates of the viewer.
+        */
+    export class TemplateManager {
+            containerElement: HTMLElement;
+            /**
+                * Will be triggered when any template is initialized
+                */
+            onTemplateInit: Observable<Template>;
+            /**
+                * Will be triggered when any template is fully loaded
+                */
+            onTemplateLoaded: Observable<Template>;
+            /**
+                * Will be triggered when a template state changes
+                */
+            onTemplateStateChange: Observable<Template>;
+            /**
+                * Will be triggered when all templates finished loading
+                */
+            onAllLoaded: Observable<TemplateManager>;
+            /**
+                * Will be triggered when any event on any template is triggered.
+                */
+            onEventTriggered: Observable<EventCallback>;
+            /**
+                * This template manager's event manager. In charge of callback registrations to native event types
+                */
+            eventManager: EventManager;
+            constructor(containerElement: HTMLElement);
+            /**
+                * Initialize the template(s) for the viewer. Called bay the Viewer class
+                * @param templates the templates to be used to initialize the main template
+                */
+            initTemplate(templates: {
+                    [key: string]: ITemplateConfiguration;
+            }): Promise<void>;
+            /**
+                * Get the canvas in the template tree.
+                * There must be one and only one canvas inthe template.
+                */
+            getCanvas(): HTMLCanvasElement | null;
+            /**
+                * Get a specific template from the template tree
+                * @param name the name of the template to load
+                */
+            getTemplate(name: string): Template | undefined;
+            /**
+                * Dispose the template manager
+                */
+            dispose(): void;
+    }
+    /**
+        * This class represents a single template in the viewer's template tree.
+        * An example for a template is a single canvas, an overlay (containing sub-templates) or the navigation bar.
+        * A template is injected using the template manager in the correct position.
+        * The template is rendered using Handlebars and can use Handlebars' features (such as parameter injection)
+        *
+        * For further information please refer to the documentation page, https://doc.babylonjs.com
+        */
+    export class Template {
+            name: string;
+            /**
+                * Will be triggered when the template is loaded
+                */
+            onLoaded: Observable<Template>;
+            /**
+                * will be triggered when the template is appended to the tree
+                */
+            onAppended: Observable<Template>;
+            /**
+                * Will be triggered when the template's state changed (shown, hidden)
+                */
+            onStateChange: Observable<Template>;
+            /**
+                * Will be triggered when an event is triggered on ths template.
+                * The event is a native browser event (like mouse or pointer events)
+                */
+            onEventTriggered: Observable<EventCallback>;
+            onParamsUpdated: Observable<Template>;
+            onHTMLRendered: Observable<Template>;
+            /**
+                * is the template loaded?
+                */
+            isLoaded: boolean;
+            /**
+                * This is meant to be used to track the show and hide functions.
+                * This is NOT (!!) a flag to check if the element is actually visible to the user.
+                */
+            isShown: boolean;
+            /**
+                * Is this template a part of the HTML tree (the template manager injected it)
+                */
+            isInHtmlTree: boolean;
+            /**
+                * The HTML element containing this template
+                */
+            parent: HTMLElement;
+            /**
+                * A promise that is fulfilled when the template finished loading.
+                */
+            initPromise: Promise<Template>;
+            constructor(name: string, _configuration: ITemplateConfiguration);
+            /**
+                * Some templates have parameters (like background color for example).
+                * The parameters are provided to Handlebars which in turn generates the template.
+                * This function will update the template with the new parameters
+                *
+                * Note that when updating parameters the events will be registered again (after being cleared).
+                *
+                * @param params the new template parameters
+                */
+            updateParams(params: {
+                    [key: string]: string | number | boolean | object;
+            }, append?: boolean): void;
+            redraw(): void;
+            /**
+                * Get the template'S configuration
+                */
+            readonly configuration: ITemplateConfiguration;
+            /**
+                * A template can be a parent element for other templates or HTML elements.
+                * This function will deliver all child HTML elements of this template.
+                */
+            getChildElements(): Array<string>;
+            /**
+                * Appending the template to a parent HTML element.
+                * If a parent is already set and you wish to replace the old HTML with new one, forceRemove should be true.
+                * @param parent the parent to which the template is added
+                * @param forceRemove if the parent already exists, shoud the template be removed from it?
+                */
+            appendTo(parent: HTMLElement, forceRemove?: boolean): void;
+            /**
+                * Show the template using the provided visibilityFunction, or natively using display: flex.
+                * The provided function returns a promise that should be fullfilled when the element is shown.
+                * Since it is a promise async operations are more than possible.
+                * See the default viewer for an opacity example.
+                * @param visibilityFunction The function to execute to show the template.
+                */
+            show(visibilityFunction?: (template: Template) => Promise<Template>): Promise<Template>;
+            /**
+                * Hide the template using the provided visibilityFunction, or natively using display: none.
+                * The provided function returns a promise that should be fullfilled when the element is hidden.
+                * Since it is a promise async operations are more than possible.
+                * See the default viewer for an opacity example.
+                * @param visibilityFunction The function to execute to show the template.
+                */
+            hide(visibilityFunction?: (template: Template) => Promise<Template>): Promise<Template>;
+            /**
+                * Dispose this template
+                */
+            dispose(): void;
+    }
+}
+
 declare module 'babylonjs-viewer/configuration/interfaces/modelConfiguration' {
     import { IModelAnimationConfiguration } from "babylonjs-viewer/configuration/interfaces/modelAnimationConfiguration";
     export interface IModelConfiguration {
@@ -1702,41 +1624,6 @@ declare module 'babylonjs-viewer/configuration/interfaces/environmentMapConfigur
     }
 }
 
-declare module 'babylonjs-viewer/templating/eventManager' {
-    import { EventCallback, TemplateManager } from "babylonjs-viewer/templating/templateManager";
-    /**
-        * The EventManager is in charge of registering user interctions with the viewer.
-        * It is used in the TemplateManager
-        */
-    export class EventManager {
-            constructor(_templateManager: TemplateManager);
-            /**
-                * Register a new callback to a specific template.
-                * The best example for the usage can be found in the DefaultViewer
-                *
-                * @param templateName the templateName to register the event to
-                * @param callback The callback to be executed
-                * @param eventType the type of event to register
-                * @param selector an optional selector. if not defined the parent object in the template will be selected
-                */
-            registerCallback(templateName: string, callback: (eventData: EventCallback) => void, eventType?: string, selector?: string): void;
-            /**
-                * This will remove a registered event from the defined template.
-                * Each one of the variables apart from the template name are optional, but one must be provided.
-                *
-                * @param templateName the templateName
-                * @param callback the callback to remove (optional)
-                * @param eventType the event type to remove (optional)
-                * @param selector the selector from which to remove the event (optional)
-                */
-            unregisterCallback(templateName: string, callback: (eventData: EventCallback) => void, eventType?: string, selector?: string): void;
-            /**
-                * Dispose the event manager
-                */
-            dispose(): void;
-    }
-}
-
 declare module 'babylonjs-viewer/labs/viewerLabs' {
     import { PBREnvironment } from "babylonjs-viewer/labs/environmentSerializer";
     import { ShadowLight, Vector3, Scene } from 'babylonjs';
@@ -1788,6 +1675,41 @@ declare module 'babylonjs-viewer/labs/viewerLabs' {
     }
 }
 
+declare module 'babylonjs-viewer/templating/eventManager' {
+    import { EventCallback, TemplateManager } from "babylonjs-viewer/templating/templateManager";
+    /**
+        * The EventManager is in charge of registering user interctions with the viewer.
+        * It is used in the TemplateManager
+        */
+    export class EventManager {
+            constructor(_templateManager: TemplateManager);
+            /**
+                * Register a new callback to a specific template.
+                * The best example for the usage can be found in the DefaultViewer
+                *
+                * @param templateName the templateName to register the event to
+                * @param callback The callback to be executed
+                * @param eventType the type of event to register
+                * @param selector an optional selector. if not defined the parent object in the template will be selected
+                */
+            registerCallback(templateName: string, callback: (eventData: EventCallback) => void, eventType?: string, selector?: string): void;
+            /**
+                * This will remove a registered event from the defined template.
+                * Each one of the variables apart from the template name are optional, but one must be provided.
+                *
+                * @param templateName the templateName
+                * @param callback the callback to remove (optional)
+                * @param eventType the event type to remove (optional)
+                * @param selector the selector from which to remove the event (optional)
+                */
+            unregisterCallback(templateName: string, callback: (eventData: EventCallback) => void, eventType?: string, selector?: string): void;
+            /**
+                * Dispose the event manager
+                */
+            dispose(): void;
+    }
+}
+
 declare module 'babylonjs-viewer/configuration/interfaces/modelAnimationConfiguration' {
     /**
         * Defines an animation to be applied to a model (translation, scale or rotation).

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

@@ -11,7 +11,7 @@
   - New GUI control: [InputPassword](https://doc.babylonjs.com/how_to/gui#inputpassword) ([theom](https://github.com/theom))
   - New GUI container [SelectionPanel](http://doc.babylonjs.com/how_to/selector) ([JohnK](https://github.com/BabylonJSGuide))
 - Gizmo Support ([TrevorDev](https://github.com/TrevorDev))
-  - Gizmo and GizmoManager classes used to manipulate meshes in a scene. Gizmo types include: position, scale, rotation and bounding box. [Doc](http://doc.babylonjs.com/how_to/gizmo) ([TrevorDev](https://github.com/TrevorDev))
+  - Gizmo and GizmoManager classes used to manipulate meshes in a scene. Gizmo types include: position, scale, rotation and bounding box [Doc](http://doc.babylonjs.com/how_to/gizmo) ([TrevorDev](https://github.com/TrevorDev))
   - New behaviors: PointerDragBehavior, SixDofDragBehavior and MultiPointerScaleBehavior to enable smooth drag and drop/scaling with mouse or 6dof controller on a mesh. [Doc](http://doc.babylonjs.com/how_to/meshbehavior) ([TrevorDev](https://github.com/TrevorDev))
   - Added attachToBoxBehavior to attach UI to a bounding box ([TrevorDev](https://github.com/TrevorDev))
   - Gizmo manager's internal gizmos are now public ([TrevorDev](https://github.com/TrevorDev))

+ 1 - 1
gui/src/2D/controls/control.ts

@@ -960,7 +960,7 @@ export class Control {
     /** @hidden */
     protected _applyStates(context: CanvasRenderingContext2D): void {
         if (this._isFontSizeInPercentage) {
-            this._resetFontCache();
+            this._fontSet = true;
         }
 
         if (this._fontSet) {

+ 38 - 0
src/Gizmos/babylon.gizmoManager.ts

@@ -11,6 +11,8 @@ module BABYLON {
         private _pointerObserver: Nullable<Observer<PointerInfo>> = null;
         private _attachedMesh: Nullable<AbstractMesh> = null;
         private _boundingBoxColor = BABYLON.Color3.FromHexString("#0984e3");
+        private _defaultUtilityLayer:UtilityLayerRenderer;
+        private _defaultKeepDepthUtilityLayer:UtilityLayerRenderer;
         /**
          * When bounding box gizmo is enabled, this can be used to track drag/end events
          */
@@ -28,7 +30,15 @@ module BABYLON {
          * Instatiates a gizmo manager
          * @param scene the scene to overlay the gizmos on top of
          */
+<<<<<<< HEAD
         constructor(private scene: Scene) {
+=======
+        constructor(private scene:Scene){
+            this._defaultKeepDepthUtilityLayer = new UtilityLayerRenderer(scene);
+            this._defaultKeepDepthUtilityLayer.utilityLayerScene.autoClearDepthAndStencil = false;
+            this._defaultUtilityLayer = new UtilityLayerRenderer(scene);
+            
+>>>>>>> 747ca4d7ec7c52281e24f222de0c930976354dad
             this.gizmos = {positionGizmo: null, rotationGizmo: null, scaleGizmo: null, boundingBoxGizmo: null};
 
             // Instatiate/dispose gizmos based on pointer actions
@@ -92,10 +102,17 @@ module BABYLON {
         /**
          * If the position gizmo is enabled
          */
+<<<<<<< HEAD
         public set positionGizmoEnabled(value: boolean) {
             if (value) {
                 if (!this.gizmos.positionGizmo) {
                     this.gizmos.positionGizmo = new PositionGizmo();
+=======
+        public set positionGizmoEnabled(value:boolean){
+            if(value){
+                if(!this.gizmos.positionGizmo){
+                    this.gizmos.positionGizmo = new PositionGizmo(this._defaultUtilityLayer);
+>>>>>>> 747ca4d7ec7c52281e24f222de0c930976354dad
                 }
                 this.gizmos.positionGizmo.attachedMesh = this._attachedMesh;
             }else if (this.gizmos.positionGizmo) {
@@ -109,10 +126,17 @@ module BABYLON {
         /**
          * If the rotation gizmo is enabled
          */
+<<<<<<< HEAD
         public set rotationGizmoEnabled(value: boolean) {
             if (value) {
                 if (!this.gizmos.rotationGizmo) {
                     this.gizmos.rotationGizmo = new RotationGizmo();
+=======
+        public set rotationGizmoEnabled(value:boolean){
+            if(value){
+                if(!this.gizmos.rotationGizmo){
+                    this.gizmos.rotationGizmo = new RotationGizmo(this._defaultUtilityLayer);
+>>>>>>> 747ca4d7ec7c52281e24f222de0c930976354dad
                 }
                 this.gizmos.rotationGizmo.attachedMesh = this._attachedMesh;
             }else if (this.gizmos.rotationGizmo) {
@@ -126,9 +150,15 @@ module BABYLON {
         /**
          * If the scale gizmo is enabled
          */
+<<<<<<< HEAD
         public set scaleGizmoEnabled(value: boolean) {
             if (value) {
                 this.gizmos.scaleGizmo = this.gizmos.scaleGizmo || new ScaleGizmo();
+=======
+        public set scaleGizmoEnabled(value:boolean){
+            if(value){
+                this.gizmos.scaleGizmo = this.gizmos.scaleGizmo || new ScaleGizmo(this._defaultUtilityLayer);
+>>>>>>> 747ca4d7ec7c52281e24f222de0c930976354dad
                 this.gizmos.scaleGizmo.attachedMesh = this._attachedMesh;
             }else if (this.gizmos.scaleGizmo) {
                 this.gizmos.scaleGizmo.attachedMesh = null;
@@ -141,9 +171,15 @@ module BABYLON {
         /**
          * If the boundingBox gizmo is enabled
          */
+<<<<<<< HEAD
         public set boundingBoxGizmoEnabled(value: boolean) {
             if (value) {
                 this.gizmos.boundingBoxGizmo = this.gizmos.boundingBoxGizmo || new BoundingBoxGizmo(this._boundingBoxColor);
+=======
+        public set boundingBoxGizmoEnabled(value:boolean){
+            if(value){
+                this.gizmos.boundingBoxGizmo = this.gizmos.boundingBoxGizmo || new BoundingBoxGizmo(this._boundingBoxColor, this._defaultKeepDepthUtilityLayer);
+>>>>>>> 747ca4d7ec7c52281e24f222de0c930976354dad
                 this.gizmos.boundingBoxGizmo.attachedMesh = this._attachedMesh;
                 if (this._attachedMesh) {
                     this._attachedMesh.removeBehavior(this.boundingBoxDragBehavior);
@@ -169,6 +205,8 @@ module BABYLON {
                     gizmo.dispose();
                 }
             }
+            this._defaultKeepDepthUtilityLayer.dispose();
+            this._defaultUtilityLayer.dispose();
             this.boundingBoxDragBehavior.detach();
         }
     }

+ 197 - 0
src/Gizmos/babylon.planeRotationGizmo.ts

@@ -1,3 +1,4 @@
+<<<<<<< HEAD
 module BABYLON {
     /**
      * Single plane rotation gizmo
@@ -191,4 +192,200 @@ module BABYLON {
             super.dispose();
         }
     }
+=======
+module BABYLON {
+    /**
+     * Single plane rotation gizmo
+     */
+    export class PlaneRotationGizmo extends Gizmo {
+        /**
+         * Drag behavior responsible for the gizmos dragging interactions
+         */
+        public dragBehavior:PointerDragBehavior;
+        private _pointerObserver:Nullable<Observer<PointerInfo>> = null;
+        
+        /**
+         * Rotation distance in radians that the gizmo will snap to (Default: 0)
+         */
+        public snapDistance = 0;
+        /**
+         * Event that fires each time the gizmo snaps to a new location.
+         * * snapDistance is the the change in distance
+         */
+        public onSnapObservable = new Observable<{snapDistance:number}>();
+
+        /**
+         * Creates a PlaneRotationGizmo
+         * @param gizmoLayer The utility layer the gizmo will be added to
+         * @param planeNormal The normal of the plane which the gizmo will be able to rotate on
+         * @param color The color of the gizmo
+         * @param tessellation Amount of tessellation to be used when creating rotation circles
+         */
+        constructor(planeNormal:Vector3, color:Color3 = Color3.Gray(), gizmoLayer:UtilityLayerRenderer = UtilityLayerRenderer.DefaultUtilityLayer, tessellation = 32){
+            super(gizmoLayer);
+            
+            // Create Material
+            var coloredMaterial = new BABYLON.StandardMaterial("", gizmoLayer.utilityLayerScene);
+            coloredMaterial.disableLighting = true;
+            coloredMaterial.emissiveColor = color;
+            
+            var hoverMaterial = new BABYLON.StandardMaterial("", gizmoLayer.utilityLayerScene);
+            hoverMaterial.disableLighting = true;
+            hoverMaterial.emissiveColor = color.add(new Color3(0.3,0.3,0.3));
+
+            // Build mesh on root node
+            var parentMesh = new BABYLON.AbstractMesh("", gizmoLayer.utilityLayerScene);
+
+            // Create circle out of lines
+            var radius = 0.8;
+            var points = new Array<Vector3>();
+            for(var i = 0;i < tessellation;i++){
+                var radian = (2*Math.PI) * (i/(tessellation-1));
+                points.push(new Vector3(radius*Math.sin(radian), 0, radius*Math.cos(radian)));
+            }
+            let rotationMesh = Mesh.CreateLines("", points, gizmoLayer.utilityLayerScene);
+            rotationMesh.color = coloredMaterial.emissiveColor;
+            
+            // Position arrow pointing in its drag axis
+            rotationMesh.scaling.scaleInPlace(0.26);
+            rotationMesh.material = coloredMaterial;
+            rotationMesh.rotation.x = Math.PI/2;
+            parentMesh.addChild(rotationMesh);
+            parentMesh.lookAt(this._rootMesh.position.subtract(planeNormal));
+            
+            this._rootMesh.addChild(parentMesh);
+            parentMesh.scaling.scaleInPlace(1/3);
+            // Add drag behavior to handle events when the gizmo is dragged
+            this.dragBehavior = new PointerDragBehavior({dragPlaneNormal: planeNormal});
+            this.dragBehavior.moveAttached = false;
+            this.dragBehavior.maxDragAngle =  Math.PI*9/20;
+            this.dragBehavior._useAlternatePickedPointAboveMaxDragAngle = true;
+            this._rootMesh.addBehavior(this.dragBehavior);
+
+            var lastDragPosition = new Vector3();
+
+            this.dragBehavior.onDragStartObservable.add((e)=>{
+                if(this.attachedMesh){
+                    lastDragPosition.copyFrom(e.dragPlanePoint);
+                }
+            })
+
+            var rotationMatrix = new Matrix();
+            var planeNormalTowardsCamera = new Vector3();
+            var localPlaneNormalTowardsCamera = new Vector3();
+
+            var tmpSnapEvent = {snapDistance: 0};
+            var currentSnapDragDistance = 0;
+            var tmpMatrix = new BABYLON.Matrix();
+            var tmpVector = new BABYLON.Vector3();
+            var amountToRotate = new BABYLON.Quaternion();
+            this.dragBehavior.onDragObservable.add((event)=>{
+                if(this.attachedMesh){
+                    if(!this.attachedMesh.rotationQuaternion){
+                        this.attachedMesh.rotationQuaternion = Quaternion.RotationYawPitchRoll(this.attachedMesh.rotation.y, this.attachedMesh.rotation.x, this.attachedMesh.rotation.z);
+                    }
+                    // Calc angle over full 360 degree (https://stackoverflow.com/questions/43493711/the-angle-between-two-3d-vectors-with-a-result-range-0-360)
+                    var newVector = event.dragPlanePoint.subtract(this.attachedMesh.absolutePosition).normalize();
+                    var originalVector = lastDragPosition.subtract(this.attachedMesh.absolutePosition).normalize();
+                    var cross = Vector3.Cross(newVector,originalVector);
+                    var dot = Vector3.Dot(newVector,originalVector);
+                    var angle = Math.atan2(cross.length(), dot);
+                    planeNormalTowardsCamera.copyFrom(planeNormal);
+                    localPlaneNormalTowardsCamera.copyFrom(planeNormal);
+                    if(this.updateGizmoRotationToMatchAttachedMesh){
+                        this.attachedMesh.rotationQuaternion.toRotationMatrix(rotationMatrix);
+                        localPlaneNormalTowardsCamera = Vector3.TransformCoordinates(planeNormalTowardsCamera, rotationMatrix);
+                    }
+                    // Flip up vector depending on which side the camera is on
+                    if(gizmoLayer.utilityLayerScene.activeCamera){
+                        var camVec = gizmoLayer.utilityLayerScene.activeCamera.position.subtract(this.attachedMesh.position);
+                        if(Vector3.Dot(camVec, localPlaneNormalTowardsCamera) > 0){
+                            planeNormalTowardsCamera.scaleInPlace(-1);
+                            localPlaneNormalTowardsCamera.scaleInPlace(-1);
+                        }
+                    }
+                    var halfCircleSide = Vector3.Dot(localPlaneNormalTowardsCamera, cross) > 0.0;
+                    if (halfCircleSide) angle = -angle;
+                    
+                    // Snapping logic
+                    var snapped = false;
+                    if(this.snapDistance != 0){
+                        currentSnapDragDistance+=angle
+                        if(Math.abs(currentSnapDragDistance)>this.snapDistance){
+                            var dragSteps = Math.floor(currentSnapDragDistance/this.snapDistance);
+                            currentSnapDragDistance = currentSnapDragDistance % this.snapDistance;
+                            angle = this.snapDistance*dragSteps;
+                            snapped = true;
+                        }else{
+                            angle = 0;
+                        }
+                    }
+
+                    // If the mesh has a parent, convert needed world rotation to local rotation
+                    tmpMatrix.reset();
+                    if(this.attachedMesh.parent){
+                        this.attachedMesh.parent.computeWorldMatrix().invertToRef(tmpMatrix);
+                        tmpMatrix.getRotationMatrixToRef(tmpMatrix);
+                        Vector3.TransformCoordinatesToRef(planeNormalTowardsCamera, tmpMatrix, planeNormalTowardsCamera);
+                    }
+
+                    // Convert angle and axis to quaternion (http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm)
+                    var quaternionCoefficient = Math.sin(angle/2);
+                    amountToRotate.set(planeNormalTowardsCamera.x*quaternionCoefficient,planeNormalTowardsCamera.y*quaternionCoefficient,planeNormalTowardsCamera.z*quaternionCoefficient,Math.cos(angle/2));
+
+                    // If the meshes local scale is inverted (eg. loaded gltf file parent with z scale of -1) the rotation needs to be inverted on the y axis
+                    if(tmpMatrix.determinant() > 0){
+                        amountToRotate.toEulerAnglesToRef(tmpVector);
+                        BABYLON.Quaternion.RotationYawPitchRollToRef(tmpVector.y, -tmpVector.x, -tmpVector.z, amountToRotate);
+                    }
+
+                     if(this.updateGizmoRotationToMatchAttachedMesh){
+                        // Rotate selected mesh quaternion over fixed axis
+                        this.attachedMesh.rotationQuaternion.multiplyToRef(amountToRotate,this.attachedMesh.rotationQuaternion);
+                     }else{
+                         // Rotate selected mesh quaternion over rotated axis
+                        amountToRotate.multiplyToRef(this.attachedMesh.rotationQuaternion,this.attachedMesh.rotationQuaternion);
+                     }
+                     
+
+                    lastDragPosition.copyFrom(event.dragPlanePoint);
+                    if(snapped){
+                        tmpSnapEvent.snapDistance = angle;
+                        this.onSnapObservable.notifyObservers(tmpSnapEvent);
+                    }
+                }
+            })
+
+            this._pointerObserver = gizmoLayer.utilityLayerScene.onPointerObservable.add((pointerInfo, eventState)=>{
+                if(this._customMeshSet){
+                    return;
+                }
+                var isHovered = pointerInfo.pickInfo && (this._rootMesh.getChildMeshes().indexOf(<Mesh>pointerInfo.pickInfo.pickedMesh) != -1);
+                var material = isHovered ? hoverMaterial : coloredMaterial;
+                this._rootMesh.getChildMeshes().forEach((m)=>{
+                    m.material = material;
+                    if((<LinesMesh>m).color){
+                        (<LinesMesh>m).color = material.emissiveColor
+                    }
+                });
+            });
+        }
+
+        protected _attachedMeshChanged(value:Nullable<AbstractMesh>){
+            if(this.dragBehavior){
+                this.dragBehavior.enabled = value ? true : false;
+            }
+        }
+
+        /**
+         * Disposes of the gizmo
+         */
+        public dispose(){
+            this.onSnapObservable.clear();
+            this.gizmoLayer.utilityLayerScene.onPointerObservable.remove(this._pointerObserver);
+            this.dragBehavior.detach();
+            super.dispose();
+        }
+    }
+>>>>>>> 747ca4d7ec7c52281e24f222de0c930976354dad
 }

+ 9 - 0
src/Gizmos/babylon.rotationGizmo.ts

@@ -26,12 +26,21 @@ module BABYLON {
         /**
          * Creates a RotationGizmo
          * @param gizmoLayer The utility layer the gizmo will be added to
+         * @param tessellation Amount of tessellation to be used when creating rotation circles
          */
+<<<<<<< HEAD
         constructor(gizmoLayer: UtilityLayerRenderer= UtilityLayerRenderer.DefaultUtilityLayer) {
             super(gizmoLayer);
             this.xGizmo = new PlaneRotationGizmo(new Vector3(1, 0, 0), BABYLON.Color3.Red().scale(0.5), gizmoLayer);
             this.yGizmo = new PlaneRotationGizmo(new Vector3(0, 1, 0), BABYLON.Color3.Green().scale(0.5), gizmoLayer);
             this.zGizmo = new PlaneRotationGizmo(new Vector3(0, 0, 1), BABYLON.Color3.Blue().scale(0.5), gizmoLayer);
+=======
+        constructor(gizmoLayer:UtilityLayerRenderer=UtilityLayerRenderer.DefaultUtilityLayer, tessellation = 32){
+            super(gizmoLayer);
+            this.xGizmo = new PlaneRotationGizmo(new Vector3(1,0,0), BABYLON.Color3.Red().scale(0.5), gizmoLayer, tessellation);
+            this.yGizmo = new PlaneRotationGizmo(new Vector3(0,1,0), BABYLON.Color3.Green().scale(0.5), gizmoLayer, tessellation);
+            this.zGizmo = new PlaneRotationGizmo(new Vector3(0,0,1), BABYLON.Color3.Blue().scale(0.5), gizmoLayer, tessellation);
+>>>>>>> 747ca4d7ec7c52281e24f222de0c930976354dad
             this.attachedMesh = null;
         }
 

+ 13 - 1
src/Particles/babylon.subEmitter.ts

@@ -38,7 +38,19 @@ module BABYLON {
             /**
              * the particle system to be used by the sub emitter
              */
-            public particleSystem: ParticleSystem) {
+            public particleSystem: ParticleSystem
+        ) {
+            // Create mesh as emitter to support rotation
+            if(!particleSystem.emitter || !(<AbstractMesh>particleSystem.emitter).dispose){
+                particleSystem.emitter = new BABYLON.AbstractMesh("SubemitterSystemEmitter", particleSystem.getScene());
+            }
+
+            // Automatically dispose of subemitter when system is disposed
+            particleSystem.onDisposeObservable.add(()=>{
+                if(particleSystem.emitter && (<AbstractMesh>particleSystem.emitter).dispose){
+                    (<AbstractMesh>particleSystem.emitter).dispose();
+                }
+            })
         }
         /**
          * Clones the sub emitter