Browse Source

Added metadata to materials + nightly

David Catuhe 6 years ago
parent
commit
17fd1bf389

File diff suppressed because it is too large
+ 10880 - 10861
Playground/babylon.d.txt


File diff suppressed because it is too large
+ 10929 - 10910
dist/preview release/babylon.d.ts


File diff suppressed because it is too large
+ 1 - 1
dist/preview release/babylon.js


+ 49 - 3
dist/preview release/babylon.max.js

@@ -29045,6 +29045,23 @@ var BABYLON;
             return null;
         };
         /**
+         * Gets a morph target using a given id (if many are found, this function will pick the first one)
+         * @param id defines the id to search for
+         * @return the found morph target or null if not found at all.
+         */
+        Scene.prototype.getMorphTargetById = function (id) {
+            for (var managerIndex = 0; managerIndex < this.morphTargetManagers.length; ++managerIndex) {
+                var morphTargetManager = this.morphTargetManagers[managerIndex];
+                for (var index = 0; index < morphTargetManager.numTargets; ++index) {
+                    var target = morphTargetManager.getTarget(index);
+                    if (target.id === id) {
+                        return target;
+                    }
+                }
+            }
+            return null;
+        };
+        /**
          * Gets a boolean indicating if the given mesh is active
          * @param mesh defines the mesh to look for
          * @returns true if the mesh is in the active list
@@ -36740,6 +36757,10 @@ var BABYLON;
          */
         function Material(name, scene, doNotAdd) {
             /**
+             * Gets or sets user defined metadata
+             */
+            this.metadata = null;
+            /**
              * Specifies if the ready state should be checked on each call
              */
             this.checkReadyOnEveryCall = false;
@@ -55251,9 +55272,17 @@ var BABYLON;
                 var targetedAnimation = parsedAnimationGroup.targetedAnimations[i];
                 var animation = BABYLON.Animation.Parse(targetedAnimation.animation);
                 var id = targetedAnimation.targetId;
-                var targetNode = scene.getNodeByID(id);
-                if (targetNode != null) {
-                    animationGroup.addTargetedAnimation(animation, targetNode);
+                if (targetedAnimation.animation.property === "influence") { // morph target animation
+                    var morphTarget = scene.getMorphTargetById(id);
+                    if (morphTarget) {
+                        animationGroup.addTargetedAnimation(animation, morphTarget);
+                    }
+                }
+                else {
+                    var targetNode = scene.getNodeByID(id);
+                    if (targetNode != null) {
+                        animationGroup.addTargetedAnimation(animation, targetNode);
+                    }
                 }
             }
             if (parsedAnimationGroup.from !== null && parsedAnimationGroup.from !== null) {
@@ -104595,6 +104624,7 @@ var BABYLON;
 
 //# sourceMappingURL=babylon.gizmoManager.js.map
 
+
 var BABYLON;
 (function (BABYLON) {
     /**
@@ -104759,6 +104789,9 @@ var BABYLON;
             serializationObject.name = this.name;
             serializationObject.influence = this.influence;
             serializationObject.positions = Array.prototype.slice.call(this.getPositions());
+            if (this.id != null) {
+                serializationObject.id = this.id;
+            }
             if (this.hasNormals) {
                 serializationObject.normals = Array.prototype.slice.call(this.getNormals());
             }
@@ -104769,6 +104802,13 @@ var BABYLON;
             BABYLON.Animation.AppendSerializedAnimations(this, serializationObject);
             return serializationObject;
         };
+        /**
+         * Returns the string "MorphTarget"
+         * @returns "MorphTarget"
+         */
+        MorphTarget.prototype.getClassName = function () {
+            return "MorphTarget";
+        };
         // Statics
         /**
          * Creates a new target from serialized data
@@ -104778,6 +104818,9 @@ var BABYLON;
         MorphTarget.Parse = function (serializationObject) {
             var result = new MorphTarget(serializationObject.name, serializationObject.influence);
             result.setPositions(serializationObject.positions);
+            if (serializationObject.id != null) {
+                result.id = serializationObject.id;
+            }
             if (serializationObject.normals) {
                 result.setNormals(serializationObject.normals);
             }
@@ -104814,6 +104857,9 @@ var BABYLON;
             }
             return result;
         };
+        __decorate([
+            BABYLON.serialize()
+        ], MorphTarget.prototype, "id", void 0);
         return MorphTarget;
     }());
     BABYLON.MorphTarget = MorphTarget;

+ 49 - 3
dist/preview release/babylon.no-module.max.js

@@ -29012,6 +29012,23 @@ var BABYLON;
             return null;
         };
         /**
+         * Gets a morph target using a given id (if many are found, this function will pick the first one)
+         * @param id defines the id to search for
+         * @return the found morph target or null if not found at all.
+         */
+        Scene.prototype.getMorphTargetById = function (id) {
+            for (var managerIndex = 0; managerIndex < this.morphTargetManagers.length; ++managerIndex) {
+                var morphTargetManager = this.morphTargetManagers[managerIndex];
+                for (var index = 0; index < morphTargetManager.numTargets; ++index) {
+                    var target = morphTargetManager.getTarget(index);
+                    if (target.id === id) {
+                        return target;
+                    }
+                }
+            }
+            return null;
+        };
+        /**
          * Gets a boolean indicating if the given mesh is active
          * @param mesh defines the mesh to look for
          * @returns true if the mesh is in the active list
@@ -36707,6 +36724,10 @@ var BABYLON;
          */
         function Material(name, scene, doNotAdd) {
             /**
+             * Gets or sets user defined metadata
+             */
+            this.metadata = null;
+            /**
              * Specifies if the ready state should be checked on each call
              */
             this.checkReadyOnEveryCall = false;
@@ -55218,9 +55239,17 @@ var BABYLON;
                 var targetedAnimation = parsedAnimationGroup.targetedAnimations[i];
                 var animation = BABYLON.Animation.Parse(targetedAnimation.animation);
                 var id = targetedAnimation.targetId;
-                var targetNode = scene.getNodeByID(id);
-                if (targetNode != null) {
-                    animationGroup.addTargetedAnimation(animation, targetNode);
+                if (targetedAnimation.animation.property === "influence") { // morph target animation
+                    var morphTarget = scene.getMorphTargetById(id);
+                    if (morphTarget) {
+                        animationGroup.addTargetedAnimation(animation, morphTarget);
+                    }
+                }
+                else {
+                    var targetNode = scene.getNodeByID(id);
+                    if (targetNode != null) {
+                        animationGroup.addTargetedAnimation(animation, targetNode);
+                    }
                 }
             }
             if (parsedAnimationGroup.from !== null && parsedAnimationGroup.from !== null) {
@@ -104562,6 +104591,7 @@ var BABYLON;
 
 //# sourceMappingURL=babylon.gizmoManager.js.map
 
+
 var BABYLON;
 (function (BABYLON) {
     /**
@@ -104726,6 +104756,9 @@ var BABYLON;
             serializationObject.name = this.name;
             serializationObject.influence = this.influence;
             serializationObject.positions = Array.prototype.slice.call(this.getPositions());
+            if (this.id != null) {
+                serializationObject.id = this.id;
+            }
             if (this.hasNormals) {
                 serializationObject.normals = Array.prototype.slice.call(this.getNormals());
             }
@@ -104736,6 +104769,13 @@ var BABYLON;
             BABYLON.Animation.AppendSerializedAnimations(this, serializationObject);
             return serializationObject;
         };
+        /**
+         * Returns the string "MorphTarget"
+         * @returns "MorphTarget"
+         */
+        MorphTarget.prototype.getClassName = function () {
+            return "MorphTarget";
+        };
         // Statics
         /**
          * Creates a new target from serialized data
@@ -104745,6 +104785,9 @@ var BABYLON;
         MorphTarget.Parse = function (serializationObject) {
             var result = new MorphTarget(serializationObject.name, serializationObject.influence);
             result.setPositions(serializationObject.positions);
+            if (serializationObject.id != null) {
+                result.id = serializationObject.id;
+            }
             if (serializationObject.normals) {
                 result.setNormals(serializationObject.normals);
             }
@@ -104781,6 +104824,9 @@ var BABYLON;
             }
             return result;
         };
+        __decorate([
+            BABYLON.serialize()
+        ], MorphTarget.prototype, "id", void 0);
         return MorphTarget;
     }());
     BABYLON.MorphTarget = MorphTarget;

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/babylon.worker.js


+ 49 - 3
dist/preview release/es6.js

@@ -29012,6 +29012,23 @@ var BABYLON;
             return null;
         };
         /**
+         * Gets a morph target using a given id (if many are found, this function will pick the first one)
+         * @param id defines the id to search for
+         * @return the found morph target or null if not found at all.
+         */
+        Scene.prototype.getMorphTargetById = function (id) {
+            for (var managerIndex = 0; managerIndex < this.morphTargetManagers.length; ++managerIndex) {
+                var morphTargetManager = this.morphTargetManagers[managerIndex];
+                for (var index = 0; index < morphTargetManager.numTargets; ++index) {
+                    var target = morphTargetManager.getTarget(index);
+                    if (target.id === id) {
+                        return target;
+                    }
+                }
+            }
+            return null;
+        };
+        /**
          * Gets a boolean indicating if the given mesh is active
          * @param mesh defines the mesh to look for
          * @returns true if the mesh is in the active list
@@ -36707,6 +36724,10 @@ var BABYLON;
          */
         function Material(name, scene, doNotAdd) {
             /**
+             * Gets or sets user defined metadata
+             */
+            this.metadata = null;
+            /**
              * Specifies if the ready state should be checked on each call
              */
             this.checkReadyOnEveryCall = false;
@@ -55218,9 +55239,17 @@ var BABYLON;
                 var targetedAnimation = parsedAnimationGroup.targetedAnimations[i];
                 var animation = BABYLON.Animation.Parse(targetedAnimation.animation);
                 var id = targetedAnimation.targetId;
-                var targetNode = scene.getNodeByID(id);
-                if (targetNode != null) {
-                    animationGroup.addTargetedAnimation(animation, targetNode);
+                if (targetedAnimation.animation.property === "influence") { // morph target animation
+                    var morphTarget = scene.getMorphTargetById(id);
+                    if (morphTarget) {
+                        animationGroup.addTargetedAnimation(animation, morphTarget);
+                    }
+                }
+                else {
+                    var targetNode = scene.getNodeByID(id);
+                    if (targetNode != null) {
+                        animationGroup.addTargetedAnimation(animation, targetNode);
+                    }
                 }
             }
             if (parsedAnimationGroup.from !== null && parsedAnimationGroup.from !== null) {
@@ -104562,6 +104591,7 @@ var BABYLON;
 
 //# sourceMappingURL=babylon.gizmoManager.js.map
 
+
 var BABYLON;
 (function (BABYLON) {
     /**
@@ -104726,6 +104756,9 @@ var BABYLON;
             serializationObject.name = this.name;
             serializationObject.influence = this.influence;
             serializationObject.positions = Array.prototype.slice.call(this.getPositions());
+            if (this.id != null) {
+                serializationObject.id = this.id;
+            }
             if (this.hasNormals) {
                 serializationObject.normals = Array.prototype.slice.call(this.getNormals());
             }
@@ -104736,6 +104769,13 @@ var BABYLON;
             BABYLON.Animation.AppendSerializedAnimations(this, serializationObject);
             return serializationObject;
         };
+        /**
+         * Returns the string "MorphTarget"
+         * @returns "MorphTarget"
+         */
+        MorphTarget.prototype.getClassName = function () {
+            return "MorphTarget";
+        };
         // Statics
         /**
          * Creates a new target from serialized data
@@ -104745,6 +104785,9 @@ var BABYLON;
         MorphTarget.Parse = function (serializationObject) {
             var result = new MorphTarget(serializationObject.name, serializationObject.influence);
             result.setPositions(serializationObject.positions);
+            if (serializationObject.id != null) {
+                result.id = serializationObject.id;
+            }
             if (serializationObject.normals) {
                 result.setNormals(serializationObject.normals);
             }
@@ -104781,6 +104824,9 @@ var BABYLON;
             }
             return result;
         };
+        __decorate([
+            BABYLON.serialize()
+        ], MorphTarget.prototype, "id", void 0);
         return MorphTarget;
     }());
     BABYLON.MorphTarget = MorphTarget;

+ 200 - 4
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;
     }
@@ -1038,6 +1038,169 @@ 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: Element;
+            /**
+                * 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: Element);
+            /**
+                * 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 {
@@ -1436,6 +1599,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 {
+    /**
         * 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.

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/viewer/babylon.viewer.js


File diff suppressed because it is too large
+ 1 - 1
dist/preview release/viewer/babylon.viewer.max.js


+ 205 - 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;
     }
@@ -1115,7 +1115,172 @@ 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: Element;
+            /**
+                * 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: Element);
+            /**
+                * 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' {
@@ -1557,6 +1722,41 @@ 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';

+ 7 - 2
src/Materials/babylon.material.ts

@@ -377,6 +377,11 @@ module BABYLON {
         public name: string;
 
         /**
+         * Gets or sets user defined metadata
+         */
+        public metadata: any = null;
+
+        /**
          * Specifies if the ready state should be checked on each call
          */
         @serialize()
@@ -769,7 +774,7 @@ module BABYLON {
         public _indexInSceneMaterialArray = -1;
 
         /** @hidden */
-        public meshMap: Nullable<{[id: string]: AbstractMesh | undefined}>;
+        public meshMap: Nullable<{ [id: string]: AbstractMesh | undefined }>;
 
         /**
          * Creates a material instance
@@ -1362,7 +1367,7 @@ module BABYLON {
         }
 
         /** @hidden */
-        private  releaseVertexArrayObject(mesh: AbstractMesh, forceDisposeEffect?: boolean) {
+        private releaseVertexArrayObject(mesh: AbstractMesh, forceDisposeEffect?: boolean) {
             if ((<Mesh>mesh).geometry) {
                 var geometry = <Geometry>((<Mesh>mesh).geometry);
                 const scene = this.getScene();