diff options
Diffstat (limited to 'scene')
-rw-r--r-- | scene/3d/gpu_particles_collision_3d.cpp | 47 | ||||
-rw-r--r-- | scene/3d/gpu_particles_collision_3d.h | 9 |
2 files changed, 55 insertions, 1 deletions
diff --git a/scene/3d/gpu_particles_collision_3d.cpp b/scene/3d/gpu_particles_collision_3d.cpp index 1fcd5160f6..1cfd889272 100644 --- a/scene/3d/gpu_particles_collision_3d.cpp +++ b/scene/3d/gpu_particles_collision_3d.cpp @@ -127,6 +127,10 @@ GPUParticlesCollisionBox3D::~GPUParticlesCollisionBox3D() { void GPUParticlesCollisionSDF3D::_find_meshes(const AABB &p_aabb, Node *p_at_node, List<PlotMesh> &plot_meshes) { MeshInstance3D *mi = Object::cast_to<MeshInstance3D>(p_at_node); if (mi && mi->is_visible_in_tree()) { + if ((mi->get_layer_mask() & bake_mask) == 0) { + return; + } + Ref<Mesh> mesh = mi->get_mesh(); if (mesh.is_valid()) { AABB aabb = mesh->get_aabb(); @@ -445,7 +449,7 @@ Ref<Image> GPUParticlesCollisionSDF3D::bake() { //compute bvh - ERR_FAIL_COND_V(faces.size() <= 1, Ref<Image>()); + ERR_FAIL_COND_V_MSG(faces.size() <= 1, Ref<Image>(), "No faces detected during GPUParticlesCollisionSDF3D bake. Check whether there are visible meshes matching the bake mask within its extents."); LocalVector<FacePos> face_pos; @@ -499,6 +503,16 @@ Ref<Image> GPUParticlesCollisionSDF3D::bake() { return ret; } +TypedArray<String> GPUParticlesCollisionSDF3D::get_configuration_warnings() const { + TypedArray<String> warnings = Node::get_configuration_warnings(); + + if (bake_mask == 0) { + warnings.push_back(RTR("The Bake Mask has no bits enabled, which means baking will not produce any collision for this GPUParticlesCollisionSDF3D.\nTo resolve this, enable at least one bit in the Bake Mask property.")); + } + + return warnings; +} + void GPUParticlesCollisionSDF3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_extents", "extents"), &GPUParticlesCollisionSDF3D::set_extents); ClassDB::bind_method(D_METHOD("get_extents"), &GPUParticlesCollisionSDF3D::get_extents); @@ -512,9 +526,15 @@ void GPUParticlesCollisionSDF3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_thickness", "thickness"), &GPUParticlesCollisionSDF3D::set_thickness); ClassDB::bind_method(D_METHOD("get_thickness"), &GPUParticlesCollisionSDF3D::get_thickness); + ClassDB::bind_method(D_METHOD("set_bake_mask", "mask"), &GPUParticlesCollisionSDF3D::set_bake_mask); + ClassDB::bind_method(D_METHOD("get_bake_mask"), &GPUParticlesCollisionSDF3D::get_bake_mask); + ClassDB::bind_method(D_METHOD("set_bake_mask_value", "layer_number", "value"), &GPUParticlesCollisionSDF3D::set_bake_mask_value); + ClassDB::bind_method(D_METHOD("get_bake_mask_value", "layer_number"), &GPUParticlesCollisionSDF3D::get_bake_mask_value); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "extents", PROPERTY_HINT_RANGE, "0.01,1024,0.01,or_greater,suffix:m"), "set_extents", "get_extents"); ADD_PROPERTY(PropertyInfo(Variant::INT, "resolution", PROPERTY_HINT_ENUM, "16,32,64,128,256,512,suffix:px"), "set_resolution", "get_resolution"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "thickness", PROPERTY_HINT_RANGE, "0.0,2.0,0.01,suffix:m"), "set_thickness", "get_thickness"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "bake_mask", PROPERTY_HINT_LAYERS_3D_RENDER), "set_bake_mask", "get_bake_mask"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture3D"), "set_texture", "get_texture"); BIND_ENUM_CONSTANT(RESOLUTION_16); @@ -553,6 +573,31 @@ GPUParticlesCollisionSDF3D::Resolution GPUParticlesCollisionSDF3D::get_resolutio return resolution; } +void GPUParticlesCollisionSDF3D::set_bake_mask(uint32_t p_mask) { + bake_mask = p_mask; + update_configuration_warnings(); +} + +uint32_t GPUParticlesCollisionSDF3D::get_bake_mask() const { + return bake_mask; +} + +void GPUParticlesCollisionSDF3D::set_bake_mask_value(int p_layer_number, bool p_value) { + ERR_FAIL_COND_MSG(p_layer_number < 1 || p_layer_number > 20, vformat("The render layer number (%d) must be between 1 and 20 (inclusive).", p_layer_number)); + uint32_t mask = get_bake_mask(); + if (p_value) { + mask |= 1 << (p_layer_number - 1); + } else { + mask &= ~(1 << (p_layer_number - 1)); + } + set_bake_mask(mask); +} + +bool GPUParticlesCollisionSDF3D::get_bake_mask_value(int p_layer_number) const { + ERR_FAIL_COND_V_MSG(p_layer_number < 1 || p_layer_number > 20, false, vformat("The render layer number (%d) must be between 1 and 20 (inclusive).", p_layer_number)); + return bake_mask & (1 << (p_layer_number - 1)); +} + void GPUParticlesCollisionSDF3D::set_texture(const Ref<Texture3D> &p_texture) { texture = p_texture; RID tex = texture.is_valid() ? texture->get_rid() : RID(); diff --git a/scene/3d/gpu_particles_collision_3d.h b/scene/3d/gpu_particles_collision_3d.h index 4b2cb930fa..712bd015ff 100644 --- a/scene/3d/gpu_particles_collision_3d.h +++ b/scene/3d/gpu_particles_collision_3d.h @@ -110,6 +110,7 @@ public: private: Vector3 extents = Vector3(1, 1, 1); Resolution resolution = RESOLUTION_64; + uint32_t bake_mask = 0xFFFFFFFF; Ref<Texture3D> texture; float thickness = 1.0; @@ -161,6 +162,8 @@ protected: static void _bind_methods(); public: + virtual TypedArray<String> get_configuration_warnings() const override; + void set_thickness(float p_thickness); float get_thickness() const; @@ -170,6 +173,12 @@ public: void set_resolution(Resolution p_resolution); Resolution get_resolution() const; + void set_bake_mask(uint32_t p_mask); + uint32_t get_bake_mask() const; + + void set_bake_mask_value(int p_layer_number, bool p_enable); + bool get_bake_mask_value(int p_layer_number) const; + void set_texture(const Ref<Texture3D> &p_texture); Ref<Texture3D> get_texture() const; |