1 /** 2 GPU-based 3D particle emitter. 3 4 Copyright: 5 Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. 6 Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) 7 Copyright (c) 2017-2018 Godot-D contributors 8 9 License: $(LINK2 https://opensource.org/licenses/MIT, MIT License) 10 11 12 */ 13 module godot.particles; 14 import std.meta : AliasSeq, staticIndexOf; 15 import std.traits : Unqual; 16 import godot.d.traits; 17 import godot.core; 18 import godot.c; 19 import godot.d.bind; 20 import godot.d.reference; 21 import godot.globalenums; 22 import godot.object; 23 import godot.classdb; 24 import godot.geometryinstance; 25 import godot.visualinstance; 26 import godot.mesh; 27 import godot.material; 28 /** 29 GPU-based 3D particle emitter. 30 31 3D particle node used to create a variety of particle systems and effects. $(D Particles) features an emitter that generates some number of particles at a given rate. 32 Use the `process_material` property to add a $(D ParticlesMaterial) to configure particle appearance and behavior. Alternatively, you can add a $(D ShaderMaterial) which will be applied to all particles. 33 $(B Note:) $(D Particles) only work when using the GLES3 renderer. If using the GLES2 renderer, use $(D CPUParticles) instead. You can convert $(D Particles) to $(D CPUParticles) by selecting the node, clicking the $(B Particles) menu at the top of the 3D editor viewport then choosing $(B Convert to CPUParticles). 34 $(B Note:) After working on a Particles node, remember to update its $(D visibilityAabb) by selecting it, clicking the $(B Particles) menu at the top of the 3D editor viewport then choose $(B Generate Visibility AABB). Otherwise, particles may suddenly disappear depending on the camera position and angle. 35 */ 36 @GodotBaseClass struct Particles 37 { 38 package(godot) enum string _GODOT_internal_name = "Particles"; 39 public: 40 @nogc nothrow: 41 union { /** */ godot_object _godot_object; /** */ GeometryInstance _GODOT_base; } 42 alias _GODOT_base this; 43 alias BaseClasses = AliasSeq!(typeof(_GODOT_base), typeof(_GODOT_base).BaseClasses); 44 package(godot) __gshared bool _classBindingInitialized = false; 45 package(godot) static struct GDNativeClassBinding 46 { 47 __gshared: 48 @GodotName("capture_aabb") GodotMethod!(AABB) captureAabb; 49 @GodotName("get_amount") GodotMethod!(long) getAmount; 50 @GodotName("get_draw_order") GodotMethod!(Particles.DrawOrder) getDrawOrder; 51 @GodotName("get_draw_pass_mesh") GodotMethod!(Mesh, long) getDrawPassMesh; 52 @GodotName("get_draw_passes") GodotMethod!(long) getDrawPasses; 53 @GodotName("get_explosiveness_ratio") GodotMethod!(double) getExplosivenessRatio; 54 @GodotName("get_fixed_fps") GodotMethod!(long) getFixedFps; 55 @GodotName("get_fractional_delta") GodotMethod!(bool) getFractionalDelta; 56 @GodotName("get_lifetime") GodotMethod!(double) getLifetime; 57 @GodotName("get_one_shot") GodotMethod!(bool) getOneShot; 58 @GodotName("get_pre_process_time") GodotMethod!(double) getPreProcessTime; 59 @GodotName("get_process_material") GodotMethod!(Material) getProcessMaterial; 60 @GodotName("get_randomness_ratio") GodotMethod!(double) getRandomnessRatio; 61 @GodotName("get_speed_scale") GodotMethod!(double) getSpeedScale; 62 @GodotName("get_use_local_coordinates") GodotMethod!(bool) getUseLocalCoordinates; 63 @GodotName("get_visibility_aabb") GodotMethod!(AABB) getVisibilityAabb; 64 @GodotName("is_emitting") GodotMethod!(bool) isEmitting; 65 @GodotName("restart") GodotMethod!(void) restart; 66 @GodotName("set_amount") GodotMethod!(void, long) setAmount; 67 @GodotName("set_draw_order") GodotMethod!(void, long) setDrawOrder; 68 @GodotName("set_draw_pass_mesh") GodotMethod!(void, long, Mesh) setDrawPassMesh; 69 @GodotName("set_draw_passes") GodotMethod!(void, long) setDrawPasses; 70 @GodotName("set_emitting") GodotMethod!(void, bool) setEmitting; 71 @GodotName("set_explosiveness_ratio") GodotMethod!(void, double) setExplosivenessRatio; 72 @GodotName("set_fixed_fps") GodotMethod!(void, long) setFixedFps; 73 @GodotName("set_fractional_delta") GodotMethod!(void, bool) setFractionalDelta; 74 @GodotName("set_lifetime") GodotMethod!(void, double) setLifetime; 75 @GodotName("set_one_shot") GodotMethod!(void, bool) setOneShot; 76 @GodotName("set_pre_process_time") GodotMethod!(void, double) setPreProcessTime; 77 @GodotName("set_process_material") GodotMethod!(void, Material) setProcessMaterial; 78 @GodotName("set_randomness_ratio") GodotMethod!(void, double) setRandomnessRatio; 79 @GodotName("set_speed_scale") GodotMethod!(void, double) setSpeedScale; 80 @GodotName("set_use_local_coordinates") GodotMethod!(void, bool) setUseLocalCoordinates; 81 @GodotName("set_visibility_aabb") GodotMethod!(void, AABB) setVisibilityAabb; 82 } 83 /// 84 pragma(inline, true) bool opEquals(in Particles other) const 85 { return _godot_object.ptr is other._godot_object.ptr; } 86 /// 87 pragma(inline, true) typeof(null) opAssign(typeof(null) n) 88 { _godot_object.ptr = n; return null; } 89 /// 90 pragma(inline, true) bool opEquals(typeof(null) n) const 91 { return _godot_object.ptr is n; } 92 /// 93 size_t toHash() const @trusted { return cast(size_t)_godot_object.ptr; } 94 mixin baseCasts; 95 /// Construct a new instance of Particles. 96 /// Note: use `memnew!Particles` instead. 97 static Particles _new() 98 { 99 static godot_class_constructor constructor; 100 if(constructor is null) constructor = _godot_api.godot_get_class_constructor("Particles"); 101 if(constructor is null) return typeof(this).init; 102 return cast(Particles)(constructor()); 103 } 104 @disable new(size_t s); 105 /// 106 enum DrawOrder : int 107 { 108 /** 109 Particles are drawn in the order emitted. 110 */ 111 drawOrderIndex = 0, 112 /** 113 Particles are drawn in order of remaining lifetime. 114 */ 115 drawOrderLifetime = 1, 116 /** 117 Particles are drawn in order of depth. 118 */ 119 drawOrderViewDepth = 2, 120 } 121 /// 122 enum Constants : int 123 { 124 drawOrderIndex = 0, 125 drawOrderLifetime = 1, 126 drawOrderViewDepth = 2, 127 /** 128 Maximum number of draw passes supported. 129 */ 130 maxDrawPasses = 4, 131 } 132 /** 133 Returns the axis-aligned bounding box that contains all the particles that are active in the current frame. 134 */ 135 AABB captureAabb() const 136 { 137 checkClassBinding!(typeof(this))(); 138 return ptrcall!(AABB)(GDNativeClassBinding.captureAabb, _godot_object); 139 } 140 /** 141 142 */ 143 long getAmount() const 144 { 145 checkClassBinding!(typeof(this))(); 146 return ptrcall!(long)(GDNativeClassBinding.getAmount, _godot_object); 147 } 148 /** 149 150 */ 151 Particles.DrawOrder getDrawOrder() const 152 { 153 checkClassBinding!(typeof(this))(); 154 return ptrcall!(Particles.DrawOrder)(GDNativeClassBinding.getDrawOrder, _godot_object); 155 } 156 /** 157 Returns the $(D Mesh) that is drawn at index `pass`. 158 */ 159 Ref!Mesh getDrawPassMesh(in long pass) const 160 { 161 checkClassBinding!(typeof(this))(); 162 return ptrcall!(Mesh)(GDNativeClassBinding.getDrawPassMesh, _godot_object, pass); 163 } 164 /** 165 166 */ 167 long getDrawPasses() const 168 { 169 checkClassBinding!(typeof(this))(); 170 return ptrcall!(long)(GDNativeClassBinding.getDrawPasses, _godot_object); 171 } 172 /** 173 174 */ 175 double getExplosivenessRatio() const 176 { 177 checkClassBinding!(typeof(this))(); 178 return ptrcall!(double)(GDNativeClassBinding.getExplosivenessRatio, _godot_object); 179 } 180 /** 181 182 */ 183 long getFixedFps() const 184 { 185 checkClassBinding!(typeof(this))(); 186 return ptrcall!(long)(GDNativeClassBinding.getFixedFps, _godot_object); 187 } 188 /** 189 190 */ 191 bool getFractionalDelta() const 192 { 193 checkClassBinding!(typeof(this))(); 194 return ptrcall!(bool)(GDNativeClassBinding.getFractionalDelta, _godot_object); 195 } 196 /** 197 198 */ 199 double getLifetime() const 200 { 201 checkClassBinding!(typeof(this))(); 202 return ptrcall!(double)(GDNativeClassBinding.getLifetime, _godot_object); 203 } 204 /** 205 206 */ 207 bool getOneShot() const 208 { 209 checkClassBinding!(typeof(this))(); 210 return ptrcall!(bool)(GDNativeClassBinding.getOneShot, _godot_object); 211 } 212 /** 213 214 */ 215 double getPreProcessTime() const 216 { 217 checkClassBinding!(typeof(this))(); 218 return ptrcall!(double)(GDNativeClassBinding.getPreProcessTime, _godot_object); 219 } 220 /** 221 222 */ 223 Ref!Material getProcessMaterial() const 224 { 225 checkClassBinding!(typeof(this))(); 226 return ptrcall!(Material)(GDNativeClassBinding.getProcessMaterial, _godot_object); 227 } 228 /** 229 230 */ 231 double getRandomnessRatio() const 232 { 233 checkClassBinding!(typeof(this))(); 234 return ptrcall!(double)(GDNativeClassBinding.getRandomnessRatio, _godot_object); 235 } 236 /** 237 238 */ 239 double getSpeedScale() const 240 { 241 checkClassBinding!(typeof(this))(); 242 return ptrcall!(double)(GDNativeClassBinding.getSpeedScale, _godot_object); 243 } 244 /** 245 246 */ 247 bool getUseLocalCoordinates() const 248 { 249 checkClassBinding!(typeof(this))(); 250 return ptrcall!(bool)(GDNativeClassBinding.getUseLocalCoordinates, _godot_object); 251 } 252 /** 253 254 */ 255 AABB getVisibilityAabb() const 256 { 257 checkClassBinding!(typeof(this))(); 258 return ptrcall!(AABB)(GDNativeClassBinding.getVisibilityAabb, _godot_object); 259 } 260 /** 261 262 */ 263 bool isEmitting() const 264 { 265 checkClassBinding!(typeof(this))(); 266 return ptrcall!(bool)(GDNativeClassBinding.isEmitting, _godot_object); 267 } 268 /** 269 Restarts the particle emission, clearing existing particles. 270 */ 271 void restart() 272 { 273 checkClassBinding!(typeof(this))(); 274 ptrcall!(void)(GDNativeClassBinding.restart, _godot_object); 275 } 276 /** 277 278 */ 279 void setAmount(in long amount) 280 { 281 checkClassBinding!(typeof(this))(); 282 ptrcall!(void)(GDNativeClassBinding.setAmount, _godot_object, amount); 283 } 284 /** 285 286 */ 287 void setDrawOrder(in long order) 288 { 289 checkClassBinding!(typeof(this))(); 290 ptrcall!(void)(GDNativeClassBinding.setDrawOrder, _godot_object, order); 291 } 292 /** 293 Sets the $(D Mesh) that is drawn at index `pass`. 294 */ 295 void setDrawPassMesh(in long pass, Mesh mesh) 296 { 297 checkClassBinding!(typeof(this))(); 298 ptrcall!(void)(GDNativeClassBinding.setDrawPassMesh, _godot_object, pass, mesh); 299 } 300 /** 301 302 */ 303 void setDrawPasses(in long passes) 304 { 305 checkClassBinding!(typeof(this))(); 306 ptrcall!(void)(GDNativeClassBinding.setDrawPasses, _godot_object, passes); 307 } 308 /** 309 310 */ 311 void setEmitting(in bool emitting) 312 { 313 checkClassBinding!(typeof(this))(); 314 ptrcall!(void)(GDNativeClassBinding.setEmitting, _godot_object, emitting); 315 } 316 /** 317 318 */ 319 void setExplosivenessRatio(in double ratio) 320 { 321 checkClassBinding!(typeof(this))(); 322 ptrcall!(void)(GDNativeClassBinding.setExplosivenessRatio, _godot_object, ratio); 323 } 324 /** 325 326 */ 327 void setFixedFps(in long fps) 328 { 329 checkClassBinding!(typeof(this))(); 330 ptrcall!(void)(GDNativeClassBinding.setFixedFps, _godot_object, fps); 331 } 332 /** 333 334 */ 335 void setFractionalDelta(in bool enable) 336 { 337 checkClassBinding!(typeof(this))(); 338 ptrcall!(void)(GDNativeClassBinding.setFractionalDelta, _godot_object, enable); 339 } 340 /** 341 342 */ 343 void setLifetime(in double secs) 344 { 345 checkClassBinding!(typeof(this))(); 346 ptrcall!(void)(GDNativeClassBinding.setLifetime, _godot_object, secs); 347 } 348 /** 349 350 */ 351 void setOneShot(in bool enable) 352 { 353 checkClassBinding!(typeof(this))(); 354 ptrcall!(void)(GDNativeClassBinding.setOneShot, _godot_object, enable); 355 } 356 /** 357 358 */ 359 void setPreProcessTime(in double secs) 360 { 361 checkClassBinding!(typeof(this))(); 362 ptrcall!(void)(GDNativeClassBinding.setPreProcessTime, _godot_object, secs); 363 } 364 /** 365 366 */ 367 void setProcessMaterial(Material material) 368 { 369 checkClassBinding!(typeof(this))(); 370 ptrcall!(void)(GDNativeClassBinding.setProcessMaterial, _godot_object, material); 371 } 372 /** 373 374 */ 375 void setRandomnessRatio(in double ratio) 376 { 377 checkClassBinding!(typeof(this))(); 378 ptrcall!(void)(GDNativeClassBinding.setRandomnessRatio, _godot_object, ratio); 379 } 380 /** 381 382 */ 383 void setSpeedScale(in double scale) 384 { 385 checkClassBinding!(typeof(this))(); 386 ptrcall!(void)(GDNativeClassBinding.setSpeedScale, _godot_object, scale); 387 } 388 /** 389 390 */ 391 void setUseLocalCoordinates(in bool enable) 392 { 393 checkClassBinding!(typeof(this))(); 394 ptrcall!(void)(GDNativeClassBinding.setUseLocalCoordinates, _godot_object, enable); 395 } 396 /** 397 398 */ 399 void setVisibilityAabb(in AABB aabb) 400 { 401 checkClassBinding!(typeof(this))(); 402 ptrcall!(void)(GDNativeClassBinding.setVisibilityAabb, _godot_object, aabb); 403 } 404 /** 405 The number of particles emitted in one emission cycle (corresponding to the $(D lifetime)). 406 $(B Note:) Changing $(D amount) will reset the particle emission, therefore removing all particles that were already emitted before changing $(D amount). 407 */ 408 @property long amount() 409 { 410 return getAmount(); 411 } 412 /// ditto 413 @property void amount(long v) 414 { 415 setAmount(v); 416 } 417 /** 418 Particle draw order. Uses $(D draworder) values. 419 */ 420 @property Particles.DrawOrder drawOrder() 421 { 422 return getDrawOrder(); 423 } 424 /// ditto 425 @property void drawOrder(long v) 426 { 427 setDrawOrder(v); 428 } 429 /** 430 $(D Mesh) that is drawn for the first draw pass. 431 */ 432 @property Mesh drawPass1() 433 { 434 return getDrawPassMesh(0); 435 } 436 /// ditto 437 @property void drawPass1(Mesh v) 438 { 439 setDrawPassMesh(0, v); 440 } 441 /** 442 $(D Mesh) that is drawn for the second draw pass. 443 */ 444 @property Mesh drawPass2() 445 { 446 return getDrawPassMesh(1); 447 } 448 /// ditto 449 @property void drawPass2(Mesh v) 450 { 451 setDrawPassMesh(1, v); 452 } 453 /** 454 $(D Mesh) that is drawn for the third draw pass. 455 */ 456 @property Mesh drawPass3() 457 { 458 return getDrawPassMesh(2); 459 } 460 /// ditto 461 @property void drawPass3(Mesh v) 462 { 463 setDrawPassMesh(2, v); 464 } 465 /** 466 $(D Mesh) that is drawn for the fourth draw pass. 467 */ 468 @property Mesh drawPass4() 469 { 470 return getDrawPassMesh(3); 471 } 472 /// ditto 473 @property void drawPass4(Mesh v) 474 { 475 setDrawPassMesh(3, v); 476 } 477 /** 478 The number of draw passes when rendering particles. 479 */ 480 @property long drawPasses() 481 { 482 return getDrawPasses(); 483 } 484 /// ditto 485 @property void drawPasses(long v) 486 { 487 setDrawPasses(v); 488 } 489 /** 490 If `true`, particles are being emitted. 491 */ 492 @property bool emitting() 493 { 494 return isEmitting(); 495 } 496 /// ditto 497 @property void emitting(bool v) 498 { 499 setEmitting(v); 500 } 501 /** 502 Time ratio between each emission. If `0`, particles are emitted continuously. If `1`, all particles are emitted simultaneously. 503 */ 504 @property double explosiveness() 505 { 506 return getExplosivenessRatio(); 507 } 508 /// ditto 509 @property void explosiveness(double v) 510 { 511 setExplosivenessRatio(v); 512 } 513 /** 514 The particle system's frame rate is fixed to a value. For instance, changing the value to 2 will make the particles render at 2 frames per second. Note this does not slow down the simulation of the particle system itself. 515 */ 516 @property long fixedFps() 517 { 518 return getFixedFps(); 519 } 520 /// ditto 521 @property void fixedFps(long v) 522 { 523 setFixedFps(v); 524 } 525 /** 526 If `true`, results in fractional delta calculation which has a smoother particles display effect. 527 */ 528 @property bool fractDelta() 529 { 530 return getFractionalDelta(); 531 } 532 /// ditto 533 @property void fractDelta(bool v) 534 { 535 setFractionalDelta(v); 536 } 537 /** 538 The amount of time each particle will exist (in seconds). 539 */ 540 @property double lifetime() 541 { 542 return getLifetime(); 543 } 544 /// ditto 545 @property void lifetime(double v) 546 { 547 setLifetime(v); 548 } 549 /** 550 If `true`, particles use the parent node's coordinate space. If `false`, they use global coordinates. 551 */ 552 @property bool localCoords() 553 { 554 return getUseLocalCoordinates(); 555 } 556 /// ditto 557 @property void localCoords(bool v) 558 { 559 setUseLocalCoordinates(v); 560 } 561 /** 562 If `true`, only `amount` particles will be emitted. 563 */ 564 @property bool oneShot() 565 { 566 return getOneShot(); 567 } 568 /// ditto 569 @property void oneShot(bool v) 570 { 571 setOneShot(v); 572 } 573 /** 574 Amount of time to preprocess the particles before animation starts. Lets you start the animation some time after particles have started emitting. 575 */ 576 @property double preprocess() 577 { 578 return getPreProcessTime(); 579 } 580 /// ditto 581 @property void preprocess(double v) 582 { 583 setPreProcessTime(v); 584 } 585 /** 586 Emission randomness ratio. 587 */ 588 @property double randomness() 589 { 590 return getRandomnessRatio(); 591 } 592 /// ditto 593 @property void randomness(double v) 594 { 595 setRandomnessRatio(v); 596 } 597 /** 598 Speed scaling ratio. A value of `0` can be used to pause the particles. 599 */ 600 @property double speedScale() 601 { 602 return getSpeedScale(); 603 } 604 /// ditto 605 @property void speedScale(double v) 606 { 607 setSpeedScale(v); 608 } 609 /** 610 The $(D AABB) that determines the node's region which needs to be visible on screen for the particle system to be active. 611 Grow the box if particles suddenly appear/disappear when the node enters/exits the screen. The $(D AABB) can be grown via code or with the $(B Particles → Generate AABB) editor tool. 612 $(B Note:) If the $(D ParticlesMaterial) in use is configured to cast shadows, you may want to enlarge this AABB to ensure the shadow is updated when particles are off-screen. 613 */ 614 @property AABB visibilityAabb() 615 { 616 return getVisibilityAabb(); 617 } 618 /// ditto 619 @property void visibilityAabb(AABB v) 620 { 621 setVisibilityAabb(v); 622 } 623 }