scenePropertyGridComponent.tsx 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. import * as React from "react";
  2. import { Nullable } from "babylonjs/types";
  3. import { Observable } from "babylonjs/Misc/observable";
  4. import { Tools } from "babylonjs/Misc/tools";
  5. import { Vector3 } from "babylonjs/Maths/math.vector";
  6. import { BaseTexture } from "babylonjs/Materials/Textures/baseTexture";
  7. import { CubeTexture } from "babylonjs/Materials/Textures/cubeTexture";
  8. import { ImageProcessingConfiguration } from "babylonjs/Materials/imageProcessingConfiguration";
  9. import { Scene } from "babylonjs/scene";
  10. import { PropertyChangedEvent } from "../../../propertyChangedEvent";
  11. import { LineContainerComponent } from "../../lineContainerComponent";
  12. import { RadioButtonLineComponent } from "../../lines/radioLineComponent";
  13. import { Color3LineComponent } from "../../lines/color3LineComponent";
  14. import { CheckBoxLineComponent } from "../../lines/checkBoxLineComponent";
  15. import { FogPropertyGridComponent } from "./fogPropertyGridComponent";
  16. import { FileButtonLineComponent } from "../../../../sharedUiComponents/lines/fileButtonLineComponent";
  17. import { TextureLinkLineComponent } from "../../lines/textureLinkLineComponent";
  18. import { Vector3LineComponent } from "../../lines/vector3LineComponent";
  19. import { FloatLineComponent } from "../../lines/floatLineComponent";
  20. import { SliderLineComponent } from "../../lines/sliderLineComponent";
  21. import { OptionsLineComponent } from "../../lines/optionsLineComponent";
  22. import { LockObject } from "./lockObject";
  23. import { GlobalState } from '../../../globalState';
  24. import { ButtonLineComponent } from '../../../../sharedUiComponents/lines/buttonLineComponent';
  25. import { AnimationGridComponent } from './animations/animationPropertyGridComponent';
  26. interface IScenePropertyGridComponentProps {
  27. globalState: GlobalState;
  28. scene: Scene;
  29. lockObject: LockObject;
  30. onPropertyChangedObservable?: Observable<PropertyChangedEvent>;
  31. onSelectionChangedObservable?: Observable<any>;
  32. }
  33. export class ScenePropertyGridComponent extends React.Component<IScenePropertyGridComponentProps> {
  34. private _storedEnvironmentTexture: Nullable<BaseTexture>;
  35. private _renderingModeGroupObservable = new Observable<RadioButtonLineComponent>();
  36. constructor(props: IScenePropertyGridComponentProps) {
  37. super(props);
  38. }
  39. setRenderingModes(point: boolean, wireframe: boolean) {
  40. const scene = this.props.scene;
  41. scene.forcePointsCloud = point;
  42. scene.forceWireframe = wireframe;
  43. }
  44. switchIBL() {
  45. const scene = this.props.scene;
  46. if (scene.environmentTexture) {
  47. this._storedEnvironmentTexture = scene.environmentTexture;
  48. scene.environmentTexture = null;
  49. } else {
  50. scene.environmentTexture = this._storedEnvironmentTexture;
  51. this._storedEnvironmentTexture = null;
  52. }
  53. }
  54. updateEnvironmentTexture(file: File) {
  55. let isFileDDS = file.name.toLowerCase().indexOf(".dds") > 0;
  56. let isFileEnv = file.name.toLowerCase().indexOf(".env") > 0;
  57. if (!isFileDDS && !isFileEnv) {
  58. console.error("Unable to update environment texture. Please select a dds or env file.");
  59. return;
  60. }
  61. const scene = this.props.scene;
  62. Tools.ReadFile(file, (data) => {
  63. var blob = new Blob([data], { type: "octet/stream" });
  64. var url = URL.createObjectURL(blob);
  65. if (isFileDDS) {
  66. scene.environmentTexture = CubeTexture.CreateFromPrefilteredData(url, scene, ".dds");
  67. }
  68. else {
  69. scene.environmentTexture = new CubeTexture(url, scene,
  70. undefined, undefined, undefined,
  71. () => {
  72. },
  73. (message) => {
  74. if (message) {
  75. console.error(message);
  76. }
  77. },
  78. undefined, undefined,
  79. ".env");
  80. }
  81. }, undefined, true);
  82. }
  83. updateGravity(newValue: Vector3) {
  84. const scene = this.props.scene;
  85. const physicsEngine = scene.getPhysicsEngine()!;
  86. physicsEngine.setGravity(newValue);
  87. }
  88. updateTimeStep(newValue: number) {
  89. const scene = this.props.scene;
  90. const physicsEngine = scene.getPhysicsEngine()!;
  91. physicsEngine.setTimeStep(newValue);
  92. }
  93. normalizeScene() {
  94. const scene = this.props.scene;
  95. scene.meshes.forEach((mesh) => {
  96. mesh.normalizeToUnitCube(true);
  97. mesh.computeWorldMatrix(true);
  98. });
  99. }
  100. render() {
  101. const scene = this.props.scene;
  102. const physicsEngine = scene.getPhysicsEngine();
  103. let dummy: Nullable<{ gravity: Vector3, timeStep: number }> = null;
  104. if (physicsEngine) {
  105. dummy = {
  106. gravity: physicsEngine.gravity,
  107. timeStep: physicsEngine.getTimeStep()
  108. };
  109. }
  110. const imageProcessing = scene.imageProcessingConfiguration;
  111. var toneMappingOptions = [
  112. { label: "Standard", value: ImageProcessingConfiguration.TONEMAPPING_STANDARD },
  113. { label: "ACES", value: ImageProcessingConfiguration.TONEMAPPING_ACES }
  114. ];
  115. var vignetteModeOptions = [
  116. { label: "Multiply", value: ImageProcessingConfiguration.VIGNETTEMODE_MULTIPLY },
  117. { label: "Opaque", value: ImageProcessingConfiguration.VIGNETTEMODE_OPAQUE }
  118. ];
  119. return (
  120. <div className="pane">
  121. <LineContainerComponent globalState={this.props.globalState} title="RENDERING MODE">
  122. <RadioButtonLineComponent onSelectionChangedObservable={this._renderingModeGroupObservable} label="Point" isSelected={() => scene.forcePointsCloud} onSelect={() => this.setRenderingModes(true, false)} />
  123. <RadioButtonLineComponent onSelectionChangedObservable={this._renderingModeGroupObservable} label="Wireframe" isSelected={() => scene.forceWireframe} onSelect={() => this.setRenderingModes(false, true)} />
  124. <RadioButtonLineComponent onSelectionChangedObservable={this._renderingModeGroupObservable} label="Solid" isSelected={() => !scene.forcePointsCloud && !scene.forceWireframe} onSelect={() => this.setRenderingModes(false, false)} />
  125. </LineContainerComponent>
  126. <LineContainerComponent globalState={this.props.globalState} title="ENVIRONMENT">
  127. <Color3LineComponent label="Clear color" target={scene} propertyName="clearColor" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  128. <CheckBoxLineComponent label="Clear color enabled" target={scene} propertyName="autoClear" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  129. <Color3LineComponent label="Ambient color" target={scene} propertyName="ambientColor" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  130. <CheckBoxLineComponent label="Environment texture (IBL)" isSelected={() => scene.environmentTexture != null} onSelect={() => this.switchIBL()} />
  131. {
  132. scene.environmentTexture &&
  133. <TextureLinkLineComponent label="Env. texture" texture={scene.environmentTexture} onSelectionChangedObservable={this.props.onSelectionChangedObservable} />
  134. }
  135. <FileButtonLineComponent label="Update environment texture" onClick={(file) => this.updateEnvironmentTexture(file)} accept=".dds, .env" />
  136. <SliderLineComponent minimum={0} maximum={2} step={0.01} label="IBL Intensity" target={scene} propertyName="environmentIntensity" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  137. <FogPropertyGridComponent globalState={this.props.globalState} lockObject={this.props.lockObject} scene={scene} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  138. </LineContainerComponent>
  139. <AnimationGridComponent globalState={this.props.globalState} animatable={scene} scene={scene} lockObject={this.props.lockObject} />
  140. <LineContainerComponent globalState={this.props.globalState} title="MATERIAL IMAGE PROCESSING">
  141. <SliderLineComponent minimum={0} maximum={4} step={0.1} label="Contrast" target={imageProcessing} propertyName="contrast" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  142. <SliderLineComponent minimum={0} maximum={4} step={0.1} label="Exposure" target={imageProcessing} propertyName="exposure" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  143. <CheckBoxLineComponent label="Tone mapping" target={imageProcessing} propertyName="toneMappingEnabled" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  144. <OptionsLineComponent label="Tone mapping type" options={toneMappingOptions} target={imageProcessing} propertyName="toneMappingType" onPropertyChangedObservable={this.props.onPropertyChangedObservable} onSelect={(value) => this.setState({ mode: value })} />
  145. <CheckBoxLineComponent label="Vignette" target={imageProcessing} propertyName="vignetteEnabled" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  146. <SliderLineComponent minimum={0} maximum={4} step={0.1} label="Vignette weight" target={imageProcessing} propertyName="vignetteWeight" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  147. <SliderLineComponent minimum={0} maximum={1} step={0.1} label="Vignette stretch" target={imageProcessing} propertyName="vignetteStretch" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  148. <SliderLineComponent minimum={0} maximum={Math.PI} step={0.1} label="Vignette FOV" target={imageProcessing} propertyName="vignetteCameraFov" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  149. <SliderLineComponent minimum={0} maximum={1} step={0.1} label="Vignette center X" target={imageProcessing} propertyName="vignetteCentreX" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  150. <SliderLineComponent minimum={0} maximum={1} step={0.1} label="Vignette center Y" target={imageProcessing} propertyName="vignetteCentreY" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  151. <Color3LineComponent label="Vignette color" target={imageProcessing} propertyName="vignetteColor" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  152. <OptionsLineComponent label="Vignette blend mode" options={vignetteModeOptions} target={imageProcessing} propertyName="vignetteBlendMode" onPropertyChangedObservable={this.props.onPropertyChangedObservable} onSelect={(value) => this.setState({ mode: value })} />
  153. </LineContainerComponent>
  154. {
  155. dummy !== null &&
  156. <LineContainerComponent globalState={this.props.globalState} title="PHYSICS" closed={true}>
  157. <FloatLineComponent lockObject={this.props.lockObject} label="Time step" target={dummy} propertyName="timeStep" onChange={(newValue) => this.updateTimeStep(newValue)} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  158. <Vector3LineComponent label="Gravity" target={dummy} propertyName="gravity" onChange={(newValue) => this.updateGravity(newValue)} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  159. </LineContainerComponent>
  160. }
  161. <LineContainerComponent globalState={this.props.globalState} title="COLLISIONS" closed={true}>
  162. <Vector3LineComponent label="Gravity" target={scene} propertyName="gravity" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  163. </LineContainerComponent>
  164. <LineContainerComponent globalState={this.props.globalState} title="SHADOWS" closed={true}>
  165. <ButtonLineComponent label="Normalize scene" onClick={() => this.normalizeScene()} />
  166. </LineContainerComponent>
  167. </div>
  168. );
  169. }
  170. }