inputNodePropertyComponent.tsx 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. import * as React from "react";
  2. import { GlobalState } from '../../globalState';
  3. import { FloatLineComponent } from '../../sharedComponents/floatLineComponent';
  4. import { FloatPropertyTabComponent } from '../../components/propertyTab/properties/floatPropertyTabComponent';
  5. import { SliderLineComponent } from '../../sharedComponents/sliderLineComponent';
  6. import { Vector2PropertyTabComponent } from '../../components/propertyTab/properties/vector2PropertyTabComponent';
  7. import { Color3PropertyTabComponent } from '../../components/propertyTab/properties/color3PropertyTabComponent';
  8. import { Vector3PropertyTabComponent } from '../../components/propertyTab/properties/vector3PropertyTabComponent';
  9. import { Vector4PropertyTabComponent } from '../../components/propertyTab/properties/vector4PropertyTabComponent';
  10. import { MatrixPropertyTabComponent } from '../../components/propertyTab/properties/matrixPropertyTabComponent';
  11. import { LineContainerComponent } from '../../sharedComponents/lineContainerComponent';
  12. import { OptionsLineComponent } from '../../sharedComponents/optionsLineComponent';
  13. import { NodeMaterialBlockConnectionPointTypes } from 'babylonjs/Materials/Node/Enums/nodeMaterialBlockConnectionPointTypes';
  14. import { NodeMaterialSystemValues } from 'babylonjs/Materials/Node/Enums/nodeMaterialSystemValues';
  15. import { AnimatedInputBlockTypes } from 'babylonjs/Materials/Node/Blocks/Input/animatedInputBlockTypes';
  16. import { IPropertyComponentProps } from './propertyComponentProps';
  17. import { InputBlock } from 'babylonjs/Materials/Node/Blocks/Input/inputBlock';
  18. import { GeneralPropertyTabComponent } from './genericNodePropertyComponent';
  19. import { TextInputLineComponent } from '../../sharedComponents/textInputLineComponent';
  20. import { CheckBoxLineComponent } from '../../sharedComponents/checkBoxLineComponent';
  21. import { Color4PropertyTabComponent } from '../../components/propertyTab/properties/color4PropertyTabComponent';
  22. import { Nullable } from 'babylonjs/types';
  23. import { Observer } from 'babylonjs/Misc/observable';
  24. export class InputPropertyTabComponent extends React.Component<IPropertyComponentProps> {
  25. private onValueChangedObserver: Nullable<Observer<InputBlock>>;
  26. constructor(props: IPropertyComponentProps) {
  27. super(props)
  28. }
  29. componentDidMount() {
  30. let inputBlock = this.props.block as InputBlock;
  31. this.onValueChangedObserver = inputBlock.onValueChangedObservable.add(() => {
  32. this.forceUpdate()
  33. this.props.globalState.onUpdateRequiredObservable.notifyObservers();
  34. });
  35. }
  36. componentWillUnmount() {
  37. let inputBlock = this.props.block as InputBlock;
  38. if (this.onValueChangedObserver) {
  39. inputBlock.onValueChangedObservable.remove(this.onValueChangedObserver);
  40. this.onValueChangedObserver = null;
  41. }
  42. }
  43. renderValue(globalState: GlobalState) {
  44. let inputBlock = this.props.block as InputBlock;
  45. switch (inputBlock.type) {
  46. case NodeMaterialBlockConnectionPointTypes.Float: {
  47. let cantDisplaySlider = (isNaN(inputBlock.min) || isNaN(inputBlock.max) || inputBlock.min === inputBlock.max);
  48. return (
  49. <>
  50. <CheckBoxLineComponent label="Is boolean" target={inputBlock} propertyName="isBoolean" />
  51. {
  52. inputBlock.isBoolean &&
  53. <CheckBoxLineComponent label="Value" isSelected={() => {
  54. return inputBlock.value === 1
  55. }} onSelect={(value) => {
  56. inputBlock.value = value ? 1 : 0;
  57. if (inputBlock.isConstant) {
  58. this.props.globalState.onRebuildRequiredObservable.notifyObservers();
  59. }
  60. this.props.globalState.onUpdateRequiredObservable.notifyObservers();
  61. }}/>
  62. }
  63. {
  64. !inputBlock.isBoolean &&
  65. <FloatLineComponent globalState={this.props.globalState} label="Min" target={inputBlock} propertyName="min" onChange={() => this.forceUpdate()}></FloatLineComponent>
  66. }
  67. {
  68. !inputBlock.isBoolean &&
  69. <FloatLineComponent globalState={this.props.globalState} label="Max" target={inputBlock} propertyName="max" onChange={() => this.forceUpdate()}></FloatLineComponent>
  70. }
  71. {
  72. !inputBlock.isBoolean && cantDisplaySlider &&
  73. <FloatPropertyTabComponent globalState={globalState} inputBlock={inputBlock} />
  74. }
  75. {
  76. !inputBlock.isBoolean && !cantDisplaySlider &&
  77. <SliderLineComponent label="Value" target={inputBlock} propertyName="value" step={Math.abs(inputBlock.max - inputBlock.min) / 100.0} minimum={Math.min(inputBlock.min, inputBlock.max)} maximum={inputBlock.max} onChange={() => {
  78. if (inputBlock.isConstant) {
  79. this.props.globalState.onRebuildRequiredObservable.notifyObservers();
  80. }
  81. }}/>
  82. }
  83. </>
  84. );
  85. }
  86. case NodeMaterialBlockConnectionPointTypes.Vector2:
  87. return (
  88. <Vector2PropertyTabComponent globalState={globalState} inputBlock={inputBlock} />
  89. );
  90. case NodeMaterialBlockConnectionPointTypes.Color3:
  91. return (
  92. <Color3PropertyTabComponent globalState={globalState} inputBlock={inputBlock} />
  93. );
  94. case NodeMaterialBlockConnectionPointTypes.Color4:
  95. return (
  96. <Color4PropertyTabComponent globalState={globalState} inputBlock={inputBlock} />
  97. );
  98. case NodeMaterialBlockConnectionPointTypes.Vector3:
  99. return (
  100. <Vector3PropertyTabComponent globalState={globalState} inputBlock={inputBlock} />
  101. );
  102. case NodeMaterialBlockConnectionPointTypes.Vector4:
  103. return (
  104. <Vector4PropertyTabComponent globalState={globalState} inputBlock={inputBlock} />
  105. );
  106. case NodeMaterialBlockConnectionPointTypes.Matrix:
  107. return (
  108. <MatrixPropertyTabComponent globalState={globalState} inputBlock={inputBlock} />
  109. );
  110. }
  111. return null;
  112. }
  113. setDefaultValue() {
  114. let inputBlock = this.props.block as InputBlock;
  115. inputBlock.setDefaultValue();
  116. }
  117. render() {
  118. let inputBlock = this.props.block as InputBlock;
  119. var systemValuesOptions: {label: string, value: NodeMaterialSystemValues}[] = [];
  120. var attributeOptions: {label: string, value: string}[] = [];
  121. var animationOptions: {label: string, value: AnimatedInputBlockTypes}[] = [];
  122. switch(inputBlock.type) {
  123. case NodeMaterialBlockConnectionPointTypes.Float:
  124. animationOptions = [
  125. { label: "None", value: AnimatedInputBlockTypes.None },
  126. { label: "Time", value: AnimatedInputBlockTypes.Time },
  127. ];
  128. systemValuesOptions = [
  129. { label: "Delta time", value: NodeMaterialSystemValues.DeltaTime }
  130. ]
  131. break;
  132. case NodeMaterialBlockConnectionPointTypes.Matrix:
  133. systemValuesOptions = [
  134. { label: "World", value: NodeMaterialSystemValues.World },
  135. { label: "World x View", value: NodeMaterialSystemValues.WorldView },
  136. { label: "World x ViewxProjection", value: NodeMaterialSystemValues.WorldViewProjection },
  137. { label: "View", value: NodeMaterialSystemValues.View },
  138. { label: "View x Projection", value: NodeMaterialSystemValues.ViewProjection },
  139. { label: "Projection", value: NodeMaterialSystemValues.Projection }
  140. ];
  141. break;
  142. case NodeMaterialBlockConnectionPointTypes.Color3:
  143. systemValuesOptions = [
  144. { label: "Fog color", value: NodeMaterialSystemValues.FogColor }
  145. ];
  146. break;
  147. case NodeMaterialBlockConnectionPointTypes.Color4:
  148. attributeOptions = [
  149. { label: "color", value: "color" }
  150. ];
  151. break;
  152. case NodeMaterialBlockConnectionPointTypes.Vector2:
  153. attributeOptions = [
  154. { label: "uv", value: "uv" },
  155. { label: "uv2", value: "uv2" },
  156. ];
  157. break;
  158. case NodeMaterialBlockConnectionPointTypes.Vector3:
  159. systemValuesOptions = [
  160. { label: "Camera position", value: NodeMaterialSystemValues.CameraPosition }
  161. ];
  162. attributeOptions = [
  163. { label: "position", value: "position" },
  164. { label: "normal", value: "normal" },
  165. { label: "tangent", value: "tangent" },
  166. ];
  167. break;
  168. case NodeMaterialBlockConnectionPointTypes.Vector4:
  169. attributeOptions = [
  170. { label: "matricesIndices", value: "matricesIndices" },
  171. { label: "matricesWeights", value: "matricesWeights" }
  172. ];
  173. break;
  174. }
  175. var modeOptions = [
  176. { label: "User-defined", value: 0 }
  177. ];
  178. if (attributeOptions.length > 0) {
  179. modeOptions.push({ label: "Mesh attribute", value: 1 });
  180. }
  181. if (systemValuesOptions.length > 0) {
  182. modeOptions.push({ label: "System value", value: 2 });
  183. }
  184. var typeOptions = [
  185. { label: "None", value: 0 },
  186. { label: "Visible in the inspector", value: 1 },
  187. { label: "Constant", value: 2 }
  188. ];
  189. return (
  190. <div>
  191. <GeneralPropertyTabComponent globalState={this.props.globalState} block={this.props.block}/>
  192. <LineContainerComponent title="PROPERTIES">
  193. {
  194. inputBlock.isUniform && !inputBlock.isSystemValue && inputBlock.animationType === AnimatedInputBlockTypes.None &&
  195. <OptionsLineComponent label="Type" options={typeOptions} target={inputBlock}
  196. noDirectUpdate={true}
  197. getSelection={(block) => {
  198. if (block.visibleInInspector) {
  199. return 1;
  200. }
  201. if (block.isConstant) {
  202. return 2;
  203. }
  204. return 0;
  205. }}
  206. onSelect={(value: any) => {
  207. switch (value) {
  208. case 0:
  209. inputBlock.visibleInInspector = false;
  210. inputBlock.isConstant = false;
  211. break;
  212. case 1:
  213. inputBlock.visibleInInspector = true;
  214. inputBlock.isConstant = false;
  215. break;
  216. case 2:
  217. inputBlock.visibleInInspector = false;
  218. inputBlock.isConstant = true;
  219. break;
  220. }
  221. this.forceUpdate();
  222. this.props.globalState.onUpdateRequiredObservable.notifyObservers();
  223. this.props.globalState.onRebuildRequiredObservable.notifyObservers();
  224. }} />
  225. }
  226. {
  227. inputBlock.visibleInInspector &&
  228. <TextInputLineComponent globalState={this.props.globalState} label="Group" propertyName="groupInInspector" target={this.props.block}
  229. onChange={() => {
  230. this.forceUpdate();
  231. this.props.globalState.onUpdateRequiredObservable.notifyObservers();
  232. this.props.globalState.onRebuildRequiredObservable.notifyObservers();
  233. }} />
  234. }
  235. <OptionsLineComponent label="Mode" options={modeOptions} target={inputBlock}
  236. noDirectUpdate={true}
  237. getSelection={(block) => {
  238. if (block.isAttribute) {
  239. return 1;
  240. }
  241. if (block.isSystemValue) {
  242. return 2;
  243. }
  244. return 0;
  245. }}
  246. onSelect={(value: any) => {
  247. switch (value) {
  248. case 0:
  249. inputBlock.isUniform = true;
  250. inputBlock.setAsSystemValue(null);
  251. this.setDefaultValue();
  252. break;
  253. case 1:
  254. inputBlock.setAsAttribute(attributeOptions[0].value);
  255. break;
  256. case 2:
  257. inputBlock.setAsSystemValue(systemValuesOptions[0].value);
  258. break;
  259. }
  260. this.forceUpdate();
  261. this.props.globalState.onUpdateRequiredObservable.notifyObservers();
  262. this.props.globalState.onRebuildRequiredObservable.notifyObservers();
  263. }} />
  264. {
  265. inputBlock.isAttribute &&
  266. <OptionsLineComponent label="Attribute" valuesAreStrings={true} options={attributeOptions} target={inputBlock} propertyName="name" onSelect={(value: any) => {
  267. inputBlock.setAsAttribute(value);
  268. this.forceUpdate();
  269. this.props.globalState.onUpdateRequiredObservable.notifyObservers();
  270. this.props.globalState.onRebuildRequiredObservable.notifyObservers();
  271. }} />
  272. }
  273. {
  274. inputBlock.isUniform && animationOptions.length > 0 &&
  275. <OptionsLineComponent label="Animation type" options={animationOptions} target={inputBlock} propertyName="animationType" onSelect={(value: any) => {
  276. this.forceUpdate();
  277. this.props.globalState.onUpdateRequiredObservable.notifyObservers();
  278. this.props.globalState.onRebuildRequiredObservable.notifyObservers();
  279. }} />
  280. }
  281. {
  282. inputBlock.isUniform && !inputBlock.isSystemValue && inputBlock.animationType === AnimatedInputBlockTypes.None &&
  283. this.renderValue(this.props.globalState)
  284. }
  285. {
  286. inputBlock.isUniform && inputBlock.isSystemValue &&
  287. <OptionsLineComponent label="System value" options={systemValuesOptions} target={inputBlock} propertyName="systemValue" onSelect={(value: any) => {
  288. inputBlock.setAsSystemValue(value);
  289. this.forceUpdate();
  290. this.props.globalState.onUpdateRequiredObservable.notifyObservers();
  291. this.props.globalState.onRebuildRequiredObservable.notifyObservers();
  292. }} />
  293. }
  294. </LineContainerComponent>
  295. </div>
  296. );
  297. }
  298. }