particles_storage.cpp 59 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473
  1. /**************************************************************************/
  2. /* particles_storage.cpp */
  3. /**************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* https://godotengine.org */
  7. /**************************************************************************/
  8. /* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
  9. /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
  10. /* */
  11. /* Permission is hereby granted, free of charge, to any person obtaining */
  12. /* a copy of this software and associated documentation files (the */
  13. /* "Software"), to deal in the Software without restriction, including */
  14. /* without limitation the rights to use, copy, modify, merge, publish, */
  15. /* distribute, sublicense, and/or sell copies of the Software, and to */
  16. /* permit persons to whom the Software is furnished to do so, subject to */
  17. /* the following conditions: */
  18. /* */
  19. /* The above copyright notice and this permission notice shall be */
  20. /* included in all copies or substantial portions of the Software. */
  21. /* */
  22. /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
  23. /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
  24. /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
  25. /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
  26. /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
  27. /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
  28. /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
  29. /**************************************************************************/
  30. #ifdef GLES3_ENABLED
  31. #include "particles_storage.h"
  32. #include "config.h"
  33. #include "material_storage.h"
  34. #include "mesh_storage.h"
  35. #include "texture_storage.h"
  36. #include "utilities.h"
  37. #include "servers/rendering/rendering_server_globals.h"
  38. using namespace GLES3;
  39. ParticlesStorage *ParticlesStorage::singleton = nullptr;
  40. ParticlesStorage *ParticlesStorage::get_singleton() {
  41. return singleton;
  42. }
  43. ParticlesStorage::ParticlesStorage() {
  44. singleton = this;
  45. GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton();
  46. {
  47. String global_defines;
  48. global_defines += "#define MAX_GLOBAL_SHADER_UNIFORMS 256\n"; // TODO: this is arbitrary for now
  49. material_storage->shaders.particles_process_shader.initialize(global_defines, 1);
  50. }
  51. {
  52. // default material and shader for particles shader
  53. particles_shader.default_shader = material_storage->shader_allocate();
  54. material_storage->shader_initialize(particles_shader.default_shader);
  55. material_storage->shader_set_code(particles_shader.default_shader, R"(
  56. // Default particles shader.
  57. shader_type particles;
  58. void process() {
  59. COLOR = vec4(1.0);
  60. }
  61. )");
  62. particles_shader.default_material = material_storage->material_allocate();
  63. material_storage->material_initialize(particles_shader.default_material);
  64. material_storage->material_set_shader(particles_shader.default_material, particles_shader.default_shader);
  65. }
  66. {
  67. particles_shader.copy_shader.initialize();
  68. particles_shader.copy_shader_version = particles_shader.copy_shader.version_create();
  69. }
  70. }
  71. ParticlesStorage::~ParticlesStorage() {
  72. singleton = nullptr;
  73. GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton();
  74. material_storage->material_free(particles_shader.default_material);
  75. material_storage->shader_free(particles_shader.default_shader);
  76. particles_shader.copy_shader.version_free(particles_shader.copy_shader_version);
  77. }
  78. /* PARTICLES */
  79. RID ParticlesStorage::particles_allocate() {
  80. return particles_owner.allocate_rid();
  81. }
  82. void ParticlesStorage::particles_initialize(RID p_rid) {
  83. particles_owner.initialize_rid(p_rid);
  84. }
  85. void ParticlesStorage::particles_free(RID p_rid) {
  86. Particles *particles = particles_owner.get_or_null(p_rid);
  87. particles->dependency.deleted_notify(p_rid);
  88. particles->update_list.remove_from_list();
  89. _particles_free_data(particles);
  90. particles_owner.free(p_rid);
  91. }
  92. void ParticlesStorage::particles_set_mode(RID p_particles, RS::ParticlesMode p_mode) {
  93. Particles *particles = particles_owner.get_or_null(p_particles);
  94. ERR_FAIL_NULL(particles);
  95. if (particles->mode == p_mode) {
  96. return;
  97. }
  98. _particles_free_data(particles);
  99. particles->mode = p_mode;
  100. }
  101. void ParticlesStorage::particles_set_emitting(RID p_particles, bool p_emitting) {
  102. ERR_FAIL_COND_MSG(GLES3::Config::get_singleton()->disable_particles_workaround, "Due to driver bugs, GPUParticles are not supported on Adreno 3XX devices. Please use CPUParticles instead.");
  103. Particles *particles = particles_owner.get_or_null(p_particles);
  104. ERR_FAIL_NULL(particles);
  105. particles->emitting = p_emitting;
  106. }
  107. bool ParticlesStorage::particles_get_emitting(RID p_particles) {
  108. if (GLES3::Config::get_singleton()->disable_particles_workaround) {
  109. return false;
  110. }
  111. Particles *particles = particles_owner.get_or_null(p_particles);
  112. ERR_FAIL_NULL_V(particles, false);
  113. return particles->emitting;
  114. }
  115. void ParticlesStorage::_particles_free_data(Particles *particles) {
  116. particles->userdata_count = 0;
  117. particles->instance_buffer_size_cache = 0;
  118. particles->instance_buffer_stride_cache = 0;
  119. particles->num_attrib_arrays_cache = 0;
  120. particles->process_buffer_stride_cache = 0;
  121. if (particles->front_process_buffer != 0) {
  122. glDeleteVertexArrays(1, &particles->front_vertex_array);
  123. GLES3::Utilities::get_singleton()->buffer_free_data(particles->front_process_buffer);
  124. GLES3::Utilities::get_singleton()->buffer_free_data(particles->front_instance_buffer);
  125. particles->front_vertex_array = 0;
  126. particles->front_process_buffer = 0;
  127. particles->front_instance_buffer = 0;
  128. glDeleteVertexArrays(1, &particles->back_vertex_array);
  129. GLES3::Utilities::get_singleton()->buffer_free_data(particles->back_process_buffer);
  130. GLES3::Utilities::get_singleton()->buffer_free_data(particles->back_instance_buffer);
  131. particles->back_vertex_array = 0;
  132. particles->back_process_buffer = 0;
  133. particles->back_instance_buffer = 0;
  134. }
  135. if (particles->sort_buffer != 0) {
  136. GLES3::Utilities::get_singleton()->buffer_free_data(particles->last_frame_buffer);
  137. GLES3::Utilities::get_singleton()->buffer_free_data(particles->sort_buffer);
  138. particles->last_frame_buffer = 0;
  139. particles->sort_buffer = 0;
  140. particles->sort_buffer_filled = false;
  141. particles->last_frame_buffer_filled = false;
  142. }
  143. if (particles->frame_params_ubo != 0) {
  144. GLES3::Utilities::get_singleton()->buffer_free_data(particles->frame_params_ubo);
  145. particles->frame_params_ubo = 0;
  146. }
  147. }
  148. void ParticlesStorage::particles_set_amount(RID p_particles, int p_amount) {
  149. Particles *particles = particles_owner.get_or_null(p_particles);
  150. ERR_FAIL_NULL(particles);
  151. if (particles->amount == p_amount) {
  152. return;
  153. }
  154. _particles_free_data(particles);
  155. particles->amount = p_amount;
  156. particles->prev_ticks = 0;
  157. particles->phase = 0;
  158. particles->prev_phase = 0;
  159. particles->clear = true;
  160. particles->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_PARTICLES);
  161. }
  162. void ParticlesStorage::particles_set_amount_ratio(RID p_particles, float p_amount_ratio) {
  163. Particles *particles = particles_owner.get_or_null(p_particles);
  164. ERR_FAIL_NULL(particles);
  165. particles->amount_ratio = p_amount_ratio;
  166. }
  167. void ParticlesStorage::particles_set_lifetime(RID p_particles, double p_lifetime) {
  168. Particles *particles = particles_owner.get_or_null(p_particles);
  169. ERR_FAIL_NULL(particles);
  170. particles->lifetime = p_lifetime;
  171. }
  172. void ParticlesStorage::particles_set_one_shot(RID p_particles, bool p_one_shot) {
  173. Particles *particles = particles_owner.get_or_null(p_particles);
  174. ERR_FAIL_NULL(particles);
  175. particles->one_shot = p_one_shot;
  176. }
  177. void ParticlesStorage::particles_set_pre_process_time(RID p_particles, double p_time) {
  178. Particles *particles = particles_owner.get_or_null(p_particles);
  179. ERR_FAIL_NULL(particles);
  180. particles->pre_process_time = p_time;
  181. }
  182. void ParticlesStorage::particles_request_process_time(RID p_particles, real_t p_request_process_time) {
  183. Particles *particles = particles_owner.get_or_null(p_particles);
  184. ERR_FAIL_NULL(particles);
  185. particles->request_process_time = p_request_process_time;
  186. }
  187. void ParticlesStorage::particles_set_seed(RID p_particles, uint32_t p_seed) {
  188. Particles *particles = particles_owner.get_or_null(p_particles);
  189. ERR_FAIL_NULL(particles);
  190. particles->random_seed = p_seed;
  191. }
  192. void ParticlesStorage::particles_set_explosiveness_ratio(RID p_particles, real_t p_ratio) {
  193. Particles *particles = particles_owner.get_or_null(p_particles);
  194. ERR_FAIL_NULL(particles);
  195. particles->explosiveness = p_ratio;
  196. }
  197. void ParticlesStorage::particles_set_randomness_ratio(RID p_particles, real_t p_ratio) {
  198. Particles *particles = particles_owner.get_or_null(p_particles);
  199. ERR_FAIL_NULL(particles);
  200. particles->randomness = p_ratio;
  201. }
  202. void ParticlesStorage::particles_set_custom_aabb(RID p_particles, const AABB &p_aabb) {
  203. Particles *particles = particles_owner.get_or_null(p_particles);
  204. ERR_FAIL_NULL(particles);
  205. particles->custom_aabb = p_aabb;
  206. particles->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);
  207. }
  208. void ParticlesStorage::particles_set_speed_scale(RID p_particles, double p_scale) {
  209. Particles *particles = particles_owner.get_or_null(p_particles);
  210. ERR_FAIL_NULL(particles);
  211. particles->speed_scale = p_scale;
  212. }
  213. void ParticlesStorage::particles_set_use_local_coordinates(RID p_particles, bool p_enable) {
  214. Particles *particles = particles_owner.get_or_null(p_particles);
  215. ERR_FAIL_NULL(particles);
  216. particles->use_local_coords = p_enable;
  217. particles->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_PARTICLES);
  218. }
  219. void ParticlesStorage::particles_set_fixed_fps(RID p_particles, int p_fps) {
  220. Particles *particles = particles_owner.get_or_null(p_particles);
  221. ERR_FAIL_NULL(particles);
  222. particles->fixed_fps = p_fps;
  223. _particles_free_data(particles);
  224. particles->prev_ticks = 0;
  225. particles->phase = 0;
  226. particles->prev_phase = 0;
  227. particles->clear = true;
  228. particles->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_PARTICLES);
  229. }
  230. void ParticlesStorage::particles_set_interpolate(RID p_particles, bool p_enable) {
  231. Particles *particles = particles_owner.get_or_null(p_particles);
  232. ERR_FAIL_NULL(particles);
  233. particles->interpolate = p_enable;
  234. }
  235. void ParticlesStorage::particles_set_fractional_delta(RID p_particles, bool p_enable) {
  236. Particles *particles = particles_owner.get_or_null(p_particles);
  237. ERR_FAIL_NULL(particles);
  238. particles->fractional_delta = p_enable;
  239. }
  240. void ParticlesStorage::particles_set_trails(RID p_particles, bool p_enable, double p_length) {
  241. if (p_enable) {
  242. WARN_PRINT_ONCE_ED("The Compatibility renderer does not support particle trails.");
  243. }
  244. }
  245. void ParticlesStorage::particles_set_trail_bind_poses(RID p_particles, const Vector<Transform3D> &p_bind_poses) {
  246. if (p_bind_poses.size() != 0) {
  247. WARN_PRINT_ONCE_ED("The Compatibility renderer does not support particle trails.");
  248. }
  249. }
  250. void ParticlesStorage::particles_set_collision_base_size(RID p_particles, real_t p_size) {
  251. Particles *particles = particles_owner.get_or_null(p_particles);
  252. ERR_FAIL_NULL(particles);
  253. particles->collision_base_size = p_size;
  254. }
  255. void ParticlesStorage::particles_set_transform_align(RID p_particles, RS::ParticlesTransformAlign p_transform_align) {
  256. Particles *particles = particles_owner.get_or_null(p_particles);
  257. ERR_FAIL_NULL(particles);
  258. particles->transform_align = p_transform_align;
  259. }
  260. void ParticlesStorage::particles_set_process_material(RID p_particles, RID p_material) {
  261. Particles *particles = particles_owner.get_or_null(p_particles);
  262. ERR_FAIL_NULL(particles);
  263. particles->process_material = p_material;
  264. particles->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_PARTICLES); //the instance buffer may have changed
  265. }
  266. RID ParticlesStorage::particles_get_process_material(RID p_particles) const {
  267. Particles *particles = particles_owner.get_or_null(p_particles);
  268. ERR_FAIL_NULL_V(particles, RID());
  269. return particles->process_material;
  270. }
  271. void ParticlesStorage::particles_set_draw_order(RID p_particles, RS::ParticlesDrawOrder p_order) {
  272. Particles *particles = particles_owner.get_or_null(p_particles);
  273. ERR_FAIL_NULL(particles);
  274. particles->draw_order = p_order;
  275. }
  276. void ParticlesStorage::particles_set_draw_passes(RID p_particles, int p_passes) {
  277. Particles *particles = particles_owner.get_or_null(p_particles);
  278. ERR_FAIL_NULL(particles);
  279. particles->draw_passes.resize(p_passes);
  280. }
  281. void ParticlesStorage::particles_set_draw_pass_mesh(RID p_particles, int p_pass, RID p_mesh) {
  282. Particles *particles = particles_owner.get_or_null(p_particles);
  283. ERR_FAIL_NULL(particles);
  284. ERR_FAIL_INDEX(p_pass, particles->draw_passes.size());
  285. particles->draw_passes.write[p_pass] = p_mesh;
  286. particles->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_PARTICLES);
  287. }
  288. void ParticlesStorage::particles_restart(RID p_particles) {
  289. Particles *particles = particles_owner.get_or_null(p_particles);
  290. ERR_FAIL_NULL(particles);
  291. particles->restart_request = true;
  292. }
  293. void ParticlesStorage::particles_set_subemitter(RID p_particles, RID p_subemitter_particles) {
  294. if (p_subemitter_particles.is_valid()) {
  295. WARN_PRINT_ONCE_ED("The Compatibility renderer does not support particle sub-emitters.");
  296. }
  297. }
  298. void ParticlesStorage::particles_emit(RID p_particles, const Transform3D &p_transform, const Vector3 &p_velocity, const Color &p_color, const Color &p_custom, uint32_t p_emit_flags) {
  299. WARN_PRINT_ONCE_ED("The Compatibility renderer does not support manually emitting particles.");
  300. }
  301. void ParticlesStorage::particles_request_process(RID p_particles) {
  302. Particles *particles = particles_owner.get_or_null(p_particles);
  303. ERR_FAIL_NULL(particles);
  304. if (!particles->dirty) {
  305. particles->dirty = true;
  306. if (!particles->update_list.in_list()) {
  307. particle_update_list.add(&particles->update_list);
  308. }
  309. }
  310. }
  311. AABB ParticlesStorage::particles_get_current_aabb(RID p_particles) {
  312. const Particles *particles = particles_owner.get_or_null(p_particles);
  313. ERR_FAIL_NULL_V(particles, AABB());
  314. int total_amount = particles->amount;
  315. // If available, read from the sort buffer which should be 2 frames out of date.
  316. // This will help alleviate GPU stalls.
  317. GLuint read_buffer = particles->sort_buffer_filled ? particles->sort_buffer : particles->back_instance_buffer;
  318. Vector<uint8_t> buffer = Utilities::buffer_get_data(GL_ARRAY_BUFFER, read_buffer, total_amount * sizeof(ParticleInstanceData3D));
  319. ERR_FAIL_COND_V(buffer.size() != (int)(total_amount * sizeof(ParticleInstanceData3D)), AABB());
  320. Transform3D inv = particles->emission_transform.affine_inverse();
  321. AABB aabb;
  322. if (buffer.size()) {
  323. bool first = true;
  324. const uint8_t *data_ptr = (const uint8_t *)buffer.ptr();
  325. uint32_t particle_data_size = sizeof(ParticleInstanceData3D);
  326. for (int i = 0; i < total_amount; i++) {
  327. const ParticleInstanceData3D &particle_data = *(const ParticleInstanceData3D *)&data_ptr[particle_data_size * i];
  328. // If scale is 0.0, we assume the particle is inactive.
  329. if (particle_data.xform[0] > 0.0) {
  330. Vector3 pos = Vector3(particle_data.xform[3], particle_data.xform[7], particle_data.xform[11]);
  331. if (!particles->use_local_coords) {
  332. pos = inv.xform(pos);
  333. }
  334. if (first) {
  335. aabb.position = pos;
  336. first = false;
  337. } else {
  338. aabb.expand_to(pos);
  339. }
  340. }
  341. }
  342. }
  343. float longest_axis_size = 0;
  344. for (int i = 0; i < particles->draw_passes.size(); i++) {
  345. if (particles->draw_passes[i].is_valid()) {
  346. AABB maabb = MeshStorage::get_singleton()->mesh_get_aabb(particles->draw_passes[i], RID());
  347. longest_axis_size = MAX(maabb.get_longest_axis_size(), longest_axis_size);
  348. }
  349. }
  350. aabb.grow_by(longest_axis_size);
  351. return aabb;
  352. }
  353. AABB ParticlesStorage::particles_get_aabb(RID p_particles) const {
  354. const Particles *particles = particles_owner.get_or_null(p_particles);
  355. ERR_FAIL_NULL_V(particles, AABB());
  356. return particles->custom_aabb;
  357. }
  358. void ParticlesStorage::particles_set_emission_transform(RID p_particles, const Transform3D &p_transform) {
  359. Particles *particles = particles_owner.get_or_null(p_particles);
  360. ERR_FAIL_NULL(particles);
  361. particles->emission_transform = p_transform;
  362. }
  363. void ParticlesStorage::particles_set_emitter_velocity(RID p_particles, const Vector3 &p_velocity) {
  364. Particles *particles = particles_owner.get_or_null(p_particles);
  365. ERR_FAIL_NULL(particles);
  366. particles->emitter_velocity = p_velocity;
  367. }
  368. void ParticlesStorage::particles_set_interp_to_end(RID p_particles, float p_interp) {
  369. Particles *particles = particles_owner.get_or_null(p_particles);
  370. ERR_FAIL_NULL(particles);
  371. particles->interp_to_end = p_interp;
  372. }
  373. int ParticlesStorage::particles_get_draw_passes(RID p_particles) const {
  374. const Particles *particles = particles_owner.get_or_null(p_particles);
  375. ERR_FAIL_NULL_V(particles, 0);
  376. return particles->draw_passes.size();
  377. }
  378. RID ParticlesStorage::particles_get_draw_pass_mesh(RID p_particles, int p_pass) const {
  379. const Particles *particles = particles_owner.get_or_null(p_particles);
  380. ERR_FAIL_NULL_V(particles, RID());
  381. ERR_FAIL_INDEX_V(p_pass, particles->draw_passes.size(), RID());
  382. return particles->draw_passes[p_pass];
  383. }
  384. void ParticlesStorage::particles_add_collision(RID p_particles, RID p_particles_collision_instance) {
  385. Particles *particles = particles_owner.get_or_null(p_particles);
  386. ERR_FAIL_NULL(particles);
  387. particles->collisions.insert(p_particles_collision_instance);
  388. }
  389. void ParticlesStorage::particles_remove_collision(RID p_particles, RID p_particles_collision_instance) {
  390. Particles *particles = particles_owner.get_or_null(p_particles);
  391. ERR_FAIL_NULL(particles);
  392. particles->collisions.erase(p_particles_collision_instance);
  393. }
  394. void ParticlesStorage::particles_set_canvas_sdf_collision(RID p_particles, bool p_enable, const Transform2D &p_xform, const Rect2 &p_to_screen, GLuint p_texture) {
  395. Particles *particles = particles_owner.get_or_null(p_particles);
  396. ERR_FAIL_NULL(particles);
  397. particles->has_sdf_collision = p_enable;
  398. particles->sdf_collision_transform = p_xform;
  399. particles->sdf_collision_to_screen = p_to_screen;
  400. particles->sdf_collision_texture = p_texture;
  401. }
  402. // Does one step of processing particles by reading from back_process_buffer and writing to front_process_buffer.
  403. void ParticlesStorage::_particles_process(Particles *p_particles, double p_delta) {
  404. GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();
  405. GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton();
  406. double new_phase = Math::fmod(p_particles->phase + (p_delta / p_particles->lifetime), 1.0);
  407. //update current frame
  408. ParticlesFrameParams frame_params;
  409. if (p_particles->clear) {
  410. p_particles->cycle_number = 0;
  411. } else if (new_phase < p_particles->phase) {
  412. if (p_particles->one_shot) {
  413. p_particles->emitting = false;
  414. }
  415. p_particles->cycle_number++;
  416. }
  417. frame_params.emitting = p_particles->emitting;
  418. frame_params.system_phase = new_phase;
  419. frame_params.prev_system_phase = p_particles->phase;
  420. p_particles->phase = new_phase;
  421. frame_params.time = RSG::rasterizer->get_total_time();
  422. frame_params.delta = p_delta;
  423. frame_params.random_seed = p_particles->random_seed;
  424. frame_params.explosiveness = p_particles->explosiveness;
  425. frame_params.randomness = p_particles->randomness;
  426. if (p_particles->use_local_coords) {
  427. GLES3::MaterialStorage::store_transform(Transform3D(), frame_params.emission_transform);
  428. } else {
  429. GLES3::MaterialStorage::store_transform(p_particles->emission_transform, frame_params.emission_transform);
  430. }
  431. frame_params.cycle = p_particles->cycle_number;
  432. frame_params.frame = p_particles->frame_counter++;
  433. frame_params.amount_ratio = p_particles->amount_ratio;
  434. frame_params.pad1 = 0;
  435. frame_params.pad2 = 0;
  436. frame_params.interp_to_end = p_particles->interp_to_end;
  437. frame_params.emitter_velocity[0] = p_particles->emitter_velocity.x;
  438. frame_params.emitter_velocity[1] = p_particles->emitter_velocity.y;
  439. frame_params.emitter_velocity[2] = p_particles->emitter_velocity.z;
  440. { //collision and attractors
  441. frame_params.collider_count = 0;
  442. frame_params.attractor_count = 0;
  443. frame_params.particle_size = p_particles->collision_base_size;
  444. GLuint collision_heightmap_texture = 0;
  445. Transform3D to_particles;
  446. if (p_particles->use_local_coords) {
  447. to_particles = p_particles->emission_transform.affine_inverse();
  448. }
  449. if (p_particles->has_sdf_collision && p_particles->sdf_collision_texture != 0) {
  450. //2D collision
  451. Transform2D xform = p_particles->sdf_collision_transform; //will use dotproduct manually so invert beforehand
  452. if (!p_particles->use_local_coords) {
  453. Transform2D emission;
  454. emission.columns[0] = Vector2(p_particles->emission_transform.basis.get_column(0).x, p_particles->emission_transform.basis.get_column(0).y);
  455. emission.columns[1] = Vector2(p_particles->emission_transform.basis.get_column(1).x, p_particles->emission_transform.basis.get_column(1).y);
  456. emission.set_origin(Vector2(p_particles->emission_transform.origin.x, p_particles->emission_transform.origin.y));
  457. xform = xform * emission.affine_inverse();
  458. }
  459. Transform2D revert = xform.affine_inverse();
  460. frame_params.collider_count = 1;
  461. frame_params.colliders[0].transform[0] = xform.columns[0][0];
  462. frame_params.colliders[0].transform[1] = xform.columns[0][1];
  463. frame_params.colliders[0].transform[2] = 0;
  464. frame_params.colliders[0].transform[3] = xform.columns[2][0];
  465. frame_params.colliders[0].transform[4] = xform.columns[1][0];
  466. frame_params.colliders[0].transform[5] = xform.columns[1][1];
  467. frame_params.colliders[0].transform[6] = 0;
  468. frame_params.colliders[0].transform[7] = xform.columns[2][1];
  469. frame_params.colliders[0].transform[8] = revert.columns[0][0];
  470. frame_params.colliders[0].transform[9] = revert.columns[0][1];
  471. frame_params.colliders[0].transform[10] = 0;
  472. frame_params.colliders[0].transform[11] = revert.columns[2][0];
  473. frame_params.colliders[0].transform[12] = revert.columns[1][0];
  474. frame_params.colliders[0].transform[13] = revert.columns[1][1];
  475. frame_params.colliders[0].transform[14] = 0;
  476. frame_params.colliders[0].transform[15] = revert.columns[2][1];
  477. frame_params.colliders[0].extents[0] = p_particles->sdf_collision_to_screen.size.x;
  478. frame_params.colliders[0].extents[1] = p_particles->sdf_collision_to_screen.size.y;
  479. frame_params.colliders[0].extents[2] = p_particles->sdf_collision_to_screen.position.x;
  480. frame_params.colliders[0].scale = p_particles->sdf_collision_to_screen.position.y;
  481. frame_params.colliders[0].type = ParticlesFrameParams::COLLISION_TYPE_2D_SDF;
  482. collision_heightmap_texture = p_particles->sdf_collision_texture;
  483. }
  484. for (const RID &E : p_particles->collisions) {
  485. ParticlesCollisionInstance *pci = particles_collision_instance_owner.get_or_null(E);
  486. if (!pci || !pci->active) {
  487. continue;
  488. }
  489. ParticlesCollision *pc = particles_collision_owner.get_or_null(pci->collision);
  490. ERR_CONTINUE(!pc);
  491. Transform3D to_collider = pci->transform;
  492. if (p_particles->use_local_coords) {
  493. to_collider = to_particles * to_collider;
  494. }
  495. Vector3 scale = to_collider.basis.get_scale();
  496. to_collider.basis.orthonormalize();
  497. if (pc->type <= RS::PARTICLES_COLLISION_TYPE_VECTOR_FIELD_ATTRACT) {
  498. //attractor
  499. if (frame_params.attractor_count >= ParticlesFrameParams::MAX_ATTRACTORS) {
  500. continue;
  501. }
  502. ParticlesFrameParams::Attractor &attr = frame_params.attractors[frame_params.attractor_count];
  503. GLES3::MaterialStorage::store_transform(to_collider, attr.transform);
  504. attr.strength = pc->attractor_strength;
  505. attr.attenuation = pc->attractor_attenuation;
  506. attr.directionality = pc->attractor_directionality;
  507. switch (pc->type) {
  508. case RS::PARTICLES_COLLISION_TYPE_SPHERE_ATTRACT: {
  509. attr.type = ParticlesFrameParams::ATTRACTOR_TYPE_SPHERE;
  510. float radius = pc->radius;
  511. radius *= (scale.x + scale.y + scale.z) / 3.0;
  512. attr.extents[0] = radius;
  513. attr.extents[1] = radius;
  514. attr.extents[2] = radius;
  515. } break;
  516. case RS::PARTICLES_COLLISION_TYPE_BOX_ATTRACT: {
  517. attr.type = ParticlesFrameParams::ATTRACTOR_TYPE_BOX;
  518. Vector3 extents = pc->extents * scale;
  519. attr.extents[0] = extents.x;
  520. attr.extents[1] = extents.y;
  521. attr.extents[2] = extents.z;
  522. } break;
  523. case RS::PARTICLES_COLLISION_TYPE_VECTOR_FIELD_ATTRACT: {
  524. WARN_PRINT_ONCE_ED("Vector field particle attractors are not available in the Compatibility renderer.");
  525. } break;
  526. default: {
  527. }
  528. }
  529. frame_params.attractor_count++;
  530. } else {
  531. //collider
  532. if (frame_params.collider_count >= ParticlesFrameParams::MAX_COLLIDERS) {
  533. continue;
  534. }
  535. ParticlesFrameParams::Collider &col = frame_params.colliders[frame_params.collider_count];
  536. GLES3::MaterialStorage::store_transform(to_collider, col.transform);
  537. switch (pc->type) {
  538. case RS::PARTICLES_COLLISION_TYPE_SPHERE_COLLIDE: {
  539. col.type = ParticlesFrameParams::COLLISION_TYPE_SPHERE;
  540. float radius = pc->radius;
  541. radius *= (scale.x + scale.y + scale.z) / 3.0;
  542. col.extents[0] = radius;
  543. col.extents[1] = radius;
  544. col.extents[2] = radius;
  545. } break;
  546. case RS::PARTICLES_COLLISION_TYPE_BOX_COLLIDE: {
  547. col.type = ParticlesFrameParams::COLLISION_TYPE_BOX;
  548. Vector3 extents = pc->extents * scale;
  549. col.extents[0] = extents.x;
  550. col.extents[1] = extents.y;
  551. col.extents[2] = extents.z;
  552. } break;
  553. case RS::PARTICLES_COLLISION_TYPE_SDF_COLLIDE: {
  554. WARN_PRINT_ONCE_ED("SDF Particle Colliders are not available in the Compatibility renderer.");
  555. } break;
  556. case RS::PARTICLES_COLLISION_TYPE_HEIGHTFIELD_COLLIDE: {
  557. if (collision_heightmap_texture != 0) { //already taken
  558. continue;
  559. }
  560. col.type = ParticlesFrameParams::COLLISION_TYPE_HEIGHT_FIELD;
  561. Vector3 extents = pc->extents * scale;
  562. col.extents[0] = extents.x;
  563. col.extents[1] = extents.y;
  564. col.extents[2] = extents.z;
  565. collision_heightmap_texture = pc->heightfield_texture;
  566. } break;
  567. default: {
  568. }
  569. }
  570. frame_params.collider_count++;
  571. }
  572. }
  573. // Bind heightmap or SDF texture.
  574. GLuint heightmap = collision_heightmap_texture;
  575. if (heightmap == 0) {
  576. GLES3::Texture *tex = texture_storage->get_texture(texture_storage->texture_gl_get_default(GLES3::DEFAULT_GL_TEXTURE_BLACK));
  577. heightmap = tex->tex_id;
  578. }
  579. glActiveTexture(GL_TEXTURE0);
  580. glBindTexture(GL_TEXTURE_2D, heightmap);
  581. }
  582. if (p_particles->frame_params_ubo == 0) {
  583. glGenBuffers(1, &p_particles->frame_params_ubo);
  584. glBindBufferBase(GL_UNIFORM_BUFFER, PARTICLES_FRAME_UNIFORM_LOCATION, p_particles->frame_params_ubo);
  585. GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_UNIFORM_BUFFER, p_particles->frame_params_ubo, sizeof(ParticlesFrameParams), &frame_params, GL_STREAM_DRAW, "Particle Frame UBO");
  586. } else {
  587. // Update per-frame UBO.
  588. glBindBufferBase(GL_UNIFORM_BUFFER, PARTICLES_FRAME_UNIFORM_LOCATION, p_particles->frame_params_ubo);
  589. glBufferData(GL_UNIFORM_BUFFER, sizeof(ParticlesFrameParams), &frame_params, GL_STREAM_DRAW);
  590. }
  591. // Get shader and set shader uniforms;
  592. ParticleProcessMaterialData *m = static_cast<ParticleProcessMaterialData *>(material_storage->material_get_data(p_particles->process_material, RS::SHADER_PARTICLES));
  593. if (!m) {
  594. m = static_cast<ParticleProcessMaterialData *>(material_storage->material_get_data(particles_shader.default_material, RS::SHADER_PARTICLES));
  595. }
  596. ERR_FAIL_NULL(m);
  597. ParticlesShaderGLES3::ShaderVariant variant = ParticlesShaderGLES3::MODE_DEFAULT;
  598. uint32_t specialization = 0;
  599. for (uint32_t i = 0; i < PARTICLES_MAX_USERDATAS; i++) {
  600. if (m->shader_data->userdatas_used[i]) {
  601. specialization |= ParticlesShaderGLES3::USERDATA1_USED << i;
  602. }
  603. }
  604. if (p_particles->mode == RS::ParticlesMode::PARTICLES_MODE_3D) {
  605. specialization |= ParticlesShaderGLES3::MODE_3D;
  606. }
  607. RID version = particles_shader.default_shader_version;
  608. if (m->shader_data->version.is_valid() && m->shader_data->valid) {
  609. // Bind material uniform buffer and textures.
  610. m->bind_uniforms();
  611. version = m->shader_data->version;
  612. }
  613. bool success = material_storage->shaders.particles_process_shader.version_bind_shader(version, variant, specialization);
  614. if (!success) {
  615. return;
  616. }
  617. material_storage->shaders.particles_process_shader.version_set_uniform(ParticlesShaderGLES3::LIFETIME, p_particles->lifetime, version, variant, specialization);
  618. material_storage->shaders.particles_process_shader.version_set_uniform(ParticlesShaderGLES3::CLEAR, p_particles->clear, version, variant, specialization);
  619. material_storage->shaders.particles_process_shader.version_set_uniform(ParticlesShaderGLES3::TOTAL_PARTICLES, uint32_t(p_particles->amount), version, variant, specialization);
  620. material_storage->shaders.particles_process_shader.version_set_uniform(ParticlesShaderGLES3::USE_FRACTIONAL_DELTA, p_particles->fractional_delta, version, variant, specialization);
  621. p_particles->clear = false;
  622. p_particles->has_collision_cache = m->shader_data->uses_collision;
  623. glBindVertexArray(p_particles->back_vertex_array);
  624. glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, p_particles->front_process_buffer);
  625. glBeginTransformFeedback(GL_POINTS);
  626. glDrawArrays(GL_POINTS, 0, p_particles->amount);
  627. glEndTransformFeedback();
  628. glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, 0);
  629. glBindVertexArray(0);
  630. SWAP(p_particles->front_process_buffer, p_particles->back_process_buffer);
  631. SWAP(p_particles->front_vertex_array, p_particles->back_vertex_array);
  632. }
  633. void ParticlesStorage::particles_set_view_axis(RID p_particles, const Vector3 &p_axis, const Vector3 &p_up_axis) {
  634. Particles *particles = particles_owner.get_or_null(p_particles);
  635. ERR_FAIL_NULL(particles);
  636. if (particles->draw_order != RS::PARTICLES_DRAW_ORDER_VIEW_DEPTH && particles->transform_align != RS::PARTICLES_TRANSFORM_ALIGN_Z_BILLBOARD && particles->transform_align != RS::PARTICLES_TRANSFORM_ALIGN_Z_BILLBOARD_Y_TO_VELOCITY) {
  637. return;
  638. }
  639. if (particles->front_process_buffer == 0) {
  640. return; //particles have not processed yet
  641. }
  642. Vector3 axis = -p_axis; // cameras look to z negative
  643. if (particles->use_local_coords) {
  644. axis = particles->emission_transform.basis.xform_inv(axis).normalized();
  645. }
  646. // Sort will be done on CPU since we don't have compute shaders.
  647. // If the sort_buffer has valid data
  648. // Use a buffer that is 2 frames out of date to avoid stalls.
  649. if (particles->draw_order == RS::PARTICLES_DRAW_ORDER_VIEW_DEPTH && particles->sort_buffer_filled) {
  650. glBindBuffer(GL_ARRAY_BUFFER, particles->sort_buffer);
  651. ParticleInstanceData3D *particle_array;
  652. #ifndef __EMSCRIPTEN__
  653. particle_array = static_cast<ParticleInstanceData3D *>(glMapBufferRange(GL_ARRAY_BUFFER, 0, particles->amount * sizeof(ParticleInstanceData3D), GL_MAP_READ_BIT | GL_MAP_WRITE_BIT));
  654. ERR_FAIL_NULL(particle_array);
  655. #else
  656. LocalVector<ParticleInstanceData3D> particle_vector;
  657. particle_vector.resize(particles->amount);
  658. particle_array = particle_vector.ptr();
  659. godot_webgl2_glGetBufferSubData(GL_ARRAY_BUFFER, 0, particles->amount * sizeof(ParticleInstanceData3D), particle_array);
  660. #endif
  661. SortArray<ParticleInstanceData3D, ParticlesViewSort> sorter;
  662. sorter.compare.z_dir = axis;
  663. sorter.sort(particle_array, particles->amount);
  664. #ifndef __EMSCRIPTEN__
  665. glUnmapBuffer(GL_ARRAY_BUFFER);
  666. #else
  667. glBufferSubData(GL_ARRAY_BUFFER, 0, particles->amount * sizeof(ParticleInstanceData3D), particle_vector.ptr());
  668. #endif
  669. }
  670. glEnable(GL_RASTERIZER_DISCARD);
  671. glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);
  672. _particles_update_instance_buffer(particles, axis, p_up_axis);
  673. glDisable(GL_RASTERIZER_DISCARD);
  674. }
  675. void ParticlesStorage::_particles_update_buffers(Particles *particles) {
  676. GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton();
  677. uint32_t userdata_count = 0;
  678. if (particles->process_material.is_valid()) {
  679. GLES3::ParticleProcessMaterialData *material_data = static_cast<GLES3::ParticleProcessMaterialData *>(material_storage->material_get_data(particles->process_material, RS::SHADER_PARTICLES));
  680. if (material_data && material_data->shader_data->version.is_valid() && material_data->shader_data->valid) {
  681. userdata_count = material_data->shader_data->userdata_count;
  682. }
  683. }
  684. if (userdata_count != particles->userdata_count) {
  685. // Mismatch userdata, re-create buffers.
  686. _particles_free_data(particles);
  687. }
  688. if (particles->amount > 0 && particles->front_process_buffer == 0) {
  689. int total_amount = particles->amount;
  690. particles->userdata_count = userdata_count;
  691. uint32_t xform_size = particles->mode == RS::PARTICLES_MODE_2D ? 2 : 3;
  692. particles->instance_buffer_stride_cache = sizeof(float) * 4 * (xform_size + 1);
  693. particles->instance_buffer_size_cache = particles->instance_buffer_stride_cache * total_amount;
  694. particles->num_attrib_arrays_cache = 5 + userdata_count + (xform_size - 2);
  695. particles->process_buffer_stride_cache = sizeof(float) * 4 * particles->num_attrib_arrays_cache;
  696. PackedByteArray data;
  697. data.resize_initialized(particles->process_buffer_stride_cache * total_amount);
  698. PackedByteArray instance_data;
  699. instance_data.resize_initialized(particles->instance_buffer_size_cache);
  700. {
  701. glGenVertexArrays(1, &particles->front_vertex_array);
  702. glBindVertexArray(particles->front_vertex_array);
  703. glGenBuffers(1, &particles->front_process_buffer);
  704. glGenBuffers(1, &particles->front_instance_buffer);
  705. glBindBuffer(GL_ARRAY_BUFFER, particles->front_process_buffer);
  706. GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, particles->front_process_buffer, particles->process_buffer_stride_cache * total_amount, data.ptr(), GL_DYNAMIC_COPY, "Particles front process buffer");
  707. for (uint32_t j = 0; j < particles->num_attrib_arrays_cache; j++) {
  708. glEnableVertexAttribArray(j);
  709. glVertexAttribPointer(j, 4, GL_FLOAT, GL_FALSE, particles->process_buffer_stride_cache, CAST_INT_TO_UCHAR_PTR(sizeof(float) * 4 * j));
  710. }
  711. glBindVertexArray(0);
  712. glBindBuffer(GL_ARRAY_BUFFER, particles->front_instance_buffer);
  713. GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, particles->front_instance_buffer, particles->instance_buffer_size_cache, instance_data.ptr(), GL_DYNAMIC_COPY, "Particles front instance buffer");
  714. }
  715. {
  716. glGenVertexArrays(1, &particles->back_vertex_array);
  717. glBindVertexArray(particles->back_vertex_array);
  718. glGenBuffers(1, &particles->back_process_buffer);
  719. glGenBuffers(1, &particles->back_instance_buffer);
  720. glBindBuffer(GL_ARRAY_BUFFER, particles->back_process_buffer);
  721. GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, particles->back_process_buffer, particles->process_buffer_stride_cache * total_amount, data.ptr(), GL_DYNAMIC_COPY, "Particles back process buffer");
  722. for (uint32_t j = 0; j < particles->num_attrib_arrays_cache; j++) {
  723. glEnableVertexAttribArray(j);
  724. glVertexAttribPointer(j, 4, GL_FLOAT, GL_FALSE, particles->process_buffer_stride_cache, CAST_INT_TO_UCHAR_PTR(sizeof(float) * 4 * j));
  725. }
  726. glBindVertexArray(0);
  727. glBindBuffer(GL_ARRAY_BUFFER, particles->back_instance_buffer);
  728. GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, particles->back_instance_buffer, particles->instance_buffer_size_cache, instance_data.ptr(), GL_DYNAMIC_COPY, "Particles back instance buffer");
  729. }
  730. glBindBuffer(GL_ARRAY_BUFFER, 0);
  731. }
  732. }
  733. void ParticlesStorage::_particles_allocate_history_buffers(Particles *particles) {
  734. if (particles->sort_buffer == 0) {
  735. glGenBuffers(1, &particles->last_frame_buffer);
  736. glBindBuffer(GL_ARRAY_BUFFER, particles->last_frame_buffer);
  737. GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, particles->last_frame_buffer, particles->instance_buffer_size_cache, nullptr, GL_DYNAMIC_READ, "Particles last frame buffer");
  738. glGenBuffers(1, &particles->sort_buffer);
  739. glBindBuffer(GL_ARRAY_BUFFER, particles->sort_buffer);
  740. GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, particles->sort_buffer, particles->instance_buffer_size_cache, nullptr, GL_DYNAMIC_READ, "Particles sort buffer");
  741. particles->sort_buffer_filled = false;
  742. particles->last_frame_buffer_filled = false;
  743. glBindBuffer(GL_ARRAY_BUFFER, 0);
  744. }
  745. }
  746. void ParticlesStorage::_particles_update_instance_buffer(Particles *particles, const Vector3 &p_axis, const Vector3 &p_up_axis) {
  747. ParticlesCopyShaderGLES3::ShaderVariant variant = ParticlesCopyShaderGLES3::MODE_DEFAULT;
  748. uint64_t specialization = 0;
  749. if (particles->mode == RS::ParticlesMode::PARTICLES_MODE_3D) {
  750. specialization |= ParticlesCopyShaderGLES3::MODE_3D;
  751. }
  752. bool success = particles_shader.copy_shader.version_bind_shader(particles_shader.copy_shader_version, variant, specialization);
  753. if (!success) {
  754. return;
  755. }
  756. // Affect 2D only.
  757. if (particles->use_local_coords) {
  758. // In local mode, particle positions are calculated locally (relative to the node position)
  759. // and they're also drawn locally.
  760. // It works as expected, so we just pass an identity transform.
  761. particles_shader.copy_shader.version_set_uniform(ParticlesCopyShaderGLES3::INV_EMISSION_TRANSFORM, Transform3D(), particles_shader.copy_shader_version, variant, specialization);
  762. } else {
  763. // In global mode, particle positions are calculated globally (relative to the canvas origin)
  764. // but they're drawn locally.
  765. // So, we need to pass the inverse of the emission transform to bring the
  766. // particles to local coordinates before drawing.
  767. Transform3D inv = particles->emission_transform.affine_inverse();
  768. particles_shader.copy_shader.version_set_uniform(ParticlesCopyShaderGLES3::INV_EMISSION_TRANSFORM, inv, particles_shader.copy_shader_version, variant, specialization);
  769. }
  770. particles_shader.copy_shader.version_set_uniform(ParticlesCopyShaderGLES3::FRAME_REMAINDER, particles->interpolate ? particles->frame_remainder : 0.0, particles_shader.copy_shader_version, variant, specialization);
  771. particles_shader.copy_shader.version_set_uniform(ParticlesCopyShaderGLES3::ALIGN_MODE, uint32_t(particles->transform_align), particles_shader.copy_shader_version, variant, specialization);
  772. particles_shader.copy_shader.version_set_uniform(ParticlesCopyShaderGLES3::ALIGN_UP, p_up_axis, particles_shader.copy_shader_version, variant, specialization);
  773. particles_shader.copy_shader.version_set_uniform(ParticlesCopyShaderGLES3::SORT_DIRECTION, p_axis, particles_shader.copy_shader_version, variant, specialization);
  774. glBindVertexArray(particles->back_vertex_array);
  775. glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, particles->front_instance_buffer, 0, particles->instance_buffer_size_cache);
  776. glBeginTransformFeedback(GL_POINTS);
  777. if (particles->draw_order == RS::PARTICLES_DRAW_ORDER_LIFETIME) {
  778. uint32_t lifetime_split = (MIN(int(particles->amount * particles->phase), particles->amount - 1) + 1) % particles->amount;
  779. uint32_t stride = particles->process_buffer_stride_cache;
  780. glBindBuffer(GL_ARRAY_BUFFER, particles->back_process_buffer);
  781. // Offset VBO so you render starting at the newest particle.
  782. if (particles->amount - lifetime_split > 0) {
  783. glEnableVertexAttribArray(0); // Color.
  784. glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, stride, CAST_INT_TO_UCHAR_PTR(stride * lifetime_split + sizeof(float) * 4 * 0));
  785. glEnableVertexAttribArray(1); // .xyz: velocity. .z: flags.
  786. glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, stride, CAST_INT_TO_UCHAR_PTR(stride * lifetime_split + sizeof(float) * 4 * 1));
  787. glEnableVertexAttribArray(2); // Custom.
  788. glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, stride, CAST_INT_TO_UCHAR_PTR(stride * lifetime_split + sizeof(float) * 4 * 2));
  789. glEnableVertexAttribArray(3); // Xform1.
  790. glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, stride, CAST_INT_TO_UCHAR_PTR(stride * lifetime_split + sizeof(float) * 4 * 3));
  791. glEnableVertexAttribArray(4); // Xform2.
  792. glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, stride, CAST_INT_TO_UCHAR_PTR(stride * lifetime_split + sizeof(float) * 4 * 4));
  793. if (particles->mode == RS::PARTICLES_MODE_3D) {
  794. glEnableVertexAttribArray(5); // Xform3.
  795. glVertexAttribPointer(5, 4, GL_FLOAT, GL_FALSE, stride, CAST_INT_TO_UCHAR_PTR(stride * lifetime_split + sizeof(float) * 4 * 5));
  796. }
  797. uint32_t to_draw = particles->amount - lifetime_split;
  798. glDrawArrays(GL_POINTS, 0, to_draw);
  799. }
  800. // Then render from index 0 up intil the newest particle.
  801. if (lifetime_split > 0) {
  802. glEndTransformFeedback();
  803. // Now output to the second portion of the instance buffer.
  804. glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, particles->front_instance_buffer, particles->instance_buffer_stride_cache * (particles->amount - lifetime_split), particles->instance_buffer_stride_cache * (lifetime_split));
  805. glBeginTransformFeedback(GL_POINTS);
  806. // Reset back to normal.
  807. for (uint32_t j = 0; j < particles->num_attrib_arrays_cache; j++) {
  808. glEnableVertexAttribArray(j);
  809. glVertexAttribPointer(j, 4, GL_FLOAT, GL_FALSE, stride, CAST_INT_TO_UCHAR_PTR(sizeof(float) * 4 * j));
  810. }
  811. glDrawArrays(GL_POINTS, 0, lifetime_split);
  812. }
  813. } else {
  814. glDrawArrays(GL_POINTS, 0, particles->amount);
  815. }
  816. glEndTransformFeedback();
  817. glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, 0, 0, 0);
  818. glBindVertexArray(0);
  819. glBindBuffer(GL_ARRAY_BUFFER, 0);
  820. }
  821. void ParticlesStorage::update_particles() {
  822. if (!particle_update_list.first()) {
  823. // Return early to avoid unnecessary state changes.
  824. return;
  825. }
  826. RENDER_TIMESTAMP("Update GPUParticles");
  827. glEnable(GL_RASTERIZER_DISCARD);
  828. glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);
  829. GLuint global_buffer = GLES3::MaterialStorage::get_singleton()->global_shader_parameters_get_uniform_buffer();
  830. glBindBufferBase(GL_UNIFORM_BUFFER, PARTICLES_GLOBALS_UNIFORM_LOCATION, global_buffer);
  831. glBindBuffer(GL_UNIFORM_BUFFER, 0);
  832. while (particle_update_list.first()) {
  833. // Use transform feedback to process particles.
  834. Particles *particles = particle_update_list.first()->self();
  835. particles->update_list.remove_from_list();
  836. particles->dirty = false;
  837. _particles_update_buffers(particles);
  838. if (particles->restart_request) {
  839. particles->prev_ticks = 0;
  840. particles->phase = 0;
  841. particles->prev_phase = 0;
  842. particles->clear = true;
  843. particles->restart_request = false;
  844. }
  845. if (particles->inactive && !particles->emitting) {
  846. //go next
  847. continue;
  848. }
  849. if (particles->emitting) {
  850. if (particles->inactive) {
  851. //restart system from scratch
  852. particles->prev_ticks = 0;
  853. particles->phase = 0;
  854. particles->prev_phase = 0;
  855. particles->clear = true;
  856. }
  857. particles->inactive = false;
  858. particles->inactive_time = 0;
  859. } else {
  860. particles->inactive_time += particles->speed_scale * RSG::rasterizer->get_frame_delta_time();
  861. if (particles->inactive_time > particles->lifetime * 1.2) {
  862. particles->inactive = true;
  863. continue;
  864. }
  865. }
  866. // Copy the instance buffer that was last used into the last_frame buffer.
  867. // sort_buffer should now be 2 frames out of date.
  868. if (particles->draw_order == RS::PARTICLES_DRAW_ORDER_VIEW_DEPTH || particles->draw_order == RS::PARTICLES_DRAW_ORDER_REVERSE_LIFETIME) {
  869. _particles_allocate_history_buffers(particles);
  870. SWAP(particles->last_frame_buffer, particles->sort_buffer);
  871. glBindBuffer(GL_COPY_READ_BUFFER, particles->back_instance_buffer);
  872. glBindBuffer(GL_COPY_WRITE_BUFFER, particles->last_frame_buffer);
  873. glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, 0, 0, particles->instance_buffer_size_cache);
  874. // Last frame's last_frame turned into this frame's sort buffer.
  875. particles->sort_buffer_filled = particles->last_frame_buffer_filled;
  876. particles->sort_buffer_phase = particles->last_frame_phase;
  877. particles->last_frame_buffer_filled = true;
  878. particles->last_frame_phase = particles->phase;
  879. glBindBuffer(GL_COPY_READ_BUFFER, 0);
  880. glBindBuffer(GL_COPY_WRITE_BUFFER, 0);
  881. }
  882. int fixed_fps = 0;
  883. if (particles->fixed_fps > 0) {
  884. fixed_fps = particles->fixed_fps;
  885. }
  886. if (particles->clear && particles->pre_process_time > 0.0) {
  887. double frame_time;
  888. if (fixed_fps > 0) {
  889. frame_time = 1.0 / fixed_fps;
  890. } else {
  891. frame_time = 1.0 / 30.0;
  892. }
  893. double todo = particles->pre_process_time;
  894. while (todo >= 0) {
  895. _particles_process(particles, frame_time);
  896. todo -= frame_time;
  897. }
  898. }
  899. double time_scale = MAX(particles->speed_scale, 0.0);
  900. if (fixed_fps > 0) {
  901. double frame_time = 1.0 / fixed_fps;
  902. double delta = RSG::rasterizer->get_frame_delta_time();
  903. if (delta > 0.1) { //avoid recursive stalls if fps goes below 10
  904. delta = 0.1;
  905. } else if (delta <= 0.0) { //unlikely but..
  906. delta = 0.001;
  907. }
  908. double todo = particles->frame_remainder + delta * time_scale;
  909. while (todo >= frame_time) {
  910. _particles_process(particles, frame_time);
  911. todo -= frame_time;
  912. }
  913. particles->frame_remainder = todo;
  914. } else {
  915. _particles_process(particles, RSG::rasterizer->get_frame_delta_time() * time_scale);
  916. }
  917. if (particles->request_process_time > 0.0) {
  918. double frame_time;
  919. if (fixed_fps > 0) {
  920. frame_time = 1.0 / fixed_fps;
  921. } else {
  922. frame_time = 1.0 / 30.0;
  923. }
  924. float tmp_scale = particles->speed_scale;
  925. particles->speed_scale = 1.0;
  926. double todo = particles->request_process_time;
  927. while (todo >= 0) {
  928. _particles_process(particles, frame_time);
  929. todo -= frame_time;
  930. }
  931. particles->speed_scale = tmp_scale;
  932. particles->request_process_time = 0.0;
  933. }
  934. // Copy particles to instance buffer and pack Color/Custom.
  935. // We don't have camera information here, so don't copy here if we need camera information for view depth or align mode.
  936. if (particles->draw_order != RS::PARTICLES_DRAW_ORDER_VIEW_DEPTH && particles->transform_align != RS::PARTICLES_TRANSFORM_ALIGN_Z_BILLBOARD && particles->transform_align != RS::PARTICLES_TRANSFORM_ALIGN_Z_BILLBOARD_Y_TO_VELOCITY) {
  937. _particles_update_instance_buffer(particles, Vector3(0.0, 0.0, 0.0), Vector3(0.0, 0.0, 0.0));
  938. if (particles->draw_order == RS::PARTICLES_DRAW_ORDER_REVERSE_LIFETIME && particles->sort_buffer_filled) {
  939. if (particles->mode == RS::ParticlesMode::PARTICLES_MODE_2D) {
  940. _particles_reverse_lifetime_sort<ParticleInstanceData2D>(particles);
  941. } else {
  942. _particles_reverse_lifetime_sort<ParticleInstanceData3D>(particles);
  943. }
  944. }
  945. }
  946. SWAP(particles->front_instance_buffer, particles->back_instance_buffer);
  947. // At the end of update, the back_buffer contains the most up-to-date-information to read from.
  948. particles->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);
  949. }
  950. glDisable(GL_RASTERIZER_DISCARD);
  951. }
  952. template <typename ParticleInstanceData>
  953. void ParticlesStorage::_particles_reverse_lifetime_sort(Particles *particles) {
  954. glBindBuffer(GL_ARRAY_BUFFER, particles->sort_buffer);
  955. ParticleInstanceData *particle_array;
  956. uint32_t buffer_size = particles->amount * sizeof(ParticleInstanceData);
  957. #ifndef __EMSCRIPTEN__
  958. particle_array = static_cast<ParticleInstanceData *>(glMapBufferRange(GL_ARRAY_BUFFER, 0, buffer_size, GL_MAP_READ_BIT | GL_MAP_WRITE_BIT));
  959. ERR_FAIL_NULL(particle_array);
  960. #else
  961. LocalVector<ParticleInstanceData> particle_vector;
  962. particle_vector.resize(particles->amount);
  963. particle_array = particle_vector.ptr();
  964. godot_webgl2_glGetBufferSubData(GL_ARRAY_BUFFER, 0, buffer_size, particle_array);
  965. #endif
  966. uint32_t lifetime_split = (MIN(int(particles->amount * particles->sort_buffer_phase), particles->amount - 1) + 1) % particles->amount;
  967. for (uint32_t i = 0; i < lifetime_split / 2; i++) {
  968. SWAP(particle_array[i], particle_array[lifetime_split - i - 1]);
  969. }
  970. for (uint32_t i = 0; i < (particles->amount - lifetime_split) / 2; i++) {
  971. SWAP(particle_array[lifetime_split + i], particle_array[particles->amount - 1 - i]);
  972. }
  973. #ifndef __EMSCRIPTEN__
  974. glUnmapBuffer(GL_ARRAY_BUFFER);
  975. #else
  976. glBufferSubData(GL_ARRAY_BUFFER, 0, buffer_size, particle_vector.ptr());
  977. #endif
  978. glBindBuffer(GL_ARRAY_BUFFER, 0);
  979. }
  980. Dependency *ParticlesStorage::particles_get_dependency(RID p_particles) const {
  981. Particles *particles = particles_owner.get_or_null(p_particles);
  982. ERR_FAIL_NULL_V(particles, nullptr);
  983. return &particles->dependency;
  984. }
  985. bool ParticlesStorage::particles_is_inactive(RID p_particles) const {
  986. const Particles *particles = particles_owner.get_or_null(p_particles);
  987. ERR_FAIL_NULL_V(particles, false);
  988. return !particles->emitting && particles->inactive;
  989. }
  990. /* PARTICLES COLLISION API */
  991. RID ParticlesStorage::particles_collision_allocate() {
  992. return particles_collision_owner.allocate_rid();
  993. }
  994. void ParticlesStorage::particles_collision_initialize(RID p_rid) {
  995. particles_collision_owner.initialize_rid(p_rid, ParticlesCollision());
  996. }
  997. void ParticlesStorage::particles_collision_free(RID p_rid) {
  998. ParticlesCollision *particles_collision = particles_collision_owner.get_or_null(p_rid);
  999. if (particles_collision->heightfield_texture != 0) {
  1000. GLES3::Utilities::get_singleton()->texture_free_data(particles_collision->heightfield_texture);
  1001. particles_collision->heightfield_texture = 0;
  1002. glDeleteFramebuffers(1, &particles_collision->heightfield_fb);
  1003. particles_collision->heightfield_fb = 0;
  1004. }
  1005. particles_collision->dependency.deleted_notify(p_rid);
  1006. particles_collision_owner.free(p_rid);
  1007. }
  1008. GLuint ParticlesStorage::particles_collision_get_heightfield_framebuffer(RID p_particles_collision) const {
  1009. ParticlesCollision *particles_collision = particles_collision_owner.get_or_null(p_particles_collision);
  1010. ERR_FAIL_NULL_V(particles_collision, 0);
  1011. ERR_FAIL_COND_V(particles_collision->type != RS::PARTICLES_COLLISION_TYPE_HEIGHTFIELD_COLLIDE, 0);
  1012. if (particles_collision->heightfield_texture == 0) {
  1013. //create
  1014. const int resolutions[RS::PARTICLES_COLLISION_HEIGHTFIELD_RESOLUTION_MAX] = { 256, 512, 1024, 2048, 4096, 8192 };
  1015. Size2i size;
  1016. if (particles_collision->extents.x > particles_collision->extents.z) {
  1017. size.x = resolutions[particles_collision->heightfield_resolution];
  1018. size.y = int32_t(particles_collision->extents.z / particles_collision->extents.x * size.x);
  1019. } else {
  1020. size.y = resolutions[particles_collision->heightfield_resolution];
  1021. size.x = int32_t(particles_collision->extents.x / particles_collision->extents.z * size.y);
  1022. }
  1023. glGenTextures(1, &particles_collision->heightfield_texture);
  1024. glActiveTexture(GL_TEXTURE0);
  1025. glBindTexture(GL_TEXTURE_2D, particles_collision->heightfield_texture);
  1026. glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, size.x, size.y, 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr);
  1027. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  1028. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  1029. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
  1030. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
  1031. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  1032. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  1033. glGenFramebuffers(1, &particles_collision->heightfield_fb);
  1034. glBindFramebuffer(GL_FRAMEBUFFER, particles_collision->heightfield_fb);
  1035. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, particles_collision->heightfield_texture, 0);
  1036. #ifdef DEBUG_ENABLED
  1037. GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
  1038. if (status != GL_FRAMEBUFFER_COMPLETE) {
  1039. WARN_PRINT("Could create heightmap texture status: " + GLES3::TextureStorage::get_singleton()->get_framebuffer_error(status));
  1040. }
  1041. #endif
  1042. GLES3::Utilities::get_singleton()->texture_allocated_data(particles_collision->heightfield_texture, size.x * size.y * 4, "Particles collision heightfield texture");
  1043. particles_collision->heightfield_fb_size = size;
  1044. glBindTexture(GL_TEXTURE_2D, 0);
  1045. glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);
  1046. }
  1047. return particles_collision->heightfield_fb;
  1048. }
  1049. void ParticlesStorage::particles_collision_set_collision_type(RID p_particles_collision, RS::ParticlesCollisionType p_type) {
  1050. ParticlesCollision *particles_collision = particles_collision_owner.get_or_null(p_particles_collision);
  1051. ERR_FAIL_NULL(particles_collision);
  1052. if (p_type == particles_collision->type) {
  1053. return;
  1054. }
  1055. if (particles_collision->heightfield_texture != 0) {
  1056. GLES3::Utilities::get_singleton()->texture_free_data(particles_collision->heightfield_texture);
  1057. particles_collision->heightfield_texture = 0;
  1058. glDeleteFramebuffers(1, &particles_collision->heightfield_fb);
  1059. particles_collision->heightfield_fb = 0;
  1060. }
  1061. particles_collision->type = p_type;
  1062. particles_collision->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);
  1063. }
  1064. void ParticlesStorage::particles_collision_set_cull_mask(RID p_particles_collision, uint32_t p_cull_mask) {
  1065. ParticlesCollision *particles_collision = particles_collision_owner.get_or_null(p_particles_collision);
  1066. ERR_FAIL_NULL(particles_collision);
  1067. particles_collision->cull_mask = p_cull_mask;
  1068. particles_collision->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_CULL_MASK);
  1069. }
  1070. uint32_t ParticlesStorage::particles_collision_get_cull_mask(RID p_particles_collision) const {
  1071. ParticlesCollision *particles_collision = particles_collision_owner.get_or_null(p_particles_collision);
  1072. ERR_FAIL_NULL_V(particles_collision, 0);
  1073. return particles_collision->cull_mask;
  1074. }
  1075. void ParticlesStorage::particles_collision_set_sphere_radius(RID p_particles_collision, real_t p_radius) {
  1076. ParticlesCollision *particles_collision = particles_collision_owner.get_or_null(p_particles_collision);
  1077. ERR_FAIL_NULL(particles_collision);
  1078. particles_collision->radius = p_radius;
  1079. particles_collision->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);
  1080. }
  1081. void ParticlesStorage::particles_collision_set_box_extents(RID p_particles_collision, const Vector3 &p_extents) {
  1082. ParticlesCollision *particles_collision = particles_collision_owner.get_or_null(p_particles_collision);
  1083. ERR_FAIL_NULL(particles_collision);
  1084. particles_collision->extents = p_extents;
  1085. particles_collision->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);
  1086. }
  1087. void ParticlesStorage::particles_collision_set_attractor_strength(RID p_particles_collision, real_t p_strength) {
  1088. ParticlesCollision *particles_collision = particles_collision_owner.get_or_null(p_particles_collision);
  1089. ERR_FAIL_NULL(particles_collision);
  1090. particles_collision->attractor_strength = p_strength;
  1091. }
  1092. void ParticlesStorage::particles_collision_set_attractor_directionality(RID p_particles_collision, real_t p_directionality) {
  1093. ParticlesCollision *particles_collision = particles_collision_owner.get_or_null(p_particles_collision);
  1094. ERR_FAIL_NULL(particles_collision);
  1095. particles_collision->attractor_directionality = p_directionality;
  1096. }
  1097. void ParticlesStorage::particles_collision_set_attractor_attenuation(RID p_particles_collision, real_t p_curve) {
  1098. ParticlesCollision *particles_collision = particles_collision_owner.get_or_null(p_particles_collision);
  1099. ERR_FAIL_NULL(particles_collision);
  1100. particles_collision->attractor_attenuation = p_curve;
  1101. }
  1102. void ParticlesStorage::particles_collision_set_field_texture(RID p_particles_collision, RID p_texture) {
  1103. WARN_PRINT_ONCE_ED("The Compatibility renderer does not support SDF collisions in 3D particle shaders");
  1104. }
  1105. void ParticlesStorage::particles_collision_height_field_update(RID p_particles_collision) {
  1106. ParticlesCollision *particles_collision = particles_collision_owner.get_or_null(p_particles_collision);
  1107. ERR_FAIL_NULL(particles_collision);
  1108. particles_collision->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);
  1109. }
  1110. void ParticlesStorage::particles_collision_set_height_field_resolution(RID p_particles_collision, RS::ParticlesCollisionHeightfieldResolution p_resolution) {
  1111. ParticlesCollision *particles_collision = particles_collision_owner.get_or_null(p_particles_collision);
  1112. ERR_FAIL_NULL(particles_collision);
  1113. ERR_FAIL_INDEX(p_resolution, RS::PARTICLES_COLLISION_HEIGHTFIELD_RESOLUTION_MAX);
  1114. if (particles_collision->heightfield_resolution == p_resolution) {
  1115. return;
  1116. }
  1117. particles_collision->heightfield_resolution = p_resolution;
  1118. if (particles_collision->heightfield_texture != 0) {
  1119. GLES3::Utilities::get_singleton()->texture_free_data(particles_collision->heightfield_texture);
  1120. particles_collision->heightfield_texture = 0;
  1121. glDeleteFramebuffers(1, &particles_collision->heightfield_fb);
  1122. particles_collision->heightfield_fb = 0;
  1123. }
  1124. }
  1125. AABB ParticlesStorage::particles_collision_get_aabb(RID p_particles_collision) const {
  1126. ParticlesCollision *particles_collision = particles_collision_owner.get_or_null(p_particles_collision);
  1127. ERR_FAIL_NULL_V(particles_collision, AABB());
  1128. switch (particles_collision->type) {
  1129. case RS::PARTICLES_COLLISION_TYPE_SPHERE_ATTRACT:
  1130. case RS::PARTICLES_COLLISION_TYPE_SPHERE_COLLIDE: {
  1131. AABB aabb;
  1132. aabb.position = -Vector3(1, 1, 1) * particles_collision->radius;
  1133. aabb.size = Vector3(2, 2, 2) * particles_collision->radius;
  1134. return aabb;
  1135. }
  1136. default: {
  1137. AABB aabb;
  1138. aabb.position = -particles_collision->extents;
  1139. aabb.size = particles_collision->extents * 2;
  1140. return aabb;
  1141. }
  1142. }
  1143. }
  1144. Vector3 ParticlesStorage::particles_collision_get_extents(RID p_particles_collision) const {
  1145. const ParticlesCollision *particles_collision = particles_collision_owner.get_or_null(p_particles_collision);
  1146. ERR_FAIL_NULL_V(particles_collision, Vector3());
  1147. return particles_collision->extents;
  1148. }
  1149. bool ParticlesStorage::particles_collision_is_heightfield(RID p_particles_collision) const {
  1150. const ParticlesCollision *particles_collision = particles_collision_owner.get_or_null(p_particles_collision);
  1151. ERR_FAIL_NULL_V(particles_collision, false);
  1152. return particles_collision->type == RS::PARTICLES_COLLISION_TYPE_HEIGHTFIELD_COLLIDE;
  1153. }
  1154. uint32_t ParticlesStorage::particles_collision_get_height_field_mask(RID p_particles_collision) const {
  1155. const ParticlesCollision *particles_collision = particles_collision_owner.get_or_null(p_particles_collision);
  1156. ERR_FAIL_NULL_V(particles_collision, false);
  1157. return particles_collision->heightfield_mask;
  1158. }
  1159. void ParticlesStorage::particles_collision_set_height_field_mask(RID p_particles_collision, uint32_t p_heightfield_mask) {
  1160. ParticlesCollision *particles_collision = particles_collision_owner.get_or_null(p_particles_collision);
  1161. ERR_FAIL_NULL(particles_collision);
  1162. particles_collision->heightfield_mask = p_heightfield_mask;
  1163. }
  1164. Dependency *ParticlesStorage::particles_collision_get_dependency(RID p_particles_collision) const {
  1165. ParticlesCollision *pc = particles_collision_owner.get_or_null(p_particles_collision);
  1166. ERR_FAIL_NULL_V(pc, nullptr);
  1167. return &pc->dependency;
  1168. }
  1169. /* Particles collision instance */
  1170. RID ParticlesStorage::particles_collision_instance_create(RID p_collision) {
  1171. ParticlesCollisionInstance pci;
  1172. pci.collision = p_collision;
  1173. return particles_collision_instance_owner.make_rid(pci);
  1174. }
  1175. void ParticlesStorage::particles_collision_instance_free(RID p_rid) {
  1176. particles_collision_instance_owner.free(p_rid);
  1177. }
  1178. void ParticlesStorage::particles_collision_instance_set_transform(RID p_collision_instance, const Transform3D &p_transform) {
  1179. ParticlesCollisionInstance *pci = particles_collision_instance_owner.get_or_null(p_collision_instance);
  1180. ERR_FAIL_NULL(pci);
  1181. pci->transform = p_transform;
  1182. }
  1183. void ParticlesStorage::particles_collision_instance_set_active(RID p_collision_instance, bool p_active) {
  1184. ParticlesCollisionInstance *pci = particles_collision_instance_owner.get_or_null(p_collision_instance);
  1185. ERR_FAIL_NULL(pci);
  1186. pci->active = p_active;
  1187. }
  1188. #endif // GLES3_ENABLED