David Catuhe %!s(int64=6) %!d(string=hai) anos
pai
achega
14b393b67f

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 10148 - 10167
dist/preview release/babylon.d.ts


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1 - 1
dist/preview release/babylon.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1 - 1
dist/preview release/babylon.worker.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 385 - 120
dist/preview release/inspector/babylon.inspector.bundle.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1 - 1
dist/preview release/inspector/babylon.inspector.bundle.js.map


+ 44 - 33
inspector/src/Inspector.ts

@@ -14,6 +14,9 @@ interface IInternalInspectorOptions extends IInspectorOptions {
     explorerWidth?: string;
     inspectorWidth?: string;
     embedHostWidth?: string;
+    sceneExplorerRoot?: HTMLElement;
+    actionTabsRoot?: HTMLElement;
+    embedHostRoot?: HTMLElement;
 }
 
 export class Inspector {
@@ -104,6 +107,8 @@ export class Inspector {
                 noExpand: !options.enablePopup, popupMode: options.popup, onPopup: () => {
                     ReactDOM.unmountComponentAtNode(this._SceneExplorerHost!);
 
+                    this._RemoveElementFromDOM(this._SceneExplorerHost);
+
                     if (options.popup) {
                         this._SceneExplorerWindow.close();
                     }
@@ -117,9 +122,7 @@ export class Inspector {
                     ReactDOM.unmountComponentAtNode(this._SceneExplorerHost!);
                     Inspector._OpenedPane--;
 
-                    if (this._SceneExplorerHost && this._SceneExplorerHost.parentElement) {
-                        this._SceneExplorerHost.parentElement.removeChild(this._SceneExplorerHost);
-                    }
+                    this._RemoveElementFromDOM(this._SceneExplorerHost);
 
                     this._Cleanup();
 
@@ -166,6 +169,8 @@ export class Inspector {
                 globalState: this._GlobalState, scene: scene, noExpand: !options.enablePopup, popupMode: options.popup, onPopup: () => {
                     ReactDOM.unmountComponentAtNode(this._ActionTabsHost!);
 
+                    this._RemoveElementFromDOM(this._ActionTabsHost);
+
                     if (options.popup) {
                         this._ActionTabsWindow.close();
                     }
@@ -180,9 +185,7 @@ export class Inspector {
                     Inspector._OpenedPane--;
                     this._Cleanup();
 
-                    if (this._ActionTabsHost && this._ActionTabsHost.parentElement) {
-                        this._ActionTabsHost.parentElement.removeChild(this._ActionTabsHost);
-                    }
+                    this._RemoveElementFromDOM(this._ActionTabsHost);
 
                     if (options.popup) {
                         this._ActionTabsWindow.close();
@@ -230,6 +233,8 @@ export class Inspector {
                         this._EmbedHostWindow.close();
                     }
 
+                    this._RemoveElementFromDOM(this._EmbedHost);
+
                     options.popup = !options.popup;
                     options.embedMode = true;
                     options.showExplorer = true;
@@ -242,9 +247,7 @@ export class Inspector {
                     this._OpenedPane = 0;
                     this._Cleanup();
 
-                    if (this._EmbedHost && this._EmbedHost.parentElement) {
-                        this._EmbedHost.parentElement.removeChild(this._EmbedHost);
-                    }
+                    this._RemoveElementFromDOM(this._EmbedHost);
 
                     if (options.popup) {
                         this._EmbedHostWindow.close();
@@ -339,7 +342,7 @@ export class Inspector {
                 this._CreateEmbedHost(scene, options, this._CreatePopup("INSPECTOR", "_EmbedHostWindow"), Inspector.OnSelectionChangeObservable);
             }
             else {
-                let parentControl = (options.embedHostRoot ? options.embedHostRoot.parentElement : canvas!.parentElement) as HTMLElement;
+                let parentControl = (options.globalRoot ? options.globalRoot : canvas!.parentElement) as HTMLElement;
 
                 if (!options.overlay && !this._NewCanvasContainer) {
 
@@ -387,29 +390,11 @@ export class Inspector {
                 this._CreateActionTabs(scene, options, this._CreatePopup("INSPECTOR", "_ActionTabsWindow"));
             }
         } else {
-            let parentControl = (options.actionTabsRoot ? options.actionTabsRoot.parentElement : canvas!.parentElement) as HTMLElement;
+            let parentControl = (options.globalRoot ? options.globalRoot : canvas!.parentElement) as HTMLElement;
 
             if (!options.overlay && !this._NewCanvasContainer) {
 
-                // Create a container for previous elements
-                parentControl.style.display = "grid";
-                parentControl.style.gridTemplateColumns = "auto 1fr auto";
-                parentControl.style.gridTemplateRows = "100%";
-
-                this._NewCanvasContainer = parentControl.ownerDocument!.createElement("div");
-
-                while (parentControl.childElementCount > 0) {
-                    var child = parentControl.childNodes[0];
-                    parentControl.removeChild(child);
-                    this._NewCanvasContainer.appendChild(child);
-                }
-
-                parentControl.appendChild(this._NewCanvasContainer);
-
-                this._NewCanvasContainer.style.gridRow = "1";
-                this._NewCanvasContainer.style.gridColumn = "2";
-                this._NewCanvasContainer.style.width = "100%";
-                this._NewCanvasContainer.style.height = "100%";
+                this._CreateCanvasContainer(parentControl);
 
             } else if (!options.overlay && this._NewCanvasContainer && this._NewCanvasContainer.parentElement) {
                 // the root is now the parent of the canvas container
@@ -443,6 +428,28 @@ export class Inspector {
         }
     }
 
+    private static _CreateCanvasContainer(parentControl: HTMLElement) {
+        // Create a container for previous elements
+        parentControl.style.display = "grid";
+        parentControl.style.gridTemplateColumns = "auto 1fr auto";
+        parentControl.style.gridTemplateRows = "100%";
+
+        this._NewCanvasContainer = parentControl.ownerDocument!.createElement("div");
+
+        while (parentControl.childElementCount > 0) {
+            var child = parentControl.childNodes[0];
+            parentControl.removeChild(child);
+            this._NewCanvasContainer.appendChild(child);
+        }
+
+        parentControl.appendChild(this._NewCanvasContainer);
+
+        this._NewCanvasContainer.style.gridRow = "1";
+        this._NewCanvasContainer.style.gridColumn = "2";
+        this._NewCanvasContainer.style.width = "100%";
+        this._NewCanvasContainer.style.height = "100%";
+    }
+
     private static _Cleanup() {
         if (Inspector._OpenedPane === 0 && this._OnBeforeRenderObserver && this._Scene) {
             this._Scene.onBeforeRenderObservable.remove(this._OnBeforeRenderObserver);
@@ -452,13 +459,17 @@ export class Inspector {
         }
     }
 
+    private static _RemoveElementFromDOM(element: Nullable<HTMLElement>) {
+        if (element && element.parentElement) {
+            element.parentElement.removeChild(element);
+        }
+    }
+
     public static Hide() {
         if (this._ActionTabsHost) {
             ReactDOM.unmountComponentAtNode(this._ActionTabsHost);
 
-            if (this._ActionTabsHost.parentElement) {
-                this._ActionTabsHost.parentElement.removeChild(this._ActionTabsHost);
-            }
+            this._RemoveElementFromDOM(this._ActionTabsHost);
 
             this._ActionTabsHost = null;
         }

+ 0 - 1
inspector/src/components/actionTabs/actionTabs.scss

@@ -117,7 +117,6 @@
 
         .panes {
             grid-row: 2;
-            margin-bottom: 3px;
 
             display: grid;
             grid-template-rows: 1fr;

+ 22 - 10
inspector/src/components/actionTabs/lines/floatLineComponent.tsx

@@ -10,16 +10,19 @@ interface IFloatLineComponentProps {
     onPropertyChangedObservable?: Observable<PropertyChangedEvent>
 }
 
-export class FloatLineComponent extends React.Component<IFloatLineComponentProps, { value: number }> {
+export class FloatLineComponent extends React.Component<IFloatLineComponentProps, { value: string }> {
     private _localChange = false;
+    private _store: number;
 
     constructor(props: IFloatLineComponentProps) {
         super(props);
 
-        this.state = { value: this.props.target[this.props.propertyName] }
+        let currentValue = this.props.target[this.props.propertyName];
+        this.state = { value: currentValue ? currentValue.toFixed(3) : "0" }
+        this._store = currentValue;
     }
 
-    shouldComponentUpdate(nextProps: IFloatLineComponentProps, nextState: { value: number }) {
+    shouldComponentUpdate(nextProps: IFloatLineComponentProps, nextState: { value: string }) {
         if (this._localChange) {
             this._localChange = false;
             return true;
@@ -27,7 +30,7 @@ export class FloatLineComponent extends React.Component<IFloatLineComponentProps
 
         const newValue = nextProps.target[nextProps.propertyName];
         if (newValue !== nextState.value) {
-            nextState.value = newValue;
+            nextState.value = newValue.toFixed(3);
             return true;
         }
         return false;
@@ -46,14 +49,23 @@ export class FloatLineComponent extends React.Component<IFloatLineComponentProps
     }
 
     updateValue(valueString: string) {
-        const value = parseFloat(valueString);
+
+        if (/[^0-9\.\-]/g.test(valueString)) {
+            return;
+        }
+
+        let valueAsNumber = parseFloat(valueString);
+
         this._localChange = true;
+        this.setState({ value: valueString });
+
+        if (isNaN(valueAsNumber)) {
+            return;
+        }
 
-        const store = this.state.value;
-        this.props.target[this.props.propertyName] = value;
-        this.setState({ value: value });
+        this.raiseOnPropertyChanged(valueAsNumber, this._store);
 
-        this.raiseOnPropertyChanged(value, store);
+        this._store = valueAsNumber;
     }
 
     render() {
@@ -65,7 +77,7 @@ export class FloatLineComponent extends React.Component<IFloatLineComponentProps
                     {this.props.label}
                 </div>
                 <div className="value">
-                    <input className="numeric-input" value={this.state.value ? parseFloat(this.state.value.toFixed(3)) : 0} type="number" onChange={evt => this.updateValue(evt.target.value)} step={step} />
+                    <input className="numeric-input" value={this.state.value} onChange={evt => this.updateValue(evt.target.value)} step={step} />
                 </div>
             </div>
         );

+ 16 - 9
inspector/src/components/actionTabs/lines/numericInputComponent.tsx

@@ -6,36 +6,43 @@ interface INumericInputComponentProps {
     onChange: (value: number) => void
 }
 
-export class NumericInputComponent extends React.Component<INumericInputComponentProps, { value: number }> {
+export class NumericInputComponent extends React.Component<INumericInputComponentProps, { value: string }> {
     private _localChange = false;
     constructor(props: INumericInputComponentProps) {
         super(props);
 
-        this.state = { value: this.props.value }
+        this.state = { value: this.props.value.toFixed(3) }
     }
 
-    shouldComponentUpdate(nextProps: INumericInputComponentProps, nextState: { value: number }) {
+    shouldComponentUpdate(nextProps: INumericInputComponentProps, nextState: { value: string }) {
         if (this._localChange) {
             this._localChange = false;
             return true;
         }
 
-        if (nextProps.value !== nextState.value) {
-            nextState.value = nextProps.value;
+        if (nextProps.value.toString() !== nextState.value) {
+            nextState.value = nextProps.value.toFixed(3);
             return true;
         }
         return false;
     }
 
     updateValue(evt: any) {
-        let valueAsNumber = parseFloat(evt.target.value);
+        let value = evt.target.value;
 
-        if (isNaN(valueAsNumber)) {
+        if (/[^0-9\.\-]/g.test(value)) {
             return;
         }
 
+        let valueAsNumber = parseFloat(value);
+
         this._localChange = true;
-        this.setState({ value: valueAsNumber });
+        this.setState({ value: value });
+
+        if (isNaN(valueAsNumber)) {
+            return;
+        }
+
         this.props.onChange(valueAsNumber);
     }
 
@@ -49,7 +56,7 @@ export class NumericInputComponent extends React.Component<INumericInputComponen
                         {`${this.props.label}: `}
                     </div>
                 }
-                <input className="numeric-input" value={this.state.value} type="number" onChange={evt => this.updateValue(evt)} step="0.1" />
+                <input className="numeric-input" value={this.state.value} onChange={evt => this.updateValue(evt)} />
             </div>
         )
     }

+ 113 - 0
inspector/src/components/actionTabs/lines/quaternionLineComponent.tsx

@@ -0,0 +1,113 @@
+import * as React from "react";
+import { Observable, Quaternion, Vector3 } from "babylonjs";
+import { NumericInputComponent } from "./numericInputComponent";
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import { faMinus, faPlus } from "@fortawesome/free-solid-svg-icons";
+import { PropertyChangedEvent } from "../../propertyChangedEvent";
+
+interface IQuaternionLineComponentProps {
+    label: string,
+    target: any,
+    propertyName: string,
+    onPropertyChangedObservable?: Observable<PropertyChangedEvent>
+}
+
+export class QuaternionLineComponent extends React.Component<IQuaternionLineComponentProps, { isExpanded: boolean, value: Quaternion }> {
+    private _localChange = false;
+    private _eulerValue: Vector3;
+
+    constructor(props: IQuaternionLineComponentProps) {
+        super(props);
+
+        this.state = { isExpanded: false, value: this.props.target[this.props.propertyName] }
+    }
+
+    shouldComponentUpdate(nextProps: IQuaternionLineComponentProps, nextState: { isExpanded: boolean, value: Quaternion }) {
+        const nextPropsValue = nextProps.target[nextProps.propertyName];
+
+        if (!nextPropsValue.equals(nextState.value) || this._localChange) {
+            nextState.value = nextPropsValue;
+            this._localChange = false;
+            return true;
+        }
+        return false;
+    }
+
+    switchExpandState() {
+        this._localChange = true;
+        this.setState({ isExpanded: !this.state.isExpanded });
+    }
+
+    raiseOnPropertyChanged(currentValue: Quaternion, previousValue: Quaternion) {
+        if (!this.props.onPropertyChangedObservable) {
+            return;
+        }
+        this.props.onPropertyChangedObservable.notifyObservers({
+            object: this.props.target,
+            property: this.props.propertyName,
+            value: currentValue,
+            initialValue: previousValue
+        });
+    }
+
+    updateQuaternion() {
+        const store = this.state.value.clone();
+        const quaternion = this._eulerValue.toQuaternion();
+        this.props.target[this.props.propertyName] = quaternion;
+
+        this.setState({ value: quaternion });
+
+        this.raiseOnPropertyChanged(quaternion, store);
+    }
+
+    updateStateX(value: number) {
+        this._localChange = true;
+
+        this._eulerValue.x = value;
+        this.updateQuaternion();
+    }
+
+    updateStateY(value: number) {
+        this._localChange = true;
+
+        this._eulerValue.y = value;
+        this.updateQuaternion();
+    }
+
+    updateStateZ(value: number) {
+        this._localChange = true;
+
+        this._eulerValue.z = value;
+        this.updateQuaternion();
+    }
+
+    render() {
+        const chevron = this.state.isExpanded ? <FontAwesomeIcon icon={faMinus} /> : <FontAwesomeIcon icon={faPlus} />
+
+        this._eulerValue = this.state.value.toEulerAngles();
+
+        return (
+            <div className="vector3Line">
+                <div className="firstLine">
+                    <div className="label">
+                        {this.props.label}
+                    </div>
+                    <div className="vector">
+                        {`X: ${this._eulerValue.x.toFixed(2)}, Y: ${this._eulerValue.y.toFixed(2)}, Z: ${this._eulerValue.z.toFixed(2)}`}
+                    </div>
+                    <div className="expand" onClick={() => this.switchExpandState()}>
+                        {chevron}
+                    </div>
+                </div>
+                {
+                    this.state.isExpanded &&
+                    <div className="secondLine">
+                        <NumericInputComponent label="x" value={this._eulerValue.x} onChange={value => this.updateStateX(value)} />
+                        <NumericInputComponent label="y" value={this._eulerValue.y} onChange={value => this.updateStateY(value)} />
+                        <NumericInputComponent label="z" value={this._eulerValue.z} onChange={value => this.updateStateZ(value)} />
+                    </div>
+                }
+            </div>
+        );
+    }
+}

+ 1 - 1
inspector/src/components/actionTabs/lines/vector3LineComponent.tsx

@@ -44,7 +44,7 @@ export class Vector3LineComponent extends React.Component<IVector3LineComponentP
         this.props.onPropertyChangedObservable.notifyObservers({
             object: this.props.target,
             property: this.props.propertyName,
-            value: !this.state.value,
+            value: this.state.value,
             initialValue: previousValue
         });
     }

+ 2 - 2
inspector/src/components/actionTabs/tabs/propertyGrids/cameras/arcRotateCameraPropertyGridComponent.tsx

@@ -35,8 +35,8 @@ export class ArcRotateCameraPropertyGridComponent extends React.Component<IArcRo
             <div className="pane">
                 <CommonCameraPropertyGridComponent camera={camera} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                 <LineContainerComponent title="TRANSFORMS">
-                    <SliderLineComponent label="Alpha" target={camera} propertyName="alpha" minimum={0} maximum={2 * Math.PI} step={0.01} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
-                    <SliderLineComponent label="Beta" target={camera} propertyName="beta" minimum={0} maximum={2 * Math.PI} step={0.01} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <SliderLineComponent label="Alpha" target={camera} propertyName="alpha" minimum={camera.lowerAlphaLimit || 0} maximum={camera.upperAlphaLimit || 2 * Math.PI} step={0.01} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <SliderLineComponent label="Beta" target={camera} propertyName="beta" minimum={camera.lowerAlphaLimit || 0} maximum={camera.upperBetaLimit || 2 * Math.PI} step={0.01} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <FloatLineComponent label="Radius" target={camera} propertyName="radius" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                 </LineContainerComponent>
                 <LineContainerComponent title="CONTROLS" closed={true}>

+ 9 - 1
inspector/src/components/actionTabs/tabs/propertyGrids/meshes/meshPropertyGridComponent.tsx

@@ -6,6 +6,7 @@ import { TextLineComponent } from "../../../lines/textLineComponent";
 import { CheckBoxLineComponent } from "../../../lines/checkBoxLineComponent";
 import { Vector3LineComponent } from "../../../lines/vector3LineComponent";
 import { SliderLineComponent } from "../../../lines/sliderLineComponent";
+import { QuaternionLineComponent } from "../../../lines/quaternionLineComponent";
 
 interface IMeshPropertyGridComponentProps {
     mesh: Mesh,
@@ -91,7 +92,14 @@ export class MeshPropertyGridComponent extends React.Component<IMeshPropertyGrid
                 </LineContainerComponent>
                 <LineContainerComponent title="TRANSFORMS">
                     <Vector3LineComponent label="Position" target={mesh} propertyName="position" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
-                    <Vector3LineComponent label="Rotation" target={mesh} propertyName="rotation" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    {
+                        !mesh.rotationQuaternion &&
+                        <Vector3LineComponent label="Rotation" target={mesh} propertyName="rotation" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    }
+                    {
+                        mesh.rotationQuaternion &&
+                        <QuaternionLineComponent label="Rotation" target={mesh} propertyName="rotationQuaternion" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    }
                     <Vector3LineComponent label="Scaling" target={mesh} propertyName="scaling" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                 </LineContainerComponent>
                 <LineContainerComponent title="DISPLAY" closed={true}>

+ 9 - 1
inspector/src/components/actionTabs/tabs/propertyGrids/meshes/transformNodePropertyGridComponent.tsx

@@ -5,6 +5,7 @@ import { LineContainerComponent } from "../../../lineContainerComponent";
 import { CheckBoxLineComponent } from "../../../lines/checkBoxLineComponent";
 import { Vector3LineComponent } from "../../../lines/vector3LineComponent";
 import { TextLineComponent } from "../../../lines/textLineComponent";
+import { QuaternionLineComponent } from "../../../lines/quaternionLineComponent";
 
 interface ITransformNodePropertyGridComponentProps {
     transformNode: TransformNode,
@@ -29,7 +30,14 @@ export class TransformNodePropertyGridComponent extends React.Component<ITransfo
                 </LineContainerComponent>
                 <LineContainerComponent title="TRANSFORMATIONS">
                     <Vector3LineComponent label="Position" target={transformNode} propertyName="position" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
-                    <Vector3LineComponent label="Rotation" target={transformNode} propertyName="rotation" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    {
+                        !transformNode.rotationQuaternion &&
+                        <Vector3LineComponent label="Rotation" target={transformNode} propertyName="rotation" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    }
+                    {
+                        transformNode.rotationQuaternion &&
+                        <QuaternionLineComponent label="Rotation" target={transformNode} propertyName="rotationQuaternion" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    }
                     <Vector3LineComponent label="Scaling" target={transformNode} propertyName="scaling" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                 </LineContainerComponent>
             </div>

+ 47 - 2
inspector/src/components/sceneExplorer/entities/sceneTreeItemComponent.tsx

@@ -1,4 +1,4 @@
-import { Scene, Observable, PointerInfo, Observer, Nullable, IExplorerExtensibilityGroup } from "babylonjs";
+import { Scene, Observable, PointerInfo, Observer, Nullable, IExplorerExtensibilityGroup, GizmoManager } from "babylonjs";
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { faSyncAlt, faImage, faCrosshairs, faArrowsAlt, faCompress, faRedoAlt } from '@fortawesome/free-solid-svg-icons';
 import { ExtensionsComponent } from "../extensionsComponent";
@@ -18,7 +18,20 @@ export class SceneTreeItemComponent extends React.Component<ISceneTreeItemCompon
     constructor(props: ISceneTreeItemComponentProps) {
         super(props);
 
-        this.state = { isSelected: false, isInPickingMode: false, gizmoMode: 0 };
+        const scene = this.props.scene;
+        let gizmoMode = 0;
+        if (scene.metadata && scene.metadata.gizmoManager) {
+            const manager: GizmoManager = scene.metadata.gizmoManager;
+            if (manager.positionGizmoEnabled) {
+                gizmoMode = 1;
+            } else if (manager.rotationGizmoEnabled) {
+                gizmoMode = 2;
+            } else if (manager.scaleGizmoEnabled) {
+                gizmoMode = 3;
+            }
+        }
+
+        this.state = { isSelected: false, isInPickingMode: false, gizmoMode: gizmoMode };
     }
 
     shouldComponentUpdate(nextProps: ISceneTreeItemComponentProps, nextState: { isSelected: boolean, isInPickingMode: boolean }) {
@@ -74,6 +87,38 @@ export class SceneTreeItemComponent extends React.Component<ISceneTreeItemCompon
     }
 
     setGizmoMode(mode: number) {
+        const scene = this.props.scene;
+
+        if (!scene.metadata) {
+            scene.metadata = {};
+        }
+
+        if (!scene.metadata.gizmoManager) {
+            scene.metadata.gizmoManager = new GizmoManager(scene);
+        }
+
+        const manager: GizmoManager = scene.metadata.gizmoManager;
+
+        manager.positionGizmoEnabled = false;
+        manager.rotationGizmoEnabled = false;
+        manager.scaleGizmoEnabled = false;
+
+        if (this.state.gizmoMode === mode) {
+            mode = 0;
+        }
+
+        switch (mode) {
+            case 1:
+                manager.positionGizmoEnabled = true;
+                break;
+            case 2:
+                manager.rotationGizmoEnabled = true;
+                break;
+            case 3:
+                manager.scaleGizmoEnabled = true;
+                break;
+        }
+
         this.setState({ gizmoMode: mode });
     }
 

+ 37 - 29
sandbox/index-local.html

@@ -1,5 +1,6 @@
 <!DOCTYPE html>
 <html xmlns="http://www.w3.org/1999/xhtml">
+
 <head>
     <title>BabylonJS - Sandbox</title>
     <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1">
@@ -9,43 +10,49 @@
     <script src="../dist/preview%20release/gltf_validator.js"></script>
     <script src="../Tools/DevLoader/BabylonLoader.js"></script>
 </head>
+
 <body>
-    <p id="droptext">Drag and drop gltf, glb, obj or babylon files to view them</p>
-    <canvas id="renderCanvas"></canvas>
-    <div id="logo">
-    </div>
-    <div id="footer" class="footer">
-        <div id="animationBar">
-            <div class="dropdown">
-                <div id="dropdownBtn">
-                    <img src="Assets/Icon_Up.svg" id="chevronUp">
-                    <img src="Assets/Icon_Down.svg" id="chevronDown">
-                    <span id="dropdownLabel"></span>
+    <div id="root">
+        <p id="droptext">Drag and drop gltf, glb, obj or babylon files to view them</p>
+        <div id="canvasZone">
+            <canvas id="renderCanvas" touch-action="none"></canvas>
+        </div>
+        <div id="footer" class="footer">
+            <div id="animationBar">
+                <div class="dropdown">
+                    <div id="dropdownBtn">
+                        <img src="Assets/Icon_Up.svg" id="chevronUp">
+                        <img src="Assets/Icon_Down.svg" id="chevronDown">
+                        <span id="dropdownLabel"></span>
+                    </div>
+                    <div id="dropdownContent">
+                    </div>
                 </div>
-                <div id="dropdownContent">
+                <div class="row">
+                    <button id="playBtn" class="pause">
+                        <img id="playImg" src="Assets/Icon_Play.svg">
+                        <img id="pauseImg" src="Assets/Icon_Pause.svg">
+                    </button>
+                    <input id="slider" type="range" min="0" max="100" value="0" step="any">
                 </div>
             </div>
-            <div class="row">
-                <button id="playBtn" class="pause">
-                    <img id="playImg" src="Assets/Icon_Play.svg">
-                    <img id="pauseImg" src="Assets/Icon_Pause.svg">
-                </button>
-                <input id="slider" type="range" min="0" max="100" value="0" step="any">
+            <div class="footerRight">
+                <a href="javascript:void(null);" id="btnInspector" class="hidden"><img src="./Assets/Icon_EditModel.svg"
+                        alt="Display inspector" title="Display inspector" /></a>
+                <a href="javascript:void(null);">
+                    <div class="custom-upload" title="Open your scene from your hard drive (.babylon, .gltf, .glb, .obj)">
+                        <input type="file" id="files" multiple />
+                    </div>
+                </a>
             </div>
         </div>
-        <div class="footerRight">
-            <a href="javascript:void(null);" id="btnInspector" class="hidden"><img src="./Assets/Icon_EditModel.svg" alt="Display inspector" title="Display inspector" /></a> 
-            <a href="javascript:void(null);">
-                <div class="custom-upload" title="Open your scene from your hard drive (.babylon, .gltf, .glb, .obj)">
-                    <input type="file" id="files" multiple />
-                </div>
-            </a>
+        <div id="logo">
         </div>
+        <div id="errorZone"></div>
     </div>
-    <div id="errorZone"></div>
     <script>
         // prevent drag and drop of file until local scripts are loaded
-        document.ondragover = function (e) {
+        document.ondragover = function(e) {
             e.dataTransfer.dropEffect = "none";
             e.dataTransfer.effectAllowed = "none";
             e.preventDefault();
@@ -53,7 +60,7 @@
 
         BABYLONDEVTOOLS.Loader
             .require('index.js')
-            .load(function () {
+            .load(function() {
                 BABYLON.DracoCompression.Configuration.decoder = {
                     wasmUrl: "../dist/preview%20release/draco_wasm_wrapper_gltf.js",
                     wasmBinaryUrl: "../dist/preview%20release/draco_decoder_gltf.wasm",
@@ -62,4 +69,5 @@
             });
     </script>
 </body>
-</html>
+
+</html>

+ 17 - 12
sandbox/index.css

@@ -1,4 +1,4 @@
-html, body {
+html, body, #root {
     width: 100%;
     height: 100%;
     padding: 0;
@@ -12,18 +12,25 @@
     display: none;
 }
 
+#canvasZone {
+    display: block;
+    padding: 0;
+    margin: 0;
+    overflow: hidden;
+    width: 100%;
+    height: calc(100% - 56px);   
+}
+
 #renderCanvas {
     position: relative;
     overflow: hidden;
     width: 100%;
-    height: calc(100% - 56px);
-    top: 0;
+    height: 100%;
     margin: 0;
-    right: 0;
-    left: 0;
+    padding: 0;
     touch-action: none;
-    -ms-touch-action: none;    
-    margin-bottom: -4px
+    -ms-touch-action: none;  
+    display: block;
 }
 
 a {
@@ -39,17 +46,15 @@ a {
     position: relative;
     width: 100%;
     height: 56px;
-    bottom: 0;
     margin: 0;
     padding: 0;
-    right: 0;
-    left: 0;
     background-color: #3B789A;
+    font-size: 0;
 }
 
 .footerRight {
-    display: inline;
-    position: absolute;
+    display: block;
+    float: right;
     bottom: 0;
     right: 0px;
     top: 0px;

+ 35 - 28
sandbox/index.html

@@ -1,5 +1,6 @@
 <!DOCTYPE html>
 <html xmlns="http://www.w3.org/1999/xhtml">
+
 <head>
     <title>BabylonJS Sandbox - View glTF, glb, obj and babylon files</title>
     <meta name="description" content="Viewer for glTF, glb, obj and babylon files powered by BabylonJS" />
@@ -34,47 +35,53 @@
     <script src="https://preview.babylonjs.com/Oimo.js"></script>
     <script src="https://preview.babylonjs.com/gltf_validator.js"></script>
     <script src="https://preview.babylonjs.com/babylon.js"></script>
-    <script src="https://preview.babylonjs.com/inspector/babylon.inspector.bundle.js"></script> 
+    <script src="https://preview.babylonjs.com/inspector/babylon.inspector.bundle.js"></script>
 
     <script src="https://preview.babylonjs.com/loaders/babylonjs.loaders.min.js"></script>
     <script src="https://preview.babylonjs.com/serializers/babylonjs.serializers.min.js"></script>
     <script src="https://preview.babylonjs.com/materialsLibrary/babylonjs.materials.min.js"></script>
 </head>
+
 <body>
-    <p id="droptext">Drag and drop gltf, glb, obj or babylon files to view them</p>
-    <canvas id="renderCanvas" touch-action="none"></canvas>
-    <div id="logo">
-    </div>
-    <div id="footer" class="footer">
-        <div id="animationBar">
-            <div class="dropdown">
-                <div id="dropdownBtn">
-                    <img src="Assets/Icon_Up.svg" id="chevronUp">
-                    <img src="Assets/Icon_Down.svg" id="chevronDown">
-                    <span id="dropdownLabel"></span>
+    <div id="root">
+        <p id="droptext">Drag and drop gltf, glb, obj or babylon files to view them</p>
+        <div id="canvasZone">
+            <canvas id="renderCanvas" touch-action="none"></canvas>
+        </div>
+        <div id="footer" class="footer">
+            <div id="animationBar">
+                <div class="dropdown">
+                    <div id="dropdownBtn">
+                        <img src="Assets/Icon_Up.svg" id="chevronUp">
+                        <img src="Assets/Icon_Down.svg" id="chevronDown">
+                        <span id="dropdownLabel"></span>
+                    </div>
+                    <div id="dropdownContent">
+                    </div>
                 </div>
-                <div id="dropdownContent">
+                <div class="row">
+                    <button id="playBtn" class="pause">
+                        <img id="playImg" src="Assets/Icon_Play.svg">
+                        <img id="pauseImg" src="Assets/Icon_Pause.svg">
+                    </button>
+                    <input id="slider" type="range" min="0" max="100" value="0" step="any">
                 </div>
             </div>
-            <div class="row">
-                <button id="playBtn" class="pause">
-                    <img id="playImg" src="Assets/Icon_Play.svg">
-                    <img id="pauseImg" src="Assets/Icon_Pause.svg">
-                </button>
-                <input id="slider" type="range" min="0" max="100" value="0" step="any">
+            <div class="footerRight">
+                <a href="javascript:void(null);" id="btnInspector" class="hidden"><img src="./Assets/Icon_EditModel.svg"
+                        alt="Display inspector" title="Display inspector" /></a>
+                <a href="javascript:void(null);">
+                    <div class="custom-upload" title="Open your scene from your hard drive (.babylon, .gltf, .glb, .obj)">
+                        <input type="file" id="files" multiple />
+                    </div>
+                </a>
             </div>
-        </div>               
-        <div class="footerRight">
-            <a href="javascript:void(null);" id="btnInspector" class="hidden"><img src="./Assets/Icon_EditModel.svg" alt="Display inspector" title="Display inspector" /></a> 
-            <a href="javascript:void(null);">
-                <div class="custom-upload" title="Open your scene from your hard drive (.babylon, .gltf, .glb, .obj)">
-                    <input type="file" id="files" multiple />
-                </div>
-            </a>
         </div>
     </div>
+    <div id="logo">
+    </div>
     <div id="errorZone"></div>
     <script src="index.js"></script>
 </body>
 
-</html>
+</html>

+ 3 - 5
src/Debug/babylon.debugLayer.ts

@@ -16,9 +16,7 @@ module BABYLON {
 
     export interface IInspectorOptions {
         overlay?: boolean;
-        sceneExplorerRoot?: HTMLElement;
-        actionTabsRoot?: HTMLElement;
-        embedHostRoot?: HTMLElement;
+        globalRoot?: HTMLElement;
         showExplorer?: boolean;
         showInspector?: boolean;
         embedMode?: boolean;
@@ -92,7 +90,7 @@ module BABYLON {
         }
 
         /** Creates the inspector window. */
-        private _createInspector(config: Partial<IInspectorOptions>) {
+        private _createInspector(config?: Partial<IInspectorOptions>) {
             if (this.isVisible()) {
                 return;
             }
@@ -131,7 +129,7 @@ module BABYLON {
           * Launch the debugLayer.
           * @param config Define the configuration of the inspector
           */
-        public show(config: IInspectorOptions): void {
+        public show(config?: IInspectorOptions): void {
 
             if (typeof this.BJSINSPECTOR == 'undefined') {
                 // Load inspector and add it to the DOM