diff options
Diffstat (limited to 'modules/bullet/soft_body_bullet.cpp')
-rw-r--r-- | modules/bullet/soft_body_bullet.cpp | 70 |
1 files changed, 43 insertions, 27 deletions
diff --git a/modules/bullet/soft_body_bullet.cpp b/modules/bullet/soft_body_bullet.cpp index bbbb0e7851..c0ffffa364 100644 --- a/modules/bullet/soft_body_bullet.cpp +++ b/modules/bullet/soft_body_bullet.cpp @@ -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) {} @@ -70,7 +71,7 @@ void SoftBodyBullet::update_rendering_server(RenderingServerHandler *p_rendering 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(RenderingServerHandler *p_rendering 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; } @@ -187,22 +191,24 @@ void SoftBodyBullet::get_node_position(int p_node_index, Vector3 &r_position) co } } -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; } } @@ -289,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 @@ -363,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() { @@ -413,20 +421,28 @@ 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); + pinned_nodes.remove_at(id); } } |