Browse Source

Merge remote-tracking branch 'upstream/master'

sebastien 7 năm trước cách đây
mục cha
commit
e445af8187

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 5243 - 5084
Playground/babylon.d.txt


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 3695 - 3687
dist/preview release/babylon.d.ts


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1 - 1
dist/preview release/babylon.js


+ 36 - 4
dist/preview release/babylon.max.js

@@ -17598,6 +17598,7 @@ var BABYLON;
             this._scene = (scene || BABYLON.Engine.LastCreatedScene);
             this.uniqueId = this._scene.getUniqueId();
             this._initCache();
+            this._scene.rootNodes.push(this);
         }
         /**
          * Add a new node constructor
@@ -17640,12 +17641,17 @@ var BABYLON;
                 if (this._parentNode === parent) {
                     return;
                 }
+                var previousParentNode = this._parentNode;
                 // Remove self from list of children of parent
                 if (this._parentNode && this._parentNode._children !== undefined && this._parentNode._children !== null) {
                     var index = this._parentNode._children.indexOf(this);
                     if (index !== -1) {
                         this._parentNode._children.splice(index, 1);
                     }
+                    if (!parent) {
+                        // Need to add this node to the rootNodes
+                        this._scene.rootNodes.push(this);
+                    }
                 }
                 // Store new parent
                 this._parentNode = parent;
@@ -17655,6 +17661,13 @@ var BABYLON;
                         this._parentNode._children = new Array();
                     }
                     this._parentNode._children.push(this);
+                    if (!previousParentNode) {
+                        // Need to remove from rootNodes
+                        var rootNodeIndex = this._scene.rootNodes.indexOf(this);
+                        if (rootNodeIndex > -1) {
+                            this._scene.rootNodes.splice(rootNodeIndex, 1);
+                        }
+                    }
                 }
             },
             enumerable: true,
@@ -17952,6 +17965,9 @@ var BABYLON;
          * @returns an array of {BABYLON.Node}
          */
         Node.prototype.getChildren = function (predicate) {
+            if (!predicate) {
+                return this._children;
+            }
             return this.getDescendants(true, predicate);
         };
         /** @hidden */
@@ -18085,7 +18101,15 @@ var BABYLON;
                     transformNode.computeWorldMatrix(true);
                 }
             }
-            this.parent = null;
+            if (!this.parent) {
+                var rootNodeIndex = this._scene.rootNodes.indexOf(this);
+                if (rootNodeIndex > -1) {
+                    this._scene.rootNodes.splice(rootNodeIndex, 1);
+                }
+            }
+            else {
+                this.parent = null;
+            }
             // Callback
             this.onDisposeObservable.notifyObservers(this);
             this.onDisposeObservable.clear();
@@ -23784,6 +23808,10 @@ var BABYLON;
      */
     var AbstractScene = /** @class */ (function () {
         function AbstractScene() {
+            /**
+             * Gets the list of root nodes (ie. nodes with no parent)
+             */
+            this.rootNodes = new Array();
             /** All of the cameras added to this scene
              * @see http://doc.babylonjs.com/babylon101/cameras
              */
@@ -98367,7 +98395,7 @@ var BABYLON;
                 // Listening to the proper controller values changes to confirm teleportation
                 if (Math.sqrt(stateObject.y * stateObject.y + stateObject.x * stateObject.x) < this._padSensibilityDown) {
                     if (this._teleportActive) {
-                        this._teleportCamera(this._haloCenter);
+                        this.teleportCamera(this._haloCenter);
                     }
                     gazer._teleportationRequestInitiated = false;
                 }
@@ -98436,7 +98464,7 @@ var BABYLON;
                     var ray = new BABYLON.Ray(position, this._workingVector);
                     var hit = this._scene.pickWithRay(ray, this._raySelectionPredicate);
                     if (hit && hit.pickedPoint && hit.pickedMesh && this._isTeleportationFloor(hit.pickedMesh) && hit.distance < 5) {
-                        this._teleportCamera(hit.pickedPoint);
+                        this.teleportCamera(hit.pickedPoint);
                     }
                     gazer._teleportationBackRequestInitiated = true;
                 }
@@ -98626,7 +98654,11 @@ var BABYLON;
                 this._teleportationTarget.position.y += 0.1;
             }
         };
-        VRExperienceHelper.prototype._teleportCamera = function (location) {
+        /**
+         * Teleports the users feet to the desired location
+         * @param location The location where the user's feet should be placed
+         */
+        VRExperienceHelper.prototype.teleportCamera = function (location) {
             var _this = this;
             if (!(this.currentVRCamera instanceof BABYLON.FreeCamera)) {
                 return;

+ 36 - 4
dist/preview release/babylon.no-module.max.js

@@ -17565,6 +17565,7 @@ var BABYLON;
             this._scene = (scene || BABYLON.Engine.LastCreatedScene);
             this.uniqueId = this._scene.getUniqueId();
             this._initCache();
+            this._scene.rootNodes.push(this);
         }
         /**
          * Add a new node constructor
@@ -17607,12 +17608,17 @@ var BABYLON;
                 if (this._parentNode === parent) {
                     return;
                 }
+                var previousParentNode = this._parentNode;
                 // Remove self from list of children of parent
                 if (this._parentNode && this._parentNode._children !== undefined && this._parentNode._children !== null) {
                     var index = this._parentNode._children.indexOf(this);
                     if (index !== -1) {
                         this._parentNode._children.splice(index, 1);
                     }
+                    if (!parent) {
+                        // Need to add this node to the rootNodes
+                        this._scene.rootNodes.push(this);
+                    }
                 }
                 // Store new parent
                 this._parentNode = parent;
@@ -17622,6 +17628,13 @@ var BABYLON;
                         this._parentNode._children = new Array();
                     }
                     this._parentNode._children.push(this);
+                    if (!previousParentNode) {
+                        // Need to remove from rootNodes
+                        var rootNodeIndex = this._scene.rootNodes.indexOf(this);
+                        if (rootNodeIndex > -1) {
+                            this._scene.rootNodes.splice(rootNodeIndex, 1);
+                        }
+                    }
                 }
             },
             enumerable: true,
@@ -17919,6 +17932,9 @@ var BABYLON;
          * @returns an array of {BABYLON.Node}
          */
         Node.prototype.getChildren = function (predicate) {
+            if (!predicate) {
+                return this._children;
+            }
             return this.getDescendants(true, predicate);
         };
         /** @hidden */
@@ -18052,7 +18068,15 @@ var BABYLON;
                     transformNode.computeWorldMatrix(true);
                 }
             }
-            this.parent = null;
+            if (!this.parent) {
+                var rootNodeIndex = this._scene.rootNodes.indexOf(this);
+                if (rootNodeIndex > -1) {
+                    this._scene.rootNodes.splice(rootNodeIndex, 1);
+                }
+            }
+            else {
+                this.parent = null;
+            }
             // Callback
             this.onDisposeObservable.notifyObservers(this);
             this.onDisposeObservable.clear();
@@ -23751,6 +23775,10 @@ var BABYLON;
      */
     var AbstractScene = /** @class */ (function () {
         function AbstractScene() {
+            /**
+             * Gets the list of root nodes (ie. nodes with no parent)
+             */
+            this.rootNodes = new Array();
             /** All of the cameras added to this scene
              * @see http://doc.babylonjs.com/babylon101/cameras
              */
@@ -98334,7 +98362,7 @@ var BABYLON;
                 // Listening to the proper controller values changes to confirm teleportation
                 if (Math.sqrt(stateObject.y * stateObject.y + stateObject.x * stateObject.x) < this._padSensibilityDown) {
                     if (this._teleportActive) {
-                        this._teleportCamera(this._haloCenter);
+                        this.teleportCamera(this._haloCenter);
                     }
                     gazer._teleportationRequestInitiated = false;
                 }
@@ -98403,7 +98431,7 @@ var BABYLON;
                     var ray = new BABYLON.Ray(position, this._workingVector);
                     var hit = this._scene.pickWithRay(ray, this._raySelectionPredicate);
                     if (hit && hit.pickedPoint && hit.pickedMesh && this._isTeleportationFloor(hit.pickedMesh) && hit.distance < 5) {
-                        this._teleportCamera(hit.pickedPoint);
+                        this.teleportCamera(hit.pickedPoint);
                     }
                     gazer._teleportationBackRequestInitiated = true;
                 }
@@ -98593,7 +98621,11 @@ var BABYLON;
                 this._teleportationTarget.position.y += 0.1;
             }
         };
-        VRExperienceHelper.prototype._teleportCamera = function (location) {
+        /**
+         * Teleports the users feet to the desired location
+         * @param location The location where the user's feet should be placed
+         */
+        VRExperienceHelper.prototype.teleportCamera = function (location) {
             var _this = this;
             if (!(this.currentVRCamera instanceof BABYLON.FreeCamera)) {
                 return;

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1 - 1
dist/preview release/babylon.worker.js


+ 36 - 4
dist/preview release/es6.js

@@ -17565,6 +17565,7 @@ var BABYLON;
             this._scene = (scene || BABYLON.Engine.LastCreatedScene);
             this.uniqueId = this._scene.getUniqueId();
             this._initCache();
+            this._scene.rootNodes.push(this);
         }
         /**
          * Add a new node constructor
@@ -17607,12 +17608,17 @@ var BABYLON;
                 if (this._parentNode === parent) {
                     return;
                 }
+                var previousParentNode = this._parentNode;
                 // Remove self from list of children of parent
                 if (this._parentNode && this._parentNode._children !== undefined && this._parentNode._children !== null) {
                     var index = this._parentNode._children.indexOf(this);
                     if (index !== -1) {
                         this._parentNode._children.splice(index, 1);
                     }
+                    if (!parent) {
+                        // Need to add this node to the rootNodes
+                        this._scene.rootNodes.push(this);
+                    }
                 }
                 // Store new parent
                 this._parentNode = parent;
@@ -17622,6 +17628,13 @@ var BABYLON;
                         this._parentNode._children = new Array();
                     }
                     this._parentNode._children.push(this);
+                    if (!previousParentNode) {
+                        // Need to remove from rootNodes
+                        var rootNodeIndex = this._scene.rootNodes.indexOf(this);
+                        if (rootNodeIndex > -1) {
+                            this._scene.rootNodes.splice(rootNodeIndex, 1);
+                        }
+                    }
                 }
             },
             enumerable: true,
@@ -17919,6 +17932,9 @@ var BABYLON;
          * @returns an array of {BABYLON.Node}
          */
         Node.prototype.getChildren = function (predicate) {
+            if (!predicate) {
+                return this._children;
+            }
             return this.getDescendants(true, predicate);
         };
         /** @hidden */
@@ -18052,7 +18068,15 @@ var BABYLON;
                     transformNode.computeWorldMatrix(true);
                 }
             }
-            this.parent = null;
+            if (!this.parent) {
+                var rootNodeIndex = this._scene.rootNodes.indexOf(this);
+                if (rootNodeIndex > -1) {
+                    this._scene.rootNodes.splice(rootNodeIndex, 1);
+                }
+            }
+            else {
+                this.parent = null;
+            }
             // Callback
             this.onDisposeObservable.notifyObservers(this);
             this.onDisposeObservable.clear();
@@ -23751,6 +23775,10 @@ var BABYLON;
      */
     var AbstractScene = /** @class */ (function () {
         function AbstractScene() {
+            /**
+             * Gets the list of root nodes (ie. nodes with no parent)
+             */
+            this.rootNodes = new Array();
             /** All of the cameras added to this scene
              * @see http://doc.babylonjs.com/babylon101/cameras
              */
@@ -98334,7 +98362,7 @@ var BABYLON;
                 // Listening to the proper controller values changes to confirm teleportation
                 if (Math.sqrt(stateObject.y * stateObject.y + stateObject.x * stateObject.x) < this._padSensibilityDown) {
                     if (this._teleportActive) {
-                        this._teleportCamera(this._haloCenter);
+                        this.teleportCamera(this._haloCenter);
                     }
                     gazer._teleportationRequestInitiated = false;
                 }
@@ -98403,7 +98431,7 @@ var BABYLON;
                     var ray = new BABYLON.Ray(position, this._workingVector);
                     var hit = this._scene.pickWithRay(ray, this._raySelectionPredicate);
                     if (hit && hit.pickedPoint && hit.pickedMesh && this._isTeleportationFloor(hit.pickedMesh) && hit.distance < 5) {
-                        this._teleportCamera(hit.pickedPoint);
+                        this.teleportCamera(hit.pickedPoint);
                     }
                     gazer._teleportationBackRequestInitiated = true;
                 }
@@ -98593,7 +98621,11 @@ var BABYLON;
                 this._teleportationTarget.position.y += 0.1;
             }
         };
-        VRExperienceHelper.prototype._teleportCamera = function (location) {
+        /**
+         * Teleports the users feet to the desired location
+         * @param location The location where the user's feet should be placed
+         */
+        VRExperienceHelper.prototype.teleportCamera = function (location) {
             var _this = this;
             if (!(this.currentVRCamera instanceof BABYLON.FreeCamera)) {
                 return;

+ 168 - 0
dist/preview release/gui/babylon.gui.d.ts

@@ -1596,6 +1596,174 @@ declare module BABYLON.GUI {
     }
 }
 declare module BABYLON.GUI {
+    /** Class used to create a RadioGroup
+        * which contains groups of radio buttons
+     */
+    export class SelectorGroup {
+            /** name of SelectorGroup */
+            name: string;
+            /**
+                * Creates a new SelectorGroup
+                * @param name of group, used as a group heading
+                */
+            constructor(
+            /** name of SelectorGroup */
+            name: string);
+            /** Gets the groupPanel of the SelectorGroup  */
+            readonly groupPanel: StackPanel;
+            /** Gets the selectors array */
+            readonly selectors: StackPanel[];
+            /** Gets and sets the group header */
+            header: string;
+            /** @hidden*/
+            _getSelector(selectorNb: number): StackPanel | undefined;
+            /** Removes the selector at the given position
+             * @param selectorNb the position of the selector within the group
+            */
+            removeSelector(selectorNb: number): void;
+    }
+    /** Class used to create a CheckboxGroup
+        * which contains groups of checkbox buttons
+     */
+    export class CheckboxGroup extends SelectorGroup {
+            /** Adds a checkbox as a control
+                * @param text is the label for the selector
+                * @param func is the function called when the Selector is checked
+                * @param checked is true when Selector is checked
+                */
+            addCheckbox(text: string, func?: (s: boolean) => void, checked?: boolean): void;
+            /** @hidden */
+            _setSelectorLabel(selectorNb: number, label: string): void;
+            /** @hidden */
+            _setSelectorLabelColor(selectorNb: number, color: string): void;
+            /** @hidden */
+            _setSelectorButtonColor(selectorNb: number, color: string): void;
+            /** @hidden */
+            _setSelectorButtonBackground(selectorNb: number, color: string): void;
+    }
+    /** Class used to create a RadioGroup
+        * which contains groups of radio buttons
+     */
+    export class RadioGroup extends SelectorGroup {
+            /** Adds a radio button as a control
+                * @param label is the label for the selector
+                * @param func is the function called when the Selector is checked
+                * @param checked is true when Selector is checked
+                */
+            addRadio(label: string, func?: (n: number) => void, checked?: boolean): void;
+            /** @hidden */
+            _setSelectorLabel(selectorNb: number, label: string): void;
+            /** @hidden */
+            _setSelectorLabelColor(selectorNb: number, color: string): void;
+            /** @hidden */
+            _setSelectorButtonColor(selectorNb: number, color: string): void;
+            /** @hidden */
+            _setSelectorButtonBackground(selectorNb: number, color: string): void;
+    }
+    /** Class used to create a SliderGroup
+        * which contains groups of slider buttons
+     */
+    export class SliderGroup extends SelectorGroup {
+            /**
+                * Adds a slider to the SelectorGroup
+                * @param label is the label for the SliderBar
+                * @param func is the function called when the Slider moves
+                * @param unit is a string describing the units used, eg degrees or metres
+                * @param min is the minimum value for the Slider
+                * @param max is the maximum value for the Slider
+                * @param value is the start value for the Slider between min and max
+                * @param onValueChange is the function used to format the value displayed, eg radians to degrees
+                */
+            addSlider(label: string, func?: (v: number) => void, unit?: string, min?: number, max?: number, value?: number, onValueChange?: (v: number) => number): void;
+            /** @hidden */
+            _setSelectorLabel(selectorNb: number, label: string): void;
+            /** @hidden */
+            _setSelectorLabelColor(selectorNb: number, color: string): void;
+            /** @hidden */
+            _setSelectorButtonColor(selectorNb: number, color: string): void;
+            /** @hidden */
+            _setSelectorButtonBackground(selectorNb: number, color: string): void;
+    }
+    /** Class used to hold the controls for the checkboxes, radio buttons and sliders */
+    export class SelectionPanel extends Rectangle {
+            /** name of SelectionPanel */
+            name: string;
+            /** an array of SelectionGroups */
+            groups: SelectorGroup[];
+            /**
+             * Creates a new SelectionPanel
+             * @param name of SelectionPanel
+             * @param groups is an array of SelectionGroups
+             */
+            constructor(
+            /** name of SelectionPanel */
+            name: string, 
+            /** an array of SelectionGroups */
+            groups?: SelectorGroup[]);
+            protected _getTypeName(): string;
+            /** Gets or sets the headerColor */
+            headerColor: string;
+            /** Gets or sets the button color */
+            buttonColor: string;
+            /** Gets or sets the label color */
+            labelColor: string;
+            /** Gets or sets the button background */
+            buttonBackground: string;
+            /** Gets or sets the color of separator bar */
+            barColor: string;
+            /** Add a group to the selection panel
+                * @param group is the selector group to add
+                */
+            addGroup(group: SelectorGroup): void;
+            /** Remove the group from the given position
+                * @param groupNb is the position of the group in the list
+                */
+            removeGroup(groupNb: number): void;
+            /** Change a group header label
+                * @param label is the new group header label
+                * @param groupNb is the number of the group to relabel
+                * */
+            setHeaderName(label: string, groupNb: number): void;
+            /** Change selector label to the one given
+                * @param label is the new selector label
+                * @param groupNb is the number of the groupcontaining the selector
+                * @param selectorNb is the number of the selector within a group to relabel
+                * */
+            relabel(label: string, groupNb: number, selectorNb: number): void;
+            /** For a given group position remove the selector at the given position
+                * @param groupNb is the number of the group to remove the selector from
+                * @param selectorNb is the number of the selector within the group
+                */
+            removeFromGroupSelector(groupNb: number, selectorNb: number): void;
+            /** For a given group position of correct type add a checkbox button
+                * @param groupNb is the number of the group to remove the selector from
+                * @param label is the label for the selector
+                * @param func is the function called when the Selector is checked
+                * @param checked is true when Selector is checked
+                */
+            addToGroupCheckbox(groupNb: number, label: string, func?: () => void, checked?: boolean): void;
+            /** For a given group position of correct type add a radio button
+                * @param groupNb is the number of the group to remove the selector from
+                * @param label is the label for the selector
+                * @param func is the function called when the Selector is checked
+                * @param checked is true when Selector is checked
+                */
+            addToGroupRadio(groupNb: number, label: string, func?: () => void, checked?: boolean): void;
+            /**
+                * For a given slider group add a slider
+                * @param groupNb is the number of the group to add the slider to
+                * @param label is the label for the Slider
+                * @param func is the function called when the Slider moves
+                * @param unit is a string describing the units used, eg degrees or metres
+                * @param min is the minimum value for the Slider
+                * @param max is the maximum value for the Slider
+                * @param value is the start value for the Slider between min and max
+                * @param onVal is the function used to format the value displayed, eg radians to degrees
+                */
+            addToGroupSlider(groupNb: number, label: string, func?: () => void, unit?: string, min?: number, max?: number, value?: number, onVal?: (v: number) => number): void;
+    }
+}
+declare module BABYLON.GUI {
     /**
         * Enum that determines the text-wrapping mode to use.
         */

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1 - 1
dist/preview release/gui/babylon.gui.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1 - 1
dist/preview release/gui/babylon.gui.min.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1 - 1
dist/preview release/gui/babylon.gui.min.js.map


+ 340 - 0
dist/preview release/gui/babylon.gui.module.d.ts

@@ -39,6 +39,7 @@ declare module 'babylonjs-gui/2D/controls' {
     export * from "babylonjs-gui/2D/controls/multiLine";
     export * from "babylonjs-gui/2D/controls/radioButton";
     export * from "babylonjs-gui/2D/controls/stackPanel";
+    export * from "babylonjs-gui/2D/controls/selector";
     export * from "babylonjs-gui/2D/controls/textBlock";
     export * from "babylonjs-gui/2D/controls/virtualKeyboard";
     export * from "babylonjs-gui/2D/controls/slider";
@@ -1733,6 +1734,177 @@ declare module 'babylonjs-gui/2D/controls/stackPanel' {
     }
 }
 
+declare module 'babylonjs-gui/2D/controls/selector' {
+    import { Rectangle } from "babylonjs-gui/2D/controls/rectangle";
+    import { StackPanel } from "babylonjs-gui/2D/controls/stackPanel";
+    /** Class used to create a RadioGroup
+        * which contains groups of radio buttons
+     */
+    export class SelectorGroup {
+            /** name of SelectorGroup */
+            name: string;
+            /**
+                * Creates a new SelectorGroup
+                * @param name of group, used as a group heading
+                */
+            constructor(
+            /** name of SelectorGroup */
+            name: string);
+            /** Gets the groupPanel of the SelectorGroup  */
+            readonly groupPanel: StackPanel;
+            /** Gets the selectors array */
+            readonly selectors: StackPanel[];
+            /** Gets and sets the group header */
+            header: string;
+            /** @hidden*/
+            _getSelector(selectorNb: number): StackPanel | undefined;
+            /** Removes the selector at the given position
+             * @param selectorNb the position of the selector within the group
+            */
+            removeSelector(selectorNb: number): void;
+    }
+    /** Class used to create a CheckboxGroup
+        * which contains groups of checkbox buttons
+     */
+    export class CheckboxGroup extends SelectorGroup {
+            /** Adds a checkbox as a control
+                * @param text is the label for the selector
+                * @param func is the function called when the Selector is checked
+                * @param checked is true when Selector is checked
+                */
+            addCheckbox(text: string, func?: (s: boolean) => void, checked?: boolean): void;
+            /** @hidden */
+            _setSelectorLabel(selectorNb: number, label: string): void;
+            /** @hidden */
+            _setSelectorLabelColor(selectorNb: number, color: string): void;
+            /** @hidden */
+            _setSelectorButtonColor(selectorNb: number, color: string): void;
+            /** @hidden */
+            _setSelectorButtonBackground(selectorNb: number, color: string): void;
+    }
+    /** Class used to create a RadioGroup
+        * which contains groups of radio buttons
+     */
+    export class RadioGroup extends SelectorGroup {
+            /** Adds a radio button as a control
+                * @param label is the label for the selector
+                * @param func is the function called when the Selector is checked
+                * @param checked is true when Selector is checked
+                */
+            addRadio(label: string, func?: (n: number) => void, checked?: boolean): void;
+            /** @hidden */
+            _setSelectorLabel(selectorNb: number, label: string): void;
+            /** @hidden */
+            _setSelectorLabelColor(selectorNb: number, color: string): void;
+            /** @hidden */
+            _setSelectorButtonColor(selectorNb: number, color: string): void;
+            /** @hidden */
+            _setSelectorButtonBackground(selectorNb: number, color: string): void;
+    }
+    /** Class used to create a SliderGroup
+        * which contains groups of slider buttons
+     */
+    export class SliderGroup extends SelectorGroup {
+            /**
+                * Adds a slider to the SelectorGroup
+                * @param label is the label for the SliderBar
+                * @param func is the function called when the Slider moves
+                * @param unit is a string describing the units used, eg degrees or metres
+                * @param min is the minimum value for the Slider
+                * @param max is the maximum value for the Slider
+                * @param value is the start value for the Slider between min and max
+                * @param onValueChange is the function used to format the value displayed, eg radians to degrees
+                */
+            addSlider(label: string, func?: (v: number) => void, unit?: string, min?: number, max?: number, value?: number, onValueChange?: (v: number) => number): void;
+            /** @hidden */
+            _setSelectorLabel(selectorNb: number, label: string): void;
+            /** @hidden */
+            _setSelectorLabelColor(selectorNb: number, color: string): void;
+            /** @hidden */
+            _setSelectorButtonColor(selectorNb: number, color: string): void;
+            /** @hidden */
+            _setSelectorButtonBackground(selectorNb: number, color: string): void;
+    }
+    /** Class used to hold the controls for the checkboxes, radio buttons and sliders */
+    export class SelectionPanel extends Rectangle {
+            /** name of SelectionPanel */
+            name: string;
+            /** an array of SelectionGroups */
+            groups: SelectorGroup[];
+            /**
+             * Creates a new SelectionPanel
+             * @param name of SelectionPanel
+             * @param groups is an array of SelectionGroups
+             */
+            constructor(
+            /** name of SelectionPanel */
+            name: string, 
+            /** an array of SelectionGroups */
+            groups?: SelectorGroup[]);
+            protected _getTypeName(): string;
+            /** Gets or sets the headerColor */
+            headerColor: string;
+            /** Gets or sets the button color */
+            buttonColor: string;
+            /** Gets or sets the label color */
+            labelColor: string;
+            /** Gets or sets the button background */
+            buttonBackground: string;
+            /** Gets or sets the color of separator bar */
+            barColor: string;
+            /** Add a group to the selection panel
+                * @param group is the selector group to add
+                */
+            addGroup(group: SelectorGroup): void;
+            /** Remove the group from the given position
+                * @param groupNb is the position of the group in the list
+                */
+            removeGroup(groupNb: number): void;
+            /** Change a group header label
+                * @param label is the new group header label
+                * @param groupNb is the number of the group to relabel
+                * */
+            setHeaderName(label: string, groupNb: number): void;
+            /** Change selector label to the one given
+                * @param label is the new selector label
+                * @param groupNb is the number of the groupcontaining the selector
+                * @param selectorNb is the number of the selector within a group to relabel
+                * */
+            relabel(label: string, groupNb: number, selectorNb: number): void;
+            /** For a given group position remove the selector at the given position
+                * @param groupNb is the number of the group to remove the selector from
+                * @param selectorNb is the number of the selector within the group
+                */
+            removeFromGroupSelector(groupNb: number, selectorNb: number): void;
+            /** For a given group position of correct type add a checkbox button
+                * @param groupNb is the number of the group to remove the selector from
+                * @param label is the label for the selector
+                * @param func is the function called when the Selector is checked
+                * @param checked is true when Selector is checked
+                */
+            addToGroupCheckbox(groupNb: number, label: string, func?: () => void, checked?: boolean): void;
+            /** For a given group position of correct type add a radio button
+                * @param groupNb is the number of the group to remove the selector from
+                * @param label is the label for the selector
+                * @param func is the function called when the Selector is checked
+                * @param checked is true when Selector is checked
+                */
+            addToGroupRadio(groupNb: number, label: string, func?: () => void, checked?: boolean): void;
+            /**
+                * For a given slider group add a slider
+                * @param groupNb is the number of the group to add the slider to
+                * @param label is the label for the Slider
+                * @param func is the function called when the Slider moves
+                * @param unit is a string describing the units used, eg degrees or metres
+                * @param min is the minimum value for the Slider
+                * @param max is the maximum value for the Slider
+                * @param value is the start value for the Slider between min and max
+                * @param onVal is the function used to format the value displayed, eg radians to degrees
+                */
+            addToGroupSlider(groupNb: number, label: string, func?: () => void, unit?: string, min?: number, max?: number, value?: number, onVal?: (v: number) => number): void;
+    }
+}
+
 declare module 'babylonjs-gui/2D/controls/textBlock' {
     import { Observable } from "babylonjs";
     import { Measure } from "babylonjs-gui/2D/measure";
@@ -4202,6 +4374,174 @@ declare module BABYLON.GUI {
     }
 }
 declare module BABYLON.GUI {
+    /** Class used to create a RadioGroup
+        * which contains groups of radio buttons
+     */
+    export class SelectorGroup {
+            /** name of SelectorGroup */
+            name: string;
+            /**
+                * Creates a new SelectorGroup
+                * @param name of group, used as a group heading
+                */
+            constructor(
+            /** name of SelectorGroup */
+            name: string);
+            /** Gets the groupPanel of the SelectorGroup  */
+            readonly groupPanel: StackPanel;
+            /** Gets the selectors array */
+            readonly selectors: StackPanel[];
+            /** Gets and sets the group header */
+            header: string;
+            /** @hidden*/
+            _getSelector(selectorNb: number): StackPanel | undefined;
+            /** Removes the selector at the given position
+             * @param selectorNb the position of the selector within the group
+            */
+            removeSelector(selectorNb: number): void;
+    }
+    /** Class used to create a CheckboxGroup
+        * which contains groups of checkbox buttons
+     */
+    export class CheckboxGroup extends SelectorGroup {
+            /** Adds a checkbox as a control
+                * @param text is the label for the selector
+                * @param func is the function called when the Selector is checked
+                * @param checked is true when Selector is checked
+                */
+            addCheckbox(text: string, func?: (s: boolean) => void, checked?: boolean): void;
+            /** @hidden */
+            _setSelectorLabel(selectorNb: number, label: string): void;
+            /** @hidden */
+            _setSelectorLabelColor(selectorNb: number, color: string): void;
+            /** @hidden */
+            _setSelectorButtonColor(selectorNb: number, color: string): void;
+            /** @hidden */
+            _setSelectorButtonBackground(selectorNb: number, color: string): void;
+    }
+    /** Class used to create a RadioGroup
+        * which contains groups of radio buttons
+     */
+    export class RadioGroup extends SelectorGroup {
+            /** Adds a radio button as a control
+                * @param label is the label for the selector
+                * @param func is the function called when the Selector is checked
+                * @param checked is true when Selector is checked
+                */
+            addRadio(label: string, func?: (n: number) => void, checked?: boolean): void;
+            /** @hidden */
+            _setSelectorLabel(selectorNb: number, label: string): void;
+            /** @hidden */
+            _setSelectorLabelColor(selectorNb: number, color: string): void;
+            /** @hidden */
+            _setSelectorButtonColor(selectorNb: number, color: string): void;
+            /** @hidden */
+            _setSelectorButtonBackground(selectorNb: number, color: string): void;
+    }
+    /** Class used to create a SliderGroup
+        * which contains groups of slider buttons
+     */
+    export class SliderGroup extends SelectorGroup {
+            /**
+                * Adds a slider to the SelectorGroup
+                * @param label is the label for the SliderBar
+                * @param func is the function called when the Slider moves
+                * @param unit is a string describing the units used, eg degrees or metres
+                * @param min is the minimum value for the Slider
+                * @param max is the maximum value for the Slider
+                * @param value is the start value for the Slider between min and max
+                * @param onValueChange is the function used to format the value displayed, eg radians to degrees
+                */
+            addSlider(label: string, func?: (v: number) => void, unit?: string, min?: number, max?: number, value?: number, onValueChange?: (v: number) => number): void;
+            /** @hidden */
+            _setSelectorLabel(selectorNb: number, label: string): void;
+            /** @hidden */
+            _setSelectorLabelColor(selectorNb: number, color: string): void;
+            /** @hidden */
+            _setSelectorButtonColor(selectorNb: number, color: string): void;
+            /** @hidden */
+            _setSelectorButtonBackground(selectorNb: number, color: string): void;
+    }
+    /** Class used to hold the controls for the checkboxes, radio buttons and sliders */
+    export class SelectionPanel extends Rectangle {
+            /** name of SelectionPanel */
+            name: string;
+            /** an array of SelectionGroups */
+            groups: SelectorGroup[];
+            /**
+             * Creates a new SelectionPanel
+             * @param name of SelectionPanel
+             * @param groups is an array of SelectionGroups
+             */
+            constructor(
+            /** name of SelectionPanel */
+            name: string, 
+            /** an array of SelectionGroups */
+            groups?: SelectorGroup[]);
+            protected _getTypeName(): string;
+            /** Gets or sets the headerColor */
+            headerColor: string;
+            /** Gets or sets the button color */
+            buttonColor: string;
+            /** Gets or sets the label color */
+            labelColor: string;
+            /** Gets or sets the button background */
+            buttonBackground: string;
+            /** Gets or sets the color of separator bar */
+            barColor: string;
+            /** Add a group to the selection panel
+                * @param group is the selector group to add
+                */
+            addGroup(group: SelectorGroup): void;
+            /** Remove the group from the given position
+                * @param groupNb is the position of the group in the list
+                */
+            removeGroup(groupNb: number): void;
+            /** Change a group header label
+                * @param label is the new group header label
+                * @param groupNb is the number of the group to relabel
+                * */
+            setHeaderName(label: string, groupNb: number): void;
+            /** Change selector label to the one given
+                * @param label is the new selector label
+                * @param groupNb is the number of the groupcontaining the selector
+                * @param selectorNb is the number of the selector within a group to relabel
+                * */
+            relabel(label: string, groupNb: number, selectorNb: number): void;
+            /** For a given group position remove the selector at the given position
+                * @param groupNb is the number of the group to remove the selector from
+                * @param selectorNb is the number of the selector within the group
+                */
+            removeFromGroupSelector(groupNb: number, selectorNb: number): void;
+            /** For a given group position of correct type add a checkbox button
+                * @param groupNb is the number of the group to remove the selector from
+                * @param label is the label for the selector
+                * @param func is the function called when the Selector is checked
+                * @param checked is true when Selector is checked
+                */
+            addToGroupCheckbox(groupNb: number, label: string, func?: () => void, checked?: boolean): void;
+            /** For a given group position of correct type add a radio button
+                * @param groupNb is the number of the group to remove the selector from
+                * @param label is the label for the selector
+                * @param func is the function called when the Selector is checked
+                * @param checked is true when Selector is checked
+                */
+            addToGroupRadio(groupNb: number, label: string, func?: () => void, checked?: boolean): void;
+            /**
+                * For a given slider group add a slider
+                * @param groupNb is the number of the group to add the slider to
+                * @param label is the label for the Slider
+                * @param func is the function called when the Slider moves
+                * @param unit is a string describing the units used, eg degrees or metres
+                * @param min is the minimum value for the Slider
+                * @param max is the maximum value for the Slider
+                * @param value is the start value for the Slider between min and max
+                * @param onVal is the function used to format the value displayed, eg radians to degrees
+                */
+            addToGroupSlider(groupNb: number, label: string, func?: () => void, unit?: string, min?: number, max?: number, value?: number, onVal?: (v: number) => number): void;
+    }
+}
+declare module BABYLON.GUI {
     /**
         * Enum that determines the text-wrapping mode to use.
         */

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1 - 1
dist/preview release/inspector/babylon.inspector.bundle.js.map


+ 20 - 0
dist/preview release/viewer/babylon.viewer.d.ts

@@ -2079,6 +2079,26 @@ declare module BabylonViewer {
     }
 }
 declare module BabylonViewer {
+    export interface ISkyboxConfiguration {
+        cubeTexture?: {
+            noMipMap?: boolean;
+            gammaSpace?: boolean;
+            url?: string | Array<string>;
+        };
+        color?: {
+            r: number;
+            g: number;
+            b: number;
+        };
+        pbr?: boolean;
+        scale?: number;
+        blur?: number;
+        material?: {
+            imageProcessingConfiguration?: IImageProcessingConfiguration;
+            [propName: string]: any;
+        };
+        infiniteDistance?: boolean;
+    }
 }
 declare module BabylonViewer {
     /**

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1 - 1
dist/preview release/viewer/babylon.viewer.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 3 - 3
dist/preview release/viewer/babylon.viewer.max.js


+ 21 - 1
dist/preview release/viewer/babylon.viewer.module.d.ts

@@ -2236,7 +2236,27 @@ declare module 'babylonjs-viewer/configuration/interfaces/sceneOptimizerConfigur
 }
 
 declare module 'babylonjs-viewer/configuration/interfaces/skyboxConfiguration' {
-    
+    import { IImageProcessingConfiguration } from "babylonjs-viewer/configuration/interfaces/imageProcessingConfiguration";
+    export interface ISkyboxConfiguration {
+        cubeTexture?: {
+            noMipMap?: boolean;
+            gammaSpace?: boolean;
+            url?: string | Array<string>;
+        };
+        color?: {
+            r: number;
+            g: number;
+            b: number;
+        };
+        pbr?: boolean;
+        scale?: number;
+        blur?: number;
+        material?: {
+            imageProcessingConfiguration?: IImageProcessingConfiguration;
+            [propName: string]: any;
+        };
+        infiniteDistance?: boolean;
+    }
 }
 
 declare module 'babylonjs-viewer/configuration/interfaces/templateConfiguration' {

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

@@ -65,6 +65,7 @@
 
 ### Core Engine
 
+- Added `scene.rootNodes` to track root nodes (ie. nodes with no parent) ([Deltakosh](https://github.com/deltakosh))
 - Added `scene.pickSpriteWithRay` function ([Deltakosh](https://github.com/deltakosh))
 - Added support for multiple clip planes. [Demo](https://www.babylonjs-playground.com/#Y6W087) ([Deltakosh](https://github.com/deltakosh))
 - Added new `MixMaterial` to the Materials Library allowing to mix up to 8 textures ([julien-moreau](https://github.com/julien-moreau))
@@ -119,6 +120,8 @@
 - Added supports for reflectionMatrix in Skybox Mode Cube Texture allowing offsetting the world center or rotating the matrix ([sebavan](http://www.github.com/sebavan))
 - Improved performance of cached nodes but ensuring parent always updates cache. This removes failed isSynchronized test that meant computeWorldMatrix would always have to rebuild. On large scenes this could double framerate. ([Bolloxim](https://github.com/Bolloxim))
 - Added FXAA and MSAA support to the StandardRenderingPipeline ([julien-moreau](https://github.com/julien-moreau))
+- Make teleportCamera public in VR experience helper ([TrevorDev](https://github.com/TrevorDev))
+
 
 ### glTF Loader
 

+ 7 - 3
src/Cameras/VR/babylon.vrExperienceHelper.ts

@@ -1253,7 +1253,7 @@ module BABYLON {
                 // Listening to the proper controller values changes to confirm teleportation
                 if (Math.sqrt(stateObject.y * stateObject.y + stateObject.x * stateObject.x) < this._padSensibilityDown) {
                     if (this._teleportActive) {
-                        this._teleportCamera(this._haloCenter);
+                        this.teleportCamera(this._haloCenter);
                     }
 
                     gazer._teleportationRequestInitiated = false;
@@ -1328,7 +1328,7 @@ module BABYLON {
                     var ray = new Ray(position, this._workingVector);
                     var hit = this._scene.pickWithRay(ray, this._raySelectionPredicate);
                     if (hit && hit.pickedPoint && hit.pickedMesh && this._isTeleportationFloor(hit.pickedMesh) && hit.distance < 5) {
-                        this._teleportCamera(hit.pickedPoint);
+                        this.teleportCamera(hit.pickedPoint);
                     }
 
                     gazer._teleportationBackRequestInitiated = true;
@@ -1558,7 +1558,11 @@ module BABYLON {
         private _workingVector = Vector3.Zero();
         private _workingQuaternion = Quaternion.Identity();
         private _workingMatrix = Matrix.Identity();
-        private _teleportCamera(location: Vector3) {
+        /**
+         * Teleports the users feet to the desired location
+         * @param location The location where the user's feet should be placed
+         */
+        public teleportCamera(location: Vector3) {
             if (!(this.currentVRCamera instanceof FreeCamera)) {
                 return;
             }

+ 5 - 0
src/babylon.abstractScene.ts

@@ -86,6 +86,11 @@
             }
         }
 
+       /**
+        * Gets the list of root nodes (ie. nodes with no parent)
+        */
+       public rootNodes = new Array<Node>();
+
         /** All of the cameras added to this scene
          * @see http://doc.babylonjs.com/babylon101/cameras
          */

+ 31 - 1
src/babylon.node.ts

@@ -120,12 +120,19 @@
                 return;
             }
 
+            const previousParentNode = this._parentNode;
+
             // Remove self from list of children of parent
             if (this._parentNode && this._parentNode._children !== undefined && this._parentNode._children !== null) {
                 var index = this._parentNode._children.indexOf(this);
                 if (index !== -1) {
                     this._parentNode._children.splice(index, 1);
                 }
+
+                if (!parent) {
+                    // Need to add this node to the rootNodes
+                    this._scene.rootNodes.push(this);
+                }
             }
 
             // Store new parent
@@ -137,6 +144,15 @@
                     this._parentNode._children = new Array<Node>();
                 }
                 this._parentNode._children.push(this);
+
+                if (!previousParentNode) {
+                    // Need to remove from rootNodes
+                    const rootNodeIndex = this._scene.rootNodes.indexOf(this);
+
+                    if (rootNodeIndex > -1) {
+                        this._scene.rootNodes.splice(rootNodeIndex, 1);
+                    }
+                }
             }
         }
 
@@ -195,6 +211,8 @@
             this._scene = <Scene>(scene || Engine.LastCreatedScene);
             this.uniqueId = this._scene.getUniqueId();
             this._initCache();
+
+            this._scene.rootNodes.push(this);
         }
 
         /**
@@ -496,6 +514,10 @@
          * @returns an array of {BABYLON.Node}
          */
         public getChildren(predicate?: (node: Node) => boolean): Node[] {
+            if (!predicate) {
+                return this._children;
+            }
+
             return this.getDescendants(true, predicate);
         }
 
@@ -640,7 +662,15 @@
                 }
             }
 
-            this.parent = null;
+            if (!this.parent) {
+                const rootNodeIndex = this._scene.rootNodes.indexOf(this);
+
+                if (rootNodeIndex > -1) {
+                    this._scene.rootNodes.splice(rootNodeIndex, 1);
+                }
+            } else {
+                this.parent = null;
+            }
 
             // Callback
             this.onDisposeObservable.notifyObservers(this);