summaryrefslogtreecommitdiff
path: root/scene/3d/soft_body_3d.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scene/3d/soft_body_3d.cpp')
-rw-r--r--scene/3d/soft_body_3d.cpp333
1 files changed, 161 insertions, 172 deletions
diff --git a/scene/3d/soft_body_3d.cpp b/scene/3d/soft_body_3d.cpp
index 6092818252..7eb189e890 100644
--- a/scene/3d/soft_body_3d.cpp
+++ b/scene/3d/soft_body_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,14 +30,7 @@
#include "soft_body_3d.h"
-#include "core/list.h"
-#include "core/object.h"
-#include "core/os/os.h"
-#include "core/rid.h"
-#include "scene/3d/collision_object_3d.h"
#include "scene/3d/physics_body_3d.h"
-#include "scene/3d/skeleton_3d.h"
-#include "servers/physics_server_3d.h"
SoftBodyRenderingServerHandler::SoftBodyRenderingServerHandler() {}
@@ -48,28 +41,28 @@ void SoftBodyRenderingServerHandler::prepare(RID p_mesh, int p_surface) {
mesh = p_mesh;
surface = p_surface;
-#ifndef _MSC_VER
-#warning Softbody is not working, needs to be redone considering that these functions no longer exist
-#endif
-#if 0
- const uint32_t surface_format = RS::get_singleton()->mesh_surface_get_format(mesh, surface);
- const int surface_vertex_len = RS::get_singleton()->mesh_surface_get_array_len(mesh, p_surface);
- const int surface_index_len = RS::get_singleton()->mesh_surface_get_array_index_len(mesh, p_surface);
+
+ RS::SurfaceData surface_data = RS::get_singleton()->mesh_get_surface(mesh, surface);
+
uint32_t surface_offsets[RS::ARRAY_MAX];
+ uint32_t vertex_stride;
+ uint32_t attrib_stride;
+ uint32_t skin_stride;
+ RS::get_singleton()->mesh_surface_make_offsets_from_format(surface_data.format, surface_data.vertex_count, surface_data.index_count, surface_offsets, vertex_stride, attrib_stride, skin_stride);
- buffer = RS::get_singleton()->mesh_surface_get_array(mesh, surface);
- stride = RS::get_singleton()->mesh_surface_make_offsets_from_format(surface_format, surface_vertex_len, surface_index_len, surface_offsets);
+ buffer = surface_data.vertex_data;
+ stride = vertex_stride;
offset_vertices = surface_offsets[RS::ARRAY_VERTEX];
offset_normal = surface_offsets[RS::ARRAY_NORMAL];
-#endif
}
void SoftBodyRenderingServerHandler::clear() {
+ buffer.resize(0);
+ stride = 0;
+ offset_vertices = 0;
+ offset_normal = 0;
- if (mesh.is_valid()) {
- buffer.resize(0);
- }
-
+ surface = 0;
mesh = RID();
}
@@ -78,28 +71,26 @@ void SoftBodyRenderingServerHandler::open() {
}
void SoftBodyRenderingServerHandler::close() {
- //write_buffer.release();
+ write_buffer = nullptr;
}
void SoftBodyRenderingServerHandler::commit_changes() {
- RS::get_singleton()->mesh_surface_update_region(mesh, surface, 0, buffer);
+ RS::get_singleton()->mesh_surface_update_vertex_region(mesh, surface, 0, buffer);
}
void SoftBodyRenderingServerHandler::set_vertex(int p_vertex_id, const void *p_vector3) {
- copymem(&write_buffer[p_vertex_id * stride + offset_vertices], p_vector3, sizeof(float) * 3);
+ memcpy(&write_buffer[p_vertex_id * stride + offset_vertices], p_vector3, sizeof(float) * 3);
}
void SoftBodyRenderingServerHandler::set_normal(int p_vertex_id, const void *p_vector3) {
- copymem(&write_buffer[p_vertex_id * stride + offset_normal], p_vector3, sizeof(float) * 3);
+ memcpy(&write_buffer[p_vertex_id * stride + offset_normal], p_vector3, sizeof(float) * 3);
}
void SoftBodyRenderingServerHandler::set_aabb(const AABB &p_aabb) {
RS::get_singleton()->mesh_set_custom_aabb(mesh, p_aabb);
}
-SoftBody3D::PinnedPoint::PinnedPoint() :
- point_index(-1),
- spatial_attachment(nullptr) {
+SoftBody3D::PinnedPoint::PinnedPoint() {
}
SoftBody3D::PinnedPoint::PinnedPoint(const PinnedPoint &obj_tocopy) {
@@ -109,7 +100,7 @@ SoftBody3D::PinnedPoint::PinnedPoint(const PinnedPoint &obj_tocopy) {
offset = obj_tocopy.offset;
}
-SoftBody3D::PinnedPoint SoftBody3D::PinnedPoint::operator=(const PinnedPoint &obj) {
+SoftBody3D::PinnedPoint &SoftBody3D::PinnedPoint::operator=(const PinnedPoint &obj) {
point_index = obj.point_index;
spatial_attachment_path = obj.spatial_attachment_path;
spatial_attachment = obj.spatial_attachment;
@@ -118,8 +109,9 @@ SoftBody3D::PinnedPoint SoftBody3D::PinnedPoint::operator=(const PinnedPoint &ob
}
void SoftBody3D::_update_pickable() {
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return;
+ }
bool pickable = ray_pickable && is_visible_in_tree();
PhysicsServer3D::get_singleton()->soft_body_set_ray_pickable(physics_rid, pickable);
}
@@ -129,11 +121,9 @@ bool SoftBody3D::_set(const StringName &p_name, const Variant &p_value) {
String which = name.get_slicec('/', 0);
if ("pinned_points" == which) {
-
return _set_property_pinned_points_indices(p_value);
} else if ("attachments" == which) {
-
int idx = name.get_slicec('/', 1).to_int();
String what = name.get_slicec('/', 2);
@@ -161,7 +151,6 @@ bool SoftBody3D::_get(const StringName &p_name, Variant &r_ret) const {
return true;
} else if ("attachments" == which) {
-
int idx = name.get_slicec('/', 1).to_int();
String what = name.get_slicec('/', 2);
@@ -172,7 +161,6 @@ bool SoftBody3D::_get(const StringName &p_name, Variant &r_ret) const {
}
void SoftBody3D::_get_property_list(List<PropertyInfo> *p_list) const {
-
const int pinned_points_indices_size = pinned_points.size();
p_list->push_back(PropertyInfo(Variant::PACKED_INT32_ARRAY, "pinned_points"));
@@ -185,7 +173,6 @@ void SoftBody3D::_get_property_list(List<PropertyInfo> *p_list) const {
}
bool SoftBody3D::_set_property_pinned_points_indices(const Array &p_indices) {
-
const int p_indices_size = p_indices.size();
{ // Remove the pined points on physics server that will be removed by resize
@@ -204,8 +191,9 @@ bool SoftBody3D::_set_property_pinned_points_indices(const Array &p_indices) {
for (int i = 0; i < p_indices_size; ++i) {
point_index = p_indices.get(i);
if (w[i].point_index != point_index) {
- if (-1 != w[i].point_index)
+ if (-1 != w[i].point_index) {
pin_point(w[i].point_index, false);
+ }
w[i].point_index = point_index;
pin_point(w[i].point_index, true);
}
@@ -251,36 +239,35 @@ bool SoftBody3D::_get_property_pinned_points(int p_item, const String &p_what, V
return true;
}
-void SoftBody3D::_changed_callback(Object *p_changed, const char *p_prop) {
+void SoftBody3D::_softbody_changed() {
prepare_physics_server();
_reset_points_offsets();
#ifdef TOOLS_ENABLED
- if (p_changed == this) {
- update_configuration_warning();
- }
+ update_configuration_warnings();
#endif
}
void SoftBody3D::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_WORLD: {
-
if (Engine::get_singleton()->is_editor_hint()) {
-
- add_change_receptor(this);
+ // I have no idea what this is supposed to do, it's really weird
+ // leaving for upcoming PK work on physics
+ //add_change_receptor(this);
}
- RID space = get_world()->get_space();
+ RID space = get_world_3d()->get_space();
PhysicsServer3D::get_singleton()->soft_body_set_space(physics_rid, space);
prepare_physics_server();
} break;
+
case NOTIFICATION_READY: {
- if (!parent_collision_ignore.is_empty())
+ if (!parent_collision_ignore.is_empty()) {
add_collision_exception_with(get_node(parent_collision_ignore));
-
+ }
} break;
- case NOTIFICATION_TRANSFORM_CHANGED: {
+ case NOTIFICATION_TRANSFORM_CHANGED: {
if (Engine::get_singleton()->is_editor_hint()) {
_reset_points_offsets();
return;
@@ -290,35 +277,43 @@ void SoftBody3D::_notification(int p_what) {
set_notify_transform(false);
// Required to be top level with Transform at center of world in order to modify RenderingServer only to support custom Transform
- set_as_toplevel(true);
- set_transform(Transform());
+ set_as_top_level(true);
+ set_transform(Transform3D());
set_notify_transform(true);
-
} break;
- case NOTIFICATION_VISIBILITY_CHANGED: {
+ case NOTIFICATION_VISIBILITY_CHANGED: {
_update_pickable();
-
} break;
- case NOTIFICATION_EXIT_WORLD: {
+ case NOTIFICATION_EXIT_WORLD: {
PhysicsServer3D::get_singleton()->soft_body_set_space(physics_rid, RID());
-
} break;
- }
-#ifdef TOOLS_ENABLED
+ case NOTIFICATION_DISABLED: {
+ if (is_inside_tree() && (disable_mode == DISABLE_MODE_REMOVE)) {
+ prepare_physics_server();
+ }
+ } break;
- if (p_what == NOTIFICATION_LOCAL_TRANSFORM_CHANGED) {
- if (Engine::get_singleton()->is_editor_hint()) {
- update_configuration_warning();
- }
- }
+ case NOTIFICATION_ENABLED: {
+ if (is_inside_tree() && (disable_mode == DISABLE_MODE_REMOVE)) {
+ prepare_physics_server();
+ }
+ } break;
+#ifdef TOOLS_ENABLED
+ case NOTIFICATION_LOCAL_TRANSFORM_CHANGED: {
+ if (Engine::get_singleton()->is_editor_hint()) {
+ update_configuration_warnings();
+ }
+ } break;
#endif
+ }
}
void SoftBody3D::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("get_physics_rid"), &SoftBody3D::get_physics_rid);
ClassDB::bind_method(D_METHOD("set_collision_mask", "collision_mask"), &SoftBody3D::set_collision_mask);
ClassDB::bind_method(D_METHOD("get_collision_mask"), &SoftBody3D::get_collision_mask);
@@ -326,15 +321,18 @@ void SoftBody3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_collision_layer", "collision_layer"), &SoftBody3D::set_collision_layer);
ClassDB::bind_method(D_METHOD("get_collision_layer"), &SoftBody3D::get_collision_layer);
- ClassDB::bind_method(D_METHOD("set_collision_mask_bit", "bit", "value"), &SoftBody3D::set_collision_mask_bit);
- ClassDB::bind_method(D_METHOD("get_collision_mask_bit", "bit"), &SoftBody3D::get_collision_mask_bit);
+ ClassDB::bind_method(D_METHOD("set_collision_mask_value", "layer_number", "value"), &SoftBody3D::set_collision_mask_value);
+ ClassDB::bind_method(D_METHOD("get_collision_mask_value", "layer_number"), &SoftBody3D::get_collision_mask_value);
- ClassDB::bind_method(D_METHOD("set_collision_layer_bit", "bit", "value"), &SoftBody3D::set_collision_layer_bit);
- ClassDB::bind_method(D_METHOD("get_collision_layer_bit", "bit"), &SoftBody3D::get_collision_layer_bit);
+ ClassDB::bind_method(D_METHOD("set_collision_layer_value", "layer_number", "value"), &SoftBody3D::set_collision_layer_value);
+ ClassDB::bind_method(D_METHOD("get_collision_layer_value", "layer_number"), &SoftBody3D::get_collision_layer_value);
ClassDB::bind_method(D_METHOD("set_parent_collision_ignore", "parent_collision_ignore"), &SoftBody3D::set_parent_collision_ignore);
ClassDB::bind_method(D_METHOD("get_parent_collision_ignore"), &SoftBody3D::get_parent_collision_ignore);
+ ClassDB::bind_method(D_METHOD("set_disable_mode", "mode"), &SoftBody3D::set_disable_mode);
+ ClassDB::bind_method(D_METHOD("get_disable_mode"), &SoftBody3D::get_disable_mode);
+
ClassDB::bind_method(D_METHOD("get_collision_exceptions"), &SoftBody3D::get_collision_exceptions);
ClassDB::bind_method(D_METHOD("add_collision_exception_with", "body"), &SoftBody3D::add_collision_exception_with);
ClassDB::bind_method(D_METHOD("remove_collision_exception_with", "body"), &SoftBody3D::remove_collision_exception_with);
@@ -348,24 +346,20 @@ void SoftBody3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_linear_stiffness", "linear_stiffness"), &SoftBody3D::set_linear_stiffness);
ClassDB::bind_method(D_METHOD("get_linear_stiffness"), &SoftBody3D::get_linear_stiffness);
- ClassDB::bind_method(D_METHOD("set_areaAngular_stiffness", "areaAngular_stiffness"), &SoftBody3D::set_areaAngular_stiffness);
- ClassDB::bind_method(D_METHOD("get_areaAngular_stiffness"), &SoftBody3D::get_areaAngular_stiffness);
-
- ClassDB::bind_method(D_METHOD("set_volume_stiffness", "volume_stiffness"), &SoftBody3D::set_volume_stiffness);
- ClassDB::bind_method(D_METHOD("get_volume_stiffness"), &SoftBody3D::get_volume_stiffness);
-
ClassDB::bind_method(D_METHOD("set_pressure_coefficient", "pressure_coefficient"), &SoftBody3D::set_pressure_coefficient);
ClassDB::bind_method(D_METHOD("get_pressure_coefficient"), &SoftBody3D::get_pressure_coefficient);
- ClassDB::bind_method(D_METHOD("set_pose_matching_coefficient", "pose_matching_coefficient"), &SoftBody3D::set_pose_matching_coefficient);
- ClassDB::bind_method(D_METHOD("get_pose_matching_coefficient"), &SoftBody3D::get_pose_matching_coefficient);
-
ClassDB::bind_method(D_METHOD("set_damping_coefficient", "damping_coefficient"), &SoftBody3D::set_damping_coefficient);
ClassDB::bind_method(D_METHOD("get_damping_coefficient"), &SoftBody3D::get_damping_coefficient);
ClassDB::bind_method(D_METHOD("set_drag_coefficient", "drag_coefficient"), &SoftBody3D::set_drag_coefficient);
ClassDB::bind_method(D_METHOD("get_drag_coefficient"), &SoftBody3D::get_drag_coefficient);
+ ClassDB::bind_method(D_METHOD("get_point_transform", "point_index"), &SoftBody3D::get_point_transform);
+
+ ClassDB::bind_method(D_METHOD("set_point_pinned", "point_index", "pinned", "attachment_path"), &SoftBody3D::pin_point, DEFVAL(NodePath()));
+ ClassDB::bind_method(D_METHOD("is_point_pinned", "point_index"), &SoftBody3D::is_point_pinned);
+
ClassDB::bind_method(D_METHOD("set_ray_pickable", "ray_pickable"), &SoftBody3D::set_ray_pickable);
ClassDB::bind_method(D_METHOD("is_ray_pickable"), &SoftBody3D::is_ray_pickable);
@@ -377,41 +371,37 @@ void SoftBody3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "simulation_precision", PROPERTY_HINT_RANGE, "1,100,1"), "set_simulation_precision", "get_simulation_precision");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "total_mass", PROPERTY_HINT_RANGE, "0.01,10000,1"), "set_total_mass", "get_total_mass");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "linear_stiffness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_linear_stiffness", "get_linear_stiffness");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "areaAngular_stiffness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_areaAngular_stiffness", "get_areaAngular_stiffness");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volume_stiffness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_volume_stiffness", "get_volume_stiffness");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "pressure_coefficient"), "set_pressure_coefficient", "get_pressure_coefficient");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "damping_coefficient", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_damping_coefficient", "get_damping_coefficient");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "drag_coefficient", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_drag_coefficient", "get_drag_coefficient");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "pose_matching_coefficient", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_pose_matching_coefficient", "get_pose_matching_coefficient");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ray_pickable"), "set_ray_pickable", "is_ray_pickable");
-}
-String SoftBody3D::get_configuration_warning() const {
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "disable_mode", PROPERTY_HINT_ENUM, "Remove,KeepActive"), "set_disable_mode", "get_disable_mode");
- String warning = MeshInstance3D::get_configuration_warning();
+ BIND_ENUM_CONSTANT(DISABLE_MODE_REMOVE);
+ BIND_ENUM_CONSTANT(DISABLE_MODE_KEEP_ACTIVE);
+}
- if (get_mesh().is_null()) {
- if (!warning.empty())
- warning += "\n\n";
+TypedArray<String> SoftBody3D::get_configuration_warnings() const {
+ TypedArray<String> warnings = Node::get_configuration_warnings();
- warning += TTR("This body will be ignored until you set a mesh.");
+ if (get_mesh().is_null()) {
+ warnings.push_back(TTR("This body will be ignored until you set a mesh."));
}
- Transform t = get_transform();
+ Transform3D t = get_transform();
if ((ABS(t.basis.get_axis(0).length() - 1.0) > 0.05 || ABS(t.basis.get_axis(1).length() - 1.0) > 0.05 || ABS(t.basis.get_axis(2).length() - 1.0) > 0.05)) {
- if (!warning.empty())
- warning += "\n\n";
-
- warning += TTR("Size changes to SoftBody3D will be overridden by the physics engine when running.\nChange the size in children collision shapes instead.");
+ warnings.push_back(TTR("Size changes to SoftBody3D will be overridden by the physics engine when running.\nChange the size in children collision shapes instead."));
}
- return warning;
+ return warnings;
}
void SoftBody3D::_update_physics_server() {
- if (!simulation_started)
+ if (!simulation_started) {
return;
+ }
_update_cache_pin_points_datas();
// Submit bone attachment
@@ -425,17 +415,17 @@ void SoftBody3D::_update_physics_server() {
}
void SoftBody3D::_draw_soft_mesh() {
- if (get_mesh().is_null())
+ if (get_mesh().is_null()) {
return;
+ }
if (!rendering_server_handler.is_ready()) {
-
rendering_server_handler.prepare(get_mesh()->get_rid(), 0);
/// Necessary in order to render the mesh correctly (Soft body nodes are in global space)
simulation_started = true;
- call_deferred("set_as_toplevel", true);
- call_deferred("set_transform", Transform());
+ call_deferred(SNAME("set_as_top_level"), true);
+ call_deferred(SNAME("set_transform"), Transform3D());
}
_update_physics_server();
@@ -448,24 +438,23 @@ void SoftBody3D::_draw_soft_mesh() {
}
void SoftBody3D::prepare_physics_server() {
-
+#ifdef TOOLS_ENABLED
if (Engine::get_singleton()->is_editor_hint()) {
-
- if (get_mesh().is_valid())
+ if (get_mesh().is_valid()) {
PhysicsServer3D::get_singleton()->soft_body_set_mesh(physics_rid, get_mesh());
- else
+ } else {
PhysicsServer3D::get_singleton()->soft_body_set_mesh(physics_rid, nullptr);
+ }
return;
}
+#endif
- if (get_mesh().is_valid()) {
-
+ if (get_mesh().is_valid() && (is_enabled() || (disable_mode != DISABLE_MODE_REMOVE))) {
become_mesh_owner();
PhysicsServer3D::get_singleton()->soft_body_set_mesh(physics_rid, get_mesh());
RS::get_singleton()->connect("frame_pre_draw", callable_mp(this, &SoftBody3D::_draw_soft_mesh));
} else {
-
PhysicsServer3D::get_singleton()->soft_body_set_mesh(physics_rid, nullptr);
if (RS::get_singleton()->is_connected("frame_pre_draw", callable_mp(this, &SoftBody3D::_draw_soft_mesh))) {
RS::get_singleton()->disconnect("frame_pre_draw", callable_mp(this, &SoftBody3D::_draw_soft_mesh));
@@ -474,14 +463,15 @@ void SoftBody3D::prepare_physics_server() {
}
void SoftBody3D::become_mesh_owner() {
- if (mesh.is_null())
+ if (mesh.is_null()) {
return;
+ }
if (!mesh_owner) {
mesh_owner = true;
Vector<Ref<Material>> copy_materials;
- copy_materials.append_array(materials);
+ copy_materials.append_array(surface_override_materials);
ERR_FAIL_COND(!mesh->get_surface_count());
@@ -491,18 +481,17 @@ void SoftBody3D::become_mesh_owner() {
Dictionary surface_lods = mesh->surface_get_lods(0);
uint32_t surface_format = mesh->surface_get_format(0);
- surface_format &= ~(Mesh::ARRAY_COMPRESS_NORMAL);
surface_format |= Mesh::ARRAY_FLAG_USE_DYNAMIC_UPDATE;
Ref<ArrayMesh> soft_mesh;
- soft_mesh.instance();
+ soft_mesh.instantiate();
soft_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, surface_arrays, surface_blend_arrays, surface_lods, surface_format);
soft_mesh->surface_set_material(0, mesh->surface_get_material(0));
set_mesh(soft_mesh);
for (int i = copy_materials.size() - 1; 0 <= i; --i) {
- set_surface_material(i, copy_materials[i]);
+ set_surface_override_material(i, copy_materials[i]);
}
}
}
@@ -515,6 +504,7 @@ void SoftBody3D::set_collision_mask(uint32_t p_mask) {
uint32_t SoftBody3D::get_collision_mask() const {
return collision_mask;
}
+
void SoftBody3D::set_collision_layer(uint32_t p_layer) {
collision_layer = p_layer;
PhysicsServer3D::get_singleton()->soft_body_set_collision_layer(physics_rid, p_layer);
@@ -524,30 +514,62 @@ uint32_t SoftBody3D::get_collision_layer() const {
return collision_layer;
}
-void SoftBody3D::set_collision_mask_bit(int p_bit, bool p_value) {
+void SoftBody3D::set_collision_layer_value(int p_layer_number, bool p_value) {
+ ERR_FAIL_COND_MSG(p_layer_number < 1, "Collision layer number must be between 1 and 32 inclusive.");
+ ERR_FAIL_COND_MSG(p_layer_number > 32, "Collision layer number must be between 1 and 32 inclusive.");
+ uint32_t collision_layer = get_collision_layer();
+ if (p_value) {
+ collision_layer |= 1 << (p_layer_number - 1);
+ } else {
+ collision_layer &= ~(1 << (p_layer_number - 1));
+ }
+ set_collision_layer(collision_layer);
+}
+
+bool SoftBody3D::get_collision_layer_value(int p_layer_number) const {
+ ERR_FAIL_COND_V_MSG(p_layer_number < 1, false, "Collision layer number must be between 1 and 32 inclusive.");
+ ERR_FAIL_COND_V_MSG(p_layer_number > 32, false, "Collision layer number must be between 1 and 32 inclusive.");
+ return get_collision_layer() & (1 << (p_layer_number - 1));
+}
+
+void SoftBody3D::set_collision_mask_value(int p_layer_number, bool p_value) {
+ ERR_FAIL_COND_MSG(p_layer_number < 1, "Collision layer number must be between 1 and 32 inclusive.");
+ ERR_FAIL_COND_MSG(p_layer_number > 32, "Collision layer number must be between 1 and 32 inclusive.");
uint32_t mask = get_collision_mask();
- if (p_value)
- mask |= 1 << p_bit;
- else
- mask &= ~(1 << p_bit);
+ if (p_value) {
+ mask |= 1 << (p_layer_number - 1);
+ } else {
+ mask &= ~(1 << (p_layer_number - 1));
+ }
set_collision_mask(mask);
}
-bool SoftBody3D::get_collision_mask_bit(int p_bit) const {
- return get_collision_mask() & (1 << p_bit);
+bool SoftBody3D::get_collision_mask_value(int p_layer_number) const {
+ ERR_FAIL_COND_V_MSG(p_layer_number < 1, false, "Collision layer number must be between 1 and 32 inclusive.");
+ ERR_FAIL_COND_V_MSG(p_layer_number > 32, false, "Collision layer number must be between 1 and 32 inclusive.");
+ return get_collision_mask() & (1 << (p_layer_number - 1));
}
-void SoftBody3D::set_collision_layer_bit(int p_bit, bool p_value) {
- uint32_t layer = get_collision_layer();
- if (p_value)
- layer |= 1 << p_bit;
- else
- layer &= ~(1 << p_bit);
- set_collision_layer(layer);
+void SoftBody3D::set_disable_mode(DisableMode p_mode) {
+ if (disable_mode == p_mode) {
+ return;
+ }
+
+ bool inside_tree = is_inside_tree();
+
+ if (inside_tree && (disable_mode == DISABLE_MODE_REMOVE)) {
+ prepare_physics_server();
+ }
+
+ disable_mode = p_mode;
+
+ if (inside_tree && (disable_mode == DISABLE_MODE_REMOVE)) {
+ prepare_physics_server();
+ }
}
-bool SoftBody3D::get_collision_layer_bit(int p_bit) const {
- return get_collision_layer() & (1 << p_bit);
+SoftBody3D::DisableMode SoftBody3D::get_disable_mode() const {
+ return disable_mode;
}
void SoftBody3D::set_parent_collision_ignore(const NodePath &p_parent_collision_ignore) {
@@ -573,8 +595,7 @@ Array SoftBody3D::get_collision_exceptions() {
List<RID> exceptions;
PhysicsServer3D::get_singleton()->soft_body_get_collision_exceptions(physics_rid, &exceptions);
Array ret;
- for (List<RID>::Element *E = exceptions.front(); E; E = E->next()) {
- RID body = E->get();
+ for (const RID &body : exceptions) {
ObjectID instance_id = PhysicsServer3D::get_singleton()->body_get_object_instance_id(body);
Object *obj = ObjectDB::get_instance(instance_id);
PhysicsBody3D *physics_body = Object::cast_to<PhysicsBody3D>(obj);
@@ -621,34 +642,10 @@ real_t SoftBody3D::get_linear_stiffness() {
return PhysicsServer3D::get_singleton()->soft_body_get_linear_stiffness(physics_rid);
}
-void SoftBody3D::set_areaAngular_stiffness(real_t p_areaAngular_stiffness) {
- PhysicsServer3D::get_singleton()->soft_body_set_areaAngular_stiffness(physics_rid, p_areaAngular_stiffness);
-}
-
-real_t SoftBody3D::get_areaAngular_stiffness() {
- return PhysicsServer3D::get_singleton()->soft_body_get_areaAngular_stiffness(physics_rid);
-}
-
-void SoftBody3D::set_volume_stiffness(real_t p_volume_stiffness) {
- PhysicsServer3D::get_singleton()->soft_body_set_volume_stiffness(physics_rid, p_volume_stiffness);
-}
-
-real_t SoftBody3D::get_volume_stiffness() {
- return PhysicsServer3D::get_singleton()->soft_body_get_volume_stiffness(physics_rid);
-}
-
real_t SoftBody3D::get_pressure_coefficient() {
return PhysicsServer3D::get_singleton()->soft_body_get_pressure_coefficient(physics_rid);
}
-void SoftBody3D::set_pose_matching_coefficient(real_t p_pose_matching_coefficient) {
- PhysicsServer3D::get_singleton()->soft_body_set_pose_matching_coefficient(physics_rid, p_pose_matching_coefficient);
-}
-
-real_t SoftBody3D::get_pose_matching_coefficient() {
- return PhysicsServer3D::get_singleton()->soft_body_get_pose_matching_coefficient(physics_rid);
-}
-
void SoftBody3D::set_pressure_coefficient(real_t p_pressure_coefficient) {
PhysicsServer3D::get_singleton()->soft_body_set_pressure_coefficient(physics_rid, p_pressure_coefficient);
}
@@ -691,25 +688,16 @@ bool SoftBody3D::is_point_pinned(int p_point_index) const {
}
void SoftBody3D::set_ray_pickable(bool p_ray_pickable) {
-
ray_pickable = p_ray_pickable;
_update_pickable();
}
bool SoftBody3D::is_ray_pickable() const {
-
return ray_pickable;
}
SoftBody3D::SoftBody3D() :
- physics_rid(PhysicsServer3D::get_singleton()->soft_body_create()),
- mesh_owner(false),
- collision_mask(1),
- collision_layer(1),
- simulation_started(false),
- pinned_points_cache_dirty(true),
- ray_pickable(true) {
-
+ physics_rid(PhysicsServer3D::get_singleton()->soft_body_create()) {
PhysicsServer3D::get_singleton()->body_attach_object_instance_id(physics_rid, get_instance_id());
}
@@ -730,19 +718,19 @@ void SoftBody3D::_make_cache_dirty() {
}
void SoftBody3D::_update_cache_pin_points_datas() {
- if (!pinned_points_cache_dirty)
+ if (!pinned_points_cache_dirty) {
return;
+ }
pinned_points_cache_dirty = false;
PinnedPoint *w = pinned_points.ptrw();
for (int i = pinned_points.size() - 1; 0 <= i; --i) {
-
if (!w[i].spatial_attachment_path.is_empty()) {
w[i].spatial_attachment = Object::cast_to<Node3D>(get_node(w[i].spatial_attachment_path));
}
if (!w[i].spatial_attachment) {
- ERR_PRINT("Node3D node not defined in the pinned point, Softbody undefined behaviour!");
+ ERR_PRINT("Node3D node not defined in the pinned point, this is undefined behavior for SoftBody3D!");
}
}
}
@@ -754,7 +742,6 @@ void SoftBody3D::_pin_point_on_physics_server(int p_point_index, bool pin) {
void SoftBody3D::_add_pinned_point(int p_point_index, const NodePath &p_spatial_attachment_path) {
SoftBody3D::PinnedPoint *pinned_point;
if (-1 == _get_pinned_point(p_point_index, pinned_point)) {
-
// Create new
PinnedPoint pp;
pp.point_index = p_point_index;
@@ -768,7 +755,6 @@ void SoftBody3D::_add_pinned_point(int p_point_index, const NodePath &p_spatial_
pinned_points.push_back(pp);
} else {
-
pinned_point->point_index = p_point_index;
pinned_point->spatial_attachment_path = p_spatial_attachment_path;
@@ -780,19 +766,22 @@ void SoftBody3D::_add_pinned_point(int p_point_index, const NodePath &p_spatial_
}
void SoftBody3D::_reset_points_offsets() {
-
- if (!Engine::get_singleton()->is_editor_hint())
+ if (!Engine::get_singleton()->is_editor_hint()) {
return;
+ }
const PinnedPoint *r = pinned_points.ptr();
PinnedPoint *w = pinned_points.ptrw();
for (int i = pinned_points.size() - 1; 0 <= i; --i) {
+ if (!r[i].spatial_attachment) {
+ if (!r[i].spatial_attachment_path.is_empty() && has_node(r[i].spatial_attachment_path)) {
+ w[i].spatial_attachment = Object::cast_to<Node3D>(get_node(r[i].spatial_attachment_path));
+ }
+ }
- if (!r[i].spatial_attachment)
- w[i].spatial_attachment = Object::cast_to<Node3D>(get_node(r[i].spatial_attachment_path));
-
- if (!r[i].spatial_attachment)
+ if (!r[i].spatial_attachment) {
continue;
+ }
w[i].offset = (r[i].spatial_attachment->get_global_transform().affine_inverse() * get_global_transform()).xform(PhysicsServer3D::get_singleton()->soft_body_get_point_global_position(physics_rid, r[i].point_index));
}