1/**************************************************************************/
2/* gpu_particles_collision_3d.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 GPU_PARTICLES_COLLISION_3D_H
32#define GPU_PARTICLES_COLLISION_3D_H
33
34#include "core/templates/local_vector.h"
35#include "scene/3d/visual_instance_3d.h"
36
37class GPUParticlesCollision3D : public VisualInstance3D {
38 GDCLASS(GPUParticlesCollision3D, VisualInstance3D);
39
40 uint32_t cull_mask = 0xFFFFFFFF;
41 RID collision;
42
43protected:
44 _FORCE_INLINE_ RID _get_collision() { return collision; }
45 static void _bind_methods();
46
47 GPUParticlesCollision3D(RS::ParticlesCollisionType p_type);
48
49public:
50 void set_cull_mask(uint32_t p_cull_mask);
51 uint32_t get_cull_mask() const;
52
53 ~GPUParticlesCollision3D();
54};
55
56class GPUParticlesCollisionSphere3D : public GPUParticlesCollision3D {
57 GDCLASS(GPUParticlesCollisionSphere3D, GPUParticlesCollision3D);
58
59 real_t radius = 1.0;
60
61protected:
62 static void _bind_methods();
63
64public:
65 void set_radius(real_t p_radius);
66 real_t get_radius() const;
67
68 virtual AABB get_aabb() const override;
69
70 GPUParticlesCollisionSphere3D();
71 ~GPUParticlesCollisionSphere3D();
72};
73
74class GPUParticlesCollisionBox3D : public GPUParticlesCollision3D {
75 GDCLASS(GPUParticlesCollisionBox3D, GPUParticlesCollision3D);
76
77 Vector3 size = Vector3(2, 2, 2);
78
79protected:
80 static void _bind_methods();
81#ifndef DISABLE_DEPRECATED
82 bool _set(const StringName &p_name, const Variant &p_value);
83 bool _get(const StringName &p_name, Variant &r_property) const;
84#endif // DISABLE_DEPRECATED
85
86public:
87 void set_size(const Vector3 &p_size);
88 Vector3 get_size() const;
89
90 virtual AABB get_aabb() const override;
91
92 GPUParticlesCollisionBox3D();
93 ~GPUParticlesCollisionBox3D();
94};
95
96class GPUParticlesCollisionSDF3D : public GPUParticlesCollision3D {
97 GDCLASS(GPUParticlesCollisionSDF3D, GPUParticlesCollision3D);
98
99public:
100 enum Resolution {
101 RESOLUTION_16,
102 RESOLUTION_32,
103 RESOLUTION_64,
104 RESOLUTION_128,
105 RESOLUTION_256,
106 RESOLUTION_512,
107 RESOLUTION_MAX,
108 };
109
110 typedef void (*BakeBeginFunc)(int);
111 typedef void (*BakeStepFunc)(int, const String &);
112 typedef void (*BakeEndFunc)();
113
114private:
115 Vector3 size = Vector3(2, 2, 2);
116 Resolution resolution = RESOLUTION_64;
117 uint32_t bake_mask = 0xFFFFFFFF;
118 Ref<Texture3D> texture;
119 float thickness = 1.0;
120
121 struct PlotMesh {
122 Ref<Mesh> mesh;
123 Transform3D local_xform;
124 };
125
126 void _find_meshes(const AABB &p_aabb, Node *p_at_node, List<PlotMesh> &plot_meshes);
127
128 struct BVH {
129 enum {
130 LEAF_BIT = 1 << 30,
131 LEAF_MASK = LEAF_BIT - 1
132 };
133 AABB bounds;
134 uint32_t children[2] = {};
135 };
136
137 struct FacePos {
138 Vector3 center;
139 uint32_t index = 0;
140 };
141
142 struct FaceSort {
143 uint32_t axis = 0;
144 bool operator()(const FacePos &p_left, const FacePos &p_right) const {
145 return p_left.center[axis] < p_right.center[axis];
146 }
147 };
148
149 uint32_t _create_bvh(LocalVector<BVH> &bvh_tree, FacePos *p_faces, uint32_t p_face_count, const Face3 *p_triangles, float p_thickness);
150
151 struct ComputeSDFParams {
152 float *cells = nullptr;
153 Vector3i size;
154 float cell_size = 0.0;
155 Vector3 cell_offset;
156 const BVH *bvh = nullptr;
157 const Face3 *triangles = nullptr;
158 float thickness = 0.0;
159 };
160
161 void _find_closest_distance(const Vector3 &p_pos, const BVH *p_bvh, uint32_t p_bvh_cell, const Face3 *p_triangles, float p_thickness, float &r_closest_distance);
162 void _compute_sdf_z(uint32_t p_z, ComputeSDFParams *params);
163 void _compute_sdf(ComputeSDFParams *params);
164
165protected:
166 static void _bind_methods();
167#ifndef DISABLE_DEPRECATED
168 bool _set(const StringName &p_name, const Variant &p_value);
169 bool _get(const StringName &p_name, Variant &r_property) const;
170#endif // DISABLE_DEPRECATED
171
172public:
173 virtual PackedStringArray get_configuration_warnings() const override;
174
175 void set_thickness(float p_thickness);
176 float get_thickness() const;
177
178 void set_size(const Vector3 &p_size);
179 Vector3 get_size() const;
180
181 void set_resolution(Resolution p_resolution);
182 Resolution get_resolution() const;
183
184 void set_bake_mask(uint32_t p_mask);
185 uint32_t get_bake_mask() const;
186
187 void set_bake_mask_value(int p_layer_number, bool p_enable);
188 bool get_bake_mask_value(int p_layer_number) const;
189
190 void set_texture(const Ref<Texture3D> &p_texture);
191 Ref<Texture3D> get_texture() const;
192
193 Vector3i get_estimated_cell_size() const;
194 Ref<Image> bake();
195
196 virtual AABB get_aabb() const override;
197
198 static BakeBeginFunc bake_begin_function;
199 static BakeStepFunc bake_step_function;
200 static BakeEndFunc bake_end_function;
201
202 GPUParticlesCollisionSDF3D();
203 ~GPUParticlesCollisionSDF3D();
204};
205
206VARIANT_ENUM_CAST(GPUParticlesCollisionSDF3D::Resolution)
207
208class GPUParticlesCollisionHeightField3D : public GPUParticlesCollision3D {
209 GDCLASS(GPUParticlesCollisionHeightField3D, GPUParticlesCollision3D);
210
211public:
212 enum Resolution {
213 RESOLUTION_256,
214 RESOLUTION_512,
215 RESOLUTION_1024,
216 RESOLUTION_2048,
217 RESOLUTION_4096,
218 RESOLUTION_8192,
219 RESOLUTION_MAX,
220 };
221
222 enum UpdateMode {
223 UPDATE_MODE_WHEN_MOVED,
224 UPDATE_MODE_ALWAYS,
225 };
226
227private:
228 Vector3 size = Vector3(2, 2, 2);
229 Resolution resolution = RESOLUTION_1024;
230 bool follow_camera_mode = false;
231
232 UpdateMode update_mode = UPDATE_MODE_WHEN_MOVED;
233
234protected:
235 void _notification(int p_what);
236 static void _bind_methods();
237#ifndef DISABLE_DEPRECATED
238 bool _set(const StringName &p_name, const Variant &p_value);
239 bool _get(const StringName &p_name, Variant &r_property) const;
240#endif // DISABLE_DEPRECATED
241
242public:
243 void set_size(const Vector3 &p_size);
244 Vector3 get_size() const;
245
246 void set_resolution(Resolution p_resolution);
247 Resolution get_resolution() const;
248
249 void set_update_mode(UpdateMode p_update_mode);
250 UpdateMode get_update_mode() const;
251
252 void set_follow_camera_enabled(bool p_enabled);
253 bool is_follow_camera_enabled() const;
254
255 virtual AABB get_aabb() const override;
256
257 GPUParticlesCollisionHeightField3D();
258 ~GPUParticlesCollisionHeightField3D();
259};
260
261VARIANT_ENUM_CAST(GPUParticlesCollisionHeightField3D::Resolution)
262VARIANT_ENUM_CAST(GPUParticlesCollisionHeightField3D::UpdateMode)
263
264class GPUParticlesAttractor3D : public VisualInstance3D {
265 GDCLASS(GPUParticlesAttractor3D, VisualInstance3D);
266
267 uint32_t cull_mask = 0xFFFFFFFF;
268 RID collision;
269 real_t strength = 1.0;
270 real_t attenuation = 1.0;
271 real_t directionality = 0.0;
272
273protected:
274 _FORCE_INLINE_ RID _get_collision() { return collision; }
275 static void _bind_methods();
276
277 GPUParticlesAttractor3D(RS::ParticlesCollisionType p_type);
278
279public:
280 void set_cull_mask(uint32_t p_cull_mask);
281 uint32_t get_cull_mask() const;
282
283 void set_strength(real_t p_strength);
284 real_t get_strength() const;
285
286 void set_attenuation(real_t p_attenuation);
287 real_t get_attenuation() const;
288
289 void set_directionality(real_t p_directionality);
290 real_t get_directionality() const;
291
292 ~GPUParticlesAttractor3D();
293};
294
295class GPUParticlesAttractorSphere3D : public GPUParticlesAttractor3D {
296 GDCLASS(GPUParticlesAttractorSphere3D, GPUParticlesAttractor3D);
297
298 real_t radius = 1.0;
299
300protected:
301 static void _bind_methods();
302
303public:
304 void set_radius(real_t p_radius);
305 real_t get_radius() const;
306
307 virtual AABB get_aabb() const override;
308
309 GPUParticlesAttractorSphere3D();
310 ~GPUParticlesAttractorSphere3D();
311};
312
313class GPUParticlesAttractorBox3D : public GPUParticlesAttractor3D {
314 GDCLASS(GPUParticlesAttractorBox3D, GPUParticlesAttractor3D);
315
316 Vector3 size = Vector3(2, 2, 2);
317
318protected:
319 static void _bind_methods();
320#ifndef DISABLE_DEPRECATED
321 bool _set(const StringName &p_name, const Variant &p_value);
322 bool _get(const StringName &p_name, Variant &r_property) const;
323#endif // DISABLE_DEPRECATED
324
325public:
326 void set_size(const Vector3 &p_size);
327 Vector3 get_size() const;
328
329 virtual AABB get_aabb() const override;
330
331 GPUParticlesAttractorBox3D();
332 ~GPUParticlesAttractorBox3D();
333};
334
335class GPUParticlesAttractorVectorField3D : public GPUParticlesAttractor3D {
336 GDCLASS(GPUParticlesAttractorVectorField3D, GPUParticlesAttractor3D);
337
338 Vector3 size = Vector3(2, 2, 2);
339 Ref<Texture3D> texture;
340
341protected:
342 static void _bind_methods();
343#ifndef DISABLE_DEPRECATED
344 bool _set(const StringName &p_name, const Variant &p_value);
345 bool _get(const StringName &p_name, Variant &r_property) const;
346#endif // DISABLE_DEPRECATED
347
348public:
349 void set_size(const Vector3 &p_size);
350 Vector3 get_size() const;
351
352 void set_texture(const Ref<Texture3D> &p_texture);
353 Ref<Texture3D> get_texture() const;
354
355 virtual AABB get_aabb() const override;
356
357 GPUParticlesAttractorVectorField3D();
358 ~GPUParticlesAttractorVectorField3D();
359};
360
361#endif // GPU_PARTICLES_COLLISION_3D_H
362