Bullet Softbody collision

Hello,

I have the following code based on the manual soft body ellipsoid example. The problem is it falls through the floor when moved, if you press the “w” key to apply velocity a few times. I’m not sure how I go about fixing that. I wondered if anyone had any ideas?

#include "pandaFramework.h"
#include "windowFramework.h"
#include "nodePath.h"
#include "clockObject.h"
 
#include "asyncTask.h"
#include "genericAsyncTask.h"
 
#include "bulletWorld.h"
#include "bulletPlaneShape.h"
#include "bulletBoxShape.h"
#include "bulletSoftBodyWorldInfo.h"
#include "bulletSoftBodyMaterial.h"
#include "bulletSoftBodyConfig.h"
#include "GeomVertexFormat.h"
#include "bulletHelper.h"

void Move(const Event* event, void* data);
 
BulletWorld *get_physics_world() {
    // physics_world is supposed to be an global variable,
    // but declaring global variables is not cool
    // for good programmers lol, instead, should use static keyword.
    static BulletWorld *physics_world = new BulletWorld();
    return physics_world;
}
 
AsyncTask::DoneStatus update_scene(GenericAsyncTask* task, void* data) {
    // Get dt (from Python example) and apply to do_physics(float, int, int);
    ClockObject *co = ClockObject::get_global_clock();
    get_physics_world()->do_physics(co->get_dt(), 10, 1.0 / 180.0);
 
    return AsyncTask::DS_cont;
}
 
int main(int argc, char *argv[]) {
    // All variables.
    PandaFramework framework;
    PT(WindowFramework) window;
    NodePath camera;
    PT(AsyncTaskManager) task_mgr;
 
    // Init everything :D
    framework.open_framework(argc, argv);
    window = framework.open_window();
    window->enable_keyboard();
    window->setup_trackball();
 
    camera = window->get_camera_group();
    task_mgr = AsyncTaskManager::get_global_ptr();
 
    // Make physics simulation.
    // Static world stuff.
    get_physics_world()->set_gravity(0, 0, -9.81f);

	 BulletSoftBodyWorldInfo info = get_physics_world()->get_world_info();
	 info.set_air_density(1.2);
	 info.set_water_density(0);
	 info.set_water_normal(LVector3(0,0,0));

	LPoint3 centre = LPoint3(0,0,0);
	LVector3 radius = LVector3(1,1,1);// * 1.5;

	PT(BulletSoftBodyNode) bodyNode = BulletSoftBodyNode::make_ellipsoid(info,centre,radius,128);
	bodyNode->set_name("Ellipsoid");
	BulletSoftBodyMaterial material = bodyNode->get_material(0);
	material.setLinearStiffness(1);
	bodyNode->get_cfg().set_dynamic_friction_coefficient(1);
	bodyNode->get_cfg().set_damping_coefficient(0.001);
	bodyNode->get_cfg().set_pressure_coefficient(2500);

	bodyNode->get_cfg().set_collision_flag(BulletSoftBodyConfig::CF_sdf_rigid_soft,true);
	bodyNode->get_cfg().set_collision_flag(BulletSoftBodyConfig::CF_cluster_soft_soft,true);
	bodyNode->get_cfg().set_collision_flag(BulletSoftBodyConfig::CF_cluster_self,false);

	bodyNode->set_total_mass(25,false);
	bodyNode->set_pose(true,false);
	bodyNode->generate_clusters(8);
	bodyNode->cluster_com(0);

	//bodynode getters
	float mass = bodyNode->get_mass(0);
	int clusters = bodyNode->get_num_clusters();
	int materials = bodyNode->get_num_materials();
	int nodes = bodyNode->get_num_nodes();
	float totalMass = bodyNode->get_total_mass();
	float volume = bodyNode->get_volume();

	printf("mass: %f\n",mass);
	printf("clusters: %d\n",clusters);
	printf("materials: %f\n",materials);
	printf("nodes: %f\n",nodes);
	printf("total mass: %f\n",totalMass);
	printf("volume: %f\n",volume);

	NodePath bodyNP = window->get_render().attach_new_node(bodyNode);
	bodyNP.set_pos(0,0,0);
	bodyNP.set_h(0.0);
	get_physics_world()->attach_soft_body(bodyNode);

	static const GeomVertexFormat* fmt = GeomVertexFormat::get_v3n3t2();
	PT(Geom) geom = BulletHelper::make_geom_from_faces(bodyNode,fmt,true);
	bodyNode->link_geom(geom);
	
	PT(BulletDebugNode) visNode = new BulletDebugNode("EllipsoidVisual");
	NodePath visNP = bodyNP.attach_new_node(visNode);
	
	PT(BulletPlaneShape) floor_shape = new BulletPlaneShape(LVecBase3f(0, 0, 10), 1);
    PT(BulletRigidBodyNode) floor_rigid_node = new BulletRigidBodyNode("Ground");
 
    floor_rigid_node->add_shape(floor_shape);
 
    NodePath np_ground = window->get_render().attach_new_node(floor_rigid_node);
    np_ground.set_pos(0, 0, -2);
    get_physics_world()->attach_rigid_body(floor_rigid_node);
	visNode->add_child(floor_rigid_node);
 
    visNode->show_bounding_boxes(false);
	visNode->show_constraints(true);
	visNode->show_normals(true);
	visNode->show_wireframe(true);

	get_physics_world()->set_debug_node(visNode);
	visNP.show();
	np_ground.show();

	visNP.set_collide_mask(CollideMask::all_on());
	bodyNP.set_collide_mask(CollideMask::all_on());
	np_ground.set_collide_mask(CollideMask::all_on());

    PT(GenericAsyncTask) task;
    task = new GenericAsyncTask("Scene update", &update_scene, (void*) NULL);
    task_mgr->add(task);

	framework.define_key("w", "forward", Move,  bodyNode);
 
    framework.main_loop();
    framework.close_framework();
 
    return (0);
}

void Move(const Event* event, void* data)
{
	BulletSoftBodyNode* node = static_cast<BulletSoftBodyNode*>(data);
	node->set_velocity(LVector3f(0,0,10));
}