particleSystemPropertyGridComponent.tsx 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537
  1. import * as React from "react";
  2. import { Observable } from "babylonjs/Misc/observable";
  3. import { PropertyChangedEvent } from "../../../../propertyChangedEvent";
  4. import { LineContainerComponent } from "../../../lineContainerComponent";
  5. import { TextLineComponent } from "../../../lines/textLineComponent";
  6. import { LockObject } from "../lockObject";
  7. import { GlobalState } from '../../../../globalState';
  8. import { CustomPropertyGridComponent } from '../customPropertyGridComponent';
  9. import { IParticleSystem } from 'babylonjs/Particles/IParticleSystem';
  10. import { FloatLineComponent } from '../../../lines/floatLineComponent';
  11. import { ButtonLineComponent } from '../../../lines/buttonLineComponent';
  12. import { TextureLinkLineComponent } from '../../../lines/textureLinkLineComponent';
  13. import { OptionsLineComponent } from '../../../lines/optionsLineComponent';
  14. import { ParticleSystem } from 'babylonjs/Particles/particleSystem';
  15. import { Color4LineComponent } from '../../../lines/color4LineComponent';
  16. import { Vector3LineComponent } from '../../../lines/vector3LineComponent';
  17. import { CheckBoxLineComponent } from '../../../lines/checkBoxLineComponent';
  18. import { SliderLineComponent } from '../../../lines/sliderLineComponent';
  19. import { BoxParticleEmitter } from 'babylonjs/Particles/EmitterTypes/boxParticleEmitter';
  20. import { ConeParticleEmitter } from 'babylonjs/Particles/EmitterTypes/coneParticleEmitter';
  21. import { CylinderParticleEmitter } from 'babylonjs/Particles/EmitterTypes/cylinderParticleEmitter';
  22. import { HemisphericParticleEmitter } from 'babylonjs/Particles/EmitterTypes/hemisphericParticleEmitter';
  23. import { PointParticleEmitter } from 'babylonjs/Particles/EmitterTypes/pointParticleEmitter';
  24. import { SphereParticleEmitter } from 'babylonjs/Particles/EmitterTypes/sphereParticleEmitter';
  25. import { BoxEmitterGridComponent } from './boxEmitterGridComponent';
  26. import { ConeEmitterGridComponent } from './coneEmitterGridComponent';
  27. import { CylinderEmitterGridComponent } from './cylinderEmitterGridComponent';
  28. import { HemisphericEmitterGridComponent } from './hemisphericEmitterGridComponent';
  29. import { PointEmitterGridComponent } from './pointEmitterGridComponent';
  30. import { SphereEmitterGridComponent } from './sphereEmitterGridComponent';
  31. import { Vector3 } from 'babylonjs/Maths/math.vector';
  32. import { AbstractMesh } from 'babylonjs/Meshes/abstractMesh';
  33. import { MeshParticleEmitter } from 'babylonjs/Particles/EmitterTypes/meshParticleEmitter';
  34. import { MeshEmitterGridComponent } from './meshEmitterGridComponent';
  35. import { ValueGradientGridComponent, GradientGridMode } from './valueGradientGridComponent';
  36. import { Color3, Color4 } from 'babylonjs/Maths/math.color';
  37. import { GPUParticleSystem } from 'babylonjs/Particles/gpuParticleSystem';
  38. interface IParticleSystemPropertyGridComponentProps {
  39. globalState: GlobalState;
  40. system: IParticleSystem,
  41. lockObject: LockObject,
  42. onSelectionChangedObservable?: Observable<any>,
  43. onPropertyChangedObservable?: Observable<PropertyChangedEvent>
  44. }
  45. export class ParticleSystemPropertyGridComponent extends React.Component<IParticleSystemPropertyGridComponentProps> {
  46. constructor(props: IParticleSystemPropertyGridComponentProps) {
  47. super(props);
  48. }
  49. renderEmitter() {
  50. const system = this.props.system;
  51. const replaySource = "particlesystem.particleEmitterType";
  52. switch(system.particleEmitterType?.getClassName()) {
  53. case "BoxParticleEmitter":
  54. return (
  55. <BoxEmitterGridComponent replaySourceReplacement={replaySource}
  56. globalState={this.props.globalState} emitter={system.particleEmitterType as BoxParticleEmitter} onPropertyChangedObservable={this.props.onPropertyChangedObservable}/>
  57. );
  58. case "ConeParticleEmitter":
  59. return (
  60. <ConeEmitterGridComponent replaySourceReplacement={replaySource}
  61. globalState={this.props.globalState} emitter={system.particleEmitterType as ConeParticleEmitter} onPropertyChangedObservable={this.props.onPropertyChangedObservable}/>
  62. );
  63. case "CylinderParticleEmitter":
  64. return (
  65. <CylinderEmitterGridComponent replaySourceReplacement={replaySource}
  66. lockObject={this.props.lockObject} globalState={this.props.globalState} emitter={system.particleEmitterType as CylinderParticleEmitter} onPropertyChangedObservable={this.props.onPropertyChangedObservable}/>
  67. );
  68. case "HemisphericParticleEmitter":
  69. return (
  70. <HemisphericEmitterGridComponent replaySourceReplacement={replaySource}
  71. lockObject={this.props.lockObject} globalState={this.props.globalState} emitter={system.particleEmitterType as HemisphericParticleEmitter} onPropertyChangedObservable={this.props.onPropertyChangedObservable}/>
  72. );
  73. case "MeshParticleEmitter":
  74. return (
  75. <MeshEmitterGridComponent replaySourceReplacement={replaySource}
  76. lockObject={this.props.lockObject} scene={system.getScene()} globalState={this.props.globalState} emitter={system.particleEmitterType as MeshParticleEmitter} onPropertyChangedObservable={this.props.onPropertyChangedObservable}/>
  77. );
  78. case "PointParticleEmitter":
  79. return (
  80. <PointEmitterGridComponent replaySourceReplacement={replaySource}
  81. lockObject={this.props.lockObject} globalState={this.props.globalState} emitter={system.particleEmitterType as PointParticleEmitter} onPropertyChangedObservable={this.props.onPropertyChangedObservable}/>
  82. );
  83. case "SphereParticleEmitter":
  84. return (
  85. <SphereEmitterGridComponent replaySourceReplacement={replaySource}
  86. lockObject={this.props.lockObject} globalState={this.props.globalState} emitter={system.particleEmitterType as SphereParticleEmitter} onPropertyChangedObservable={this.props.onPropertyChangedObservable}/>
  87. );
  88. }
  89. return null;
  90. }
  91. raiseOnPropertyChanged(property: string, newValue: any, previousValue: any) {
  92. if (!this.props.onPropertyChangedObservable) {
  93. return;
  94. }
  95. const system = this.props.system;
  96. this.props.onPropertyChangedObservable.notifyObservers({
  97. object: system,
  98. property: property,
  99. value: newValue,
  100. initialValue: previousValue
  101. });
  102. }
  103. renderControls() {
  104. const system = this.props.system;
  105. if (system instanceof GPUParticleSystem) {
  106. let isStarted = system.isStarted() && !system.isStopped();
  107. return (
  108. <ButtonLineComponent label={isStarted ? "Pause" : "Start"} onClick={() => {
  109. if (isStarted) {
  110. system.stop();
  111. } else {
  112. system.start();
  113. }
  114. this.forceUpdate();
  115. }} />
  116. );
  117. }
  118. let isStarted = system.isStarted();
  119. return (
  120. <>
  121. {
  122. !system.isStopping() &&
  123. <ButtonLineComponent label={isStarted ? "Stop" : "Start"} onClick={() => {
  124. if (isStarted) {
  125. system.stop();
  126. } else {
  127. system.start();
  128. }
  129. this.forceUpdate();
  130. }} />
  131. }
  132. {
  133. system.isStopping() &&
  134. <TextLineComponent label="System is stoppping..." ignoreValue={true}/>
  135. }
  136. </>
  137. )
  138. }
  139. render() {
  140. const system = this.props.system;
  141. var blendModeOptions = [
  142. { label: "Add", value: ParticleSystem.BLENDMODE_ADD },
  143. { label: "Multiply", value: ParticleSystem.BLENDMODE_MULTIPLY },
  144. { label: "Multiply Add", value: ParticleSystem.BLENDMODE_MULTIPLYADD },
  145. { label: "OneOne", value: ParticleSystem.BLENDMODE_ONEONE },
  146. { label: "Standard", value: ParticleSystem.BLENDMODE_STANDARD },
  147. ];
  148. var particleEmitterTypeOptions = [
  149. { label: "Box", value: 0 },
  150. { label: "Cone", value: 1 },
  151. { label: "Cylinder", value: 2 },
  152. { label: "Hemispheric", value: 3 },
  153. { label: "Mesh", value: 4 },
  154. { label: "Point", value: 5 },
  155. { label: "Sphere", value: 6 },
  156. ];
  157. var meshEmitters = this.props.system.getScene().meshes.filter(m => !!m.name);
  158. var emitterOptions = [
  159. { label: "None", value: -1 },
  160. { label: "Vector3", value: 0 }
  161. ];
  162. meshEmitters.sort((a, b) => a.name.localeCompare(b.name));
  163. emitterOptions.push(...meshEmitters.map((v, i) => {
  164. return {label: v.name, value: i + 1}
  165. }));
  166. let isStarted = system.isStarted();
  167. if (system instanceof GPUParticleSystem) {
  168. isStarted = !system.isStopped();
  169. }
  170. return (
  171. <div className="pane">
  172. <CustomPropertyGridComponent globalState={this.props.globalState} target={system}
  173. lockObject={this.props.lockObject}
  174. onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  175. <LineContainerComponent globalState={this.props.globalState} title="GENERAL">
  176. <TextLineComponent label="ID" value={system.id} />
  177. <TextLineComponent label="Class" value={system.getClassName()} />
  178. <TextLineComponent label="Capacity" value={system.getCapacity().toString()} />
  179. <TextLineComponent label="Capacity" value={system.getActiveCount().toString()} />
  180. <TextureLinkLineComponent label="Texture" texture={system.particleTexture} onSelectionChangedObservable={this.props.onSelectionChangedObservable}/>
  181. <OptionsLineComponent label="Blend mode" options={blendModeOptions} target={system} propertyName="blendMode" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  182. <Vector3LineComponent label="Gravity" target={system} propertyName="gravity"
  183. onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  184. <CheckBoxLineComponent label="Is billboard" target={system} propertyName="isBillboardBased" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  185. <CheckBoxLineComponent label="Is local" target={system} propertyName="isLocal" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  186. <SliderLineComponent label="Update speed" target={system} propertyName="updateSpeed" minimum={0} maximum={1} step={0.01} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  187. </LineContainerComponent>
  188. <LineContainerComponent globalState={this.props.globalState} title="OPTIONS">
  189. {this.renderControls()}
  190. <ButtonLineComponent label={"Dispose"} onClick={() => {
  191. this.props.globalState.onSelectionChangedObservable.notifyObservers(null);
  192. system.dispose();
  193. }} />
  194. </LineContainerComponent>
  195. <LineContainerComponent globalState={this.props.globalState} title="EMITTER">
  196. <OptionsLineComponent
  197. label="Emitter"
  198. options={emitterOptions}
  199. target={system}
  200. propertyName="emitter"
  201. noDirectUpdate={true}
  202. onSelect={(value: number) => {
  203. switch(value) {
  204. case -1:
  205. this.raiseOnPropertyChanged("emitter", null, system.emitter);
  206. system.emitter = null;
  207. break;
  208. case 0:
  209. this.raiseOnPropertyChanged("emitter", Vector3.Zero(), system.emitter);
  210. system.emitter = Vector3.Zero();
  211. break;
  212. default:
  213. this.raiseOnPropertyChanged("emitter", meshEmitters[value - 1], system.emitter);
  214. system.emitter = meshEmitters[value - 1];
  215. }
  216. this.forceUpdate();
  217. }}
  218. extractValue={() => {
  219. if (!system.emitter) {
  220. return -1;
  221. }
  222. if ((system.emitter as Vector3).x !== undefined) {
  223. return 0;
  224. }
  225. let meshIndex = meshEmitters.indexOf(system.emitter as AbstractMesh)
  226. if (meshIndex > -1) {
  227. return meshIndex + 1;
  228. }
  229. return -1;
  230. }}
  231. />
  232. {
  233. system.emitter && ((system.emitter as Vector3).x === undefined) &&
  234. <TextLineComponent label="Link to emitter" value={(system.emitter as AbstractMesh).name} onLink={() => this.props.globalState.onSelectionChangedObservable.notifyObservers(system.emitter)}/>
  235. }
  236. {
  237. system.emitter && ((system.emitter as Vector3).x !== undefined) &&
  238. <Vector3LineComponent label="Position" target={system} propertyName="emitter" onPropertyChangedObservable={this.props.onPropertyChangedObservable}/>
  239. }
  240. <OptionsLineComponent
  241. label="Type"
  242. options={particleEmitterTypeOptions}
  243. target={system}
  244. propertyName="particleEmitterType"
  245. noDirectUpdate={true}
  246. onSelect={(value: number) => {
  247. const currentType = system.particleEmitterType;
  248. switch(value) {
  249. case 0:
  250. system.particleEmitterType = new BoxParticleEmitter();
  251. break;
  252. case 1:
  253. system.particleEmitterType = new ConeParticleEmitter();
  254. break;
  255. case 2:
  256. system.particleEmitterType = new CylinderParticleEmitter();
  257. break;
  258. case 3:
  259. system.particleEmitterType = new HemisphericParticleEmitter();
  260. break;
  261. case 4:
  262. system.particleEmitterType = new MeshParticleEmitter();
  263. break;
  264. case 5:
  265. system.particleEmitterType = new PointParticleEmitter();
  266. break;
  267. case 6:
  268. system.particleEmitterType = new SphereParticleEmitter();
  269. break;
  270. }
  271. this.raiseOnPropertyChanged("particleEmitterType", system.particleEmitterType, currentType)
  272. this.forceUpdate();
  273. }}
  274. extractValue={() => {
  275. switch(system.particleEmitterType?.getClassName()) {
  276. case "BoxParticleEmitter":
  277. return 0;
  278. case "ConeParticleEmitter":
  279. return 1;
  280. case "CylinderParticleEmitter":
  281. return 2;
  282. case "HemisphericParticleEmitter":
  283. return 3;
  284. case "MeshParticleEmitter":
  285. return 4;
  286. case "PointParticleEmitter":
  287. return 5;
  288. case "SphereParticleEmitter":
  289. return 6;
  290. }
  291. return 0;
  292. }}/>
  293. {
  294. this.renderEmitter()
  295. }
  296. </LineContainerComponent>
  297. <LineContainerComponent globalState={this.props.globalState} title="EMISSION">
  298. <FloatLineComponent lockObject={this.props.lockObject} label="Rate" target={system} propertyName="emitRate" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  299. <ValueGradientGridComponent globalState={this.props.globalState} gradients={system.getEmitRateGradients()!}
  300. label="Velocity gradients"
  301. docLink="https://doc.babylonjs.com/babylon101/particles#emit-rate-over-time"
  302. onCreateRequired={() => {
  303. system.addEmitRateGradient(0, 50, 50);
  304. this.props.globalState.onCodeChangedObservable.notifyObservers({
  305. object: system,
  306. code: `TARGET.addEmitRateGradient(0, 50, 50);`
  307. });
  308. }}
  309. mode={GradientGridMode.Factor}
  310. host={system}
  311. codeRecorderPropertyName="getEmitRateGradients()"
  312. lockObject={this.props.lockObject}/>
  313. <FloatLineComponent lockObject={this.props.lockObject} label="Min emit power" target={system} propertyName="minEmitPower" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  314. <FloatLineComponent lockObject={this.props.lockObject} label="Max emit power" target={system} propertyName="maxEmitPower" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  315. <ValueGradientGridComponent globalState={this.props.globalState} gradients={system.getVelocityGradients()!}
  316. label="Velocity gradients"
  317. docLink="https://doc.babylonjs.com/babylon101/particles#velocity-over-time"
  318. onCreateRequired={() => {
  319. system.addVelocityGradient(0, 0.1, 0.1);
  320. this.props.globalState.onCodeChangedObservable.notifyObservers({
  321. object: system,
  322. code: `TARGET.addVelocityGradient(0, 0.1, 0.1);`
  323. });
  324. }}
  325. mode={GradientGridMode.Factor}
  326. host={system}
  327. codeRecorderPropertyName="getVelocityGradients()"
  328. lockObject={this.props.lockObject}/>
  329. <ValueGradientGridComponent globalState={this.props.globalState} gradients={system.getLimitVelocityGradients()!}
  330. label="Limit velocity gradients"
  331. docLink="https://doc.babylonjs.com/babylon101/particles#limit-velocity-over-time"
  332. onCreateRequired={() => {
  333. system.addLimitVelocityGradient(0, 0.1, 0.1);
  334. this.props.globalState.onCodeChangedObservable.notifyObservers({
  335. object: system,
  336. code: `TARGET.addLimitVelocityGradient(0, 0.1, 0.1);`
  337. });
  338. }}
  339. mode={GradientGridMode.Factor}
  340. host={system}
  341. codeRecorderPropertyName="getLimitVelocityGradients()"
  342. lockObject={this.props.lockObject}/>
  343. <ValueGradientGridComponent globalState={this.props.globalState} gradients={system.getDragGradients()!}
  344. label="Drag gradients"
  345. docLink="https://doc.babylonjs.com/babylon101/particles#drag-factor"
  346. onCreateRequired={() => {
  347. system.addDragGradient(0, 0.1, 0.1);
  348. this.props.globalState.onCodeChangedObservable.notifyObservers({
  349. object: system,
  350. code: `TARGET.addDragGradient(0, 0.1, 0.1);`
  351. });
  352. }}
  353. host={system}
  354. codeRecorderPropertyName="getDragGradients()"
  355. mode={GradientGridMode.Factor}
  356. lockObject={this.props.lockObject}/>
  357. </LineContainerComponent>
  358. <LineContainerComponent globalState={this.props.globalState} title="SIZE">
  359. <FloatLineComponent lockObject={this.props.lockObject} label="Min size" target={system} propertyName="minSize" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  360. <FloatLineComponent lockObject={this.props.lockObject} label="Max size" target={system} propertyName="maxSize" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  361. <FloatLineComponent lockObject={this.props.lockObject} label="Min scale X" target={system} propertyName="minScaleX" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  362. <FloatLineComponent lockObject={this.props.lockObject} label="Max scale X" target={system} propertyName="maxScaleX" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  363. <FloatLineComponent lockObject={this.props.lockObject} label="Min scale Y" target={system} propertyName="minScaleY" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  364. <FloatLineComponent lockObject={this.props.lockObject} label="Max scale Y" target={system} propertyName="maxScaleY" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  365. <ValueGradientGridComponent globalState={this.props.globalState} gradients={system.getStartSizeGradients()!}
  366. label="Start size gradients"
  367. docLink="https://doc.babylonjs.com/babylon101/particles#start-size-over-time"
  368. onCreateRequired={() => {
  369. system.addStartSizeGradient(0, 1, 1);
  370. this.props.globalState.onCodeChangedObservable.notifyObservers({
  371. object: system,
  372. code: `TARGET.addStartSizeGradient(0, 1, 1);`
  373. });
  374. }}
  375. host={system}
  376. codeRecorderPropertyName="getStartSizeGradients()"
  377. mode={GradientGridMode.Factor}
  378. lockObject={this.props.lockObject}/>
  379. <ValueGradientGridComponent globalState={this.props.globalState} gradients={system.getSizeGradients()!}
  380. label="Size gradients"
  381. docLink="https://doc.babylonjs.com/babylon101/particles#size"
  382. onCreateRequired={() => {
  383. system.addSizeGradient(0, 1, 1);
  384. this.props.globalState.onCodeChangedObservable.notifyObservers({
  385. object: system,
  386. code: `TARGET.addSizeGradient(0, 1, 1);`
  387. });
  388. }}
  389. host={system}
  390. codeRecorderPropertyName="getSizeGradients()"
  391. mode={GradientGridMode.Factor}
  392. lockObject={this.props.lockObject}/>
  393. </LineContainerComponent>
  394. <LineContainerComponent globalState={this.props.globalState} title="LIFETIME">
  395. <FloatLineComponent lockObject={this.props.lockObject} label="Min lifetime" target={system} propertyName="minLifeTime" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  396. <FloatLineComponent lockObject={this.props.lockObject} label="Max lifetime" target={system} propertyName="maxLifeTime" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  397. <FloatLineComponent lockObject={this.props.lockObject} label="Target stop duration" target={system} propertyName="targetStopDuration" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  398. <ValueGradientGridComponent globalState={this.props.globalState} gradients={system.getLifeTimeGradients()!}
  399. label="Lifetime gradients"
  400. docLink="https://doc.babylonjs.com/babylon101/particles#lifetime"
  401. onCreateRequired={() => {
  402. system.addLifeTimeGradient(0, 1, 1);
  403. this.props.globalState.onCodeChangedObservable.notifyObservers({
  404. object: system,
  405. code: `TARGET.addLifeTimeGradient(0, 1, 1);`
  406. });
  407. }}
  408. host={system}
  409. codeRecorderPropertyName="getLifeTimeGradients()"
  410. mode={GradientGridMode.Factor}
  411. lockObject={this.props.lockObject}/>
  412. </LineContainerComponent>
  413. <LineContainerComponent globalState={this.props.globalState} title="COLORS">
  414. <Color4LineComponent label="Color 1" target={system} propertyName="color1"
  415. onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  416. <Color4LineComponent label="Color 2" target={system} propertyName="color2"
  417. onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  418. <Color4LineComponent label="Color dead" target={system} propertyName="colorDead"
  419. onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  420. <ValueGradientGridComponent globalState={this.props.globalState} gradients={system.getColorGradients()!}
  421. label="Color gradients"
  422. docLink="https://doc.babylonjs.com/babylon101/particles#particle-colors"
  423. onCreateRequired={() => {
  424. system.addColorGradient(0, new Color4(0, 0, 0, 1), new Color4(1, 1, 1, 1));
  425. this.props.globalState.onCodeChangedObservable.notifyObservers({
  426. object: system,
  427. code: `TARGET.addColorGradient(0, new BABYLON.Color4(0, 0, 0, 1), new BABYLON.Color4(1, 1, 1, 1));`
  428. });
  429. }}
  430. host={system}
  431. codeRecorderPropertyName="getColorGradients()"
  432. mode={GradientGridMode.Color4}
  433. lockObject={this.props.lockObject}/>
  434. <CheckBoxLineComponent label="Use ramp grandients" target={system} propertyName="useRampGradients"/>
  435. <ValueGradientGridComponent globalState={this.props.globalState} gradients={system.getRampGradients()!}
  436. label="Ramp gradients"
  437. docLink="https://doc.babylonjs.com/babylon101/particles#ramp-gradients"
  438. onCreateRequired={() => {
  439. system.addRampGradient(0, Color3.White());
  440. this.props.globalState.onCodeChangedObservable.notifyObservers({
  441. object: system,
  442. code: `TARGET.addRampGradient(0, BABYLON.Color3.White());`
  443. });
  444. }}
  445. mode={GradientGridMode.Color3}
  446. host={system}
  447. codeRecorderPropertyName="getRampGradients()"
  448. lockObject={this.props.lockObject}/>
  449. <ValueGradientGridComponent globalState={this.props.globalState} gradients={system.getColorRemapGradients()!}
  450. label="Color remap gradients"
  451. docLink="https://doc.babylonjs.com/babylon101/particles#ramp-gradients"
  452. onCreateRequired={() => {
  453. system.addColorRemapGradient(0, 1, 1);
  454. this.props.globalState.onCodeChangedObservable.notifyObservers({
  455. object: system,
  456. code: `TARGET.addColorRemapGradient(0, 1, 1);`
  457. });
  458. }}
  459. host={system}
  460. codeRecorderPropertyName="getColorRemapGradients()"
  461. mode={GradientGridMode.Factor}
  462. lockObject={this.props.lockObject}/>
  463. <ValueGradientGridComponent globalState={this.props.globalState} gradients={system.getAlphaRemapGradients()!}
  464. label="Alpha remap gradients"
  465. docLink="https://doc.babylonjs.com/babylon101/particles#ramp-gradients"
  466. onCreateRequired={() => {
  467. system.addAlphaRemapGradient(0, 1, 1);
  468. this.props.globalState.onCodeChangedObservable.notifyObservers({
  469. object: system,
  470. code: `TARGET.addAlphaRemapGradient(0, 1, 1);`
  471. });
  472. }}
  473. host={system}
  474. codeRecorderPropertyName="getAlphaRemapGradients()"
  475. mode={GradientGridMode.Factor}
  476. lockObject={this.props.lockObject}/>
  477. </LineContainerComponent>
  478. <LineContainerComponent globalState={this.props.globalState} title="ROTATION">
  479. <FloatLineComponent lockObject={this.props.lockObject} label="Min angular speed" target={system} propertyName="minAngularSpeed" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  480. <FloatLineComponent lockObject={this.props.lockObject} label="Max angular speed" target={system} propertyName="maxAngularSpeed" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  481. <FloatLineComponent lockObject={this.props.lockObject} label="Min initial rotation" target={system} propertyName="minInitialRotation" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  482. <FloatLineComponent lockObject={this.props.lockObject} label="Max initial rotation" target={system} propertyName="maxInitialRotation" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  483. <ValueGradientGridComponent globalState={this.props.globalState} gradients={system.getAngularSpeedGradients()!}
  484. label="Angular speed gradients"
  485. docLink="hhttps://doc.babylonjs.com/babylon101/particles#rotation"
  486. onCreateRequired={() => {
  487. system.addAngularSpeedGradient(0, 0.1, 0.1);
  488. this.props.globalState.onCodeChangedObservable.notifyObservers({
  489. object: system,
  490. code: `TARGET.addAngularSpeedGradient(0, 0.1, 0.1);`
  491. });
  492. }}
  493. host={system}
  494. codeRecorderPropertyName="getAngularSpeedGradients()"
  495. mode={GradientGridMode.Factor}
  496. lockObject={this.props.lockObject}/>
  497. </LineContainerComponent>
  498. </div>
  499. );
  500. }
  501. }