Browse Source

Associated with #6224

David Catuhe 6 years ago
parent
commit
848402864b

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

@@ -22,6 +22,7 @@
 - Added enterPointerlock and exitPointerlock (Separated from enterFullscreen) ([aWeirdo](https://github.com/aWeirdo/))
 
 ### Inspector
+- Added support for Euler edition only for angles (can be turned off in the new inspector settings) ([Deltakosh](https://github.com/deltakosh/))
 - Added support for `ShadowGenerator` ([Deltakosh](https://github.com/deltakosh/))
 - Added support for scene normalization ([Deltakosh](https://github.com/deltakosh/))
 - Added support for morph targets ([Deltakosh](https://github.com/deltakosh/))

+ 10 - 8
inspector/src/components/actionTabs/actionTabsComponent.tsx

@@ -3,7 +3,7 @@ import { Nullable } from "babylonjs/types";
 import { Observer } from "babylonjs/Misc/observable";
 import { Scene } from "babylonjs/scene";
 import { TabsComponent } from "./tabsComponent";
-import { faFileAlt, faWrench, faBug, faChartBar } from '@fortawesome/free-solid-svg-icons';
+import { faFileAlt, faWrench, faBug, faChartBar, faCog } from '@fortawesome/free-solid-svg-icons';
 import { StatisticsTabComponent } from "./tabs/statisticsTabComponent";
 import { DebugTabComponent } from "./tabs/debugTabComponent";
 import Resizable from "re-resizable";
@@ -11,6 +11,7 @@ import { PropertyGridTabComponent } from "./tabs/propertyGridTabComponent";
 import { HeaderComponent } from "../headerComponent";
 import { ToolsTabComponent } from "./tabs/toolsTabComponent";
 import { GlobalState } from "../../components/globalState";
+import { SettingsTabComponent } from './tabs/settingsTabComponent';
 
 require("./actionTabs.scss");
 
@@ -36,7 +37,7 @@ export class ActionTabsComponent extends React.Component<IActionTabsComponentPro
 
         let initialIndex = 0;
 
-        if(this.props.globalState){
+        if (this.props.globalState) {
             const validationResutls = this.props.globalState.validationResults;
             if (validationResutls) {
                 if (validationResutls.issues.numErrors || validationResutls.issues.numWarnings) {
@@ -44,13 +45,13 @@ export class ActionTabsComponent extends React.Component<IActionTabsComponentPro
                 }
             }
         }
-        
+
 
         this.state = { selectedEntity: null, selectedIndex: initialIndex }
     }
 
     componentWillMount() {
-        if(this.props.globalState){
+        if (this.props.globalState) {
             this._onSelectionChangeObserver = this.props.globalState.onSelectionChangedObservable.add((entity) => {
                 this.setState({ selectedEntity: entity, selectedIndex: 0 });
             });
@@ -62,7 +63,7 @@ export class ActionTabsComponent extends React.Component<IActionTabsComponentPro
     }
 
     componentWillUnmount() {
-        if(this.props.globalState){
+        if (this.props.globalState) {
             if (this._onSelectionChangeObserver) {
                 this.props.globalState.onSelectionChangedObservable.remove(this._onSelectionChangeObserver);
             }
@@ -74,13 +75,13 @@ export class ActionTabsComponent extends React.Component<IActionTabsComponentPro
     }
 
     changeSelectedTab(index: number) {
-        if(this.props.globalState){
+        if (this.props.globalState) {
             this.props.globalState.onTabChangedObservable.notifyObservers(index);
         }
     }
 
     renderContent() {
-        if(this.props.globalState && this.props.scene){
+        if (this.props.globalState && this.props.scene) {
             return (
                 <TabsComponent selectedIndex={this.state.selectedIndex} onSelectedIndexChange={(value) => this.changeSelectedTab(value)}>
                     <PropertyGridTabComponent
@@ -91,9 +92,10 @@ export class ActionTabsComponent extends React.Component<IActionTabsComponentPro
                     <DebugTabComponent title="Debug" icon={faBug} scene={this.props.scene} globalState={this.props.globalState} />
                     <StatisticsTabComponent title="Statistics" icon={faChartBar} scene={this.props.scene} globalState={this.props.globalState} />
                     <ToolsTabComponent title="Tools" icon={faWrench} scene={this.props.scene} globalState={this.props.globalState} />
+                    <SettingsTabComponent title="Settings" icon={faCog} scene={this.props.scene} globalState={this.props.globalState} />
                 </TabsComponent>
             )
-        }else{
+        } else {
             return null;
         }
     }

+ 57 - 5
inspector/src/components/actionTabs/lines/quaternionLineComponent.tsx

@@ -1,25 +1,30 @@
 import * as React from "react";
 import { Observable } from "babylonjs/Misc/observable";
-import { Quaternion } from "babylonjs/Maths/math";
+import { Quaternion, Vector3 } from "babylonjs/Maths/math";
 import { NumericInputComponent } from "./numericInputComponent";
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { faMinus, faPlus } from "@fortawesome/free-solid-svg-icons";
 import { PropertyChangedEvent } from "../../propertyChangedEvent";
+import { Tools } from 'babylonjs/Misc/tools';
+import { SliderLineComponent } from './sliderLineComponent';
 
 interface IQuaternionLineComponentProps {
     label: string;
     target: any;
+    useEuler?: boolean;
     propertyName: string;
     onPropertyChangedObservable?: Observable<PropertyChangedEvent>;
 }
 
-export class QuaternionLineComponent extends React.Component<IQuaternionLineComponentProps, { isExpanded: boolean, value: Quaternion }> {
+export class QuaternionLineComponent extends React.Component<IQuaternionLineComponentProps, { isExpanded: boolean, value: Quaternion, eulerValue: Vector3 }> {
     private _localChange = false;
 
     constructor(props: IQuaternionLineComponentProps) {
         super(props);
 
-        this.state = { isExpanded: false, value: this.props.target[this.props.propertyName].clone() }
+        let quat = this.props.target[this.props.propertyName].clone();
+
+        this.state = { isExpanded: false, value: quat, eulerValue: quat.toEulerAngles() }
     }
 
     shouldComponentUpdate(nextProps: IQuaternionLineComponentProps, nextState: { isExpanded: boolean, value: Quaternion }) {
@@ -87,10 +92,42 @@ export class QuaternionLineComponent extends React.Component<IQuaternionLineComp
         this.updateQuaternion();
     }
 
+    updateQuaternionFromEuler() {
+        let quat = this.state.eulerValue.toQuaternion();
+        this.state.value.x = quat.x;
+        this.state.value.y = quat.y;
+        this.state.value.z = quat.z;
+        this.state.value.w = quat.w;
+
+        this.updateQuaternion();
+    }
+
+    updateStateEulerX(value: number) {
+        this._localChange = true;
+
+        this.state.eulerValue.x = Tools.ToRadians(value);
+        this.updateQuaternionFromEuler();
+    }
+
+    updateStateEulerY(value: number) {
+        this._localChange = true;
+
+        this.state.eulerValue.y = Tools.ToRadians(value);
+        this.updateQuaternionFromEuler();
+    }
+
+    updateStateEulerZ(value: number) {
+        this._localChange = true;
+
+        this.state.eulerValue.z = Tools.ToRadians(value);
+        this.updateQuaternionFromEuler();
+    }
+
     render() {
         const chevron = this.state.isExpanded ? <FontAwesomeIcon icon={faMinus} /> : <FontAwesomeIcon icon={faPlus} />
 
         let quat = this.state.value;
+        let euler = this.state.eulerValue;
 
         return (
             <div className="vector3Line">
@@ -99,14 +136,21 @@ export class QuaternionLineComponent extends React.Component<IQuaternionLineComp
                         {this.props.label}
                     </div>
                     <div className="vector">
-                        {`X: ${quat.x.toFixed(1)}, Y: ${quat.y.toFixed(1)}, Z: ${quat.z.toFixed(1)}, W: ${quat.w.toFixed(1)}`}
+                        {
+                            !this.props.useEuler &&
+                            `X: ${quat.x.toFixed(1)}, Y: ${quat.y.toFixed(1)}, Z: ${quat.z.toFixed(1)}, W: ${quat.w.toFixed(1)}`
+                        }
+                        {
+                            this.props.useEuler &&
+                            `X: ${Tools.ToDegrees(euler.x).toFixed(2)}, Y: ${Tools.ToDegrees(euler.y).toFixed(2)}, Z: ${Tools.ToDegrees(euler.z).toFixed(2)}`
+                        }
                     </div>
                     <div className="expand" onClick={() => this.switchExpandState()}>
                         {chevron}
                     </div>
                 </div>
                 {
-                    this.state.isExpanded &&
+                    this.state.isExpanded && !this.props.useEuler &&
                     <div className="secondLine">
                         <NumericInputComponent label="x" value={quat.x} onChange={value => this.updateStateX(value)} />
                         <NumericInputComponent label="y" value={quat.y} onChange={value => this.updateStateY(value)} />
@@ -114,6 +158,14 @@ export class QuaternionLineComponent extends React.Component<IQuaternionLineComp
                         <NumericInputComponent label="w" value={quat.w} onChange={value => this.updateStateW(value)} />
                     </div>
                 }
+                {
+                    this.state.isExpanded && this.props.useEuler &&
+                    <div className="secondLine">
+                        <SliderLineComponent label="x" minimum={0} maximum={360} step={0.1} directValue={Tools.ToDegrees(euler.x)} onChange={value => this.updateStateEulerX(value)} />
+                        <SliderLineComponent label="y" minimum={0} maximum={360} step={0.1} directValue={Tools.ToDegrees(euler.y)} onChange={value => this.updateStateEulerY(value)} />
+                        <SliderLineComponent label="z" minimum={0} maximum={360} step={0.1} directValue={Tools.ToDegrees(euler.z)} onChange={value => this.updateStateEulerZ(value)} />
+                    </div>
+                }
             </div>
         );
     }

+ 26 - 6
inspector/src/components/actionTabs/lines/vector3LineComponent.tsx

@@ -6,6 +6,8 @@ import { NumericInputComponent } from "./numericInputComponent";
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { faMinus, faPlus } from "@fortawesome/free-solid-svg-icons";
 import { PropertyChangedEvent } from "../../propertyChangedEvent";
+import { SliderLineComponent } from './sliderLineComponent';
+import { Tools } from 'babylonjs/Misc/tools';
 
 interface IVector3LineComponentProps {
     label: string;
@@ -13,6 +15,7 @@ interface IVector3LineComponentProps {
     propertyName: string;
     step?: number;
     onChange?: (newvalue: Vector3) => void;
+    useEuler?: boolean,
     onPropertyChangedObservable?: Observable<PropertyChangedEvent>;
 }
 
@@ -27,11 +30,15 @@ export class Vector3LineComponent extends React.Component<IVector3LineComponentP
     constructor(props: IVector3LineComponentProps) {
         super(props);
 
-        this.state = { isExpanded: false, value: this.props.target[this.props.propertyName].clone() }
+        this.state = { isExpanded: false, value: this.getCurrentValue().clone() }
+    }
+
+    getCurrentValue() {
+        return this.props.target[this.props.propertyName];
     }
 
     shouldComponentUpdate(nextProps: IVector3LineComponentProps, nextState: { isExpanded: boolean, value: Vector3 }) {
-        const nextPropsValue = nextProps.target[nextProps.propertyName];
+        const nextPropsValue = this.getCurrentValue();
 
         if (!nextPropsValue.equals(nextState.value) || this._localChange) {
             nextState.value = nextPropsValue.clone();
@@ -71,7 +78,6 @@ export class Vector3LineComponent extends React.Component<IVector3LineComponentP
         this.raiseOnPropertyChanged(store);
     }
 
-
     updateStateX(value: number) {
         this._localChange = true;
 
@@ -103,21 +109,35 @@ export class Vector3LineComponent extends React.Component<IVector3LineComponentP
                         {this.props.label}
                     </div>
                     <div className="vector">
-                        {`X: ${this.state.value.x.toFixed(2)}, Y: ${this.state.value.y.toFixed(2)}, Z: ${this.state.value.z.toFixed(2)}`}
-
+                        {
+                            !this.props.useEuler &&
+                            `X: ${this.state.value.x.toFixed(2)}, Y: ${this.state.value.y.toFixed(2)}, Z: ${this.state.value.z.toFixed(2)}`
+                        }
+                        {
+                            this.props.useEuler &&
+                            `X: ${Tools.ToDegrees(this.state.value.x).toFixed(2)}, Y: ${Tools.ToDegrees(this.state.value.y).toFixed(2)}, Z: ${Tools.ToDegrees(this.state.value.z).toFixed(2)}`
+                        }
                     </div>
                     <div className="expand hoverIcon" onClick={() => this.switchExpandState()} title="Expand">
                         {chevron}
                     </div>
                 </div>
                 {
-                    this.state.isExpanded &&
+                    this.state.isExpanded && !this.props.useEuler &&
                     <div className="secondLine">
                         <NumericInputComponent label="x" step={this.props.step} value={this.state.value.x} onChange={value => this.updateStateX(value)} />
                         <NumericInputComponent label="y" step={this.props.step} value={this.state.value.y} onChange={value => this.updateStateY(value)} />
                         <NumericInputComponent label="z" step={this.props.step} value={this.state.value.z} onChange={value => this.updateStateZ(value)} />
                     </div>
                 }
+                {
+                    this.state.isExpanded && this.props.useEuler &&
+                    <div className="secondLine">
+                        <SliderLineComponent label="x" minimum={0} maximum={360} step={0.1} directValue={Tools.ToDegrees(this.state.value.x)} onChange={value => this.updateStateX(Tools.ToRadians(value))} />
+                        <SliderLineComponent label="y" minimum={0} maximum={360} step={0.1} directValue={Tools.ToDegrees(this.state.value.y)} onChange={value => this.updateStateY(Tools.ToRadians(value))} />
+                        <SliderLineComponent label="z" minimum={0} maximum={360} step={0.1} directValue={Tools.ToDegrees(this.state.value.z)} onChange={value => this.updateStateZ(Tools.ToRadians(value))} />
+                    </div>
+                }
             </div>
         );
     }

+ 1 - 1
inspector/src/components/actionTabs/tabs/propertyGrids/customPropertyGridComponent.tsx

@@ -43,7 +43,7 @@ export class CustomPropertyGridComponent extends React.Component<ICustomProperty
                 )
             case InspectableType.Quaternion:
                 return (
-                    <QuaternionLineComponent key={inspectable.label} label={inspectable.label} target={this.props.target} propertyName={inspectable.propertyName}
+                    <QuaternionLineComponent useEuler={this.props.globalState.onlyUseEulers} key={inspectable.label} label={inspectable.label} target={this.props.target} propertyName={inspectable.propertyName}
                         onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                 )
             case InspectableType.Color3:

+ 2 - 2
inspector/src/components/actionTabs/tabs/propertyGrids/meshes/bonePropertyGridComponent.tsx

@@ -36,11 +36,11 @@ export class BonePropertyGridComponent extends React.Component<IBonePropertyGrid
                     <Vector3LineComponent label="Position" target={bone} propertyName="position" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     {
                         !bone.rotationQuaternion &&
-                        <Vector3LineComponent label="Rotation" target={bone} propertyName="rotation" step={0.01} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                        <Vector3LineComponent label="Rotation" useEuler={this.props.globalState.onlyUseEulers} target={bone} propertyName="rotation" step={0.01} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     }
                     {
                         bone.rotationQuaternion &&
-                        <QuaternionLineComponent label="Rotation" target={bone} propertyName="rotationQuaternion" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                        <QuaternionLineComponent label="Rotation" useEuler={this.props.globalState.onlyUseEulers} target={bone} propertyName="rotationQuaternion" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     }
                     <Vector3LineComponent label="Scaling" target={bone} propertyName="scaling" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                 </LineContainerComponent>

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

@@ -243,8 +243,8 @@ export class MeshPropertyGridComponent extends React.Component<IMeshPropertyGrid
                     <TextLineComponent label="Faces" value={(mesh.getTotalIndices() / 3).toFixed(0)} />
                     <TextLineComponent label="Sub-meshes" value={mesh.subMeshes ? mesh.subMeshes.length.toString() : "0"} />
                     <TextLineComponent label="Has skeleton" value={mesh.skeleton ? "Yes" : "No"} />
-                    <CheckBoxLineComponent label="IsEnabled" isSelected={() => mesh.isEnabled()} onSelect={(value) => mesh.setEnabled(value)} />
-                    <CheckBoxLineComponent label="IsPickable" target={mesh} propertyName="isPickable" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <CheckBoxLineComponent label="Is enabled" isSelected={() => mesh.isEnabled()} onSelect={(value) => mesh.setEnabled(value)} />
+                    <CheckBoxLineComponent label="Is pickable" target={mesh} propertyName="isPickable" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     {
                         mesh.material &&
                         <TextLineComponent label="Material" value={mesh.material.name} onLink={() => this.onMaterialLink()} />
@@ -258,11 +258,11 @@ export class MeshPropertyGridComponent extends React.Component<IMeshPropertyGrid
                     <Vector3LineComponent label="Position" target={mesh} propertyName="position" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     {
                         !mesh.rotationQuaternion &&
-                        <Vector3LineComponent label="Rotation" target={mesh} propertyName="rotation" step={0.01} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                        <Vector3LineComponent label="Rotation" useEuler={this.props.globalState.onlyUseEulers} target={mesh} propertyName="rotation" step={0.01} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     }
                     {
                         mesh.rotationQuaternion &&
-                        <QuaternionLineComponent label="Rotation" target={mesh} propertyName="rotationQuaternion" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                        <QuaternionLineComponent label="Rotation" useEuler={this.props.globalState.onlyUseEulers} target={mesh} propertyName="rotationQuaternion" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     }
                     <Vector3LineComponent label="Scaling" target={mesh} propertyName="scaling" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                 </LineContainerComponent>

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

@@ -42,11 +42,11 @@ export class TransformNodePropertyGridComponent extends React.Component<ITransfo
                     <Vector3LineComponent label="Position" target={transformNode} propertyName="position" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     {
                         !transformNode.rotationQuaternion &&
-                        <Vector3LineComponent label="Rotation" target={transformNode} propertyName="rotation" step={0.01} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                        <Vector3LineComponent label="Rotation" useEuler={this.props.globalState.onlyUseEulers} target={transformNode} propertyName="rotation" step={0.01} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     }
                     {
                         transformNode.rotationQuaternion &&
-                        <QuaternionLineComponent label="Rotation" target={transformNode} propertyName="rotationQuaternion" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                        <QuaternionLineComponent label="Rotation" useEuler={this.props.globalState.onlyUseEulers} target={transformNode} propertyName="rotationQuaternion" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     }
                     <Vector3LineComponent label="Scaling" target={transformNode} propertyName="scaling" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                 </LineContainerComponent>

+ 20 - 0
inspector/src/components/actionTabs/tabs/settingsTabComponent.tsx

@@ -0,0 +1,20 @@
+import * as React from "react";
+import { PaneComponent, IPaneComponentProps } from "../paneComponent";
+import { CheckBoxLineComponent } from '../lines/checkBoxLineComponent';
+
+export class SettingsTabComponent extends PaneComponent {
+
+    constructor(props: IPaneComponentProps) {
+        super(props);
+    }
+
+    render() {
+        const state = this.props.globalState;
+
+        return (
+            <div className="pane">
+                <CheckBoxLineComponent label="Only display Euler values" target={state} propertyName="onlyUseEulers" />
+            </div>
+        );
+    }
+}

+ 17 - 0
inspector/src/components/globalState.ts

@@ -9,6 +9,7 @@ import { Light } from "babylonjs/Lights/light";
 import { LightGizmo } from "babylonjs/Gizmos/lightGizmo";
 import { PropertyChangedEvent } from "./propertyChangedEvent";
 import { ReplayRecorder } from './replayRecorder';
+import { Tools } from '../tools';
 
 export class GlobalState {
     public onSelectionChangedObservable: Observable<any>;
@@ -29,6 +30,22 @@ export class GlobalState {
 
     public recorder = new ReplayRecorder();
 
+    private _onlyUseEulers: Nullable<boolean> = null;
+
+    public get onlyUseEulers(): boolean {
+        if (this._onlyUseEulers === null) {
+            this._onlyUseEulers = Tools.ReadLocalBooleanSettings("settings_onlyUseEulers", true);
+        }
+
+        return this._onlyUseEulers!;
+    }
+
+    public set onlyUseEulers(value: boolean) {
+        this._onlyUseEulers = value;
+
+        Tools.StoreLocalBooleanSettings("settings_onlyUseEulers", value);
+    }
+
     public init(propertyChangedObservable: Observable<PropertyChangedEvent>) {
         this.onPropertyChangedObservable = propertyChangedObservable;
 

+ 14 - 0
inspector/src/tools.ts

@@ -1,4 +1,18 @@
 export class Tools {
+    public static StoreLocalBooleanSettings(key: string, value: boolean) {
+        if (typeof (Storage) !== "undefined") {
+            localStorage.setItem(key, value ? "true" : "false");
+        }
+    }
+
+    public static ReadLocalBooleanSettings(key: string, defaultValue: boolean): boolean {
+        if (typeof (Storage) !== "undefined" && localStorage.getItem(key) !== null) {
+            return localStorage.getItem(key) === "true";
+        } else {
+            return defaultValue;
+        }
+    }
+
     public static LookForItem(item: any, selectedEntity: any): boolean {
         if (item === selectedEntity) {
             return true;