nodeMaterialPropertyGridComponent.tsx 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. import * as React from "react";
  2. import { Observable } from "babylonjs/Misc/observable";
  3. import { NodeMaterial } from "babylonjs/Materials/Node/nodeMaterial";
  4. import { PropertyChangedEvent } from "../../../../propertyChangedEvent";
  5. import { LineContainerComponent } from "../../../lineContainerComponent";
  6. import { CommonMaterialPropertyGridComponent } from "./commonMaterialPropertyGridComponent";
  7. import { LockObject } from "../../../../../sharedUiComponents/tabs/propertyGrids/lockObject";
  8. import { GlobalState } from '../../../../globalState';
  9. import { ButtonLineComponent } from '../../../../../sharedUiComponents/lines/buttonLineComponent';
  10. import { CheckBoxLineComponent } from '../../../../../sharedUiComponents/lines/checkBoxLineComponent';
  11. import { FloatLineComponent } from '../../../../../sharedUiComponents/lines/floatLineComponent';
  12. import { Color3LineComponent } from '../../../../../sharedUiComponents/lines/color3LineComponent';
  13. import { Vector3LineComponent } from '../../../../../sharedUiComponents/lines/vector3LineComponent';
  14. import { Vector4LineComponent } from '../../../../../sharedUiComponents/lines/vector4LineComponent';
  15. import { Vector2LineComponent } from '../../../../../sharedUiComponents/lines/vector2LineComponent';
  16. import { TextureLinkLineComponent } from '../../../lines/textureLinkLineComponent';
  17. import { SliderLineComponent } from '../../../../../sharedUiComponents/lines/sliderLineComponent';
  18. import { NodeMaterialBlockConnectionPointTypes } from 'babylonjs/Materials/Node/Enums/nodeMaterialBlockConnectionPointTypes';
  19. import { InputBlock } from 'babylonjs/Materials/Node/Blocks/Input/inputBlock';
  20. import { GradientPropertyTabComponent } from '../../gradientNodePropertyComponent';
  21. import { Color4LineComponent } from "../../../../../sharedUiComponents/lines/color4LineComponent";
  22. interface INodeMaterialPropertyGridComponentProps {
  23. globalState: GlobalState;
  24. material: NodeMaterial;
  25. lockObject: LockObject;
  26. onSelectionChangedObservable?: Observable<any>;
  27. onPropertyChangedObservable?: Observable<PropertyChangedEvent>;
  28. }
  29. export class NodeMaterialPropertyGridComponent extends React.Component<INodeMaterialPropertyGridComponentProps> {
  30. private _onDebugSelectionChangeObservable = new Observable<TextureLinkLineComponent>();
  31. constructor(props: INodeMaterialPropertyGridComponentProps) {
  32. super(props);
  33. }
  34. edit() {
  35. this.props.material.edit();
  36. }
  37. renderTextures() {
  38. const material = this.props.material;
  39. const onDebugSelectionChangeObservable = this._onDebugSelectionChangeObservable;
  40. let textureBlocks = material.getTextureBlocks();
  41. if (!textureBlocks || textureBlocks.length === 0) {
  42. return null;
  43. }
  44. return (
  45. <LineContainerComponent globalState={this.props.globalState} title="TEXTURES">
  46. {
  47. textureBlocks.map((textureBlock, i) => {
  48. return (
  49. <TextureLinkLineComponent label={textureBlock.name}
  50. key={"nodematText" + i}
  51. texture={textureBlock.texture}
  52. material={material}
  53. onTextureCreated={texture => textureBlock.texture = texture}
  54. onSelectionChangedObservable={this.props.onSelectionChangedObservable}
  55. onDebugSelectionChangeObservable={onDebugSelectionChangeObservable} />
  56. )
  57. })
  58. }
  59. </LineContainerComponent>
  60. );
  61. }
  62. renderInputBlock(block: InputBlock) {
  63. switch (block.type) {
  64. case NodeMaterialBlockConnectionPointTypes.Float:
  65. let cantDisplaySlider = (isNaN(block.min) || isNaN(block.max) || block.min === block.max);
  66. return (
  67. <div key={block.name}>
  68. {
  69. block.isBoolean &&
  70. <CheckBoxLineComponent key={block.name} label={block.name} target={block} propertyName="value" onPropertyChangedObservable={this.props.onPropertyChangedObservable}/>
  71. }
  72. {
  73. !block.isBoolean && cantDisplaySlider &&
  74. <FloatLineComponent key={block.name} lockObject={this.props.lockObject} label={block.name} target={block} propertyName="value"
  75. onPropertyChangedObservable={this.props.onPropertyChangedObservable}
  76. />
  77. }
  78. {
  79. !block.isBoolean && !cantDisplaySlider &&
  80. <SliderLineComponent key={block.name} label={block.name} target={block} propertyName="value" step={(block.max - block.min) / 100.0} minimum={block.min} maximum={block.max} onPropertyChangedObservable={this.props.onPropertyChangedObservable}/>
  81. }
  82. </div>
  83. );
  84. case NodeMaterialBlockConnectionPointTypes.Color3:
  85. return (
  86. <Color3LineComponent key={block.name} label={block.name} target={block} propertyName="value"
  87. onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  88. )
  89. case NodeMaterialBlockConnectionPointTypes.Color4:
  90. return (
  91. <Color4LineComponent key={block.name} label={block.name} target={block} propertyName="value"
  92. onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  93. )
  94. case NodeMaterialBlockConnectionPointTypes.Vector2:
  95. return (
  96. <Vector2LineComponent key={block.name} label={block.name} target={block} propertyName="value"
  97. onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  98. )
  99. case NodeMaterialBlockConnectionPointTypes.Vector3:
  100. return (
  101. <Vector3LineComponent key={block.name} label={block.name} target={block} propertyName="value"
  102. onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  103. )
  104. case NodeMaterialBlockConnectionPointTypes.Vector4:
  105. return (
  106. <Vector4LineComponent key={block.name} label={block.name} target={block} propertyName="value"
  107. onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  108. )
  109. }
  110. return null;
  111. }
  112. renderInputValues() {
  113. let configurableInputBlocks = this.props.material.getInputBlocks().filter(block => {
  114. return block.visibleInInspector && block.isUniform && !block.isSystemValue
  115. }).sort( (a, b) => {
  116. return a.name.localeCompare(b.name);
  117. });
  118. let namedGroups: string[] = [];
  119. configurableInputBlocks.forEach(block => {
  120. if (!block.groupInInspector) {
  121. return;
  122. }
  123. if (namedGroups.indexOf(block.groupInInspector) === -1) {
  124. namedGroups.push(block.groupInInspector);
  125. }
  126. });
  127. namedGroups.sort();
  128. let gradiantNodeMaterialBlocks = this.props.material.attachedBlocks.filter(block => {
  129. return block.visibleInInspector && block.getClassName() === 'GradientBlock'
  130. }).sort( (a, b) => {
  131. return a.name.localeCompare(b.name);
  132. });
  133. let inputBlockContainer = configurableInputBlocks.length > 0 ?
  134. <LineContainerComponent globalState={this.props.globalState} title="INPUTS"> {
  135. configurableInputBlocks.filter(block => !block.groupInInspector).map(block => {
  136. return this.renderInputBlock(block);
  137. })
  138. }
  139. </LineContainerComponent> : null;
  140. return (
  141. <>
  142. {inputBlockContainer}
  143. {
  144. namedGroups.map((name, i) => {
  145. return (
  146. <LineContainerComponent key={"inputValue" + i} globalState={this.props.globalState} title={name.toUpperCase()}>
  147. {
  148. configurableInputBlocks.filter(block => block.groupInInspector === name).map(block => {
  149. return this.renderInputBlock(block);
  150. })
  151. }
  152. </LineContainerComponent>
  153. )
  154. })
  155. }
  156. {
  157. gradiantNodeMaterialBlocks.map((block,i) => {
  158. return (
  159. <LineContainerComponent key={block.name +i} globalState={this.props.globalState} title={block.name.toUpperCase()}>
  160. {
  161. <GradientPropertyTabComponent globalState={this.props.globalState} block={block}/>
  162. }
  163. </LineContainerComponent>
  164. )
  165. })
  166. }
  167. </>
  168. );
  169. }
  170. render() {
  171. const material = this.props.material;
  172. return (
  173. <div className="pane">
  174. <CommonMaterialPropertyGridComponent globalState={this.props.globalState} lockObject={this.props.lockObject} material={material} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  175. <LineContainerComponent globalState={this.props.globalState} title="CONFIGURATION">
  176. <CheckBoxLineComponent label="Ignore alpha" target={material} propertyName="ignoreAlpha" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  177. <ButtonLineComponent label="Node Material Editor" onClick={() => this.edit()} />
  178. </LineContainerComponent>
  179. {
  180. this.renderInputValues()
  181. }
  182. {
  183. this.renderTextures()
  184. }
  185. </div>
  186. );
  187. }
  188. }