Browse Source

Merge pull request #9446 from msDestiny14/msDestiny14/tooling

[NME] Adding ability to make input node's properties visible in the properties of a custom frame
Pamela W 4 years ago
parent
commit
a733e4ec00

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

@@ -24,6 +24,10 @@
 
 - Added support for sounds in the inspector ([Deltakosh](https://github.com/deltakosh))
 
+### NME
+
+- Added ability to make input node's properties visible in the properties of a custom frame ([msDestiny14](https://github.com/msDestiny14))
+
 ### GUI
 
 - Added a `FocusableButton` gui control to simplify creating menus with keyboard navigation ([Flux159](https://github.com/Flux159))

+ 110 - 0
nodeEditor/src/components/propertyTab/inputsPropertyTabComponent.tsx

@@ -0,0 +1,110 @@
+import * as React from "react";
+import { GlobalState } from '../../globalState';
+import { LineContainerComponent } from '../../sharedComponents/lineContainerComponent';
+import { CheckBoxLineComponent } from '../../sharedComponents/checkBoxLineComponent';
+import { SliderLineComponent } from '../../sharedComponents/sliderLineComponent';
+import { InputBlock } from 'babylonjs/Materials/Node/Blocks/Input/inputBlock';
+import { NodeMaterialBlockConnectionPointTypes } from 'babylonjs/Materials/Node/Enums/nodeMaterialBlockConnectionPointTypes';
+import { Color3LineComponent } from '../../sharedComponents/color3LineComponent';
+import { FloatLineComponent } from '../../sharedComponents/floatLineComponent';
+import { Color4LineComponent } from '../../sharedComponents/color4LineComponent';
+import { Vector2LineComponent } from '../../sharedComponents/vector2LineComponent';
+import { Vector3LineComponent } from '../../sharedComponents/vector3LineComponent';
+import { Vector4LineComponent } from '../../sharedComponents/vector4LineComponent';
+
+require("./propertyTab.scss");
+
+interface IInputsPropertyTabComponentProps {
+    globalState: GlobalState;
+    inputs: InputBlock[];
+}
+
+export class InputsPropertyTabComponent extends React.Component<IInputsPropertyTabComponentProps> {
+
+    constructor(props: IInputsPropertyTabComponentProps) {
+        super(props);
+    }
+
+    processInputBlockUpdate(ib: InputBlock) {
+        this.props.globalState.onUpdateRequiredObservable.notifyObservers();
+
+        if (ib.isConstant) {
+            this.props.globalState.onRebuildRequiredObservable.notifyObservers();
+        }
+    }
+
+    renderInputBlock(block: InputBlock) {
+        switch (block.type) {
+            case NodeMaterialBlockConnectionPointTypes.Float:
+                    let cantDisplaySlider = (isNaN(block.min) || isNaN(block.max) || block.min === block.max);
+                    return (
+                        <div key={block.uniqueId} >
+                            {
+                                block.isBoolean &&
+                                <CheckBoxLineComponent key={block.uniqueId} label={block.name} target={block} propertyName="value"
+                                onValueChanged={() => {
+                                    this.processInputBlockUpdate(block);
+                                }}/>
+                            }
+                            {
+                                !block.isBoolean && cantDisplaySlider &&
+                                <FloatLineComponent globalState={this.props.globalState} key={block.uniqueId} label={block.name} target={block} propertyName="value"
+                                onChange={() => this.processInputBlockUpdate(block)}/>
+                            }
+                            {
+                                !block.isBoolean && !cantDisplaySlider &&
+                                <SliderLineComponent key={block.uniqueId} label={block.name} target={block} propertyName="value"
+                                step={(block.max - block.min) / 100.0} minimum={block.min} maximum={block.max} globalState={this.props.globalState}
+                                onChange={() => this.processInputBlockUpdate(block)}/>
+                            }
+                        </div>
+                    );
+            case NodeMaterialBlockConnectionPointTypes.Color3:
+                return (
+                    <Color3LineComponent globalState={this.props.globalState} key={block.uniqueId} label={block.name} target={block}
+                        propertyName="value"
+                        onChange={() => this.processInputBlockUpdate(block)}
+                    />
+                );
+            case NodeMaterialBlockConnectionPointTypes.Color4:
+                return (
+                    <Color4LineComponent globalState={this.props.globalState} key={block.uniqueId} label={block.name} target={block} propertyName="value"
+                    onChange={() => this.processInputBlockUpdate(block)}/>
+                );
+            case NodeMaterialBlockConnectionPointTypes.Vector2:
+                return (
+                        <Vector2LineComponent globalState={this.props.globalState} key={block.uniqueId} label={block.name} target={block}
+                        propertyName="value"
+                        onChange={() => this.processInputBlockUpdate(block)}/>
+                );
+            case NodeMaterialBlockConnectionPointTypes.Vector3:
+                return (
+                    <Vector3LineComponent globalState={this.props.globalState} key={block.uniqueId} label={block.name} target={block}
+                    propertyName="value"
+                    onChange={() => this.processInputBlockUpdate(block)}/>
+                );
+            case NodeMaterialBlockConnectionPointTypes.Vector4:
+                return (
+                    <Vector4LineComponent globalState={this.props.globalState} key={block.uniqueId} label={block.name} target={block}
+                    propertyName="value"
+                    onChange={() => this.processInputBlockUpdate(block)}/>
+                );
+            }
+        return null;
+    }
+
+    render() {
+        return (
+                <LineContainerComponent title="INPUTS">
+                {
+                    this.props.inputs.map((ib) => {
+                    if (!ib.isUniform || ib.isSystemValue || !ib.name) {
+                        return null;
+                        }
+                        return this.renderInputBlock(ib);
+                    })
+                }
+                </LineContainerComponent>
+        );
+    }
+}

+ 2 - 10
nodeEditor/src/components/propertyTab/propertyTabComponent.tsx

@@ -35,6 +35,7 @@ import { OptionsLineComponent } from '../../sharedComponents/optionsLineComponen
 import { NodeMaterialModes } from 'babylonjs/Materials/Node/Enums/nodeMaterialModes';
 import { PreviewType } from '../preview/previewType';
 import { TextInputLineComponent } from '../../sharedComponents/textInputLineComponent';
+import { InputsPropertyTabComponent } from './inputsPropertyTabComponent';
 require("./propertyTab.scss");
 
 interface IPropertyTabComponentProps {
@@ -453,16 +454,7 @@ export class PropertyTabComponent extends React.Component<IPropertyTabComponentP
                             }} />
                         </LineContainerComponent>
                     }
-                    <LineContainerComponent title="INPUTS">
-                    {
-                        this.props.globalState.nodeMaterial.getInputBlocks().map((ib) => {
-                            if (!ib.isUniform || ib.isSystemValue || !ib.name) {
-                                return null;
-                            }
-                            return this.renderInputBlock(ib);
-                        })
-                    }
-                    </LineContainerComponent>
+                    <InputsPropertyTabComponent globalState={this.props.globalState} inputs={this.props.globalState.nodeMaterial.getInputBlocks()}></InputsPropertyTabComponent>
                 </div>
             </div>
         );

+ 17 - 2
nodeEditor/src/diagram/properties/framePropertyComponent.tsx

@@ -8,6 +8,8 @@ import { TextInputLineComponent } from '../../sharedComponents/textInputLineComp
 import { ButtonLineComponent } from '../../sharedComponents/buttonLineComponent';
 import { Nullable } from 'babylonjs/types';
 import { Observer } from 'babylonjs/Misc/observable';
+import { InputsPropertyTabComponent } from '../../components/propertyTab/inputsPropertyTabComponent';
+import { InputBlock } from 'babylonjs/Materials/Node/Blocks/Input/inputBlock';
 
 export interface IFramePropertyTabComponentProps {
     globalState: GlobalState
@@ -31,9 +33,21 @@ export class FramePropertyTabComponent extends React.Component<IFramePropertyTab
             this.props.frame.onExpandStateChanged.remove(this.onFrameExpandStateChangedObserver);
             this.onFrameExpandStateChangedObserver = null;
         }
-    }    
+    }
+    
+    render() {
+
+        let configurableInputBlocks: InputBlock[] = [];
+        this.props.frame.nodes.forEach(node => {
+            if(node.block.isInput && node.block.visibleOnFrame) {
+                configurableInputBlocks.push(node.block as InputBlock);
+            }
+        });
+
+        configurableInputBlocks = configurableInputBlocks.sort((a, b) => {
+            return a.name.localeCompare(b.name);
+        });
 
-    render() {      
         return (
             <div id="propertyTab">
             <div id="header">
@@ -63,6 +77,7 @@ export class FramePropertyTabComponent extends React.Component<IFramePropertyTab
                                 this.props.frame!.export();
                             }} />
                 </LineContainerComponent>
+                <InputsPropertyTabComponent globalState={this.props.globalState} inputs={configurableInputBlocks}></InputsPropertyTabComponent>
             </div>
         </div>
         );

+ 4 - 0
nodeEditor/src/diagram/properties/inputNodePropertyComponent.tsx

@@ -330,6 +330,10 @@ export class InputPropertyTabComponent extends React.Component<IPropertyComponen
                             this.props.globalState.onRebuildRequiredObservable.notifyObservers();
                         }} />
                     }
+                {
+                    inputBlock.isUniform && !inputBlock.isSystemValue && inputBlock.animationType === AnimatedInputBlockTypes.None &&
+                    <CheckBoxLineComponent label="Visible on frame" target={(this.props.block as InputBlock)} propertyName={"visibleOnFrame"}></CheckBoxLineComponent>
+                }
                 </LineContainerComponent>
             </div>
         );

+ 8 - 3
src/Materials/Node/nodeMaterialBlock.ts

@@ -156,8 +156,11 @@ export class NodeMaterialBlock {
         return null;
     }
 
-     /** Gets or sets a boolean indicating that this input can be edited in the Inspector (false by default) */
-     public visibleInInspector = false;
+    /** Gets or sets a boolean indicating that this input can be edited in the Inspector (false by default) */
+    public visibleInInspector = false;
+
+    /** Gets or sets a boolean indicating that this input can be edited from a collapsed frame*/
+    public visibleOnFrame = false;
 
     /**
      * Creates a new NodeMaterialBlock
@@ -591,7 +594,7 @@ export class NodeMaterialBlock {
 
     protected _dumpPropertiesCode() {
         let variableName = this._codeVariableName;
-        return `${variableName}.visibleInInspector = ${this.visibleInInspector};\r\n`;
+        return `${variableName}.visibleInInspector = ${this.visibleInInspector};\r\n ${variableName}.visibleOnFrame = ${this.visibleOnFrame};\r\n`;
     }
 
     /** @hidden */
@@ -712,6 +715,7 @@ export class NodeMaterialBlock {
         serializationObject.name = this.name;
         serializationObject.comments = this.comments;
         serializationObject.visibleInInspector = this.visibleInInspector;
+        serializationObject.visibleOnFrame = this.visibleOnFrame;
 
         serializationObject.inputs = [];
         serializationObject.outputs = [];
@@ -732,6 +736,7 @@ export class NodeMaterialBlock {
         this.name = serializationObject.name;
         this.comments = serializationObject.comments;
         this.visibleInInspector = !!serializationObject.visibleInInspector;
+        this.visibleOnFrame = !!serializationObject.visibleOnFrame;
         this._deserializePortDisplayNamesAndExposedOnFrame(serializationObject);
     }