Physics blob demo assertion

Hello,

I ported the Python Softbdy Traingles demo to C++ because I’d like to use it as a basis to create a softbody ball (I’m using a solid in my game at the moment for simplicity). When I run the demo I have two problems - one is that I get an assertion:

Assertion failed: get_num_geoms() == 2 at line 213 of c:\buildslave\dev_sdk_win_
amd64\build\panda3d\panda\src\bullet\bulletDebugNode.cxx

And also no wireframe despite having it enabled. I maye have screwed that up somehow. Code is below and runs in Release x64 for devel.


#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"
 
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);
//    framework->set_window_title("Bullet Physics");
 
    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(0.1);
	bodyNode->get_cfg().set_dynamic_friction_coefficient(1);
	bodyNode->get_cfg().set_damping_coefficient(0.001);
	bodyNode->get_cfg().set_pressure_coefficient(1500);
	bodyNode->set_total_mass(30,true);
	bodyNode->set_pose(true,false);

	NodePath bodyNP = window->get_render().attach_new_node(bodyNode);
	bodyNP.set_pos(15,0,12);
	bodyNP.set_h(90.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");
	visNode->add_geom(geom);
	NodePath visNP = bodyNP.attach_new_node(visNode);
	//visNode = new BulletDebugNode("Debug");
	
	PT(BulletPlaneShape) floor_shape = new BulletPlaneShape(LVecBase3f(0, 0, 1), 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->show_bounding_boxes(true);
	visNode->show_constraints(true);
	visNode->show_normals(true);
	visNode->show_wireframe(true);

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


    PT(GenericAsyncTask) task;
    task = new GenericAsyncTask("Scene update", &update_scene, (void*) NULL);
    task_mgr->add(task);
 
    framework.main_loop();
    framework.close_framework();
 
    return (0);
}

You are not supposed to add or remove geom from the BulletDebugnode yourself. By default it has two geoms, one for lines and one for triangles.

   PT(BulletDebugNode) visNode = new BulletDebugNode("EllipsoidVisual");
   visNode->add_geom(geom);

For visualisation of a soft body you might want to use an empty GeomNode and add your geom there.

Thanks enn0x, rdb already advised me on IRC that I shouldn’t add a geom to the debug node. I should’ve marked this solved.