1 | /**************************************************************************/ |
2 | /* particles_storage.h */ |
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 | |
31 | #ifndef PARTICLES_STORAGE_RD_H |
32 | #define PARTICLES_STORAGE_RD_H |
33 | |
34 | #include "core/templates/local_vector.h" |
35 | #include "core/templates/rid_owner.h" |
36 | #include "core/templates/self_list.h" |
37 | #include "servers/rendering/renderer_rd/effects/sort_effects.h" |
38 | #include "servers/rendering/renderer_rd/shaders/particles.glsl.gen.h" |
39 | #include "servers/rendering/renderer_rd/shaders/particles_copy.glsl.gen.h" |
40 | #include "servers/rendering/renderer_rd/storage_rd/material_storage.h" |
41 | #include "servers/rendering/shader_compiler.h" |
42 | #include "servers/rendering/storage/particles_storage.h" |
43 | #include "servers/rendering/storage/utilities.h" |
44 | |
45 | namespace RendererRD { |
46 | |
47 | class ParticlesStorage : public RendererParticlesStorage { |
48 | private: |
49 | static ParticlesStorage *singleton; |
50 | |
51 | /* EFFECTS */ |
52 | SortEffects *sort_effects = nullptr; |
53 | |
54 | /* PARTICLES */ |
55 | |
56 | enum { |
57 | BASE_UNIFORM_SET, |
58 | MATERIAL_UNIFORM_SET, |
59 | COLLISION_TEXTURTES_UNIFORM_SET, |
60 | }; |
61 | |
62 | const int SAMPLERS_BINDING_FIRST_INDEX = 3; |
63 | |
64 | struct ParticleData { |
65 | float xform[16]; |
66 | float velocity[3]; |
67 | uint32_t active; |
68 | float color[4]; |
69 | float custom[4]; |
70 | }; |
71 | |
72 | struct ParticlesFrameParams { |
73 | enum { |
74 | MAX_ATTRACTORS = 32, |
75 | MAX_COLLIDERS = 32, |
76 | MAX_3D_TEXTURES = 7 |
77 | }; |
78 | |
79 | enum AttractorType { |
80 | ATTRACTOR_TYPE_SPHERE, |
81 | ATTRACTOR_TYPE_BOX, |
82 | ATTRACTOR_TYPE_VECTOR_FIELD, |
83 | }; |
84 | |
85 | struct Attractor { |
86 | float transform[16]; |
87 | float extents[3]; //exents or radius |
88 | uint32_t type; |
89 | |
90 | uint32_t texture_index; //texture index for vector field |
91 | float strength; |
92 | float attenuation; |
93 | float directionality; |
94 | }; |
95 | |
96 | enum CollisionType { |
97 | COLLISION_TYPE_SPHERE, |
98 | COLLISION_TYPE_BOX, |
99 | COLLISION_TYPE_SDF, |
100 | COLLISION_TYPE_HEIGHT_FIELD, |
101 | COLLISION_TYPE_2D_SDF, |
102 | |
103 | }; |
104 | |
105 | struct Collider { |
106 | float transform[16]; |
107 | float extents[3]; //exents or radius |
108 | uint32_t type; |
109 | |
110 | uint32_t texture_index; //texture index for vector field |
111 | float scale; |
112 | uint32_t pad[2]; |
113 | }; |
114 | |
115 | uint32_t emitting; |
116 | float system_phase; |
117 | float prev_system_phase; |
118 | uint32_t cycle; |
119 | |
120 | float explosiveness; |
121 | float randomness; |
122 | float time; |
123 | float delta; |
124 | |
125 | uint32_t frame; |
126 | uint32_t pad0; |
127 | uint32_t pad1; |
128 | uint32_t pad2; |
129 | |
130 | uint32_t random_seed; |
131 | uint32_t attractor_count; |
132 | uint32_t collider_count; |
133 | float particle_size; |
134 | |
135 | float emission_transform[16]; |
136 | |
137 | Attractor attractors[MAX_ATTRACTORS]; |
138 | Collider colliders[MAX_COLLIDERS]; |
139 | }; |
140 | |
141 | struct ParticleEmissionBuffer { |
142 | struct Data { |
143 | float xform[16]; |
144 | float velocity[3]; |
145 | uint32_t flags; |
146 | float color[4]; |
147 | float custom[4]; |
148 | }; |
149 | |
150 | int32_t particle_count; |
151 | int32_t particle_max; |
152 | uint32_t pad1; |
153 | uint32_t pad2; |
154 | Data data[1]; //its 2020 and empty arrays are still non standard in C++ |
155 | }; |
156 | |
157 | struct Particles { |
158 | RS::ParticlesMode mode = RS::PARTICLES_MODE_3D; |
159 | bool inactive = true; |
160 | double inactive_time = 0.0; |
161 | bool emitting = false; |
162 | bool one_shot = false; |
163 | int amount = 0; |
164 | double lifetime = 1.0; |
165 | double pre_process_time = 0.0; |
166 | real_t explosiveness = 0.0; |
167 | real_t randomness = 0.0; |
168 | bool restart_request = false; |
169 | AABB custom_aabb = AABB(Vector3(-4, -4, -4), Vector3(8, 8, 8)); |
170 | bool use_local_coords = false; |
171 | bool has_collision_cache = false; |
172 | |
173 | bool has_sdf_collision = false; |
174 | Transform2D sdf_collision_transform; |
175 | Rect2 sdf_collision_to_screen; |
176 | RID sdf_collision_texture; |
177 | |
178 | RID process_material; |
179 | uint32_t frame_counter = 0; |
180 | RS::ParticlesTransformAlign transform_align = RS::PARTICLES_TRANSFORM_ALIGN_DISABLED; |
181 | |
182 | RS::ParticlesDrawOrder draw_order = RS::PARTICLES_DRAW_ORDER_INDEX; |
183 | |
184 | Vector<RID> draw_passes; |
185 | Vector<Transform3D> trail_bind_poses; |
186 | bool trail_bind_poses_dirty = false; |
187 | RID trail_bind_pose_buffer; |
188 | RID trail_bind_pose_uniform_set; |
189 | |
190 | RID particle_buffer; |
191 | RID particle_instance_buffer; |
192 | RID frame_params_buffer; |
193 | |
194 | uint32_t userdata_count = 0; |
195 | |
196 | RID particles_material_uniform_set; |
197 | RID particles_copy_uniform_set; |
198 | RID particles_transforms_buffer_uniform_set; |
199 | RID collision_textures_uniform_set; |
200 | |
201 | RID collision_3d_textures[ParticlesFrameParams::MAX_3D_TEXTURES]; |
202 | uint32_t collision_3d_textures_used = 0; |
203 | RID collision_heightmap_texture; |
204 | |
205 | RID particles_sort_buffer; |
206 | RID particles_sort_uniform_set; |
207 | |
208 | bool dirty = false; |
209 | Particles *update_list = nullptr; |
210 | |
211 | RID sub_emitter; |
212 | |
213 | double phase = 0.0; |
214 | double prev_phase = 0.0; |
215 | uint64_t prev_ticks = 0; |
216 | uint32_t random_seed = 0; |
217 | |
218 | uint32_t cycle_number = 0; |
219 | |
220 | double speed_scale = 1.0; |
221 | |
222 | int fixed_fps = 30; |
223 | bool interpolate = true; |
224 | bool fractional_delta = false; |
225 | double frame_remainder = 0; |
226 | real_t collision_base_size = 0.01; |
227 | |
228 | uint32_t instance_motion_vectors_current_offset = 0; |
229 | uint32_t instance_motion_vectors_previous_offset = 0; |
230 | uint64_t instance_motion_vectors_last_change = -1; |
231 | bool instance_motion_vectors_enabled = false; |
232 | |
233 | bool clear = true; |
234 | |
235 | bool force_sub_emit = false; |
236 | |
237 | Transform3D emission_transform; |
238 | |
239 | Vector<uint8_t> emission_buffer_data; |
240 | |
241 | ParticleEmissionBuffer *emission_buffer = nullptr; |
242 | RID emission_storage_buffer; |
243 | |
244 | HashSet<RID> collisions; |
245 | |
246 | Dependency dependency; |
247 | |
248 | double trail_lifetime = 0.3; |
249 | bool trails_enabled = false; |
250 | LocalVector<ParticlesFrameParams> frame_history; |
251 | LocalVector<ParticlesFrameParams> trail_params; |
252 | |
253 | Particles() { |
254 | } |
255 | }; |
256 | |
257 | void _particles_process(Particles *p_particles, double p_delta); |
258 | void _particles_allocate_emission_buffer(Particles *particles); |
259 | void _particles_free_data(Particles *particles); |
260 | void _particles_update_buffers(Particles *particles); |
261 | |
262 | struct ParticlesShader { |
263 | struct PushConstant { |
264 | float lifetime; |
265 | uint32_t clear; |
266 | uint32_t total_particles; |
267 | uint32_t trail_size; |
268 | |
269 | uint32_t use_fractional_delta; |
270 | uint32_t sub_emitter_mode; |
271 | uint32_t can_emit; |
272 | uint32_t trail_pass; |
273 | }; |
274 | |
275 | ParticlesShaderRD shader; |
276 | ShaderCompiler compiler; |
277 | |
278 | RID default_shader; |
279 | RID default_material; |
280 | RID default_shader_rd; |
281 | |
282 | RID base_uniform_set; |
283 | |
284 | struct CopyPushConstant { |
285 | float sort_direction[3]; |
286 | uint32_t total_particles; |
287 | |
288 | uint32_t trail_size; |
289 | uint32_t trail_total; |
290 | float frame_delta; |
291 | float frame_remainder; |
292 | |
293 | float align_up[3]; |
294 | uint32_t align_mode; |
295 | |
296 | uint32_t lifetime_split; |
297 | uint32_t lifetime_reverse; |
298 | uint32_t motion_vectors_current_offset; |
299 | struct { |
300 | uint32_t order_by_lifetime : 1; |
301 | uint32_t copy_mode_2d : 1; |
302 | }; |
303 | |
304 | float inv_emission_transform[16]; |
305 | }; |
306 | |
307 | enum { |
308 | MAX_USERDATAS = 6 |
309 | }; |
310 | enum { |
311 | COPY_MODE_FILL_INSTANCES, |
312 | COPY_MODE_FILL_SORT_BUFFER, |
313 | COPY_MODE_FILL_INSTANCES_WITH_SORT_BUFFER, |
314 | COPY_MODE_MAX, |
315 | }; |
316 | |
317 | ParticlesCopyShaderRD copy_shader; |
318 | RID copy_shader_version; |
319 | RID copy_pipelines[COPY_MODE_MAX * (MAX_USERDATAS + 1)]; |
320 | |
321 | LocalVector<float> pose_update_buffer; |
322 | |
323 | } particles_shader; |
324 | |
325 | Particles *particle_update_list = nullptr; |
326 | |
327 | mutable RID_Owner<Particles, true> particles_owner; |
328 | |
329 | /* Particle Shader */ |
330 | |
331 | struct ParticlesShaderData : public MaterialStorage::ShaderData { |
332 | bool valid = false; |
333 | RID version; |
334 | bool uses_collision = false; |
335 | |
336 | Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms; |
337 | |
338 | Vector<uint32_t> ubo_offsets; |
339 | uint32_t ubo_size = 0; |
340 | |
341 | String code; |
342 | |
343 | RID pipeline; |
344 | |
345 | bool uses_time = false; |
346 | |
347 | bool userdatas_used[ParticlesShader::MAX_USERDATAS] = {}; |
348 | uint32_t userdata_count = 0; |
349 | |
350 | virtual void set_code(const String &p_Code); |
351 | virtual bool is_animated() const; |
352 | virtual bool casts_shadows() const; |
353 | virtual RS::ShaderNativeSourceCode get_native_source_code() const; |
354 | |
355 | ParticlesShaderData() {} |
356 | virtual ~ParticlesShaderData(); |
357 | }; |
358 | |
359 | MaterialStorage::ShaderData *_create_particles_shader_func(); |
360 | static MaterialStorage::ShaderData *_create_particles_shader_funcs() { |
361 | return ParticlesStorage::get_singleton()->_create_particles_shader_func(); |
362 | } |
363 | |
364 | struct ParticleProcessMaterialData : public MaterialStorage::MaterialData { |
365 | ParticlesShaderData *shader_data = nullptr; |
366 | RID uniform_set; |
367 | |
368 | virtual void set_render_priority(int p_priority) {} |
369 | virtual void set_next_pass(RID p_pass) {} |
370 | virtual bool update_parameters(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty); |
371 | virtual ~ParticleProcessMaterialData(); |
372 | }; |
373 | |
374 | MaterialStorage::MaterialData *_create_particles_material_func(ParticlesShaderData *p_shader); |
375 | static MaterialStorage::MaterialData *_create_particles_material_funcs(MaterialStorage::ShaderData *p_shader) { |
376 | return ParticlesStorage::get_singleton()->_create_particles_material_func(static_cast<ParticlesShaderData *>(p_shader)); |
377 | } |
378 | |
379 | /* Particles Collision */ |
380 | |
381 | struct ParticlesCollision { |
382 | RS::ParticlesCollisionType type = RS::PARTICLES_COLLISION_TYPE_SPHERE_ATTRACT; |
383 | uint32_t cull_mask = 0xFFFFFFFF; |
384 | float radius = 1.0; |
385 | Vector3 extents = Vector3(1, 1, 1); |
386 | float attractor_strength = 1.0; |
387 | float attractor_attenuation = 1.0; |
388 | float attractor_directionality = 0.0; |
389 | RID field_texture; |
390 | RID heightfield_texture; |
391 | RID heightfield_fb; |
392 | Size2i heightfield_fb_size; |
393 | |
394 | RS::ParticlesCollisionHeightfieldResolution heightfield_resolution = RS::PARTICLES_COLLISION_HEIGHTFIELD_RESOLUTION_1024; |
395 | |
396 | Dependency dependency; |
397 | }; |
398 | |
399 | struct ParticlesCollisionInstance { |
400 | RID collision; |
401 | Transform3D transform; |
402 | bool active = false; |
403 | }; |
404 | |
405 | mutable RID_Owner<ParticlesCollision, true> particles_collision_owner; |
406 | |
407 | mutable RID_Owner<ParticlesCollisionInstance> particles_collision_instance_owner; |
408 | |
409 | public: |
410 | static ParticlesStorage *get_singleton(); |
411 | |
412 | ParticlesStorage(); |
413 | virtual ~ParticlesStorage(); |
414 | |
415 | bool free(RID p_rid); |
416 | |
417 | /* PARTICLES */ |
418 | |
419 | bool owns_particles(RID p_rid) { return particles_owner.owns(p_rid); } |
420 | |
421 | virtual RID particles_allocate() override; |
422 | virtual void particles_initialize(RID p_rid) override; |
423 | virtual void particles_free(RID p_rid) override; |
424 | |
425 | virtual void particles_set_mode(RID p_particles, RS::ParticlesMode p_mode) override; |
426 | virtual void particles_set_emitting(RID p_particles, bool p_emitting) override; |
427 | virtual void particles_set_amount(RID p_particles, int p_amount) override; |
428 | virtual void particles_set_lifetime(RID p_particles, double p_lifetime) override; |
429 | virtual void particles_set_one_shot(RID p_particles, bool p_one_shot) override; |
430 | virtual void particles_set_pre_process_time(RID p_particles, double p_time) override; |
431 | virtual void particles_set_explosiveness_ratio(RID p_particles, real_t p_ratio) override; |
432 | virtual void particles_set_randomness_ratio(RID p_particles, real_t p_ratio) override; |
433 | virtual void particles_set_custom_aabb(RID p_particles, const AABB &p_aabb) override; |
434 | virtual void particles_set_speed_scale(RID p_particles, double p_scale) override; |
435 | virtual void particles_set_use_local_coordinates(RID p_particles, bool p_enable) override; |
436 | virtual void particles_set_process_material(RID p_particles, RID p_material) override; |
437 | virtual RID particles_get_process_material(RID p_particles) const override; |
438 | |
439 | virtual void particles_set_fixed_fps(RID p_particles, int p_fps) override; |
440 | virtual void particles_set_interpolate(RID p_particles, bool p_enable) override; |
441 | virtual void particles_set_fractional_delta(RID p_particles, bool p_enable) override; |
442 | virtual void particles_set_collision_base_size(RID p_particles, real_t p_size) override; |
443 | virtual void particles_set_transform_align(RID p_particles, RS::ParticlesTransformAlign p_transform_align) override; |
444 | |
445 | virtual void particles_set_trails(RID p_particles, bool p_enable, double p_length) override; |
446 | virtual void particles_set_trail_bind_poses(RID p_particles, const Vector<Transform3D> &p_bind_poses) override; |
447 | |
448 | virtual void particles_restart(RID p_particles) override; |
449 | virtual void 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) override; |
450 | |
451 | virtual void particles_set_subemitter(RID p_particles, RID p_subemitter_particles) override; |
452 | |
453 | virtual void particles_set_draw_order(RID p_particles, RS::ParticlesDrawOrder p_order) override; |
454 | |
455 | virtual void particles_set_draw_passes(RID p_particles, int p_count) override; |
456 | virtual void particles_set_draw_pass_mesh(RID p_particles, int p_pass, RID p_mesh) override; |
457 | |
458 | virtual void particles_request_process(RID p_particles) override; |
459 | virtual AABB particles_get_current_aabb(RID p_particles) override; |
460 | virtual AABB particles_get_aabb(RID p_particles) const override; |
461 | |
462 | virtual void particles_set_emission_transform(RID p_particles, const Transform3D &p_transform) override; |
463 | |
464 | virtual bool particles_get_emitting(RID p_particles) override; |
465 | virtual int particles_get_draw_passes(RID p_particles) const override; |
466 | virtual RID particles_get_draw_pass_mesh(RID p_particles, int p_pass) const override; |
467 | |
468 | virtual void particles_set_view_axis(RID p_particles, const Vector3 &p_axis, const Vector3 &p_up_axis) override; |
469 | |
470 | virtual bool particles_is_inactive(RID p_particles) const override; |
471 | |
472 | _FORCE_INLINE_ RS::ParticlesMode particles_get_mode(RID p_particles) { |
473 | Particles *particles = particles_owner.get_or_null(p_particles); |
474 | ERR_FAIL_COND_V(!particles, RS::PARTICLES_MODE_2D); |
475 | return particles->mode; |
476 | } |
477 | |
478 | _FORCE_INLINE_ uint32_t particles_get_frame_counter(RID p_particles) { |
479 | Particles *particles = particles_owner.get_or_null(p_particles); |
480 | ERR_FAIL_COND_V(!particles, false); |
481 | return particles->frame_counter; |
482 | } |
483 | |
484 | _FORCE_INLINE_ uint32_t particles_get_amount(RID p_particles, uint32_t &r_trail_divisor) { |
485 | Particles *particles = particles_owner.get_or_null(p_particles); |
486 | ERR_FAIL_COND_V(!particles, 0); |
487 | |
488 | if (particles->trails_enabled && particles->trail_bind_poses.size() > 1) { |
489 | r_trail_divisor = particles->trail_bind_poses.size(); |
490 | } else { |
491 | r_trail_divisor = 1; |
492 | } |
493 | |
494 | return particles->amount * r_trail_divisor; |
495 | } |
496 | |
497 | _FORCE_INLINE_ bool particles_has_collision(RID p_particles) { |
498 | Particles *particles = particles_owner.get_or_null(p_particles); |
499 | ERR_FAIL_COND_V(!particles, 0); |
500 | |
501 | return particles->has_collision_cache; |
502 | } |
503 | |
504 | _FORCE_INLINE_ uint32_t particles_is_using_local_coords(RID p_particles) { |
505 | Particles *particles = particles_owner.get_or_null(p_particles); |
506 | ERR_FAIL_COND_V(!particles, false); |
507 | |
508 | return particles->use_local_coords; |
509 | } |
510 | |
511 | _FORCE_INLINE_ RID particles_get_instance_buffer_uniform_set(RID p_particles, RID p_shader, uint32_t p_set) { |
512 | Particles *particles = particles_owner.get_or_null(p_particles); |
513 | ERR_FAIL_COND_V(!particles, RID()); |
514 | if (particles->particles_transforms_buffer_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(particles->particles_transforms_buffer_uniform_set)) { |
515 | _particles_update_buffers(particles); |
516 | Vector<RD::Uniform> uniforms; |
517 | |
518 | { |
519 | RD::Uniform u; |
520 | u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; |
521 | u.binding = 0; |
522 | u.append_id(particles->particle_instance_buffer); |
523 | uniforms.push_back(u); |
524 | } |
525 | |
526 | particles->particles_transforms_buffer_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, p_shader, p_set); |
527 | } |
528 | |
529 | return particles->particles_transforms_buffer_uniform_set; |
530 | } |
531 | |
532 | void particles_get_instance_buffer_motion_vectors_offsets(RID p_particles, uint32_t &r_current_offset, uint32_t &r_prev_offset); |
533 | |
534 | virtual void particles_add_collision(RID p_particles, RID p_particles_collision_instance) override; |
535 | virtual void particles_remove_collision(RID p_particles, RID p_particles_collision_instance) override; |
536 | void particles_set_canvas_sdf_collision(RID p_particles, bool p_enable, const Transform2D &p_xform, const Rect2 &p_to_screen, RID p_texture); |
537 | |
538 | virtual void update_particles() override; |
539 | |
540 | void particles_update_dependency(RID p_particles, DependencyTracker *p_instance); |
541 | Dependency *particles_get_dependency(RID p_particles) const; |
542 | |
543 | /* Particles Collision */ |
544 | |
545 | bool owns_particles_collision(RID p_rid) { return particles_collision_owner.owns(p_rid); } |
546 | |
547 | virtual RID particles_collision_allocate() override; |
548 | virtual void particles_collision_initialize(RID p_particles_collision) override; |
549 | virtual void particles_collision_free(RID p_rid) override; |
550 | |
551 | virtual void particles_collision_set_collision_type(RID p_particles_collision, RS::ParticlesCollisionType p_type) override; |
552 | virtual void particles_collision_set_cull_mask(RID p_particles_collision, uint32_t p_cull_mask) override; |
553 | virtual void particles_collision_set_sphere_radius(RID p_particles_collision, real_t p_radius) override; //for spheres |
554 | virtual void particles_collision_set_box_extents(RID p_particles_collision, const Vector3 &p_extents) override; //for non-spheres |
555 | virtual void particles_collision_set_attractor_strength(RID p_particles_collision, real_t p_strength) override; |
556 | virtual void particles_collision_set_attractor_directionality(RID p_particles_collision, real_t p_directionality) override; |
557 | virtual void particles_collision_set_attractor_attenuation(RID p_particles_collision, real_t p_curve) override; |
558 | virtual void particles_collision_set_field_texture(RID p_particles_collision, RID p_texture) override; //for SDF and vector field, heightfield is dynamic |
559 | virtual void particles_collision_height_field_update(RID p_particles_collision) override; //for SDF and vector field |
560 | virtual void particles_collision_set_height_field_resolution(RID p_particles_collision, RS::ParticlesCollisionHeightfieldResolution p_resolution) override; //for SDF and vector field |
561 | virtual AABB particles_collision_get_aabb(RID p_particles_collision) const override; |
562 | Vector3 particles_collision_get_extents(RID p_particles_collision) const; |
563 | virtual bool particles_collision_is_heightfield(RID p_particles_collision) const override; |
564 | RID particles_collision_get_heightfield_framebuffer(RID p_particles_collision) const; |
565 | |
566 | Dependency *particles_collision_get_dependency(RID p_particles) const; |
567 | |
568 | //used from 2D and 3D |
569 | bool owns_particles_collision_instance(RID p_rid) { return particles_collision_instance_owner.owns(p_rid); } |
570 | |
571 | virtual RID particles_collision_instance_create(RID p_collision) override; |
572 | virtual void particles_collision_instance_free(RID p_rid) override; |
573 | virtual void particles_collision_instance_set_transform(RID p_collision_instance, const Transform3D &p_transform) override; |
574 | virtual void particles_collision_instance_set_active(RID p_collision_instance, bool p_active) override; |
575 | }; |
576 | |
577 | } // namespace RendererRD |
578 | |
579 | #endif // PARTICLES_STORAGE_RD_H |
580 | |