summaryrefslogtreecommitdiff
path: root/modules/bullet/soft_body_bullet.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'modules/bullet/soft_body_bullet.cpp')
-rw-r--r--modules/bullet/soft_body_bullet.cpp141
1 files changed, 66 insertions, 75 deletions
diff --git a/modules/bullet/soft_body_bullet.cpp b/modules/bullet/soft_body_bullet.cpp
index 6794d6c313..3a2370ff31 100644
--- a/modules/bullet/soft_body_bullet.cpp
+++ b/modules/bullet/soft_body_bullet.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 */
@@ -32,9 +32,10 @@
#include "bullet_types_converter.h"
#include "bullet_utilities.h"
-#include "scene/3d/soft_body_3d.h"
#include "space_bullet.h"
+#include "servers/rendering_server.h"
+
SoftBodyBullet::SoftBodyBullet() :
CollisionObjectBullet(CollisionObjectBullet::TYPE_SOFT_BODY) {}
@@ -65,12 +66,12 @@ void SoftBodyBullet::on_enter_area(AreaBullet *p_area) {}
void SoftBodyBullet::on_exit_area(AreaBullet *p_area) {}
-void SoftBodyBullet::update_rendering_server(SoftBodyRenderingServerHandler *p_rendering_server_handler) {
+void SoftBodyBullet::update_rendering_server(RenderingServerHandler *p_rendering_server_handler) {
if (!bt_soft_body) {
return;
}
- /// Update visual server vertices
+ /// Update rendering server vertices
const btSoftBody::tNodeArray &nodes(bt_soft_body->m_nodes);
const int nodes_count = nodes.size();
@@ -105,24 +106,27 @@ void SoftBodyBullet::update_rendering_server(SoftBodyRenderingServerHandler *p_r
p_rendering_server_handler->set_aabb(aabb);
}
-void SoftBodyBullet::set_soft_mesh(const Ref<Mesh> &p_mesh) {
- if (p_mesh.is_null()) {
- soft_mesh.unref();
- } else {
- soft_mesh = p_mesh;
- }
+void SoftBodyBullet::set_soft_mesh(RID p_mesh) {
+ destroy_soft_body();
+
+ soft_mesh = p_mesh;
if (soft_mesh.is_null()) {
- destroy_soft_body();
return;
}
- Array arrays = soft_mesh->surface_get_arrays(0);
- ERR_FAIL_COND(!(soft_mesh->surface_get_format(0) & RS::ARRAY_FORMAT_INDEX));
- set_trimesh_body_shape(arrays[RS::ARRAY_INDEX], arrays[RS::ARRAY_VERTEX]);
+ Array arrays = RenderingServer::get_singleton()->mesh_surface_get_arrays(soft_mesh, 0);
+ ERR_FAIL_COND(arrays.is_empty());
+
+ bool success = set_trimesh_body_shape(arrays[RS::ARRAY_INDEX], arrays[RS::ARRAY_VERTEX]);
+ if (!success) {
+ destroy_soft_body();
+ }
}
void SoftBodyBullet::destroy_soft_body() {
+ soft_mesh = RID();
+
if (!bt_soft_body) {
return;
}
@@ -136,12 +140,30 @@ void SoftBodyBullet::destroy_soft_body() {
bt_soft_body = nullptr;
}
-void SoftBodyBullet::set_soft_transform(const Transform &p_transform) {
+void SoftBodyBullet::set_soft_transform(const Transform3D &p_transform) {
reset_all_node_positions();
move_all_nodes(p_transform);
}
-void SoftBodyBullet::move_all_nodes(const Transform &p_transform) {
+AABB SoftBodyBullet::get_bounds() const {
+ if (!bt_soft_body) {
+ return AABB();
+ }
+
+ btVector3 aabb_min;
+ btVector3 aabb_max;
+ bt_soft_body->getAabb(aabb_min, aabb_max);
+
+ btVector3 size(aabb_max - aabb_min);
+
+ AABB aabb;
+ B_TO_G(aabb_min, aabb.position);
+ B_TO_G(size, aabb.size);
+
+ return aabb;
+}
+
+void SoftBodyBullet::move_all_nodes(const Transform3D &p_transform) {
if (!bt_soft_body) {
return;
}
@@ -169,41 +191,24 @@ void SoftBodyBullet::get_node_position(int p_node_index, Vector3 &r_position) co
}
}
-void SoftBodyBullet::get_node_offset(int p_node_index, Vector3 &r_offset) const {
- if (soft_mesh.is_null()) {
- return;
- }
-
- Array arrays = soft_mesh->surface_get_arrays(0);
- Vector<Vector3> vertices(arrays[RS::ARRAY_VERTEX]);
-
- if (0 <= p_node_index && vertices.size() > p_node_index) {
- r_offset = vertices[p_node_index];
- }
-}
-
-void SoftBodyBullet::get_node_offset(int p_node_index, btVector3 &r_offset) const {
- Vector3 off;
- get_node_offset(p_node_index, off);
- G_TO_B(off, r_offset);
-}
-
-void SoftBodyBullet::set_node_mass(int node_index, btScalar p_mass) {
+void SoftBodyBullet::set_node_mass(int p_node_index, btScalar p_mass) {
if (0 >= p_mass) {
- pin_node(node_index);
+ pin_node(p_node_index);
} else {
- unpin_node(node_index);
+ unpin_node(p_node_index);
}
if (bt_soft_body) {
- bt_soft_body->setMass(node_index, p_mass);
+ ERR_FAIL_INDEX(p_node_index, bt_soft_body->m_nodes.size());
+ bt_soft_body->setMass(p_node_index, p_mass);
}
}
-btScalar SoftBodyBullet::get_node_mass(int node_index) const {
+btScalar SoftBodyBullet::get_node_mass(int p_node_index) const {
if (bt_soft_body) {
- return bt_soft_body->getMass(node_index);
+ ERR_FAIL_INDEX_V(p_node_index, bt_soft_body->m_nodes.size(), 1);
+ return bt_soft_body->getMass(p_node_index);
} else {
- return -1 == search_node_pinned(node_index) ? 1 : 0;
+ return -1 == search_node_pinned(p_node_index) ? 1 : 0;
}
}
@@ -259,20 +264,6 @@ void SoftBodyBullet::set_linear_stiffness(real_t p_val) {
}
}
-void SoftBodyBullet::set_areaAngular_stiffness(real_t p_val) {
- areaAngular_stiffness = p_val;
- if (bt_soft_body) {
- mat0->m_kAST = areaAngular_stiffness;
- }
-}
-
-void SoftBodyBullet::set_volume_stiffness(real_t p_val) {
- volume_stiffness = p_val;
- if (bt_soft_body) {
- mat0->m_kVST = volume_stiffness;
- }
-}
-
void SoftBodyBullet::set_simulation_precision(int p_val) {
simulation_precision = p_val;
if (bt_soft_body) {
@@ -290,13 +281,6 @@ void SoftBodyBullet::set_pressure_coefficient(real_t p_val) {
}
}
-void SoftBodyBullet::set_pose_matching_coefficient(real_t p_val) {
- pose_matching_coefficient = p_val;
- if (bt_soft_body) {
- bt_soft_body->m_cfg.kMT = pose_matching_coefficient;
- }
-}
-
void SoftBodyBullet::set_damping_coefficient(real_t p_val) {
damping_coefficient = p_val;
if (bt_soft_body) {
@@ -311,15 +295,15 @@ void SoftBodyBullet::set_drag_coefficient(real_t p_val) {
}
}
-void SoftBodyBullet::set_trimesh_body_shape(Vector<int> p_indices, Vector<Vector3> p_vertices) {
- /// Assert the current soft body is destroyed
- destroy_soft_body();
+bool SoftBodyBullet::set_trimesh_body_shape(Vector<int> p_indices, Vector<Vector3> p_vertices) {
+ ERR_FAIL_COND_V(p_indices.is_empty(), false);
+ ERR_FAIL_COND_V(p_vertices.is_empty(), false);
- /// Parse visual server indices to physical indices.
- /// Merge all overlapping vertices and create a map of physical vertices to visual server
+ /// Parse rendering server indices to physical indices.
+ /// Merge all overlapping vertices and create a map of physical vertices to rendering server
{
- /// This is the map of visual server indices to physics indices (So it's the inverse of idices_map), Thanks to it I don't need make a heavy search in the indices_map
+ /// This is the map of rendering server indices to physics indices (So it's the inverse of idices_map), Thanks to it I don't need make a heavy search in the indices_map
Vector<int> vs_indices_to_physics_table;
{ // Map vertices
@@ -336,7 +320,7 @@ void SoftBodyBullet::set_trimesh_body_shape(Vector<int> p_indices, Vector<Vector
Map<Vector3, int>::Element *e = unique_vertices.find(p_vertices_read[vs_vertex_index]);
int vertex_id;
if (e) {
- // Already rxisting
+ // Already existing
vertex_id = e->value();
} else {
// Create new one
@@ -385,6 +369,8 @@ void SoftBodyBullet::set_trimesh_body_shape(Vector<int> p_indices, Vector<Vector
bt_soft_body = btSoftBodyHelpers::CreateFromTriMesh(fake_world_info, &bt_vertices[0], &bt_triangles[0], triangles_size, false);
setup_soft_body();
}
+
+ return true;
}
void SoftBodyBullet::setup_soft_body() {
@@ -409,8 +395,6 @@ void SoftBodyBullet::setup_soft_body() {
bt_soft_body->generateBendingConstraints(2, mat0);
mat0->m_kLST = linear_stiffness;
- mat0->m_kAST = areaAngular_stiffness;
- mat0->m_kVST = volume_stiffness;
// Clusters allow to have Soft vs Soft collision but doesn't work well right now
@@ -430,7 +414,6 @@ void SoftBodyBullet::setup_soft_body() {
bt_soft_body->m_cfg.kDP = damping_coefficient;
bt_soft_body->m_cfg.kDG = drag_coefficient;
bt_soft_body->m_cfg.kPR = pressure_coefficient;
- bt_soft_body->m_cfg.kMT = pose_matching_coefficient;
bt_soft_body->setTotalMass(total_mass);
btSoftBodyHelpers::ReoptimizeLinkOrder(bt_soft_body);
@@ -438,17 +421,25 @@ void SoftBodyBullet::setup_soft_body() {
// Set pinned nodes
for (int i = pinned_nodes.size() - 1; 0 <= i; --i) {
- bt_soft_body->setMass(pinned_nodes[i], 0);
+ const int node_index = pinned_nodes[i];
+ ERR_CONTINUE(0 > node_index || bt_soft_body->m_nodes.size() <= node_index);
+ bt_soft_body->setMass(node_index, 0);
}
}
void SoftBodyBullet::pin_node(int p_node_index) {
+ if (bt_soft_body) {
+ ERR_FAIL_INDEX(p_node_index, bt_soft_body->m_nodes.size());
+ }
if (-1 == search_node_pinned(p_node_index)) {
pinned_nodes.push_back(p_node_index);
}
}
void SoftBodyBullet::unpin_node(int p_node_index) {
+ if (bt_soft_body) {
+ ERR_FAIL_INDEX(p_node_index, bt_soft_body->m_nodes.size());
+ }
const int id = search_node_pinned(p_node_index);
if (-1 != id) {
pinned_nodes.remove(id);