import * as React from "react"; import { GlobalState } from '../../globalState'; import { Nullable } from 'babylonjs/types'; import { ButtonLineComponent } from '../../sharedComponents/buttonLineComponent'; import { LineContainerComponent } from '../../sharedComponents/lineContainerComponent'; import { StringTools } from '../../stringTools'; import { FileButtonLineComponent } from '../../sharedComponents/fileButtonLineComponent'; import { Tools } from 'babylonjs/Misc/tools'; import { SerializationTools } from '../../serializationTools'; import { CheckBoxLineComponent } from '../../sharedComponents/checkBoxLineComponent'; import { DataStorage } from '../../dataStorage'; import { GraphNode } from '../../diagram/graphNode'; import { SliderLineComponent } from '../../sharedComponents/sliderLineComponent'; import { GraphFrame } from '../../diagram/graphFrame'; import { TextLineComponent } from '../../sharedComponents/textLineComponent'; import { Engine } from 'babylonjs/Engines/engine'; import { FramePropertyTabComponent } from '../../diagram/properties/framePropertyComponent'; 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'; import { Observer } from 'babylonjs/Misc/observable'; require("./propertyTab.scss"); interface IPropertyTabComponentProps { globalState: GlobalState; } export class PropertyTabComponent extends React.Component, currentFrame: Nullable }> { private _onBuiltObserver: Nullable>; constructor(props: IPropertyTabComponentProps) { super(props) this.state = { currentNode: null, currentFrame: null }; } componentDidMount() { this.props.globalState.onSelectionChangedObservable.add(selection => { if (selection instanceof GraphNode) { this.setState({ currentNode: selection, currentFrame: null }); } else if (selection instanceof GraphFrame) { this.setState({ currentNode: null, currentFrame: selection }); } else { this.setState({ currentNode: null, currentFrame: null }); } }); this._onBuiltObserver = this.props.globalState.onBuiltObservable.add(() => { this.forceUpdate(); }); } componentWillReceiveProps() { this.props.globalState.onBuiltObservable.remove(this._onBuiltObserver); } 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 (
{ block.isBoolean && { this.processInputBlockUpdate(block); }}/> } { !block.isBoolean && cantDisplaySlider && this.processInputBlockUpdate(block)}/> } { !block.isBoolean && !cantDisplaySlider && this.processInputBlockUpdate(block)}/> }
); case NodeMaterialBlockConnectionPointTypes.Color3: return ( this.processInputBlockUpdate(block)} /> ) case NodeMaterialBlockConnectionPointTypes.Color4: return ( this.processInputBlockUpdate(block)}/> ) case NodeMaterialBlockConnectionPointTypes.Vector2: return ( this.processInputBlockUpdate(block)}/> ) case NodeMaterialBlockConnectionPointTypes.Vector3: return ( this.processInputBlockUpdate(block)}/> ) case NodeMaterialBlockConnectionPointTypes.Vector4: return ( this.processInputBlockUpdate(block)}/> ) } return null; } load(file: File) { Tools.ReadFile(file, (data) => { let decoder = new TextDecoder("utf-8"); SerializationTools.Deserialize(JSON.parse(decoder.decode(data)), this.props.globalState); }, undefined, true); } save() { let json = SerializationTools.Serialize(this.props.globalState.nodeMaterial, this.props.globalState); StringTools.DownloadAsFile(this.props.globalState.hostDocument, json, "nodeMaterial.json"); } customSave() { this.props.globalState.onLogRequiredObservable.notifyObservers({message: "Saving your material to Babylon.js snippet server...", isError: false}); this.props.globalState.customSave!.action(SerializationTools.Serialize(this.props.globalState.nodeMaterial, this.props.globalState)).then(() => { this.props.globalState.onLogRequiredObservable.notifyObservers({message: "Material saved successfully", isError: false}); }).catch(err => { this.props.globalState.onLogRequiredObservable.notifyObservers({message: err, isError: true}); }); } render() { if (this.state.currentNode) { return (
{this.state.currentNode.renderProperties()}
); } if (this.state.currentFrame) { return ( ); } let gridSize = DataStorage.ReadNumber("GridSize", 20); return (
window.open('https://doc.babylonjs.com/how_to/node_material', '_blank')}/> { this.props.globalState.nodeMaterial!.setToDefault(); this.props.globalState.onResetRequiredObservable.notifyObservers(); }} /> { this.props.globalState.onZoomToFitRequiredObservable.notifyObservers(); }} /> { this.props.globalState.onReOrganizedRequiredObservable.notifyObservers(); }} /> DataStorage.ReadBoolean("EmbedTextures", true)} onSelect={(value: boolean) => { DataStorage.StoreBoolean("EmbedTextures", value); }} /> { DataStorage.StoreNumber("GridSize", value); this.props.globalState.onGridSizeChanged.notifyObservers(); this.forceUpdate(); }} /> DataStorage.ReadBoolean("ShowGrid", true)} onSelect={(value: boolean) => { DataStorage.StoreBoolean("ShowGrid", value); this.props.globalState.onGridSizeChanged.notifyObservers(); }} /> this.load(file)} accept=".json" /> { this.save(); }} /> { this.props.globalState.customSave && { this.customSave(); }} /> } { StringTools.DownloadAsFile(this.props.globalState.hostDocument, this.props.globalState.nodeMaterial!.generateCode(), "code.txt"); }} /> { StringTools.DownloadAsFile(this.props.globalState.hostDocument, this.props.globalState.nodeMaterial!.compiledShaders, "shaders.txt"); }} /> { this.props.globalState.nodeMaterial.getInputBlocks().map(ib => { if (!ib.isUniform || ib.isSystemValue || !ib.name) { return null; } return this.renderInputBlock(ib); }) }
); } }