Exemple #1
0
void SoftBodyBullet::reload_soft_body() {

	destroy_soft_body();
	create_soft_body();

	if (bt_soft_body) {

		// TODO the softbody set new transform considering the current transform as center of world
		// like if it's local transform, so I must fix this by setting nwe transform considering the old
		btTransform bt_trans;
		G_TO_B(transform, bt_trans);
		bt_soft_body->transform(bt_trans);

		bt_soft_body->generateBendingConstraints(2, mat0);
		mat0->m_kAST = stiffness;
		mat0->m_kLST = stiffness;
		mat0->m_kVST = stiffness;

		bt_soft_body->m_cfg.piterations = simulation_precision;
		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->setTotalMass(mass);
	}
	if (space) {
		// TODO remove this please
		space->add_soft_body(this);
	}
}
Exemple #2
0
void SoftBodyBullet::set_soft_mesh(const Ref<Mesh> &p_mesh) {

	if (p_mesh.is_null())
		soft_mesh.unref();
	else
		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) & VS::ARRAY_FORMAT_INDEX));
	set_trimesh_body_shape(arrays[VS::ARRAY_INDEX], arrays[VS::ARRAY_VERTEX]);
}
Exemple #3
0
void SoftBodyBullet::set_trimesh_body_shape(PoolVector<int> p_indices, PoolVector<Vector3> p_vertices) {
	/// Assert the current soft body is destroyed
	destroy_soft_body();

	/// Parse visual server indices to physical indices.
	/// Merge all overlapping vertices and create a map of physical vertices to visual 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
		Vector<int> vs_indices_to_physics_table;

		{ // Map vertices
			indices_table.resize(0);

			int index = 0;
			Map<Vector3, int> unique_vertices;

			const int vs_vertices_size(p_vertices.size());

			PoolVector<Vector3>::Read p_vertices_read = p_vertices.read();

			for (int vs_vertex_index = 0; vs_vertex_index < vs_vertices_size; ++vs_vertex_index) {

				Map<Vector3, int>::Element *e = unique_vertices.find(p_vertices_read[vs_vertex_index]);
				int vertex_id;
				if (e) {
					// Already rxisting
					vertex_id = e->value();
				} else {
					// Create new one
					unique_vertices[p_vertices_read[vs_vertex_index]] = vertex_id = index++;
					indices_table.push_back(Vector<int>());
				}

				indices_table.write[vertex_id].push_back(vs_vertex_index);
				vs_indices_to_physics_table.push_back(vertex_id);
			}
		}

		const int indices_map_size(indices_table.size());

		Vector<btScalar> bt_vertices;

		{ // Parse vertices to bullet

			bt_vertices.resize(indices_map_size * 3);
			PoolVector<Vector3>::Read p_vertices_read = p_vertices.read();

			for (int i = 0; i < indices_map_size; ++i) {
				bt_vertices.write[3 * i + 0] = p_vertices_read[indices_table[i][0]].x;
				bt_vertices.write[3 * i + 1] = p_vertices_read[indices_table[i][0]].y;
				bt_vertices.write[3 * i + 2] = p_vertices_read[indices_table[i][0]].z;
			}
		}

		Vector<int> bt_triangles;
		const int triangles_size(p_indices.size() / 3);

		{ // Parse indices

			bt_triangles.resize(triangles_size * 3);

			PoolVector<int>::Read p_indices_read = p_indices.read();

			for (int i = 0; i < triangles_size; ++i) {
				bt_triangles.write[3 * i + 0] = vs_indices_to_physics_table[p_indices_read[3 * i + 2]];
				bt_triangles.write[3 * i + 1] = vs_indices_to_physics_table[p_indices_read[3 * i + 1]];
				bt_triangles.write[3 * i + 2] = vs_indices_to_physics_table[p_indices_read[3 * i + 0]];
			}
		}

		btSoftBodyWorldInfo fake_world_info;
		bt_soft_body = btSoftBodyHelpers::CreateFromTriMesh(fake_world_info, &bt_vertices[0], &bt_triangles[0], triangles_size, false);
		setup_soft_body();
	}
}