particleSystemPropertyGridComponent.tsx 33 KB

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