nodeMaterialPropertyGridComponent.tsx 8.6 KB

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